]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(set_iterator_to_next): After delivering a character
[gnu-emacs] / src / xdisp.c
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.
4
5 This file is part of GNU Emacs.
6
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.
11
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.
16
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. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
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.
30
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.).
38
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.
48
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! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
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.
71
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.
81
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.
87
88
89 Direct operations.
90
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.
95
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.
102
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.
108
109
110 Desired matrices.
111
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.
118
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.
125
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.
132
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.
139
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.
147
148
149 Frame matrices.
150
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.
157
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. */
169
170 #include <config.h>
171 #include <stdio.h>
172 #ifdef STDC_HEADERS
173 #include <stdlib.h>
174 #endif
175 #include "lisp.h"
176 #include "frame.h"
177 #include "window.h"
178 #include "termchar.h"
179 #include "dispextern.h"
180 #include "buffer.h"
181 #include "charset.h"
182 #include "indent.h"
183 #include "commands.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "keyboard.h"
189 #include "coding.h"
190 #include "process.h"
191 #include "region-cache.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196
197 #define min(a, b) ((a) < (b) ? (a) : (b))
198 #define max(a, b) ((a) > (b) ? (a) : (b))
199
200 #define INFINITY 10000000
201
202 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
203 extern void set_frame_menubar ();
204 extern int pending_menu_activation;
205 #endif
206
207 extern int interrupt_input;
208 extern int command_loop_level;
209
210 extern int minibuffer_auto_raise;
211
212 extern Lisp_Object Qface;
213
214 extern Lisp_Object Voverriding_local_map;
215 extern Lisp_Object Voverriding_local_map_menu_flag;
216 extern Lisp_Object Qmenu_item;
217
218 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
219 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
220 Lisp_Object Qredisplay_end_trigger_functions;
221 Lisp_Object Qinhibit_point_motion_hooks;
222 Lisp_Object QCeval, QCwhen;
223 Lisp_Object Qfontified;
224
225 /* Functions called to fontify regions of text. */
226
227 Lisp_Object Vfontification_functions;
228 Lisp_Object Qfontification_functions;
229
230 /* Non-zero means draw toolbar buttons raised when the mouse moves
231 over them. */
232
233 int auto_raise_toolbar_buttons_p;
234
235 /* Margin around toolbar buttons in pixels. */
236
237 int toolbar_button_margin;
238
239 /* Thickness of shadow to draw around toolbar buttons. */
240
241 int toolbar_button_relief;
242
243 /* Non-zero means automatically resize toolbars so that all toolbar
244 items are visible, and no blank lines remain. */
245
246 int auto_resize_toolbars_p;
247
248 /* Non-nil means don't actually do any redisplay. */
249
250 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
251
252 /* Names of text properties relevant for redisplay. */
253
254 Lisp_Object Qdisplay, Qrelative_width, Qwidth, Qalign_to;
255 extern Lisp_Object Qface, Qinvisible, Qimage;
256
257 /* Symbols used in text property values. */
258
259 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
260 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qheight, Qraise;
261
262 /* Name of the variable controlling the highlighting of trailing
263 whitespace. The implementation uses find_symbol_value to get its
264 value. */
265
266 Lisp_Object Qshow_trailing_whitespace;
267
268 /* Name of the face used to highlight trailing whitespace. */
269
270 Lisp_Object Qtrailing_whitespace;
271
272 /* The symbol `image' which is the car of the lists used to represent
273 images in Lisp. */
274
275 Lisp_Object Qimage;
276
277 /* Non-zero means print newline to stdout before next mini-buffer
278 message. */
279
280 int noninteractive_need_newline;
281
282 /* Non-zero means print newline to message log before next message. */
283
284 static int message_log_need_newline;
285
286 \f
287 /* The buffer position of the first character appearing entirely or
288 partially on the line of the selected window which contains the
289 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
290 redisplay optimization in redisplay_internal. */
291
292 static struct text_pos this_line_start_pos;
293
294 /* Number of characters past the end of the line above, including the
295 terminating newline. */
296
297 static struct text_pos this_line_end_pos;
298
299 /* The vertical positions and the height of this line. */
300
301 static int this_line_vpos;
302 static int this_line_y;
303 static int this_line_pixel_height;
304
305 /* X position at which this display line starts. Usually zero;
306 negative if first character is partially visible. */
307
308 static int this_line_start_x;
309
310 /* Buffer that this_line_.* variables are referring to. */
311
312 static struct buffer *this_line_buffer;
313
314 /* Nonzero means truncate lines in all windows less wide than the
315 frame. */
316
317 int truncate_partial_width_windows;
318
319 /* A flag to control how to display unibyte 8-bit character. */
320
321 int unibyte_display_via_language_environment;
322
323 /* Nonzero means we have more than one non-mini-buffer-only frame.
324 Not guaranteed to be accurate except while parsing
325 frame-title-format. */
326
327 int multiple_frames;
328
329 Lisp_Object Vglobal_mode_string;
330
331 /* Marker for where to display an arrow on top of the buffer text. */
332
333 Lisp_Object Voverlay_arrow_position;
334
335 /* String to display for the arrow. Only used on terminal frames. */
336
337 Lisp_Object Voverlay_arrow_string;
338
339 /* Values of those variables at last redisplay. However, if
340 Voverlay_arrow_position is a marker, last_arrow_position is its
341 numerical position. */
342
343 static Lisp_Object last_arrow_position, last_arrow_string;
344
345 /* Like mode-line-format, but for the title bar on a visible frame. */
346
347 Lisp_Object Vframe_title_format;
348
349 /* Like mode-line-format, but for the title bar on an iconified frame. */
350
351 Lisp_Object Vicon_title_format;
352
353 /* List of functions to call when a window's size changes. These
354 functions get one arg, a frame on which one or more windows' sizes
355 have changed. */
356
357 static Lisp_Object Vwindow_size_change_functions;
358
359 Lisp_Object Qmenu_bar_update_hook;
360
361 /* Nonzero if overlay arrow has been displayed once in this window. */
362
363 static int overlay_arrow_seen;
364
365 /* Nonzero means highlight the region even in nonselected windows. */
366
367 int highlight_nonselected_windows;
368
369 /* If cursor motion alone moves point off frame, try scrolling this
370 many lines up or down if that will bring it back. */
371
372 static int scroll_step;
373
374 /* Non-0 means scroll just far enough to bring point back on the
375 screen, when appropriate. */
376
377 static int scroll_conservatively;
378
379 /* Recenter the window whenever point gets within this many lines of
380 the top or bottom of the window. This value is translated into a
381 pixel value by multiplying it with CANON_Y_UNIT, which means that
382 there is really a fixed pixel height scroll margin. */
383
384 int scroll_margin;
385
386 /* Number of characters of overlap to show, when scrolling a one-line
387 window such as a minibuffer. */
388
389 static int minibuffer_scroll_overlap;
390
391 /* Number of windows showing the buffer of the selected window (or
392 another buffer with the same base buffer). keyboard.c refers to
393 this. */
394
395 int buffer_shared;
396
397 /* Vector containing glyphs for an ellipsis `...'. */
398
399 static Lisp_Object default_invis_vector[3];
400
401 /* Nonzero means display mode line highlighted. */
402
403 int mode_line_inverse_video;
404
405 /* Prompt to display in front of the mini-buffer contents. */
406
407 Lisp_Object minibuf_prompt;
408
409 /* Width of current mini-buffer prompt. Only set after display_line
410 of the line that contains the prompt. */
411
412 int minibuf_prompt_width;
413 int minibuf_prompt_pixel_width;
414
415 /* Message to display instead of mini-buffer contents. This is what
416 the functions error and message make, and command echoing uses it
417 as well. It overrides the minibuf_prompt as well as the buffer. */
418
419 char *echo_area_glyphs;
420
421 /* A Lisp string to display instead of mini-buffer contents, analogous
422 to echo_area_glyphs. If this is a string, display that string.
423 Otherwise, if echo_area_glyphs is non-null, display that. */
424
425 Lisp_Object echo_area_message;
426
427 /* This is the length of the message in echo_area_glyphs or
428 echo_area_message. */
429
430 int echo_area_glyphs_length;
431
432 /* Value of echo_area_glyphs when it was last acted on. If this is
433 nonzero, there is a message on the frame in the mini-buffer and it
434 should be erased as soon as it is no longer requested to appear. */
435
436 char *previous_echo_glyphs;
437 Lisp_Object previous_echo_area_message;
438 static int previous_echo_glyphs_length;
439
440 /* This is the window where the echo area message was displayed. It
441 is always a mini-buffer window, but it may not be the same window
442 currently active as a mini-buffer. */
443
444 Lisp_Object echo_area_window;
445
446 /* Nonzero means multibyte characters were enabled when the echo area
447 message was specified. */
448
449 int message_enable_multibyte;
450
451 /* True if we should redraw the mode lines on the next redisplay. */
452
453 int update_mode_lines;
454
455 /* Smallest number of characters before the gap at any time since last
456 redisplay that finished. Valid for current buffer when
457 try_window_id can be called. */
458
459 int beg_unchanged;
460
461 /* Smallest number of characters after the gap at any time since last
462 redisplay that finished. Valid for current buffer when
463 try_window_id can be called. */
464
465 int end_unchanged;
466
467 /* MODIFF as of last redisplay that finished; if it matches MODIFF,
468 and overlay_unchanged_modified matches OVERLAY_MODIFF, that means
469 beg_unchanged and end_unchanged contain no useful information. */
470
471 int unchanged_modified;
472
473 /* OVERLAY_MODIFF as of last redisplay that finished. */
474
475 int overlay_unchanged_modified;
476
477 /* Nonzero if window sizes or contents have changed since last
478 redisplay that finished */
479
480 int windows_or_buffers_changed;
481
482 /* Nonzero after display_mode_line if %l was used and it displayed a
483 line number. */
484
485 int line_number_displayed;
486
487 /* Maximum buffer size for which to display line numbers. */
488
489 static int line_number_display_limit;
490
491 /* Number of lines to keep in the message log buffer. t means
492 infinite. nil means don't log at all. */
493
494 Lisp_Object Vmessage_log_max;
495
496 /* A scratch glyph row with contents used for generating truncation
497 glyphs. Also used in direct_output_for_insert. */
498
499 #define MAX_SCRATCH_GLYPHS 100
500 struct glyph_row scratch_glyph_row;
501 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
502
503 /* Ascent and height of the last line processed by move_it_to. */
504
505 static int last_max_ascent, last_height;
506
507 /* The maximum distance to look ahead for text properties. Values
508 that are too small let us call compute_char_face and similar
509 functions too often which is expensive. Values that are too large
510 let us call compute_char_face and alike too often because we
511 might not be interested in text properties that far away. */
512
513 #define TEXT_PROP_DISTANCE_LIMIT 100
514
515 /* Non-zero means print traces of redisplay if compiled with
516 GLYPH_DEBUG != 0. */
517
518 #if GLYPH_DEBUG
519 int trace_redisplay_p;
520 #endif
521
522 /* Value returned from text property handlers (see below). */
523
524 enum prop_handled
525 {
526 HANDLED_NORMALLY,
527 HANDLED_RECOMPUTE_PROPS,
528 HANDLED_OVERLAY_STRING_CONSUMED,
529 HANDLED_RETURN
530 };
531
532 /* A description of text properties that redisplay is interested
533 in. */
534
535 struct props
536 {
537 /* The name of the property. */
538 Lisp_Object *name;
539
540 /* A unique index for the property. */
541 enum prop_idx idx;
542
543 /* A handler function called to set up iterator IT from the property
544 at IT's current position. Value is used to steer handle_stop. */
545 enum prop_handled (*handler) P_ ((struct it *it));
546 };
547
548 static enum prop_handled handle_face_prop P_ ((struct it *));
549 static enum prop_handled handle_invisible_prop P_ ((struct it *));
550 static enum prop_handled handle_display_prop P_ ((struct it *));
551 static enum prop_handled handle_overlay_change P_ ((struct it *));
552 static enum prop_handled handle_fontified_prop P_ ((struct it *));
553
554 /* Properties handled by iterators. */
555
556 static struct props it_props[] =
557 {
558 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
559 /* Handle `face' before `display' because some sub-properties of
560 `display' need to know the face. */
561 {&Qface, FACE_PROP_IDX, handle_face_prop},
562 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
563 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
564 {NULL, 0, NULL}
565 };
566
567 /* Value is the position described by X. If X is a marker, value is
568 the marker_position of X. Otherwise, value is X. */
569
570 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
571
572 /* Enumeration returned by some move_it_.* functions internally. */
573
574 enum move_it_result
575 {
576 /* Not used. Undefined value. */
577 MOVE_UNDEFINED,
578
579 /* Move ended at the requested buffer position or ZV. */
580 MOVE_POS_MATCH_OR_ZV,
581
582 /* Move ended at the requested X pixel position. */
583 MOVE_X_REACHED,
584
585 /* Move within a line ended at the end of a line that must be
586 continued. */
587 MOVE_LINE_CONTINUED,
588
589 /* Move within a line ended at the end of a line that would
590 be displayed truncated. */
591 MOVE_LINE_TRUNCATED,
592
593 /* Move within a line ended at a line end. */
594 MOVE_NEWLINE_OR_CR
595 };
596
597
598 \f
599 /* Function prototypes. */
600
601 static int string_char_and_length P_ ((unsigned char *, int, int *));
602 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
603 struct text_pos));
604 static int compute_window_start_on_continuation_line P_ ((struct window *));
605 static Lisp_Object eval_handler P_ ((Lisp_Object));
606 static Lisp_Object eval_form P_ ((Lisp_Object));
607 static void insert_left_trunc_glyphs P_ ((struct it *));
608 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
609 static void extend_face_to_end_of_line P_ ((struct it *));
610 static void append_space P_ ((struct it *, int));
611 static void make_cursor_line_fully_visible P_ ((struct window *));
612 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
613 static int trailing_whitespace_p P_ ((int));
614 static int message_log_check_duplicate P_ ((int, int, int, int));
615 int invisible_p P_ ((Lisp_Object, Lisp_Object));
616 int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
617 static void push_it P_ ((struct it *));
618 static void pop_it P_ ((struct it *));
619 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
620 static void redisplay_internal P_ ((int));
621 static void echo_area_display P_ ((int));
622 static void redisplay_windows P_ ((Lisp_Object));
623 static void redisplay_window P_ ((Lisp_Object, int));
624 static void update_menu_bar P_ ((struct frame *, int));
625 static int try_window_reusing_current_matrix P_ ((struct window *));
626 static int try_window_id P_ ((struct window *));
627 static int display_line P_ ((struct it *));
628 static void display_mode_lines P_ ((struct window *));
629 static void display_mode_line P_ ((struct window *, enum face_id,
630 Lisp_Object));
631 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
632 static char *decode_mode_spec P_ ((struct window *, char, int, int));
633 static void display_menu_bar P_ ((struct window *));
634 static int display_count_lines P_ ((int, int, int, int, int *));
635 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
636 int, int, struct it *, int, int, int, int));
637 static void compute_line_metrics P_ ((struct it *));
638 static void run_redisplay_end_trigger_hook P_ ((struct it *));
639 static int get_overlay_strings P_ ((struct it *));
640 static void next_overlay_string P_ ((struct it *));
641 void set_iterator_to_next P_ ((struct it *));
642 static void reseat P_ ((struct it *, struct text_pos, int));
643 static void reseat_1 P_ ((struct it *, struct text_pos, int));
644 static void back_to_previous_visible_line_start P_ ((struct it *));
645 static void reseat_at_previous_visible_line_start P_ ((struct it *));
646 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
647 static int next_element_from_display_vector P_ ((struct it *));
648 static int next_element_from_string P_ ((struct it *));
649 static int next_element_from_c_string P_ ((struct it *));
650 static int next_element_from_buffer P_ ((struct it *));
651 static int next_element_from_image P_ ((struct it *));
652 static int next_element_from_stretch P_ ((struct it *));
653 static void load_overlay_strings P_ ((struct it *));
654 static void init_from_display_pos P_ ((struct it *, struct window *,
655 struct display_pos *));
656 static void reseat_to_string P_ ((struct it *, unsigned char *,
657 Lisp_Object, int, int, int, int));
658 static int charset_at_position P_ ((struct text_pos));
659 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
660 int, int, int));
661 void move_it_vertically_backward P_ ((struct it *, int));
662 static void init_to_row_start P_ ((struct it *, struct window *,
663 struct glyph_row *));
664 static void init_to_row_end P_ ((struct it *, struct window *,
665 struct glyph_row *));
666 static void back_to_previous_line_start P_ ((struct it *));
667 static void forward_to_next_line_start P_ ((struct it *));
668 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
669 Lisp_Object, int));
670 static struct text_pos string_pos P_ ((int, Lisp_Object));
671 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
672 static int number_of_chars P_ ((unsigned char *, int));
673 static void compute_stop_pos P_ ((struct it *));
674 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
675 Lisp_Object));
676 static int face_before_or_after_it_pos P_ ((struct it *, int));
677 static int next_overlay_change P_ ((int));
678 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
679 Lisp_Object, struct text_pos *));
680
681 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
682 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
683
684 #ifdef HAVE_WINDOW_SYSTEM
685
686 static void update_toolbar P_ ((struct frame *, int));
687 static void build_desired_toolbar_string P_ ((struct frame *f));
688 static int redisplay_toolbar P_ ((struct frame *));
689 static void display_toolbar_line P_ ((struct it *));
690
691 #endif /* HAVE_WINDOW_SYSTEM */
692
693 \f
694 /***********************************************************************
695 Window display dimensions
696 ***********************************************************************/
697
698 /* Return the window-relative maximum y + 1 for glyph rows displaying
699 text in window W. This is the height of W minus the height of a
700 mode line, if any. */
701
702 INLINE int
703 window_text_bottom_y (w)
704 struct window *w;
705 {
706 struct frame *f = XFRAME (w->frame);
707 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
708
709 if (WINDOW_WANTS_MODELINE_P (w))
710 height -= CURRENT_MODE_LINE_HEIGHT (w);
711 return height;
712 }
713
714
715 /* Return the pixel width of display area AREA of window W. AREA < 0
716 means return the total width of W, not including bitmap areas to
717 the left and right of the window. */
718
719 INLINE int
720 window_box_width (w, area)
721 struct window *w;
722 int area;
723 {
724 struct frame *f = XFRAME (w->frame);
725 int width = XFASTINT (w->width);
726
727 if (!w->pseudo_window_p)
728 {
729 width -= FRAME_SCROLL_BAR_WIDTH (f) + 2 * FRAME_FLAGS_AREA_COLS (f);
730
731 if (area == TEXT_AREA)
732 {
733 if (INTEGERP (w->left_margin_width))
734 width -= XFASTINT (w->left_margin_width);
735 if (INTEGERP (w->right_margin_width))
736 width -= XFASTINT (w->right_margin_width);
737 }
738 else if (area == LEFT_MARGIN_AREA)
739 width = (INTEGERP (w->left_margin_width)
740 ? XFASTINT (w->left_margin_width) : 0);
741 else if (area == RIGHT_MARGIN_AREA)
742 width = (INTEGERP (w->right_margin_width)
743 ? XFASTINT (w->right_margin_width) : 0);
744 }
745
746 return width * CANON_X_UNIT (f);
747 }
748
749
750 /* Return the pixel height of the display area of window W, not
751 including mode lines of W, if any.. */
752
753 INLINE int
754 window_box_height (w)
755 struct window *w;
756 {
757 struct frame *f = XFRAME (w->frame);
758 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
759
760 if (WINDOW_WANTS_MODELINE_P (w))
761 height -= CURRENT_MODE_LINE_HEIGHT (w);
762
763 if (WINDOW_WANTS_TOP_LINE_P (w))
764 height -= CURRENT_TOP_LINE_HEIGHT (w);
765
766 return height;
767 }
768
769
770 /* Return the frame-relative coordinate of the left edge of display
771 area AREA of window W. AREA < 0 means return the left edge of the
772 whole window, to the right of any bitmap area at the left side of
773 W. */
774
775 INLINE int
776 window_box_left (w, area)
777 struct window *w;
778 int area;
779 {
780 struct frame *f = XFRAME (w->frame);
781 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
782
783 if (!w->pseudo_window_p)
784 {
785 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
786 + FRAME_FLAGS_AREA_WIDTH (f));
787
788 if (area == TEXT_AREA)
789 x += window_box_width (w, LEFT_MARGIN_AREA);
790 else if (area == RIGHT_MARGIN_AREA)
791 x += (window_box_width (w, LEFT_MARGIN_AREA)
792 + window_box_width (w, TEXT_AREA));
793 }
794
795 return x;
796 }
797
798
799 /* Return the frame-relative coordinate of the right edge of display
800 area AREA of window W. AREA < 0 means return the left edge of the
801 whole window, to the left of any bitmap area at the right side of
802 W. */
803
804 INLINE int
805 window_box_right (w, area)
806 struct window *w;
807 int area;
808 {
809 return window_box_left (w, area) + window_box_width (w, area);
810 }
811
812
813 /* Get the bounding box of the display area AREA of window W, without
814 mode lines, in frame-relative coordinates. AREA < 0 means the
815 whole window, not including bitmap areas to the left and right of
816 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
817 coordinates of the upper-left corner of the box. Return in
818 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
819
820 INLINE void
821 window_box (w, area, box_x, box_y, box_width, box_height)
822 struct window *w;
823 int area;
824 int *box_x, *box_y, *box_width, *box_height;
825 {
826 struct frame *f = XFRAME (w->frame);
827
828 *box_width = window_box_width (w, area);
829 *box_height = window_box_height (w);
830 *box_x = window_box_left (w, area);
831 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
832 + XFASTINT (w->top) * CANON_Y_UNIT (f));
833 if (WINDOW_WANTS_TOP_LINE_P (w))
834 *box_y += CURRENT_TOP_LINE_HEIGHT (w);
835 }
836
837
838 /* Get the bounding box of the display area AREA of window W, without
839 mode lines. AREA < 0 means the whole window, not including bitmap
840 areas to the left and right of the window. Return in *TOP_LEFT_X
841 and TOP_LEFT_Y the frame-relative pixel coordinates of the
842 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
843 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
844 box. */
845
846 INLINE void
847 window_box_edges (w, area, top_left_x, top_left_y,
848 bottom_right_x, bottom_right_y)
849 struct window *w;
850 int area;
851 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
852 {
853 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
854 bottom_right_y);
855 *bottom_right_x += *top_left_x;
856 *bottom_right_y += *top_left_y;
857 }
858
859
860 \f
861 /***********************************************************************
862 Utilities
863 ***********************************************************************/
864
865 /* Return the next character from STR which is MAXLEN bytes long.
866 Return in *LEN the length of the character. This is like
867 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
868 we find one, we return a `?', but with the length of the illegal
869 character. */
870
871 static INLINE int
872 string_char_and_length (str, maxlen, len)
873 unsigned char *str;
874 int maxlen, *len;
875 {
876 int c;
877
878 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
879 if (!CHAR_VALID_P (c, 1))
880 /* We may not change the length here because other places in Emacs
881 don't use this function, i.e. they silently accept illegal
882 characters. */
883 c = '?';
884
885 return c;
886 }
887
888
889
890 /* Given a position POS containing a valid character and byte position
891 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
892
893 static struct text_pos
894 string_pos_nchars_ahead (pos, string, nchars)
895 struct text_pos pos;
896 Lisp_Object string;
897 int nchars;
898 {
899 xassert (STRINGP (string) && nchars >= 0);
900
901 if (STRING_MULTIBYTE (string))
902 {
903 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
904 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
905 int len;
906
907 while (nchars--)
908 {
909 string_char_and_length (p, rest, &len);
910 p += len, rest -= len;
911 xassert (rest >= 0);
912 CHARPOS (pos) += 1;
913 BYTEPOS (pos) += len;
914 }
915 }
916 else
917 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
918
919 return pos;
920 }
921
922
923 /* Value is the text position, i.e. character and byte position,
924 for character position CHARPOS in STRING. */
925
926 static INLINE struct text_pos
927 string_pos (charpos, string)
928 int charpos;
929 Lisp_Object string;
930 {
931 struct text_pos pos;
932 xassert (STRINGP (string));
933 xassert (charpos >= 0);
934 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
935 return pos;
936 }
937
938
939 /* Value is a text position, i.e. character and byte position, for
940 character position CHARPOS in C string S. MULTIBYTE_P non-zero
941 means recognize multibyte characters. */
942
943 static struct text_pos
944 c_string_pos (charpos, s, multibyte_p)
945 int charpos;
946 unsigned char *s;
947 int multibyte_p;
948 {
949 struct text_pos pos;
950
951 xassert (s != NULL);
952 xassert (charpos >= 0);
953
954 if (multibyte_p)
955 {
956 int rest = strlen (s), len;
957
958 SET_TEXT_POS (pos, 0, 0);
959 while (charpos--)
960 {
961 string_char_and_length (s, rest, &len);
962 s += len, rest -= len;
963 xassert (rest >= 0);
964 CHARPOS (pos) += 1;
965 BYTEPOS (pos) += len;
966 }
967 }
968 else
969 SET_TEXT_POS (pos, charpos, charpos);
970
971 return pos;
972 }
973
974
975 /* Value is the number of characters in C string S. MULTIBYTE_P
976 non-zero means recognize multibyte characters. */
977
978 static int
979 number_of_chars (s, multibyte_p)
980 unsigned char *s;
981 int multibyte_p;
982 {
983 int nchars;
984
985 if (multibyte_p)
986 {
987 int rest = strlen (s), len;
988 unsigned char *p = (unsigned char *) s;
989
990 for (nchars = 0; rest > 0; ++nchars)
991 {
992 string_char_and_length (p, rest, &len);
993 rest -= len, p += len;
994 }
995 }
996 else
997 nchars = strlen (s);
998
999 return nchars;
1000 }
1001
1002
1003 /* Compute byte position NEWPOS->bytepos corresponding to
1004 NEWPOS->charpos. POS is a known position in string STRING.
1005 NEWPOS->charpos must be >= POS.charpos. */
1006
1007 static void
1008 compute_string_pos (newpos, pos, string)
1009 struct text_pos *newpos, pos;
1010 Lisp_Object string;
1011 {
1012 xassert (STRINGP (string));
1013 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1014
1015 if (STRING_MULTIBYTE (string))
1016 *newpos = string_pos_nchars_ahead (pos, CHARPOS (*newpos) - CHARPOS (pos),
1017 string);
1018 else
1019 BYTEPOS (*newpos) = CHARPOS (*newpos);
1020 }
1021
1022
1023 /* Return the charset of the character at position POS in
1024 current_buffer. */
1025
1026 static int
1027 charset_at_position (pos)
1028 struct text_pos pos;
1029 {
1030 int c, multibyte_p;
1031 unsigned char *p = BYTE_POS_ADDR (BYTEPOS (pos));
1032
1033 multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1034 if (multibyte_p)
1035 {
1036 int maxlen = ((BYTEPOS (pos) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
1037 - BYTEPOS (pos));
1038 int len;
1039 c = string_char_and_length (p, maxlen, &len);
1040 }
1041 else
1042 c = *p;
1043
1044 return CHAR_CHARSET (c);
1045 }
1046
1047
1048 \f
1049 /***********************************************************************
1050 Lisp form evaluation
1051 ***********************************************************************/
1052
1053 /* Error handler for eval_form. */
1054
1055 static Lisp_Object
1056 eval_handler (arg)
1057 Lisp_Object arg;
1058 {
1059 return Qnil;
1060 }
1061
1062
1063 /* Evaluate SEXPR and return the result, or nil if something went
1064 wrong. */
1065
1066 static Lisp_Object
1067 eval_form (sexpr)
1068 Lisp_Object sexpr;
1069 {
1070 int count = specpdl_ptr - specpdl;
1071 Lisp_Object val;
1072 specbind (Qinhibit_redisplay, Qt);
1073 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1074 return unbind_to (count, val);
1075 }
1076
1077
1078 \f
1079 /***********************************************************************
1080 Debugging
1081 ***********************************************************************/
1082
1083 #if 0
1084
1085 /* Define CHECK_IT to perform sanity checks on iterators.
1086 This is for debugging. It is too slow to do unconditionally. */
1087
1088 static void
1089 check_it (it)
1090 struct it *it;
1091 {
1092 if (it->method == next_element_from_string)
1093 {
1094 xassert (STRINGP (it->string));
1095 xassert (IT_STRING_CHARPOS (*it) >= 0);
1096 }
1097 else if (it->method == next_element_from_buffer)
1098 {
1099 /* Check that character and byte positions agree. */
1100 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1101 }
1102
1103 if (it->dpvec)
1104 xassert (it->current.dpvec_index >= 0);
1105 else
1106 xassert (it->current.dpvec_index < 0);
1107 }
1108
1109 #define CHECK_IT(IT) check_it ((IT))
1110
1111 #else /* not 0 */
1112
1113 #define CHECK_IT(IT) (void) 0
1114
1115 #endif /* not 0 */
1116
1117
1118 #if GLYPH_DEBUG
1119
1120 /* Check that the window end of window W is what we expect it
1121 to be---the last row in the current matrix displaying text. */
1122
1123 static void
1124 check_window_end (w)
1125 struct window *w;
1126 {
1127 if (!MINI_WINDOW_P (w)
1128 && !NILP (w->window_end_valid))
1129 {
1130 struct glyph_row *row;
1131 xassert ((row = MATRIX_ROW (w->current_matrix,
1132 XFASTINT (w->window_end_vpos)),
1133 !row->enabled_p
1134 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1135 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1136 }
1137 }
1138
1139 #define CHECK_WINDOW_END(W) check_window_end ((W))
1140
1141 #else /* not GLYPH_DEBUG */
1142
1143 #define CHECK_WINDOW_END(W) (void) 0
1144
1145 #endif /* not GLYPH_DEBUG */
1146
1147
1148 \f
1149 /***********************************************************************
1150 Iterator initialization
1151 ***********************************************************************/
1152
1153 /* Initialize IT for displaying current_buffer in window W, starting
1154 at character position CHARPOS. CHARPOS < 0 means that no buffer
1155 position is specified which is useful when the iterator is assigned
1156 a position later. BYTEPOS is the byte position corresponding to
1157 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1158
1159 If ROW is not null, calls to produce_glyphs with IT as parameter
1160 will produce glyphs in that row.
1161
1162 BASE_FACE_ID is the id of a base face to use. It must be one of
1163 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1164 TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
1165 displaying the toolbar.
1166
1167 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1168 TOP_LINE_FACE_ID, the iterator will be initialized to use the
1169 corresponding mode line glyph row of the desired matrix of W. */
1170
1171 void
1172 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1173 struct it *it;
1174 struct window *w;
1175 int charpos, bytepos;
1176 struct glyph_row *row;
1177 enum face_id base_face_id;
1178 {
1179 int highlight_region_p;
1180 Lisp_Object value;
1181
1182 /* Some precondition checks. */
1183 xassert (w != NULL && it != NULL);
1184 xassert (charpos < 0 || current_buffer == XBUFFER (w->buffer));
1185 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1186
1187 /* If face attributes have been changed since the last redisplay,
1188 free realized faces now because they depend on face definitions
1189 that might have changed. */
1190 if (face_change_count)
1191 {
1192 face_change_count = 0;
1193 free_all_realized_faces (Qnil);
1194 }
1195
1196 /* Use one of the mode line rows of W's desired matrix if
1197 appropriate. */
1198 if (row == NULL)
1199 {
1200 if (base_face_id == MODE_LINE_FACE_ID)
1201 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1202 else if (base_face_id == TOP_LINE_FACE_ID)
1203 row = MATRIX_TOP_LINE_ROW (w->desired_matrix);
1204 }
1205
1206 /* Clear IT. */
1207 bzero (it, sizeof *it);
1208 it->current.overlay_string_index = -1;
1209 it->current.dpvec_index = -1;
1210 it->charset = CHARSET_ASCII;
1211 it->base_face_id = base_face_id;
1212
1213 /* The window in which we iterate over current_buffer: */
1214 XSETWINDOW (it->window, w);
1215 it->w = w;
1216 it->f = XFRAME (w->frame);
1217
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);
1222
1223 /* Should we highlight trailing whitespace? */
1224 value = find_symbol_value (Qshow_trailing_whitespace);
1225 it->show_trailing_whitespace_p
1226 = EQ (value, Qunbound) ? 0 : !NILP (value);
1227
1228 /* Current value of the `space-width', and 'height' properties. */
1229 it->space_width = Qnil;
1230 it->font_height = Qnil;
1231
1232 /* Are control characters displayed as `^C'? */
1233 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1234
1235 /* -1 means everything between a CR and the following line end
1236 is invisible. >0 means lines indented more than this value are
1237 invisible. */
1238 it->selective = (INTEGERP (current_buffer->selective_display)
1239 ? XFASTINT (current_buffer->selective_display)
1240 : (!NILP (current_buffer->selective_display)
1241 ? -1 : 0));
1242 it->selective_display_ellipsis_p
1243 = !NILP (current_buffer->selective_display_ellipses);
1244
1245 /* Display table to use. */
1246 it->dp = window_display_table (w);
1247
1248 /* Are multibyte characters enabled in current_buffer? */
1249 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1250
1251 /* Non-zero if we should highlight the region. */
1252 highlight_region_p
1253 = (!NILP (Vtransient_mark_mode)
1254 && !NILP (current_buffer->mark_active)
1255 && XMARKER (current_buffer->mark)->buffer != 0);
1256
1257 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1258 start and end of a visible region in window IT->w. Set both to
1259 -1 to indicate no region. */
1260 if (highlight_region_p
1261 /* Maybe highlight only in selected window. */
1262 && (/* Either show region everywhere. */
1263 highlight_nonselected_windows
1264 /* Or show region in the selected window. */
1265 || w == XWINDOW (selected_window)
1266 /* Or show the region if we are in the mini-buffer and W is
1267 the window the mini-buffer refers to. */
1268 || (MINI_WINDOW_P (XWINDOW (selected_window))
1269 && w == XWINDOW (Vminibuf_scroll_window))))
1270 {
1271 int charpos = marker_position (current_buffer->mark);
1272 it->region_beg_charpos = min (PT, charpos);
1273 it->region_end_charpos = max (PT, charpos);
1274 }
1275 else
1276 it->region_beg_charpos = it->region_end_charpos = -1;
1277
1278 /* Get the position at which the redisplay_end_trigger hook should
1279 be run, if it is to be run at all. */
1280 if (MARKERP (w->redisplay_end_trigger)
1281 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1282 it->redisplay_end_trigger_charpos
1283 = marker_position (w->redisplay_end_trigger);
1284 else if (INTEGERP (w->redisplay_end_trigger))
1285 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1286
1287 /* Correct bogus values of tab_width. */
1288 it->tab_width = XINT (current_buffer->tab_width);
1289 if (it->tab_width <= 0 || it->tab_width > 1000)
1290 it->tab_width = 8;
1291
1292 /* Are lines in the display truncated? */
1293 it->truncate_lines_p
1294 = (base_face_id != DEFAULT_FACE_ID
1295 || XINT (it->w->hscroll)
1296 || (truncate_partial_width_windows
1297 && !WINDOW_FULL_WIDTH_P (it->w))
1298 || !NILP (current_buffer->truncate_lines));
1299
1300 /* Get dimensions of truncation and continuation glyphs. These are
1301 displayed as bitmaps under X, so we don't need them for such
1302 frames. */
1303 if (!FRAME_WINDOW_P (it->f))
1304 {
1305 if (it->truncate_lines_p)
1306 {
1307 /* We will need the truncation glyph. */
1308 xassert (it->glyph_row == NULL);
1309 produce_special_glyphs (it, IT_TRUNCATION);
1310 it->truncation_pixel_width = it->pixel_width;
1311 }
1312 else
1313 {
1314 /* We will need the continuation glyph. */
1315 xassert (it->glyph_row == NULL);
1316 produce_special_glyphs (it, IT_CONTINUATION);
1317 it->continuation_pixel_width = it->pixel_width;
1318 }
1319
1320 /* Reset these values to zero becaue the produce_special_glyphs
1321 above has changed them. */
1322 it->pixel_width = it->ascent = it->descent = 0;
1323 it->phys_ascent = it->phys_descent = 0;
1324 }
1325
1326 /* Set this after getting the dimensions of truncation and
1327 continuation glyphs, so that we don't produce glyphs when calling
1328 produce_special_glyphs, above. */
1329 it->glyph_row = row;
1330 it->area = TEXT_AREA;
1331
1332 /* Get the dimensions of the display area. The display area
1333 consists of the visible window area plus a horizontally scrolled
1334 part to the left of the window. All x-values are relative to the
1335 start of this total display area. */
1336 if (base_face_id != DEFAULT_FACE_ID)
1337 {
1338 /* Mode lines, menu bar in terminal frames. */
1339 it->first_visible_x = 0;
1340 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1341 }
1342 else
1343 {
1344 it->first_visible_x
1345 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1346 it->last_visible_x = (it->first_visible_x
1347 + window_box_width (w, TEXT_AREA));
1348
1349 /* If we truncate lines, leave room for the truncator glyph(s) at
1350 the right margin. Otherwise, leave room for the continuation
1351 glyph(s). Truncation and continuation glyphs are not inserted
1352 for window-based redisplay. */
1353 if (!FRAME_WINDOW_P (it->f))
1354 {
1355 if (it->truncate_lines_p)
1356 it->last_visible_x -= it->truncation_pixel_width;
1357 else
1358 it->last_visible_x -= it->continuation_pixel_width;
1359 }
1360
1361 it->top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
1362 it->current_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w) + w->vscroll;
1363 }
1364
1365 /* Leave room for a border glyph. */
1366 if (!FRAME_WINDOW_P (it->f)
1367 && !WINDOW_RIGHTMOST_P (it->w))
1368 it->last_visible_x -= 1;
1369
1370 it->last_visible_y = window_text_bottom_y (w);
1371
1372 /* For mode lines and alike, arrange for the first glyph having a
1373 left box line if the face specifies a box. */
1374 if (base_face_id != DEFAULT_FACE_ID)
1375 {
1376 struct face *face;
1377
1378 it->face_id = base_face_id;
1379
1380 /* If we have a boxed mode line, make the first character appear
1381 with a left box line. */
1382 face = FACE_FROM_ID (it->f, base_face_id);
1383 if (face->box != FACE_NO_BOX)
1384 it->start_of_box_run_p = 1;
1385 }
1386
1387 /* If a buffer position was specified, set the iterator there,
1388 getting overlays and face properties from that position. */
1389 if (charpos > 0)
1390 {
1391 it->end_charpos = ZV;
1392 it->face_id = -1;
1393 IT_CHARPOS (*it) = charpos;
1394
1395 /* Compute byte position if not specified. */
1396 if (bytepos <= 0)
1397 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1398 else
1399 IT_BYTEPOS (*it) = bytepos;
1400
1401 /* Compute faces etc. */
1402 reseat (it, it->current.pos, 1);
1403 }
1404
1405 CHECK_IT (it);
1406 }
1407
1408
1409 /* Initialize IT for the display of window W with window start POS. */
1410
1411 void
1412 start_display (it, w, pos)
1413 struct it *it;
1414 struct window *w;
1415 struct text_pos pos;
1416 {
1417 int start_at_line_beg_p;
1418 struct glyph_row *row;
1419 int first_vpos = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
1420 int first_y;
1421
1422 row = w->desired_matrix->rows + first_vpos;
1423 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1424 first_y = it->current_y;
1425
1426 /* If window start is not at a line start, move back to the line
1427 start. This makes sure that we take continuation lines into
1428 account. */
1429 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1430 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1431 if (!start_at_line_beg_p)
1432 reseat_at_previous_visible_line_start (it);
1433
1434 #if NO_PROMPT_IN_BUFFER
1435 /* Take the mini-buffer prompt width into account for tab
1436 calculations. */
1437 if (MINI_WINDOW_P (w) && IT_CHARPOS (*it) == BEGV)
1438 {
1439 /* Why is mini-buffer_prompt_width guaranteed to be set here? */
1440 it->prompt_width = minibuf_prompt_pixel_width;
1441 }
1442 #endif /* NO_PROMPT_IN_BUFFER */
1443
1444 /* If window start is not at a line start, skip forward to POS to
1445 get the correct continuation_lines_width and current_x. */
1446 if (!start_at_line_beg_p)
1447 {
1448 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1449
1450 /* If lines are continued, this line may end in the middle of a
1451 multi-glyph character (e.g. a control character displayed as
1452 \003, or in the middle of an overlay string). In this case
1453 move_it_to above will not have taken us to the start of
1454 the continuation line but to the end of the continued line. */
1455 if (!it->truncate_lines_p && it->current_x > 0)
1456 {
1457 if (it->current.dpvec_index >= 0
1458 || it->current.overlay_string_index >= 0)
1459 {
1460 set_iterator_to_next (it);
1461 move_it_in_display_line_to (it, -1, -1, 0);
1462 }
1463 it->continuation_lines_width += it->current_x;
1464 }
1465
1466 it->current_y = first_y;
1467 it->vpos = 0;
1468 it->current_x = it->hpos = 0;
1469 }
1470
1471 #if 0 /* Don't assert the following because start_display is sometimes
1472 called intentionally with a window start that is not at a
1473 line start. Please leave this code in as a comment. */
1474
1475 /* Window start should be on a line start, now. */
1476 xassert (it->continuation_lines_width
1477 || IT_CHARPOS (it) == BEGV
1478 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1479 #endif /* 0 */
1480 }
1481
1482
1483 /* Initialize IT for stepping through current_buffer in window W,
1484 starting at position POS that includes overlay string and display
1485 vector/ control character translation position information. */
1486
1487 static void
1488 init_from_display_pos (it, w, pos)
1489 struct it *it;
1490 struct window *w;
1491 struct display_pos *pos;
1492 {
1493 /* Keep in mind: the call to reseat in init_iterator skips invisible
1494 text, so we might end up at a position different from POS. This
1495 is only a problem when POS is a row start after a newline and an
1496 overlay starts there with an after-string, and the overlay has an
1497 invisible property. Since we don't skip invisible text in
1498 display_line and elsewhere immediately after consuming the
1499 newline before the row start, such a POS will not be in a string,
1500 but the call to init_iterator below will move us to the
1501 after-string. */
1502 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1503 NULL, DEFAULT_FACE_ID);
1504
1505 /* If position is within an overlay string, set up IT to
1506 the right overlay string. */
1507 if (pos->overlay_string_index >= 0)
1508 {
1509 int relative_index;
1510
1511 /* We already have the first chunk of overlay strings in
1512 IT->overlay_strings. Load more until the one for
1513 pos->overlay_string_index is in IT->overlay_strings. */
1514 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1515 {
1516 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1517 it->current.overlay_string_index = 0;
1518 while (n--)
1519 {
1520 load_overlay_strings (it);
1521 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1522 }
1523 }
1524
1525 it->current.overlay_string_index = pos->overlay_string_index;
1526 relative_index = (it->current.overlay_string_index
1527 % OVERLAY_STRING_CHUNK_SIZE);
1528 it->string = it->overlay_strings[relative_index];
1529 it->current.string_pos = pos->string_pos;
1530 it->method = next_element_from_string;
1531 }
1532 else if (CHARPOS (pos->string_pos) >= 0)
1533 {
1534 /* Recorded position is not in an overlay string, but in another
1535 string. This can only be a string from a `display' property.
1536 IT should already be filled with that string. */
1537 it->current.string_pos = pos->string_pos;
1538 xassert (STRINGP (it->string));
1539 }
1540
1541 /* Restore position in display vector translations or control
1542 character translations. */
1543 if (pos->dpvec_index >= 0)
1544 {
1545 /* This fills IT->dpvec. */
1546 get_next_display_element (it);
1547 xassert (it->dpvec && it->current.dpvec_index == 0);
1548 it->current.dpvec_index = pos->dpvec_index;
1549 }
1550
1551 CHECK_IT (it);
1552 }
1553
1554
1555 /* Initialize IT for stepping through current_buffer in window W
1556 starting at ROW->start. */
1557
1558 static void
1559 init_to_row_start (it, w, row)
1560 struct it *it;
1561 struct window *w;
1562 struct glyph_row *row;
1563 {
1564 init_from_display_pos (it, w, &row->start);
1565 it->continuation_lines_width = row->continuation_lines_width;
1566 CHECK_IT (it);
1567 }
1568
1569
1570 /* Initialize IT for stepping through current_buffer in window W
1571 starting in the line following ROW, i.e. starting at ROW->end. */
1572
1573 static void
1574 init_to_row_end (it, w, row)
1575 struct it *it;
1576 struct window *w;
1577 struct glyph_row *row;
1578 {
1579 init_from_display_pos (it, w, &row->end);
1580
1581 if (row->continued_p)
1582 it->continuation_lines_width = (row->continuation_lines_width
1583 + row->pixel_width);
1584 CHECK_IT (it);
1585 }
1586
1587
1588
1589 \f
1590 /***********************************************************************
1591 Text properties
1592 ***********************************************************************/
1593
1594 /* Called when IT reaches IT->stop_charpos. Handle text property and
1595 overlay changes. Set IT->stop_charpos to the next position where
1596 to stop. */
1597
1598 static void
1599 handle_stop (it)
1600 struct it *it;
1601 {
1602 enum prop_handled handled;
1603 int handle_overlay_change_p = 1;
1604 struct props *p;
1605
1606 it->dpvec = NULL;
1607 it->current.dpvec_index = -1;
1608
1609 do
1610 {
1611 handled = HANDLED_NORMALLY;
1612
1613 /* Call text property handlers. */
1614 for (p = it_props; p->handler; ++p)
1615 {
1616 handled = p->handler (it);
1617
1618 if (handled == HANDLED_RECOMPUTE_PROPS)
1619 break;
1620 else if (handled == HANDLED_RETURN)
1621 return;
1622 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1623 handle_overlay_change_p = 0;
1624 }
1625
1626 if (handled != HANDLED_RECOMPUTE_PROPS)
1627 {
1628 /* Don't check for overlay strings below when set to deliver
1629 characters from a display vector. */
1630 if (it->method == next_element_from_display_vector)
1631 handle_overlay_change_p = 0;
1632
1633 /* Handle overlay changes. */
1634 if (handle_overlay_change_p)
1635 handled = handle_overlay_change (it);
1636
1637 /* Determine where to stop next. */
1638 if (handled == HANDLED_NORMALLY)
1639 compute_stop_pos (it);
1640 }
1641 }
1642 while (handled == HANDLED_RECOMPUTE_PROPS);
1643 }
1644
1645
1646 /* Compute IT->stop_charpos from text property and overlay change
1647 information for IT's current position. */
1648
1649 static void
1650 compute_stop_pos (it)
1651 struct it *it;
1652 {
1653 register INTERVAL iv, next_iv;
1654 Lisp_Object object, limit, position;
1655
1656 /* If nowhere else, stop at the end. */
1657 it->stop_charpos = it->end_charpos;
1658
1659 if (STRINGP (it->string))
1660 {
1661 /* Strings are usually short, so don't limit the search for
1662 properties. */
1663 object = it->string;
1664 limit = Qnil;
1665 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1666 }
1667 else
1668 {
1669 int charpos;
1670
1671 /* If next overlay change is in front of the current stop pos
1672 (which is IT->end_charpos), stop there. Note: value of
1673 next_overlay_change is point-max if no overlay change
1674 follows. */
1675 charpos = next_overlay_change (IT_CHARPOS (*it));
1676 if (charpos < it->stop_charpos)
1677 it->stop_charpos = charpos;
1678
1679 /* If showing the region, we have to stop at the region
1680 start or end because the face might change there. */
1681 if (it->region_beg_charpos > 0)
1682 {
1683 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1684 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1685 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1686 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1687 }
1688
1689 /* Set up variables for computing the stop position from text
1690 property changes. */
1691 XSETBUFFER (object, current_buffer);
1692 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1693 XSETFASTINT (position, IT_CHARPOS (*it));
1694
1695 }
1696
1697 /* Get the interval containing IT's position. Value is a null
1698 interval if there isn't such an interval. */
1699 iv = validate_interval_range (object, &position, &position, 0);
1700 if (!NULL_INTERVAL_P (iv))
1701 {
1702 Lisp_Object values_here[LAST_PROP_IDX];
1703 struct props *p;
1704
1705 /* Get properties here. */
1706 for (p = it_props; p->handler; ++p)
1707 values_here[p->idx] = textget (iv->plist, *p->name);
1708
1709 /* Look for an interval following iv that has different
1710 properties. */
1711 for (next_iv = next_interval (iv);
1712 (!NULL_INTERVAL_P (next_iv)
1713 && (NILP (limit)
1714 || XFASTINT (limit) > next_iv->position));
1715 next_iv = next_interval (next_iv))
1716 {
1717 for (p = it_props; p->handler; ++p)
1718 {
1719 Lisp_Object new_value;
1720
1721 new_value = textget (next_iv->plist, *p->name);
1722 if (!EQ (values_here[p->idx], new_value))
1723 break;
1724 }
1725
1726 if (p->handler)
1727 break;
1728 }
1729
1730 if (!NULL_INTERVAL_P (next_iv))
1731 {
1732 if (INTEGERP (limit)
1733 && next_iv->position >= XFASTINT (limit))
1734 /* No text property change up to limit. */
1735 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1736 else
1737 /* Text properties change in next_iv. */
1738 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1739 }
1740 }
1741
1742 xassert (STRINGP (it->string)
1743 || (it->stop_charpos >= BEGV
1744 && it->stop_charpos >= IT_CHARPOS (*it)));
1745 }
1746
1747
1748 /* Return the position of the next overlay change after POS in
1749 current_buffer. Value is point-max if no overlay change
1750 follows. This is like `next-overlay-change' but doesn't use
1751 xmalloc. */
1752
1753 static int
1754 next_overlay_change (pos)
1755 int pos;
1756 {
1757 int noverlays;
1758 int endpos;
1759 Lisp_Object *overlays;
1760 int len;
1761 int i;
1762
1763 /* Get all overlays at the given position. */
1764 len = 10;
1765 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1766 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1767 if (noverlays > len)
1768 {
1769 len = noverlays;
1770 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1771 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1772 }
1773
1774 /* If any of these overlays ends before endpos,
1775 use its ending point instead. */
1776 for (i = 0; i < noverlays; ++i)
1777 {
1778 Lisp_Object oend;
1779 int oendpos;
1780
1781 oend = OVERLAY_END (overlays[i]);
1782 oendpos = OVERLAY_POSITION (oend);
1783 endpos = min (endpos, oendpos);
1784 }
1785
1786 return endpos;
1787 }
1788
1789
1790 \f
1791 /***********************************************************************
1792 Fontification
1793 ***********************************************************************/
1794
1795 /* Handle changes in the `fontified' property of the current buffer by
1796 calling hook functions from Qfontification_functions to fontify
1797 regions of text. */
1798
1799 static enum prop_handled
1800 handle_fontified_prop (it)
1801 struct it *it;
1802 {
1803 Lisp_Object prop, pos;
1804 enum prop_handled handled = HANDLED_NORMALLY;
1805
1806 /* Get the value of the `fontified' property at IT's current buffer
1807 position. (The `fontified' property doesn't have a special
1808 meaning in strings.) If the value is nil, call functions from
1809 Qfontification_functions. */
1810 if (!STRINGP (it->string)
1811 && it->s == NULL
1812 && !NILP (Vfontification_functions)
1813 && (pos = make_number (IT_CHARPOS (*it)),
1814 prop = Fget_char_property (pos, Qfontified, Qnil),
1815 NILP (prop)))
1816 {
1817 Lisp_Object args[2];
1818
1819 /* Run the hook functions. */
1820 args[0] = Qfontification_functions;
1821 args[1] = pos;
1822 Frun_hook_with_args (make_number (2), args);
1823
1824 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1825 something. This avoids an endless loop if they failed to
1826 fontify the text for which reason ever. */
1827 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1828 handled = HANDLED_RECOMPUTE_PROPS;
1829 }
1830
1831 return handled;
1832 }
1833
1834
1835 \f
1836 /***********************************************************************
1837 Faces
1838 ***********************************************************************/
1839
1840 /* Set up iterator IT from face properties at its current position.
1841 Called from handle_stop. */
1842
1843 static enum prop_handled
1844 handle_face_prop (it)
1845 struct it *it;
1846 {
1847 int new_face_id, next_stop;
1848
1849 if (!STRINGP (it->string))
1850 {
1851 new_face_id
1852 = face_at_buffer_position (it->w,
1853 IT_CHARPOS (*it),
1854 it->region_beg_charpos,
1855 it->region_end_charpos,
1856 &next_stop,
1857 (IT_CHARPOS (*it)
1858 + TEXT_PROP_DISTANCE_LIMIT),
1859 0);
1860
1861 /* Is this a start of a run of characters with box face?
1862 Caveat: this can be called for a freshly initialized
1863 iterator; face_id is -1 is this case. We know that the new
1864 face will not change until limit, i.e. if the new face has a
1865 box, all characters up to limit will have one. But, as
1866 usual, we don't know whether limit is really the end. */
1867 if (new_face_id != it->face_id)
1868 {
1869 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1870
1871 /* If new face has a box but old face has not, this is
1872 the start of a run of characters with box, i.e. it has
1873 a shadow on the left side. The value of face_id of the
1874 iterator will be -1 if this is the initial call that gets
1875 the face. In this case, we have to look in front of IT's
1876 position and see whether there is a face != new_face_id. */
1877 it->start_of_box_run_p
1878 = (new_face->box != FACE_NO_BOX
1879 && (it->face_id >= 0
1880 || IT_CHARPOS (*it) == BEG
1881 || new_face_id != face_before_it_pos (it)));
1882 it->face_box_p = new_face->box != FACE_NO_BOX;
1883 }
1884 }
1885 else
1886 {
1887 new_face_id
1888 = face_at_string_position (it->w,
1889 it->string,
1890 IT_STRING_CHARPOS (*it),
1891 (it->current.overlay_string_index >= 0
1892 ? IT_CHARPOS (*it)
1893 : 0),
1894 it->region_beg_charpos,
1895 it->region_end_charpos,
1896 &next_stop,
1897 it->base_face_id);
1898
1899 #if 0 /* This shouldn't be neccessary. Let's check it. */
1900 /* If IT is used to display a mode line we would really like to
1901 use the mode line face instead of the frame's default face. */
1902 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1903 && new_face_id == DEFAULT_FACE_ID)
1904 new_face_id = MODE_LINE_FACE_ID;
1905 #endif
1906
1907 /* Is this a start of a run of characters with box? Caveat:
1908 this can be called for a freshly allocated iterator; face_id
1909 is -1 is this case. We know that the new face will not
1910 change until the next check pos, i.e. if the new face has a
1911 box, all characters up to that position will have a
1912 box. But, as usual, we don't know whether that position
1913 is really the end. */
1914 if (new_face_id != it->face_id)
1915 {
1916 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1917 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1918
1919 /* If new face has a box but old face hasn't, this is the
1920 start of a run of characters with box, i.e. it has a
1921 shadow on the left side. */
1922 it->start_of_box_run_p
1923 = new_face->box && (old_face == NULL || !old_face->box);
1924 it->face_box_p = new_face->box != FACE_NO_BOX;
1925 }
1926 }
1927
1928 it->face_id = new_face_id;
1929 it->charset = CHARSET_ASCII;
1930 return HANDLED_NORMALLY;
1931 }
1932
1933
1934 /* Compute the face one character before or after the current position
1935 of IT. BEFORE_P non-zero means get the face in front of IT's
1936 position. Value is the id of the face. */
1937
1938 static int
1939 face_before_or_after_it_pos (it, before_p)
1940 struct it *it;
1941 int before_p;
1942 {
1943 int face_id, limit;
1944 int next_check_charpos;
1945 struct text_pos pos;
1946
1947 xassert (it->s == NULL);
1948
1949 if (STRINGP (it->string))
1950 {
1951 /* No face change past the end of the string (for the case
1952 we are padding with spaces). No face change before the
1953 string start. */
1954 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1955 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1956 return it->face_id;
1957
1958 /* Set pos to the position before or after IT's current position. */
1959 if (before_p)
1960 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1961 else
1962 pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string);
1963
1964 /* Get the face for ASCII, or unibyte. */
1965 face_id
1966 = face_at_string_position (it->w,
1967 it->string,
1968 CHARPOS (pos),
1969 (it->current.overlay_string_index >= 0
1970 ? IT_CHARPOS (*it)
1971 : 0),
1972 it->region_beg_charpos,
1973 it->region_end_charpos,
1974 &next_check_charpos,
1975 it->base_face_id);
1976
1977 /* Correct the face for charsets different from ASCII. Do it
1978 for the multibyte case only. The face returned above is
1979 suitable for unibyte text if IT->string is unibyte. */
1980 if (STRING_MULTIBYTE (it->string))
1981 {
1982 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1983 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1984 int c, len, charset;
1985
1986 c = string_char_and_length (p, rest, &len);
1987 charset = CHAR_CHARSET (c);
1988 if (charset != CHARSET_ASCII)
1989 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
1990 }
1991 }
1992 else
1993 {
1994 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1995 pos = it->current.pos;
1996
1997 if (before_p)
1998 DEC_TEXT_POS (pos);
1999 else
2000 INC_TEXT_POS (pos);
2001
2002 /* Determine face for CHARSET_ASCII, or unibyte. */
2003 face_id = face_at_buffer_position (it->w,
2004 CHARPOS (pos),
2005 it->region_beg_charpos,
2006 it->region_end_charpos,
2007 &next_check_charpos,
2008 limit, 0);
2009
2010 /* Correct the face for charsets different from ASCII. Do it
2011 for the multibyte case only. The face returned above is
2012 suitable for unibyte text if current_buffer is unibyte. */
2013 if (it->multibyte_p)
2014 {
2015 int charset = charset_at_position (pos);
2016 if (charset != CHARSET_ASCII)
2017 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
2018 }
2019 }
2020
2021 return face_id;
2022 }
2023
2024
2025 \f
2026 /***********************************************************************
2027 Invisible text
2028 ***********************************************************************/
2029
2030 /* Set up iterator IT from invisible properties at its current
2031 position. Called from handle_stop. */
2032
2033 static enum prop_handled
2034 handle_invisible_prop (it)
2035 struct it *it;
2036 {
2037 enum prop_handled handled = HANDLED_NORMALLY;
2038
2039 if (STRINGP (it->string))
2040 {
2041 extern Lisp_Object Qinvisible;
2042 Lisp_Object prop, end_charpos, limit, charpos;
2043
2044 /* Get the value of the invisible text property at the
2045 current position. Value will be nil if there is no such
2046 property. */
2047 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2048 prop = Fget_text_property (charpos, Qinvisible, it->string);
2049
2050 if (!NILP (prop))
2051 {
2052 handled = HANDLED_RECOMPUTE_PROPS;
2053
2054 /* Get the position at which the next change of the
2055 invisible text property can be found in IT->string.
2056 Value will be nil if the property value is the same for
2057 all the rest of IT->string. */
2058 XSETINT (limit, XSTRING (it->string)->size);
2059 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2060 it->string, limit);
2061
2062 /* Text at current position is invisible. The next
2063 change in the property is at position end_charpos.
2064 Move IT's current position to that position. */
2065 if (INTEGERP (end_charpos)
2066 && XFASTINT (end_charpos) < XFASTINT (limit))
2067 {
2068 struct text_pos old;
2069 old = it->current.string_pos;
2070 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2071 compute_string_pos (&it->current.string_pos, old, it->string);
2072 }
2073 else
2074 {
2075 /* The rest of the string is invisible. If this is an
2076 overlay string, proceed with the next overlay string
2077 or whatever comes and return a character from there. */
2078 if (it->current.overlay_string_index >= 0)
2079 {
2080 next_overlay_string (it);
2081 /* Don't check for overlay strings when we just
2082 finished processing them. */
2083 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2084 }
2085 else
2086 {
2087 struct Lisp_String *s = XSTRING (it->string);
2088 IT_STRING_CHARPOS (*it) = s->size;
2089 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2090 }
2091 }
2092 }
2093 }
2094 else
2095 {
2096 int visible_p, newpos, next_stop;
2097 Lisp_Object pos, prop;
2098
2099 /* First of all, is there invisible text at this position? */
2100 XSETFASTINT (pos, IT_CHARPOS (*it));
2101 prop = Fget_char_property (pos, Qinvisible, it->window);
2102
2103 /* If we are on invisible text, skip over it. */
2104 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2105 {
2106 /* Record whether we have to display an ellipsis for the
2107 invisible text. */
2108 int display_ellipsis_p
2109 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2110
2111 handled = HANDLED_RECOMPUTE_PROPS;
2112
2113 /* Loop skipping over invisible text. The loop is left at
2114 ZV or with IT on the first char being visible again. */
2115 do
2116 {
2117 /* Try to skip some invisible text. Return value is the
2118 position reached which can be equal to IT's position
2119 if there is nothing invisible here. This skips both
2120 over invisible text properties and overlays with
2121 invisible property. */
2122 newpos = skip_invisible (IT_CHARPOS (*it),
2123 &next_stop, ZV, it->window);
2124
2125 /* If we skipped nothing at all we weren't at invisible
2126 text in the first place. If everything to the end of
2127 the buffer was skipped, end the loop. */
2128 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2129 visible_p = 1;
2130 else
2131 {
2132 /* We skipped some characters but not necessarily
2133 all there are. Check if we ended up on visible
2134 text. Fget_char_property returns the property of
2135 the char before the given position, i.e. if we
2136 get visible_p = 1, this means that the char at
2137 newpos is visible. */
2138 XSETFASTINT (pos, newpos);
2139 prop = Fget_char_property (pos, Qinvisible, it->window);
2140 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2141 }
2142
2143 /* If we ended up on invisible text, proceed to
2144 skip starting with next_stop. */
2145 if (!visible_p)
2146 IT_CHARPOS (*it) = next_stop;
2147 }
2148 while (!visible_p);
2149
2150 /* The position newpos is now either ZV or on visible text. */
2151 IT_CHARPOS (*it) = newpos;
2152 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2153
2154 /* Maybe return `...' next for the end of the invisible text. */
2155 if (display_ellipsis_p)
2156 {
2157 if (it->dp
2158 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2159 {
2160 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2161 it->dpvec = v->contents;
2162 it->dpend = v->contents + v->size;
2163 }
2164 else
2165 {
2166 /* Default `...'. */
2167 it->dpvec = default_invis_vector;
2168 it->dpend = default_invis_vector + 3;
2169 }
2170
2171 /* The ellipsis display does not replace the display of
2172 the character at the new position. Indicate this by
2173 setting IT->dpvec_char_len to zero. */
2174 it->dpvec_char_len = 0;
2175
2176 it->current.dpvec_index = 0;
2177 it->method = next_element_from_display_vector;
2178 }
2179 }
2180 }
2181
2182 return handled;
2183 }
2184
2185
2186 \f
2187 /***********************************************************************
2188 'display' property
2189 ***********************************************************************/
2190
2191 /* Set up iterator IT from `display' property at its current position.
2192 Called from handle_stop. */
2193
2194 static enum prop_handled
2195 handle_display_prop (it)
2196 struct it *it;
2197 {
2198 Lisp_Object prop, object;
2199 struct text_pos *position;
2200 int space_or_image_found_p;
2201
2202 if (STRINGP (it->string))
2203 {
2204 object = it->string;
2205 position = &it->current.string_pos;
2206 }
2207 else
2208 {
2209 object = Qnil;
2210 position = &it->current.pos;
2211 }
2212
2213 /* Reset those iterator values set from display property values. */
2214 it->font_height = Qnil;
2215 it->space_width = Qnil;
2216 it->voffset = 0;
2217
2218 /* We don't support recursive `display' properties, i.e. string
2219 values that have a string `display' property, that have a string
2220 `display' property etc. */
2221 if (!it->string_from_display_prop_p)
2222 it->area = TEXT_AREA;
2223
2224 prop = Fget_char_property (make_number (position->charpos),
2225 Qdisplay, object);
2226 if (NILP (prop))
2227 return HANDLED_NORMALLY;
2228
2229 space_or_image_found_p = 0;
2230 if (CONSP (prop) && CONSP (XCAR (prop)))
2231 {
2232 while (CONSP (prop))
2233 {
2234 if (handle_single_display_prop (it, XCAR (prop), object, position))
2235 space_or_image_found_p = 1;
2236 prop = XCDR (prop);
2237 }
2238 }
2239 else if (VECTORP (prop))
2240 {
2241 int i;
2242 for (i = 0; i < XVECTOR (prop)->size; ++i)
2243 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2244 object, position))
2245 space_or_image_found_p = 1;
2246 }
2247 else
2248 {
2249 if (handle_single_display_prop (it, prop, object, position))
2250 space_or_image_found_p = 1;
2251 }
2252
2253 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2254 }
2255
2256
2257 /* Value is the position of the end of the `display' property stating
2258 at START_POS in OBJECT. */
2259
2260 static struct text_pos
2261 display_prop_end (it, object, start_pos)
2262 struct it *it;
2263 Lisp_Object object;
2264 struct text_pos start_pos;
2265 {
2266 Lisp_Object end;
2267 struct text_pos end_pos;
2268
2269 /* Characters having this form of property are not displayed, so
2270 we have to find the end of the property. */
2271 end = Fnext_single_property_change (make_number (start_pos.charpos),
2272 Qdisplay, object, Qnil);
2273 if (NILP (end))
2274 {
2275 /* A nil value of `end' means there are no changes of the
2276 property to the end of the buffer or string. */
2277 if (it->current.overlay_string_index >= 0)
2278 end_pos.charpos = XSTRING (it->string)->size;
2279 else
2280 end_pos.charpos = it->end_charpos;
2281 }
2282 else
2283 end_pos.charpos = XFASTINT (end);
2284
2285 if (STRINGP (it->string))
2286 compute_string_pos (&end_pos, start_pos, it->string);
2287 else
2288 end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
2289
2290 return end_pos;
2291 }
2292
2293
2294 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2295 is the object in which the `display' property was found. *POSITION
2296 is the position at which it was found.
2297
2298 If PROP is a `space' or `image' sub-property, set *POSITION to the
2299 end position of the `display' property.
2300
2301 Value is non-zero if a `space' or `image' property value was found. */
2302
2303 static int
2304 handle_single_display_prop (it, prop, object, position)
2305 struct it *it;
2306 Lisp_Object prop;
2307 Lisp_Object object;
2308 struct text_pos *position;
2309 {
2310 Lisp_Object value;
2311 int space_or_image_found_p = 0;
2312
2313 Lisp_Object form;
2314
2315 /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
2316 evaluated. If the result is nil, VALUE is ignored. */
2317 form = Qt;
2318 if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
2319 {
2320 prop = XCDR (prop);
2321 if (!CONSP (prop))
2322 return 0;
2323 form = XCAR (prop);
2324 prop = XCDR (prop);
2325 if (!CONSP (prop))
2326 return 0;
2327 prop = XCAR (prop);
2328 }
2329
2330 if (!NILP (form) && !EQ (form, Qt))
2331 {
2332 struct gcpro gcpro1;
2333 struct text_pos end_pos, pt;
2334
2335 end_pos = display_prop_end (it, object, *position);
2336 GCPRO1 (form);
2337
2338 /* Temporarily set point to the end position, and then evaluate
2339 the form. This makes `(eolp)' work as FORM. */
2340 CHARPOS (pt) = PT;
2341 BYTEPOS (pt) = PT_BYTE;
2342 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2343 form = eval_form (form);
2344 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2345 UNGCPRO;
2346 }
2347
2348 if (NILP (form))
2349 return 0;
2350
2351 if (CONSP (prop)
2352 && EQ (XCAR (prop), Qheight)
2353 && CONSP (XCDR (prop)))
2354 {
2355 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2356 return 0;
2357
2358 /* `(height HEIGHT)'. */
2359 it->font_height = XCAR (XCDR (prop));
2360 if (!NILP (it->font_height))
2361 {
2362 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2363 int new_height = -1;
2364
2365 if (CONSP (it->font_height)
2366 && (EQ (XCAR (it->font_height), Qplus)
2367 || EQ (XCAR (it->font_height), Qminus))
2368 && CONSP (XCDR (it->font_height))
2369 && INTEGERP (XCAR (XCDR (it->font_height))))
2370 {
2371 /* `(+ N)' or `(- N)' where N is an integer. */
2372 int steps = XINT (XCAR (XCDR (it->font_height)));
2373 if (EQ (XCAR (it->font_height), Qplus))
2374 steps = - steps;
2375 it->face_id = smaller_face (it->f, it->face_id, steps);
2376 }
2377 else if (SYMBOLP (it->font_height))
2378 {
2379 /* Call function with current height as argument.
2380 Value is the new height. */
2381 Lisp_Object form, height;
2382 struct gcpro gcpro1;
2383
2384 height = face->lface[LFACE_HEIGHT_INDEX];
2385 form = Fcons (it->font_height, Fcons (height, Qnil));
2386 GCPRO1 (form);
2387 height = eval_form (form);
2388 if (NUMBERP (height))
2389 new_height = XFLOATINT (height);
2390 UNGCPRO;
2391 }
2392 else if (NUMBERP (it->font_height))
2393 {
2394 /* Value is a multiple of the canonical char height. */
2395 struct face *face;
2396
2397 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2398 new_height = (XFLOATINT (it->font_height)
2399 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2400 }
2401 else
2402 {
2403 /* Evaluate IT->font_height with `height' bound to the
2404 current specified height to get the new height. */
2405 Lisp_Object value;
2406 int count = specpdl_ptr - specpdl;
2407
2408 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2409 value = eval_form (it->font_height);
2410 unbind_to (count, Qnil);
2411
2412 if (NUMBERP (value))
2413 new_height = XFLOATINT (value);
2414 }
2415
2416 if (new_height > 0)
2417 it->face_id = face_with_height (it->f, it->face_id, new_height);
2418 }
2419 }
2420 else if (CONSP (prop)
2421 && EQ (XCAR (prop), Qspace_width)
2422 && CONSP (XCDR (prop)))
2423 {
2424 /* `(space_width WIDTH)'. */
2425 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2426 return 0;
2427
2428 value = XCAR (XCDR (prop));
2429 if (NUMBERP (value) && XFLOATINT (value) > 0)
2430 it->space_width = value;
2431 }
2432 else if (CONSP (prop)
2433 && EQ (XCAR (prop), Qraise)
2434 && CONSP (XCDR (prop)))
2435 {
2436 #ifdef HAVE_WINDOW_SYSTEM
2437 /* `(raise FACTOR)'. */
2438 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2439 return 0;
2440
2441 value = XCAR (XCDR (prop));
2442 if (NUMBERP (value))
2443 {
2444 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2445 it->voffset = - (XFLOATINT (value)
2446 * (face->font->ascent + face->font->descent));
2447 }
2448 #endif /* HAVE_WINDOW_SYSTEM */
2449 }
2450 else if (!it->string_from_display_prop_p)
2451 {
2452 /* `(left-margin VALUE)' or `(right-margin VALUE)
2453 or `(nil VALUE)' or VALUE. */
2454 Lisp_Object location, value;
2455 struct text_pos start_pos;
2456 int valid_p;
2457
2458 /* Characters having this form of property are not displayed, so
2459 we have to find the end of the property. */
2460 space_or_image_found_p = 1;
2461 start_pos = *position;
2462 *position = display_prop_end (it, object, start_pos);
2463
2464 /* Let's stop at the new position and assume that all
2465 text properties change there. */
2466 it->stop_charpos = position->charpos;
2467
2468 if (CONSP (prop)
2469 && !EQ (XCAR (prop), Qspace)
2470 && !EQ (XCAR (prop), Qimage))
2471 {
2472 location = XCAR (prop);
2473 value = XCDR (prop);
2474 }
2475 else
2476 {
2477 location = Qnil;
2478 value = prop;
2479 }
2480
2481 #ifdef HAVE_WINDOW_SYSTEM
2482 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2483 valid_p = STRINGP (value);
2484 else
2485 valid_p = (STRINGP (value)
2486 || (CONSP (value) && EQ (XCAR (value), Qspace))
2487 || valid_image_p (value));
2488 #else /* not HAVE_WINDOW_SYSTEM */
2489 valid_p = STRINGP (value);
2490 #endif /* not HAVE_WINDOW_SYSTEM */
2491
2492 if ((EQ (location, Qleft_margin)
2493 || EQ (location, Qright_margin)
2494 || NILP (location))
2495 && valid_p)
2496 {
2497 /* Save current settings of IT so that we can restore them
2498 when we are finished with the glyph property value. */
2499 push_it (it);
2500
2501 if (NILP (location))
2502 it->area = TEXT_AREA;
2503 else if (EQ (location, Qleft_margin))
2504 it->area = LEFT_MARGIN_AREA;
2505 else
2506 it->area = RIGHT_MARGIN_AREA;
2507
2508 if (STRINGP (value))
2509 {
2510 it->string = value;
2511 it->multibyte_p = STRING_MULTIBYTE (it->string);
2512 it->current.overlay_string_index = -1;
2513 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2514 it->end_charpos = it->string_nchars
2515 = XSTRING (it->string)->size;
2516 it->method = next_element_from_string;
2517 it->stop_charpos = 0;
2518 it->string_from_display_prop_p = 1;
2519 }
2520 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2521 {
2522 it->method = next_element_from_stretch;
2523 it->object = value;
2524 it->current.pos = it->position = start_pos;
2525 }
2526 #ifdef HAVE_WINDOW_SYSTEM
2527 else
2528 {
2529 it->what = IT_IMAGE;
2530 it->image_id = lookup_image (it->f, value);
2531 it->position = start_pos;
2532 it->object = NILP (object) ? it->w->buffer : object;
2533 it->method = next_element_from_image;
2534
2535 /* Say that we don't have consumed the characters with
2536 `display' property yet. The call to pop_it in
2537 set_iterator_to_next will clean this up. */
2538 *position = start_pos;
2539 }
2540 #endif /* HAVE_WINDOW_SYSTEM */
2541 }
2542 }
2543
2544 return space_or_image_found_p;
2545 }
2546
2547
2548 \f
2549 /***********************************************************************
2550 Overlay strings
2551 ***********************************************************************/
2552
2553 /* The following structure is used to record overlay strings for
2554 later sorting in load_overlay_strings. */
2555
2556 struct overlay_entry
2557 {
2558 Lisp_Object string;
2559 int priority;
2560 int after_string_p;
2561 };
2562
2563
2564 /* Set up iterator IT from overlay strings at its current position.
2565 Called from handle_stop. */
2566
2567 static enum prop_handled
2568 handle_overlay_change (it)
2569 struct it *it;
2570 {
2571 /* Overlays are handled in current_buffer only. */
2572 if (STRINGP (it->string))
2573 return HANDLED_NORMALLY;
2574 else
2575 return (get_overlay_strings (it)
2576 ? HANDLED_RECOMPUTE_PROPS
2577 : HANDLED_NORMALLY);
2578 }
2579
2580
2581 /* Set up the next overlay string for delivery by IT, if there is an
2582 overlay string to deliver. Called by set_iterator_to_next when the
2583 end of the current overlay string is reached. If there are more
2584 overlay strings to display, IT->string and
2585 IT->current.overlay_string_index are set appropriately here.
2586 Otherwise IT->string is set to nil. */
2587
2588 static void
2589 next_overlay_string (it)
2590 struct it *it;
2591 {
2592 ++it->current.overlay_string_index;
2593 if (it->current.overlay_string_index == it->n_overlay_strings)
2594 {
2595 /* No more overlay strings. Restore IT's settings to what
2596 they were before overlay strings were processed, and
2597 continue to deliver from current_buffer. */
2598 pop_it (it);
2599 xassert (it->stop_charpos >= BEGV
2600 && it->stop_charpos <= it->end_charpos);
2601 it->string = Qnil;
2602 it->current.overlay_string_index = -1;
2603 SET_TEXT_POS (it->current.string_pos, -1, -1);
2604 it->n_overlay_strings = 0;
2605 it->method = next_element_from_buffer;
2606 }
2607 else
2608 {
2609 /* There are more overlay strings to process. If
2610 IT->current.overlay_string_index has advanced to a position
2611 where we must load IT->overlay_strings with more strings, do
2612 it. */
2613 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2614
2615 if (it->current.overlay_string_index && i == 0)
2616 load_overlay_strings (it);
2617
2618 /* Initialize IT to deliver display elements from the overlay
2619 string. */
2620 it->string = it->overlay_strings[i];
2621 it->multibyte_p = STRING_MULTIBYTE (it->string);
2622 SET_TEXT_POS (it->current.string_pos, 0, 0);
2623 it->method = next_element_from_string;
2624 it->stop_charpos = 0;
2625 }
2626
2627 CHECK_IT (it);
2628 }
2629
2630
2631 /* Compare two overlay_entry structures E1 and E2. Used as a
2632 comparison function for qsort in load_overlay_strings. Overlay
2633 strings for the same position are sorted so that
2634
2635 1. All after-strings come in front of before-strings.
2636
2637 2. Within after-strings, strings are sorted so that overlay strings
2638 from overlays with higher priorities come first.
2639
2640 2. Within before-strings, strings are sorted so that overlay
2641 strings from overlays with higher priorities come last.
2642
2643 Value is analogous to strcmp. */
2644
2645
2646 static int
2647 compare_overlay_entries (e1, e2)
2648 void *e1, *e2;
2649 {
2650 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2651 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2652 int result;
2653
2654 if (entry1->after_string_p != entry2->after_string_p)
2655 /* Let after-strings appear in front of before-strings. */
2656 result = entry1->after_string_p ? -1 : 1;
2657 else if (entry1->after_string_p)
2658 /* After-strings sorted in order of decreasing priority. */
2659 result = entry2->priority - entry1->priority;
2660 else
2661 /* Before-strings sorted in order of increasing priority. */
2662 result = entry1->priority - entry2->priority;
2663
2664 return result;
2665 }
2666
2667
2668 /* Load the vector IT->overlay_strings with overlay strings from IT's
2669 current buffer position. Set IT->n_overlays to the total number of
2670 overlay strings found.
2671
2672 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2673 a time. On entry into load_overlay_strings,
2674 IT->current.overlay_string_index gives the number of overlay
2675 strings that have already been loaded by previous calls to this
2676 function.
2677
2678 Overlay strings are sorted so that after-string strings come in
2679 front of before-string strings. Within before and after-strings,
2680 strings are sorted by overlay priority. See also function
2681 compare_overlay_entries. */
2682
2683 static void
2684 load_overlay_strings (it)
2685 struct it *it;
2686 {
2687 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2688 Lisp_Object ov, overlay, window, str;
2689 int start, end;
2690 int size = 20;
2691 int n = 0, i, j;
2692 struct overlay_entry *entries
2693 = (struct overlay_entry *) alloca (size * sizeof *entries);
2694
2695 /* Append the overlay string STRING of overlay OVERLAY to vector
2696 `entries' which has size `size' and currently contains `n'
2697 elements. AFTER_P non-zero means STRING is an after-string of
2698 OVERLAY. */
2699 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2700 do \
2701 { \
2702 Lisp_Object priority; \
2703 \
2704 if (n == size) \
2705 { \
2706 int new_size = 2 * size; \
2707 struct overlay_entry *old = entries; \
2708 entries = \
2709 (struct overlay_entry *) alloca (new_size \
2710 * sizeof *entries); \
2711 bcopy (old, entries, size * sizeof *entries); \
2712 size = new_size; \
2713 } \
2714 \
2715 entries[n].string = (STRING); \
2716 priority = Foverlay_get ((OVERLAY), Qpriority); \
2717 entries[n].priority \
2718 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2719 entries[n].after_string_p = (AFTER_P); \
2720 ++n; \
2721 } \
2722 while (0)
2723
2724 /* Process overlay before the overlay center. */
2725 for (ov = current_buffer->overlays_before;
2726 CONSP (ov);
2727 ov = XCONS (ov)->cdr)
2728 {
2729 overlay = XCONS (ov)->car;
2730 xassert (OVERLAYP (overlay));
2731 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2732 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2733
2734 if (end < IT_CHARPOS (*it))
2735 break;
2736
2737 /* Skip this overlay if it doesn't start or end at IT's current
2738 position. */
2739 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2740 continue;
2741
2742 /* Skip this overlay if it doesn't apply to IT->w. */
2743 window = Foverlay_get (overlay, Qwindow);
2744 if (WINDOWP (window) && XWINDOW (window) != it->w)
2745 continue;
2746
2747 /* If overlay has a non-empty before-string, record it. */
2748 if (start == IT_CHARPOS (*it)
2749 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2750 && XSTRING (str)->size)
2751 RECORD_OVERLAY_STRING (overlay, str, 0);
2752
2753 /* If overlay has a non-empty after-string, record it. */
2754 if (end == IT_CHARPOS (*it)
2755 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2756 && XSTRING (str)->size)
2757 RECORD_OVERLAY_STRING (overlay, str, 1);
2758 }
2759
2760 /* Process overlays after the overlay center. */
2761 for (ov = current_buffer->overlays_after;
2762 CONSP (ov);
2763 ov = XCONS (ov)->cdr)
2764 {
2765 overlay = XCONS (ov)->car;
2766 xassert (OVERLAYP (overlay));
2767 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2768 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2769
2770 if (start > IT_CHARPOS (*it))
2771 break;
2772
2773 /* Skip this overlay if it doesn't start or end at IT's current
2774 position. */
2775 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2776 continue;
2777
2778 /* Skip this overlay if it doesn't apply to IT->w. */
2779 window = Foverlay_get (overlay, Qwindow);
2780 if (WINDOWP (window) && XWINDOW (window) != it->w)
2781 continue;
2782
2783 /* If overlay has a non-empty before-string, record it. */
2784 if (start == IT_CHARPOS (*it)
2785 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2786 && XSTRING (str)->size)
2787 RECORD_OVERLAY_STRING (overlay, str, 0);
2788
2789 /* If overlay has a non-empty after-string, record it. */
2790 if (end == IT_CHARPOS (*it)
2791 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2792 && XSTRING (str)->size)
2793 RECORD_OVERLAY_STRING (overlay, str, 1);
2794 }
2795
2796 #undef RECORD_OVERLAY_STRING
2797
2798 /* Sort entries. */
2799 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2800
2801 /* Record the total number of strings to process. */
2802 it->n_overlay_strings = n;
2803
2804 /* IT->current.overlay_string_index is the number of overlay strings
2805 that have already been consumed by IT. Copy some of the
2806 remaining overlay strings to IT->overlay_strings. */
2807 i = 0;
2808 j = it->current.overlay_string_index;
2809 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2810 it->overlay_strings[i++] = entries[j++].string;
2811
2812 CHECK_IT (it);
2813 }
2814
2815
2816 /* Get the first chunk of overlay strings at IT's current buffer
2817 position. Value is non-zero if at least one overlay string was
2818 found. */
2819
2820 static int
2821 get_overlay_strings (it)
2822 struct it *it;
2823 {
2824 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2825 process. This fills IT->overlay_strings with strings, and sets
2826 IT->n_overlay_strings to the total number of strings to process.
2827 IT->pos.overlay_string_index has to be set temporarily to zero
2828 because load_overlay_strings needs this; it must be set to -1
2829 when no overlay strings are found because a zero value would
2830 indicate a position in the first overlay string. */
2831 it->current.overlay_string_index = 0;
2832 load_overlay_strings (it);
2833
2834 /* If we found overlay strings, set up IT to deliver display
2835 elements from the first one. Otherwise set up IT to deliver
2836 from current_buffer. */
2837 if (it->n_overlay_strings)
2838 {
2839 /* Make sure we know settings in current_buffer, so that we can
2840 restore meaningful values when we're done with the overlay
2841 strings. */
2842 compute_stop_pos (it);
2843 xassert (it->face_id >= 0);
2844
2845 /* Save IT's settings. They are restored after all overlay
2846 strings have been processed. */
2847 xassert (it->sp == 0);
2848 push_it (it);
2849
2850 /* Set up IT to deliver display elements from the first overlay
2851 string. */
2852 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2853 it->stop_charpos = 0;
2854 it->string = it->overlay_strings[0];
2855 it->multibyte_p = STRING_MULTIBYTE (it->string);
2856 xassert (STRINGP (it->string));
2857 it->method = next_element_from_string;
2858 }
2859 else
2860 {
2861 it->string = Qnil;
2862 it->current.overlay_string_index = -1;
2863 it->method = next_element_from_buffer;
2864 }
2865
2866 CHECK_IT (it);
2867
2868 /* Value is non-zero if we found at least one overlay string. */
2869 return STRINGP (it->string);
2870 }
2871
2872
2873 \f
2874 /***********************************************************************
2875 Saving and restoring state
2876 ***********************************************************************/
2877
2878 /* Save current settings of IT on IT->stack. Called, for example,
2879 before setting up IT for an overlay string, to be able to restore
2880 IT's settings to what they were after the overlay string has been
2881 processed. */
2882
2883 static void
2884 push_it (it)
2885 struct it *it;
2886 {
2887 struct iterator_stack_entry *p;
2888
2889 xassert (it->sp < 2);
2890 p = it->stack + it->sp;
2891
2892 p->stop_charpos = it->stop_charpos;
2893 xassert (it->face_id >= 0);
2894 p->face_id = it->face_id;
2895 p->string = it->string;
2896 p->pos = it->current;
2897 p->end_charpos = it->end_charpos;
2898 p->string_nchars = it->string_nchars;
2899 p->area = it->area;
2900 p->multibyte_p = it->multibyte_p;
2901 p->space_width = it->space_width;
2902 p->font_height = it->font_height;
2903 p->voffset = it->voffset;
2904 p->string_from_display_prop_p = it->string_from_display_prop_p;
2905 ++it->sp;
2906 }
2907
2908
2909 /* Restore IT's settings from IT->stack. Called, for example, when no
2910 more overlay strings must be processed, and we return to delivering
2911 display elements from a buffer, or when the end of a string from a
2912 `display' property is reached and we return to delivering display
2913 elements from an overlay string, or from a buffer. */
2914
2915 static void
2916 pop_it (it)
2917 struct it *it;
2918 {
2919 struct iterator_stack_entry *p;
2920
2921 xassert (it->sp > 0);
2922 --it->sp;
2923 p = it->stack + it->sp;
2924 it->stop_charpos = p->stop_charpos;
2925 it->face_id = p->face_id;
2926 it->string = p->string;
2927 it->current = p->pos;
2928 it->end_charpos = p->end_charpos;
2929 it->string_nchars = p->string_nchars;
2930 it->area = p->area;
2931 it->multibyte_p = p->multibyte_p;
2932 it->space_width = p->space_width;
2933 it->font_height = p->font_height;
2934 it->voffset = p->voffset;
2935 it->string_from_display_prop_p = p->string_from_display_prop_p;
2936 }
2937
2938
2939 \f
2940 /***********************************************************************
2941 Moving over lines
2942 ***********************************************************************/
2943
2944 /* Set IT's current position to the previous line start. */
2945
2946 static void
2947 back_to_previous_line_start (it)
2948 struct it *it;
2949 {
2950 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
2951 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2952 }
2953
2954
2955 /* Set IT's current position to the next line start. */
2956
2957 static void
2958 forward_to_next_line_start (it)
2959 struct it *it;
2960 {
2961 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
2962 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2963 }
2964
2965
2966 /* Set IT's current position to the previous visible line start. Skip
2967 invisible text that is so either due to text properties or due to
2968 selective display. Caution: this does not change IT->current_x and
2969 IT->hpos. */
2970
2971 static void
2972 back_to_previous_visible_line_start (it)
2973 struct it *it;
2974 {
2975 int visible_p = 0;
2976
2977 /* Go back one newline if not on BEGV already. */
2978 if (IT_CHARPOS (*it) > BEGV)
2979 back_to_previous_line_start (it);
2980
2981 /* Move over lines that are invisible because of selective display
2982 or text properties. */
2983 while (IT_CHARPOS (*it) > BEGV
2984 && !visible_p)
2985 {
2986 visible_p = 1;
2987
2988 /* If selective > 0, then lines indented more than that values
2989 are invisible. */
2990 if (it->selective > 0
2991 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
2992 it->selective))
2993 visible_p = 0;
2994 #ifdef USE_TEXT_PROPERTIES
2995 else
2996 {
2997 Lisp_Object prop;
2998
2999 prop = Fget_char_property (IT_CHARPOS (*it), Qinvisible, it->window);
3000 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3001 visible_p = 0;
3002 }
3003 #endif /* USE_TEXT_PROPERTIES */
3004
3005 /* Back one more newline if the current one is invisible. */
3006 if (!visible_p)
3007 back_to_previous_line_start (it);
3008 }
3009
3010 xassert (IT_CHARPOS (*it) >= BEGV);
3011 xassert (IT_CHARPOS (*it) == BEGV
3012 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3013 CHECK_IT (it);
3014 }
3015
3016
3017 /* Reseat iterator IT at the previous visible line start. Skip
3018 invisible text that is so either due to text properties or due to
3019 selective display. At the end, update IT's overlay information,
3020 face information etc. */
3021
3022 static void
3023 reseat_at_previous_visible_line_start (it)
3024 struct it *it;
3025 {
3026 back_to_previous_visible_line_start (it);
3027 reseat (it, it->current.pos, 1);
3028 CHECK_IT (it);
3029 }
3030
3031
3032 /* Reseat iterator IT on the next visible line start in the current
3033 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3034 preceding the line start. Skip over invisible text that is so
3035 because of selective display. Compute faces, overlays etc at the
3036 new position. Note that this function does not skip over text that
3037 is invisible because of text properties. */
3038
3039 static void
3040 reseat_at_next_visible_line_start (it, on_newline_p)
3041 struct it *it;
3042 int on_newline_p;
3043 {
3044 /* Restore the buffer position when currently not delivering display
3045 elements from the current buffer. This is the case, for example,
3046 when called at the end of a truncated overlay string. */
3047 while (it->sp)
3048 pop_it (it);
3049 it->method = next_element_from_buffer;
3050
3051 /* Otherwise, scan_buffer would not work. */
3052 if (IT_CHARPOS (*it) < ZV)
3053 {
3054 /* If on a newline, advance past it. Otherwise, find the next
3055 newline which automatically gives us the position following
3056 the newline. */
3057 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3058 {
3059 ++IT_CHARPOS (*it);
3060 ++IT_BYTEPOS (*it);
3061 }
3062 else
3063 forward_to_next_line_start (it);
3064
3065 /* We must either have reached the end of the buffer or end up
3066 after a newline. */
3067 xassert (IT_CHARPOS (*it) == ZV
3068 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3069
3070 /* Skip over lines that are invisible because they are indented
3071 more than the value of IT->selective. */
3072 if (it->selective > 0)
3073 while (IT_CHARPOS (*it) < ZV
3074 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3075 it->selective))
3076 forward_to_next_line_start (it);
3077
3078 /* Position on the newline if we should. */
3079 if (on_newline_p && IT_CHARPOS (*it) > BEGV)
3080 {
3081 --IT_CHARPOS (*it);
3082 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3083 }
3084
3085 /* Set the iterator there. The 0 as the last parameter of
3086 reseat means don't force a text property lookup. The lookup
3087 is then only done if we've skipped past the iterator's
3088 check_charpos'es. This optimization is important because
3089 text property lookups tend to be expensive. */
3090 reseat (it, it->current.pos, 0);
3091 }
3092
3093 CHECK_IT (it);
3094 }
3095
3096
3097 \f
3098 /***********************************************************************
3099 Changing an iterator's position
3100 ***********************************************************************/
3101
3102 /* Change IT's current position to POS in current_buffer. If FORCE_P
3103 is non-zero, always check for text properties at the new position.
3104 Otherwise, text properties are only looked up if POS >=
3105 IT->check_charpos of a property. */
3106
3107 static void
3108 reseat (it, pos, force_p)
3109 struct it *it;
3110 struct text_pos pos;
3111 int force_p;
3112 {
3113 int original_pos = IT_CHARPOS (*it);
3114
3115 reseat_1 (it, pos, 0);
3116
3117 /* Determine where to check text properties. Avoid doing it
3118 where possible because text property lookup is very expensive. */
3119 if (force_p
3120 || CHARPOS (pos) > it->stop_charpos
3121 || CHARPOS (pos) < original_pos)
3122 handle_stop (it);
3123
3124 CHECK_IT (it);
3125 }
3126
3127
3128 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3129 IT->stop_pos to POS, also. */
3130
3131 static void
3132 reseat_1 (it, pos, set_stop_p)
3133 struct it *it;
3134 struct text_pos pos;
3135 int set_stop_p;
3136 {
3137 /* Don't call this function when scanning a C string. */
3138 xassert (it->s == NULL);
3139
3140 /* POS must be a reasonable value. */
3141 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3142
3143 it->current.pos = it->position = pos;
3144 XSETBUFFER (it->object, current_buffer);
3145 it->dpvec = NULL;
3146 it->current.dpvec_index = -1;
3147 it->current.overlay_string_index = -1;
3148 IT_STRING_CHARPOS (*it) = -1;
3149 IT_STRING_BYTEPOS (*it) = -1;
3150 it->string = Qnil;
3151 it->method = next_element_from_buffer;
3152 it->sp = 0;
3153
3154 if (set_stop_p)
3155 it->stop_charpos = CHARPOS (pos);
3156 }
3157
3158
3159 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3160 If S is non-null, it is a C string to iterate over. Otherwise,
3161 STRING gives a Lisp string to iterate over.
3162
3163 If PRECISION > 0, don't return more then PRECISION number of
3164 characters from the string.
3165
3166 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3167 characters have been returned. FIELD_WIDTH < 0 means an infinite
3168 field width.
3169
3170 MULTIBYTE = 0 means disable processing of multibyte characters,
3171 MULTIBYTE > 0 means enable it,
3172 MULTIBYTE < 0 means use IT->multibyte_p.
3173
3174 IT must be initialized via a prior call to init_iterator before
3175 calling this function. */
3176
3177 static void
3178 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3179 struct it *it;
3180 unsigned char *s;
3181 Lisp_Object string;
3182 int charpos;
3183 int precision, field_width, multibyte;
3184 {
3185 /* No region in strings. */
3186 it->region_beg_charpos = it->region_end_charpos = -1;
3187
3188 /* No text property checks performed by default, but see below. */
3189 it->stop_charpos = -1;
3190
3191 /* Set iterator position and end position. */
3192 bzero (&it->current, sizeof it->current);
3193 it->current.overlay_string_index = -1;
3194 it->current.dpvec_index = -1;
3195 it->charset = CHARSET_ASCII;
3196 xassert (charpos >= 0);
3197
3198 /* Use the setting of MULTIBYTE if specified. */
3199 if (multibyte >= 0)
3200 it->multibyte_p = multibyte > 0;
3201
3202 if (s == NULL)
3203 {
3204 xassert (STRINGP (string));
3205 it->string = string;
3206 it->s = NULL;
3207 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3208 it->method = next_element_from_string;
3209 it->current.string_pos = string_pos (charpos, string);
3210 }
3211 else
3212 {
3213 it->s = s;
3214 it->string = Qnil;
3215
3216 /* Note that we use IT->current.pos, not it->current.string_pos,
3217 for displaying C strings. */
3218 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3219 if (it->multibyte_p)
3220 {
3221 it->current.pos = c_string_pos (charpos, s, 1);
3222 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3223 }
3224 else
3225 {
3226 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3227 it->end_charpos = it->string_nchars = strlen (s);
3228 }
3229
3230 it->method = next_element_from_c_string;
3231 }
3232
3233 /* PRECISION > 0 means don't return more than PRECISION characters
3234 from the string. */
3235 if (precision > 0 && it->end_charpos - charpos > precision)
3236 it->end_charpos = it->string_nchars = charpos + precision;
3237
3238 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3239 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3240 FIELD_WIDTH < 0 means infinite field width. This is useful for
3241 padding with `-' at the end of a mode line. */
3242 if (field_width < 0)
3243 field_width = INFINITY;
3244 if (field_width > it->end_charpos - charpos)
3245 it->end_charpos = charpos + field_width;
3246
3247 /* Use the standard display table for displaying strings. */
3248 if (DISP_TABLE_P (Vstandard_display_table))
3249 it->dp = XCHAR_TABLE (Vstandard_display_table);
3250
3251 it->stop_charpos = charpos;
3252 CHECK_IT (it);
3253 }
3254
3255
3256 \f
3257 /***********************************************************************
3258 Iteration
3259 ***********************************************************************/
3260
3261 /* Load IT's display element fields with information about the next
3262 display element from the current position of IT. Value is zero if
3263 end of buffer (or C string) is reached. */
3264
3265 int
3266 get_next_display_element (it)
3267 struct it *it;
3268 {
3269 /* Non-zero means that we found an display element. Zero means that
3270 we hit the end of what we iterate over. Performance note: the
3271 function pointer `method' used here turns out to be faster than
3272 using a sequence of if-statements. */
3273 int success_p = (*it->method) (it);
3274 int charset;
3275
3276 if (it->what == IT_CHARACTER)
3277 {
3278 /* Map via display table or translate control characters.
3279 IT->c, IT->len etc. have been set to the next character by
3280 the function call above. If we have a display table, and it
3281 contains an entry for IT->c, translate it. Don't do this if
3282 IT->c itself comes from a display table, otherwise we could
3283 end up in an infinite recursion. (An alternative could be to
3284 count the recursion depth of this function and signal an
3285 error when a certain maximum depth is reached.) Is it worth
3286 it? */
3287 if (success_p && it->dpvec == NULL)
3288 {
3289 Lisp_Object dv;
3290
3291 if (it->dp
3292 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3293 VECTORP (dv)))
3294 {
3295 struct Lisp_Vector *v = XVECTOR (dv);
3296
3297 /* Return the first character from the display table
3298 entry, if not empty. If empty, don't display the
3299 current character. */
3300 if (v->size)
3301 {
3302 it->dpvec_char_len = it->len;
3303 it->dpvec = v->contents;
3304 it->dpend = v->contents + v->size;
3305 it->current.dpvec_index = 0;
3306 it->method = next_element_from_display_vector;
3307 }
3308
3309 success_p = get_next_display_element (it);
3310 }
3311
3312 /* Translate control characters into `\003' or `^C' form.
3313 Control characters coming from a display table entry are
3314 currently not translated because we use IT->dpvec to hold
3315 the translation. This could easily be changed but I
3316 don't believe that it is worth doing. */
3317 else if ((it->c < ' '
3318 && (it->area != TEXT_AREA
3319 || (it->c != '\n'
3320 && it->c != '\t'
3321 && it->c != '\r')))
3322 || (it->c >= 127
3323 && it->len == 1))
3324 {
3325 /* IT->c is a control character which must be displayed
3326 either as '\003' or as `^C' where the '\\' and '^'
3327 can be defined in the display table. Fill
3328 IT->ctl_chars with glyphs for what we have to
3329 display. Then, set IT->dpvec to these glyphs. */
3330 GLYPH g;
3331
3332 if (it->c < 128 && it->ctl_arrow_p)
3333 {
3334 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3335 if (it->dp
3336 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3337 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3338 g = XINT (DISP_CTRL_GLYPH (it->dp));
3339 else
3340 g = FAST_MAKE_GLYPH ('^', 0);
3341 XSETINT (it->ctl_chars[0], g);
3342
3343 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3344 XSETINT (it->ctl_chars[1], g);
3345
3346 /* Set up IT->dpvec and return first character from it. */
3347 it->dpvec_char_len = it->len;
3348 it->dpvec = it->ctl_chars;
3349 it->dpend = it->dpvec + 2;
3350 it->current.dpvec_index = 0;
3351 it->method = next_element_from_display_vector;
3352 get_next_display_element (it);
3353 }
3354 else
3355 {
3356 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3357 if (it->dp
3358 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3359 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3360 g = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3361 else
3362 g = FAST_MAKE_GLYPH ('\\', 0);
3363 XSETINT (it->ctl_chars[0], g);
3364
3365 /* Insert three more glyphs into IT->ctl_chars for
3366 the octal display of the character. */
3367 g = FAST_MAKE_GLYPH (((it->c >> 6) & 7) + '0', 0);
3368 XSETINT (it->ctl_chars[1], g);
3369 g = FAST_MAKE_GLYPH (((it->c >> 3) & 7) + '0', 0);
3370 XSETINT (it->ctl_chars[2], g);
3371 g = FAST_MAKE_GLYPH ((it->c & 7) + '0', 0);
3372 XSETINT (it->ctl_chars[3], g);
3373
3374 /* Set up IT->dpvec and return the first character
3375 from it. */
3376 it->dpvec_char_len = it->len;
3377 it->dpvec = it->ctl_chars;
3378 it->dpend = it->dpvec + 4;
3379 it->current.dpvec_index = 0;
3380 it->method = next_element_from_display_vector;
3381 get_next_display_element (it);
3382 }
3383 }
3384 }
3385
3386 /* Adjust face id if charset changes. There are no charset
3387 changes in unibyte text because Emacs' charsets are not
3388 applicable there. */
3389 if (it->multibyte_p
3390 && success_p
3391 && (charset = CHAR_CHARSET (it->c),
3392 charset != it->charset))
3393 {
3394 it->charset = charset;
3395 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, charset);
3396 }
3397 }
3398
3399 /* Is this character the last one of a run of characters with
3400 box? If yes, set IT->end_of_box_run_p to 1. */
3401 if (it->face_box_p
3402 && it->s == NULL)
3403 {
3404 int face_id;
3405 struct face *face;
3406
3407 it->end_of_box_run_p
3408 = ((face_id = face_after_it_pos (it),
3409 face_id != it->face_id)
3410 && (face = FACE_FROM_ID (it->f, face_id),
3411 face->box == FACE_NO_BOX));
3412 }
3413
3414 /* Value is 0 if end of buffer or string reached. */
3415 return success_p;
3416 }
3417
3418
3419 /* Move IT to the next display element.
3420
3421 Functions get_next_display_element and set_iterator_to_next are
3422 separate because I find this arrangement easier to handle than a
3423 get_next_display_element function that also increments IT's
3424 position. The way it is we can first look at an iterator's current
3425 display element, decide whether it fits on a line, and if it does,
3426 increment the iterator position. The other way around we probably
3427 would either need a flag indicating whether the iterator has to be
3428 incremented the next time, or we would have to implement a
3429 decrement position function which would not be easy to write. */
3430
3431 void
3432 set_iterator_to_next (it)
3433 struct it *it;
3434 {
3435 if (it->method == next_element_from_buffer)
3436 {
3437 /* The current display element of IT is a character from
3438 current_buffer. Advance in the buffer, and maybe skip over
3439 invisible lines that are so because of selective display. */
3440 if (ITERATOR_AT_END_OF_LINE_P (it))
3441 reseat_at_next_visible_line_start (it, 0);
3442 else
3443 {
3444 xassert (it->len != 0);
3445 IT_BYTEPOS (*it) += it->len;
3446 IT_CHARPOS (*it) += 1;
3447 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3448 }
3449 }
3450 else if (it->method == next_element_from_c_string)
3451 {
3452 /* Current display element of IT is from a C string. */
3453 IT_BYTEPOS (*it) += it->len;
3454 IT_CHARPOS (*it) += 1;
3455 }
3456 else if (it->method == next_element_from_display_vector)
3457 {
3458 /* Current display element of IT is from a display table entry.
3459 Advance in the display table definition. Reset it to null if
3460 end reached, and continue with characters from buffers/
3461 strings. */
3462 struct face *face;
3463
3464 ++it->current.dpvec_index;
3465
3466 /* Restore face and charset of the iterator to what they were
3467 before the display vector entry (these entries may contain
3468 faces, and of course characters of different charsets). */
3469 it->face_id = it->saved_face_id;
3470 it->charset = FACE_FROM_ID (it->f, it->face_id)->charset;
3471
3472 if (it->dpvec + it->current.dpvec_index == it->dpend)
3473 {
3474 if (it->s)
3475 it->method = next_element_from_c_string;
3476 else if (STRINGP (it->string))
3477 it->method = next_element_from_string;
3478 else
3479 it->method = next_element_from_buffer;
3480
3481 it->dpvec = NULL;
3482 it->current.dpvec_index = -1;
3483
3484 /* Skip over characters which were displayed via IT->dpvec. */
3485 if (it->dpvec_char_len < 0)
3486 reseat_at_next_visible_line_start (it, 1);
3487 else if (it->dpvec_char_len > 0)
3488 {
3489 it->len = it->dpvec_char_len;
3490 set_iterator_to_next (it);
3491 }
3492 }
3493 }
3494 else if (it->method == next_element_from_string)
3495 {
3496 /* Current display element is a character from a Lisp string. */
3497 xassert (it->s == NULL && STRINGP (it->string));
3498 IT_STRING_BYTEPOS (*it) += it->len;
3499 IT_STRING_CHARPOS (*it) += 1;
3500
3501 consider_string_end:
3502
3503 if (it->current.overlay_string_index >= 0)
3504 {
3505 /* IT->string is an overlay string. Advance to the
3506 next, if there is one. */
3507 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3508 next_overlay_string (it);
3509 }
3510 else
3511 {
3512 /* IT->string is not an overlay string. If we reached
3513 its end, and there is something on IT->stack, proceed
3514 with what is on the stack. This can be either another
3515 string, this time an overlay string, or a buffer. */
3516 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3517 && it->sp > 0)
3518 {
3519 pop_it (it);
3520 if (!STRINGP (it->string))
3521 it->method = next_element_from_buffer;
3522 }
3523 }
3524 }
3525 else if (it->method == next_element_from_image
3526 || it->method == next_element_from_stretch)
3527 {
3528 /* The position etc with which we have to proceed are on
3529 the stack. The position may be at the end of a string,
3530 if the `display' property takes up the whole string. */
3531 pop_it (it);
3532 it->image_id = 0;
3533 if (STRINGP (it->string))
3534 {
3535 it->method = next_element_from_string;
3536 goto consider_string_end;
3537 }
3538 else
3539 it->method = next_element_from_buffer;
3540 }
3541 else
3542 /* There are no other methods defined, so this should be a bug. */
3543 abort ();
3544
3545 /* Reset flags indicating start and end of a sequence of
3546 characters with box. */
3547 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3548
3549 xassert (it->method != next_element_from_string
3550 || (STRINGP (it->string)
3551 && IT_STRING_CHARPOS (*it) >= 0));
3552 }
3553
3554
3555 /* Load IT's display element fields with information about the next
3556 display element which comes from a display table entry or from the
3557 result of translating a control character to one of the forms `^C'
3558 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3559
3560 static int
3561 next_element_from_display_vector (it)
3562 struct it *it;
3563 {
3564 /* Precondition. */
3565 xassert (it->dpvec && it->current.dpvec_index >= 0);
3566
3567 /* Remember the current face id in case glyphs specify faces.
3568 IT's face is restored in set_iterator_to_next. */
3569 it->saved_face_id = it->face_id;
3570
3571 if (INTEGERP (*it->dpvec)
3572 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3573 {
3574 int lface_id;
3575 GLYPH g;
3576
3577 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3578 it->c = FAST_GLYPH_CHAR (g);
3579 it->len = CHAR_LEN (it->c);
3580
3581 /* The entry may contain a face id to use. Such a face id is
3582 the id of a Lisp face, not a realized face. A face id of
3583 zero means no face. */
3584 lface_id = FAST_GLYPH_FACE (g);
3585 if (lface_id)
3586 {
3587 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3588 if (face_id >= 0)
3589 {
3590 it->face_id = face_id;
3591 it->charset = CHARSET_ASCII;
3592 }
3593 }
3594 }
3595 else
3596 /* Display table entry is invalid. Return a space. */
3597 it->c = ' ', it->len = 1;
3598
3599 /* Don't change position and object of the iterator here. They are
3600 still the values of the character that had this display table
3601 entry or was translated, and that's what we want. */
3602 it->what = IT_CHARACTER;
3603 return 1;
3604 }
3605
3606
3607 /* Load IT with the next display element from Lisp string IT->string.
3608 IT->current.string_pos is the current position within the string.
3609 If IT->current.overlay_string_index >= 0, the Lisp string is an
3610 overlay string. */
3611
3612 static int
3613 next_element_from_string (it)
3614 struct it *it;
3615 {
3616 struct text_pos position;
3617
3618 xassert (STRINGP (it->string));
3619 xassert (IT_STRING_CHARPOS (*it) >= 0);
3620 position = it->current.string_pos;
3621
3622 /* Time to check for invisible text? */
3623 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3624 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3625 {
3626 handle_stop (it);
3627
3628 /* Since a handler may have changed IT->method, we must
3629 recurse here. */
3630 return get_next_display_element (it);
3631 }
3632
3633 if (it->current.overlay_string_index >= 0)
3634 {
3635 /* Get the next character from an overlay string. In overlay
3636 strings, There is no field width or padding with spaces to
3637 do. */
3638 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3639 {
3640 it->what = IT_EOB;
3641 return 0;
3642 }
3643 else if (STRING_MULTIBYTE (it->string))
3644 {
3645 int remaining = (STRING_BYTES (XSTRING (it->string))
3646 - IT_STRING_BYTEPOS (*it));
3647 unsigned char *s = (XSTRING (it->string)->data
3648 + IT_STRING_BYTEPOS (*it));
3649 it->c = string_char_and_length (s, remaining, &it->len);
3650 }
3651 else
3652 {
3653 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3654 it->len = 1;
3655 }
3656 }
3657 else
3658 {
3659 /* Get the next character from a Lisp string that is not an
3660 overlay string. Such strings come from the mode line, for
3661 example. We may have to pad with spaces, or truncate the
3662 string. See also next_element_from_c_string. */
3663 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3664 {
3665 it->what = IT_EOB;
3666 return 0;
3667 }
3668 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3669 {
3670 /* Pad with spaces. */
3671 it->c = ' ', it->len = 1;
3672 CHARPOS (position) = BYTEPOS (position) = -1;
3673 }
3674 else if (STRING_MULTIBYTE (it->string))
3675 {
3676 int maxlen = (STRING_BYTES (XSTRING (it->string))
3677 - IT_STRING_BYTEPOS (*it));
3678 unsigned char *s = (XSTRING (it->string)->data
3679 + IT_STRING_BYTEPOS (*it));
3680 it->c = string_char_and_length (s, maxlen, &it->len);
3681 }
3682 else
3683 {
3684 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3685 it->len = 1;
3686 }
3687 }
3688
3689 /* Record what we have and where it came from. Note that we store a
3690 buffer position in IT->position although it could arguably be a
3691 string position. */
3692 it->what = IT_CHARACTER;
3693 it->object = it->string;
3694 it->position = position;
3695 return 1;
3696 }
3697
3698
3699 /* Load IT with next display element from C string IT->s.
3700 IT->string_nchars is the maximum number of characters to return
3701 from the string. IT->end_charpos may be greater than
3702 IT->string_nchars when this function is called, in which case we
3703 may have to return padding spaces. Value is zero if end of string
3704 reached, including padding spaces. */
3705
3706 static int
3707 next_element_from_c_string (it)
3708 struct it *it;
3709 {
3710 int success_p = 1;
3711
3712 xassert (it->s);
3713 it->what = IT_CHARACTER;
3714 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3715 it->object = Qnil;
3716
3717 /* IT's position can be greater IT->string_nchars in case a field
3718 width or precision has been specified when the iterator was
3719 initialized. */
3720 if (IT_CHARPOS (*it) >= it->end_charpos)
3721 {
3722 /* End of the game. */
3723 it->what = IT_EOB;
3724 success_p = 0;
3725 }
3726 else if (IT_CHARPOS (*it) >= it->string_nchars)
3727 {
3728 /* Pad with spaces. */
3729 it->c = ' ', it->len = 1;
3730 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3731 }
3732 else if (it->multibyte_p)
3733 {
3734 /* Implementation note: The calls to strlen apparently aren't a
3735 performance problem because there is no noticeable performance
3736 difference between Emacs running in unibyte or multibyte mode. */
3737 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
3738 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3739 maxlen, &it->len);
3740 }
3741 else
3742 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3743
3744 return success_p;
3745 }
3746
3747
3748 /* Set up IT to return characters from an ellipsis, if appropriate.
3749 The definition of the ellipsis glyphs may come from a display table
3750 entry. This function Fills IT with the first glyph from the
3751 ellipsis if an ellipsis is to be displayed. */
3752
3753 static void
3754 next_element_from_ellipsis (it)
3755 struct it *it;
3756 {
3757 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3758 {
3759 /* Use the display table definition for `...'. Invalid glyphs
3760 will be handled by the method returning elements from dpvec. */
3761 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3762 it->dpvec_char_len = it->len;
3763 it->dpvec = v->contents;
3764 it->dpend = v->contents + v->size;
3765 it->current.dpvec_index = 0;
3766 it->method = next_element_from_display_vector;
3767 get_next_display_element (it);
3768 }
3769 else if (it->selective_display_ellipsis_p)
3770 {
3771 /* Use default `...' which is stored in default_invis_vector. */
3772 it->dpvec_char_len = it->len;
3773 it->dpvec = default_invis_vector;
3774 it->dpend = default_invis_vector + 3;
3775 it->current.dpvec_index = 0;
3776 it->method = next_element_from_display_vector;
3777 get_next_display_element (it);
3778 }
3779 }
3780
3781
3782 /* Deliver an image display element. The iterator IT is already
3783 filled with image information (done in handle_display_prop). Value
3784 is always 1. */
3785
3786
3787 static int
3788 next_element_from_image (it)
3789 struct it *it;
3790 {
3791 it->what = IT_IMAGE;
3792 return 1;
3793 }
3794
3795
3796 /* Fill iterator IT with next display element from a stretch glyph
3797 property. IT->object is the value of the text property. Value is
3798 always 1. */
3799
3800 static int
3801 next_element_from_stretch (it)
3802 struct it *it;
3803 {
3804 it->what = IT_STRETCH;
3805 return 1;
3806 }
3807
3808
3809 /* Load IT with the next display element from current_buffer. Value
3810 is zero if end of buffer reached. IT->stop_charpos is the next
3811 position at which to stop and check for text properties or buffer
3812 end. */
3813
3814 static int
3815 next_element_from_buffer (it)
3816 struct it *it;
3817 {
3818 int success_p = 1;
3819
3820 /* Check this assumption, otherwise, we would never enter the
3821 if-statement, below. */
3822 xassert (IT_CHARPOS (*it) >= BEGV
3823 && IT_CHARPOS (*it) <= it->stop_charpos);
3824
3825 if (IT_CHARPOS (*it) >= it->stop_charpos)
3826 {
3827 if (IT_CHARPOS (*it) >= it->end_charpos)
3828 {
3829 int overlay_strings_follow_p;
3830
3831 /* End of the game, except when overlay strings follow that
3832 haven't been returned yet. */
3833 if (it->overlay_strings_at_end_processed_p)
3834 overlay_strings_follow_p = 0;
3835 else
3836 {
3837 it->overlay_strings_at_end_processed_p = 1;
3838 overlay_strings_follow_p
3839 = get_overlay_strings (it);
3840 }
3841
3842 if (overlay_strings_follow_p)
3843 success_p = get_next_display_element (it);
3844 else
3845 {
3846 it->what = IT_EOB;
3847 it->position = it->current.pos;
3848 success_p = 0;
3849 }
3850 }
3851 else
3852 {
3853 handle_stop (it);
3854 return get_next_display_element (it);
3855 }
3856 }
3857 else
3858 {
3859 /* No face changes, overlays etc. in sight, so just return a
3860 character from current_buffer. */
3861 unsigned char *p;
3862
3863 /* Maybe run the redisplay end trigger hook. Performance note:
3864 This doesn't seem to cost measurable time. */
3865 if (it->redisplay_end_trigger_charpos
3866 && it->glyph_row
3867 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3868 run_redisplay_end_trigger_hook (it);
3869
3870 /* Get the next character, maybe multibyte. */
3871 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3872 if (it->multibyte_p)
3873 {
3874 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3875 - IT_BYTEPOS (*it));
3876 it->c = string_char_and_length (p, maxlen, &it->len);
3877 }
3878 else
3879 it->c = *p, it->len = 1;
3880
3881 /* Record what we have and where it came from. */
3882 it->what = IT_CHARACTER;;
3883 it->object = it->w->buffer;
3884 it->position = it->current.pos;
3885
3886 /* Normally we return the character found above, except when we
3887 really want to return an ellipsis for selective display. */
3888 if (it->selective)
3889 {
3890 if (it->c == '\n')
3891 {
3892 /* A value of selective > 0 means hide lines indented more
3893 than that number of columns. */
3894 if (it->selective > 0
3895 && IT_CHARPOS (*it) + 1 < ZV
3896 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3897 IT_BYTEPOS (*it) + 1,
3898 it->selective))
3899 {
3900 next_element_from_ellipsis (it);
3901 it->dpvec_char_len = -1;
3902 }
3903 }
3904 else if (it->c == '\r' && it->selective == -1)
3905 {
3906 /* A value of selective == -1 means that everything from the
3907 CR to the end of the line is invisible, with maybe an
3908 ellipsis displayed for it. */
3909 next_element_from_ellipsis (it);
3910 it->dpvec_char_len = -1;
3911 }
3912 }
3913 }
3914
3915 /* Value is zero if end of buffer reached. */
3916 xassert (!success_p || it->len > 0);
3917 return success_p;
3918 }
3919
3920
3921 /* Run the redisplay end trigger hook for IT. */
3922
3923 static void
3924 run_redisplay_end_trigger_hook (it)
3925 struct it *it;
3926 {
3927 Lisp_Object args[3];
3928
3929 /* IT->glyph_row should be non-null, i.e. we should be actually
3930 displaying something, or otherwise we should not run the hook. */
3931 xassert (it->glyph_row);
3932
3933 /* Set up hook arguments. */
3934 args[0] = Qredisplay_end_trigger_functions;
3935 args[1] = it->window;
3936 XSETINT (args[2], it->redisplay_end_trigger_charpos);
3937 it->redisplay_end_trigger_charpos = 0;
3938
3939 /* Since we are *trying* to run these functions, don't try to run
3940 them again, even if they get an error. */
3941 it->w->redisplay_end_trigger = Qnil;
3942 Frun_hook_with_args (3, args);
3943
3944 /* Notice if it changed the face of the character we are on. */
3945 handle_face_prop (it);
3946 }
3947
3948
3949 \f
3950 /***********************************************************************
3951 Moving an iterator without producing glyphs
3952 ***********************************************************************/
3953
3954 /* Move iterator IT to a specified buffer or X position within one
3955 line on the display without producing glyphs.
3956
3957 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
3958 whichever is reached first.
3959
3960 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
3961
3962 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
3963 0 <= TO_X <= IT->last_visible_x. This means in particular, that
3964 TO_X includes the amount by which a window is horizontally
3965 scrolled.
3966
3967 Value is
3968
3969 MOVE_POS_MATCH_OR_ZV
3970 - when TO_POS or ZV was reached.
3971
3972 MOVE_X_REACHED
3973 -when TO_X was reached before TO_POS or ZV were reached.
3974
3975 MOVE_LINE_CONTINUED
3976 - when we reached the end of the display area and the line must
3977 be continued.
3978
3979 MOVE_LINE_TRUNCATED
3980 - when we reached the end of the display area and the line is
3981 truncated.
3982
3983 MOVE_NEWLINE_OR_CR
3984 - when we stopped at a line end, i.e. a newline or a CR and selective
3985 display is on. */
3986
3987 enum move_it_result
3988 move_it_in_display_line_to (it, to_charpos, to_x, op)
3989 struct it *it;
3990 int to_charpos, to_x, op;
3991 {
3992 enum move_it_result result = MOVE_UNDEFINED;
3993 struct glyph_row *saved_glyph_row;
3994
3995 /* Don't produce glyphs in produce_glyphs. */
3996 saved_glyph_row = it->glyph_row;
3997 it->glyph_row = NULL;
3998
3999 #if NO_PROMPT_IN_BUFFER
4000 /* Take a mini-buffer prompt into account. */
4001 if (MINI_WINDOW_P (it->w)
4002 && IT_CHARPOS (*it) == BEGV)
4003 {
4004 it->current_x = minibuf_prompt_pixel_width;
4005 it->hpos = minibuf_prompt_width;
4006 }
4007 #endif
4008
4009 while (1)
4010 {
4011 int x, i;
4012
4013 /* Stop when ZV or TO_CHARPOS reached. */
4014 if (!get_next_display_element (it)
4015 || ((op & MOVE_TO_POS) != 0
4016 && BUFFERP (it->object)
4017 && IT_CHARPOS (*it) >= to_charpos))
4018 {
4019 result = MOVE_POS_MATCH_OR_ZV;
4020 break;
4021 }
4022
4023 /* The call to produce_glyphs will get the metrics of the
4024 display element IT is loaded with. We record in x the
4025 x-position before this display element in case it does not
4026 fit on the line. */
4027 x = it->current_x;
4028 PRODUCE_GLYPHS (it);
4029
4030 if (it->area != TEXT_AREA)
4031 {
4032 set_iterator_to_next (it);
4033 continue;
4034 }
4035
4036 /* The number of glyphs we get back in IT->nglyphs will normally
4037 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4038 character on a terminal frame, or (iii) a line end. For the
4039 second case, IT->nglyphs - 1 padding glyphs will be present
4040 (on X frames, there is only one glyph produced for a
4041 composite character.
4042
4043 The behavior implemented below means, for continuation lines,
4044 that as many spaces of a TAB as fit on the current line are
4045 displayed there. For terminal frames, as many glyphs of a
4046 multi-glyph character are displayed in the current line, too.
4047 This is what the old redisplay code did, and we keep it that
4048 way. Under X, the whole shape of a complex character must
4049 fit on the line or it will be completely displayed in the
4050 next line.
4051
4052 Note that both for tabs and padding glyphs, all glyphs have
4053 the same width. */
4054 if (it->nglyphs)
4055 {
4056 /* More than one glyph or glyph doesn't fit on line. All
4057 glyphs have the same width. */
4058 int single_glyph_width = it->pixel_width / it->nglyphs;
4059 int new_x;
4060
4061 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4062 {
4063 new_x = x + single_glyph_width;
4064
4065 /* We want to leave anything reaching TO_X to the caller. */
4066 if ((op & MOVE_TO_X) && new_x > to_x)
4067 {
4068 it->current_x = x;
4069 result = MOVE_X_REACHED;
4070 break;
4071 }
4072 else if (/* Lines are continued. */
4073 !it->truncate_lines_p
4074 && (/* And glyph doesn't fit on the line. */
4075 new_x > it->last_visible_x
4076 /* Or it fits exactly and we're on a window
4077 system frame. */
4078 || (new_x == it->last_visible_x
4079 && FRAME_WINDOW_P (it->f))))
4080 {
4081 if (/* IT->hpos == 0 means the very first glyph
4082 doesn't fit on the line, e.g. a wide image. */
4083 it->hpos == 0
4084 || (new_x == it->last_visible_x
4085 && FRAME_WINDOW_P (it->f)))
4086 {
4087 ++it->hpos;
4088 it->current_x = new_x;
4089 if (i == it->nglyphs - 1)
4090 set_iterator_to_next (it);
4091 }
4092 else
4093 it->current_x = x;
4094
4095 result = MOVE_LINE_CONTINUED;
4096 break;
4097 }
4098 else if (new_x > it->first_visible_x)
4099 {
4100 /* Glyph is visible. Increment number of glyphs that
4101 would be displayed. */
4102 ++it->hpos;
4103 }
4104 else
4105 {
4106 /* Glyph is completely off the left margin of the display
4107 area. Nothing to do. */
4108 }
4109 }
4110
4111 if (result != MOVE_UNDEFINED)
4112 break;
4113 }
4114 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4115 {
4116 /* Stop when TO_X specified and reached. This check is
4117 necessary here because of lines consisting of a line end,
4118 only. The line end will not produce any glyphs and we
4119 would never get MOVE_X_REACHED. */
4120 xassert (it->nglyphs == 0);
4121 result = MOVE_X_REACHED;
4122 break;
4123 }
4124
4125 /* Is this a line end? If yes, we're done. */
4126 if (ITERATOR_AT_END_OF_LINE_P (it))
4127 {
4128 result = MOVE_NEWLINE_OR_CR;
4129 break;
4130 }
4131
4132 /* The current display element has been consumed. Advance
4133 to the next. */
4134 set_iterator_to_next (it);
4135
4136 /* Stop if lines are truncated and IT's current x-position is
4137 past the right edge of the window now. */
4138 if (it->truncate_lines_p
4139 && it->current_x >= it->last_visible_x)
4140 {
4141 result = MOVE_LINE_TRUNCATED;
4142 break;
4143 }
4144 }
4145
4146 /* Restore the iterator settings altered at the beginning of this
4147 function. */
4148 it->glyph_row = saved_glyph_row;
4149 return result;
4150 }
4151
4152
4153 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4154 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4155 the description of enum move_operation_enum.
4156
4157 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4158 screen line, this function will set IT to the next position >
4159 TO_CHARPOS. */
4160
4161 void
4162 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4163 struct it *it;
4164 int to_charpos, to_x, to_y, to_vpos;
4165 int op;
4166 {
4167 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4168 int line_height;
4169
4170 xassert (XBUFFER (it->w->buffer) == current_buffer);
4171
4172 while (1)
4173 {
4174 if (op & MOVE_TO_VPOS)
4175 {
4176 /* If no TO_CHARPOS and no TO_X specified, stop at the
4177 start of the line TO_VPOS. */
4178 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4179 {
4180 if (it->vpos == to_vpos)
4181 break;
4182 skip = move_it_in_display_line_to (it, -1, -1, 0);
4183 }
4184 else
4185 {
4186 /* TO_VPOS >= 0 means stop at TO_X in the line at
4187 TO_VPOS, or at TO_POS, whichever comes first. */
4188 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4189
4190 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4191 break;
4192 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4193 {
4194 /* We have reached TO_X but not in the line we want. */
4195 skip = move_it_in_display_line_to (it, to_charpos,
4196 -1, MOVE_TO_POS);
4197 if (skip == MOVE_POS_MATCH_OR_ZV)
4198 break;
4199 }
4200 }
4201 }
4202 else if (op & MOVE_TO_Y)
4203 {
4204 struct it it_backup;
4205 int done_p;
4206
4207 /* TO_Y specified means stop at TO_X in the line containing
4208 TO_Y---or at TO_CHARPOS if this is reached first. The
4209 problem is that we can't really tell whether the line
4210 contains TO_Y before we have completely scanned it, and
4211 this may skip past TO_X. What we do is to first scan to
4212 TO_X.
4213
4214 If TO_X is not specified, use a TO_X of zero. The reason
4215 is to make the outcome of this function more predictable.
4216 If we didn't use TO_X == 0, we would stop at the end of
4217 the line which is probably not what a caller would expect
4218 to happen. */
4219 skip = move_it_in_display_line_to (it, to_charpos,
4220 ((op & MOVE_TO_X)
4221 ? to_x : 0),
4222 (MOVE_TO_X
4223 | (op & MOVE_TO_POS)));
4224
4225 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4226 if (skip == MOVE_POS_MATCH_OR_ZV)
4227 break;
4228
4229 /* If TO_X was reached, we would like to know whether TO_Y
4230 is in the line. This can only be said if we know the
4231 total line height which requires us to scan the rest of
4232 the line. */
4233 done_p = 0;
4234 if (skip == MOVE_X_REACHED)
4235 {
4236 it_backup = *it;
4237 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4238 op & MOVE_TO_POS);
4239 }
4240
4241 /* Now, decide whether TO_Y is in this line. */
4242 line_height = it->max_ascent + it->max_descent;
4243
4244 if (to_y >= it->current_y
4245 && to_y < it->current_y + line_height)
4246 {
4247 if (skip == MOVE_X_REACHED)
4248 /* If TO_Y is in this line and TO_X was reached above,
4249 we scanned too far. We have to restore IT's settings
4250 to the ones before skipping. */
4251 *it = it_backup;
4252 done_p = 1;
4253 }
4254 else if (skip == MOVE_X_REACHED)
4255 {
4256 skip = skip2;
4257 if (skip == MOVE_POS_MATCH_OR_ZV)
4258 done_p = 1;
4259 }
4260
4261 if (done_p)
4262 break;
4263 }
4264 else
4265 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4266
4267 switch (skip)
4268 {
4269 case MOVE_POS_MATCH_OR_ZV:
4270 return;
4271
4272 case MOVE_NEWLINE_OR_CR:
4273 set_iterator_to_next (it);
4274 it->continuation_lines_width = 0;
4275 break;
4276
4277 case MOVE_LINE_TRUNCATED:
4278 it->continuation_lines_width = 0;
4279 reseat_at_next_visible_line_start (it, 0);
4280 if ((op & MOVE_TO_POS) != 0
4281 && IT_CHARPOS (*it) > to_charpos)
4282 goto out;
4283 break;
4284
4285 case MOVE_LINE_CONTINUED:
4286 it->continuation_lines_width += it->current_x;
4287 break;
4288
4289 default:
4290 abort ();
4291 }
4292
4293 /* Reset/increment for the next run. */
4294 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4295 it->current_x = it->hpos = 0;
4296 it->current_y += it->max_ascent + it->max_descent;
4297 ++it->vpos;
4298 last_height = it->max_ascent + it->max_descent;
4299 last_max_ascent = it->max_ascent;
4300 it->max_ascent = it->max_descent = 0;
4301 }
4302 out:;
4303 }
4304
4305
4306 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4307
4308 If DY > 0, move IT backward at least that many pixels. DY = 0
4309 means move IT backward to the preceding line start or BEGV. This
4310 function may move over more than DY pixels if IT->current_y - DY
4311 ends up in the middle of a line; in this case IT->current_y will be
4312 set to the top of the line moved to. */
4313
4314 void
4315 move_it_vertically_backward (it, dy)
4316 struct it *it;
4317 int dy;
4318 {
4319 int nlines, h, line_height;
4320 struct it it2;
4321 int start_pos = IT_CHARPOS (*it);
4322
4323 xassert (dy >= 0);
4324
4325 /* Estimate how many newlines we must move back. */
4326 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4327
4328 /* Set the iterator's position that many lines back. */
4329 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4330 back_to_previous_visible_line_start (it);
4331
4332 /* Reseat the iterator here. When moving backward, we don't want
4333 reseat to skip forward over invisible text, set up the iterator
4334 to deliver from overlay strings at the new position etc. So,
4335 use reseat_1 here. */
4336 reseat_1 (it, it->current.pos, 1);
4337
4338 /* We are now surely at a line start. */
4339 it->current_x = it->hpos = 0;
4340
4341 /* Move forward and see what y-distance we moved. First move to the
4342 start of the next line so that we get its height. We need this
4343 height to be able to tell whether we reached the specified
4344 y-distance. */
4345 it2 = *it;
4346 it2.max_ascent = it2.max_descent = 0;
4347 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4348 MOVE_TO_POS | MOVE_TO_VPOS);
4349 xassert (IT_CHARPOS (*it) >= BEGV);
4350 line_height = it2.max_ascent + it2.max_descent;
4351 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4352 xassert (IT_CHARPOS (*it) >= BEGV);
4353 h = it2.current_y - it->current_y;
4354 nlines = it2.vpos - it->vpos;
4355
4356 /* Correct IT's y and vpos position. */
4357 it->vpos -= nlines;
4358 it->current_y -= h;
4359
4360 if (dy == 0)
4361 {
4362 /* DY == 0 means move to the start of the screen line. The
4363 value of nlines is > 0 if continuation lines were involved. */
4364 if (nlines > 0)
4365 move_it_by_lines (it, nlines, 1);
4366 xassert (IT_CHARPOS (*it) <= start_pos);
4367 }
4368 else if (nlines)
4369 {
4370 /* The y-position we try to reach. Note that h has been
4371 subtracted in front of the if-statement. */
4372 int target_y = it->current_y + h - dy;
4373
4374 /* If we did not reach target_y, try to move further backward if
4375 we can. If we moved too far backward, try to move forward. */
4376 if (target_y < it->current_y
4377 && IT_CHARPOS (*it) > BEGV)
4378 {
4379 move_it_vertically (it, target_y - it->current_y);
4380 xassert (IT_CHARPOS (*it) >= BEGV);
4381 }
4382 else if (target_y >= it->current_y + line_height
4383 && IT_CHARPOS (*it) < ZV)
4384 {
4385 move_it_vertically (it, target_y - (it->current_y + line_height));
4386 xassert (IT_CHARPOS (*it) >= BEGV);
4387 }
4388 }
4389 }
4390
4391
4392 /* Move IT by a specified amount of pixel lines DY. DY negative means
4393 move backwards. DY = 0 means move to start of screen line. At the
4394 end, IT will be on the start of a screen line. */
4395
4396 void
4397 move_it_vertically (it, dy)
4398 struct it *it;
4399 int dy;
4400 {
4401 if (dy <= 0)
4402 move_it_vertically_backward (it, -dy);
4403 else if (dy > 0)
4404 {
4405 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4406 MOVE_TO_POS | MOVE_TO_Y);
4407
4408 /* If buffer ends in ZV without a newline, move to the start of
4409 the line to satisfy the post-condition. */
4410 if (IT_CHARPOS (*it) == ZV
4411 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4412 move_it_by_lines (it, 0, 0);
4413 }
4414 }
4415
4416
4417 /* Return non-zero if some text between buffer positions START_CHARPOS
4418 and END_CHARPOS is invisible. IT->window is the window for text
4419 property lookup. */
4420
4421 static int
4422 invisible_text_between_p (it, start_charpos, end_charpos)
4423 struct it *it;
4424 int start_charpos, end_charpos;
4425 {
4426 #ifdef USE_TEXT_PROPERTIES
4427 Lisp_Object prop, limit;
4428 int invisible_found_p;
4429
4430 xassert (it != NULL && start_charpos <= end_charpos);
4431
4432 /* Is text at START invisible? */
4433 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4434 it->window);
4435 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4436 invisible_found_p = 1;
4437 else
4438 {
4439 limit = Fnext_single_property_change (make_number (start_charpos),
4440 Qinvisible,
4441 Fcurrent_buffer (),
4442 make_number (end_charpos));
4443 invisible_found_p = XFASTINT (limit) < end_charpos;
4444 }
4445
4446 return invisible_found_p;
4447
4448 #else /* not USE_TEXT_PROPERTIES */
4449 return 0;
4450 #endif /* not USE_TEXT_PROPERTIES */
4451 }
4452
4453
4454 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
4455 negative means move up. DVPOS == 0 means move to the start of the
4456 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4457 NEED_Y_P is zero, IT->current_y will be left unchanged.
4458
4459 Further optimization ideas: If we would know that IT->f doesn't use
4460 a face with proportional font, we could be faster for
4461 truncate-lines nil. */
4462
4463 void
4464 move_it_by_lines (it, dvpos, need_y_p)
4465 struct it *it;
4466 int dvpos, need_y_p;
4467 {
4468 struct position pos;
4469
4470 if (!FRAME_WINDOW_P (it->f))
4471 {
4472 struct text_pos textpos;
4473
4474 /* We can use vmotion on frames without proportional fonts. */
4475 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4476 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4477 reseat (it, textpos, 1);
4478 it->vpos += pos.vpos;
4479 it->current_y += pos.vpos;
4480 }
4481 else if (dvpos == 0)
4482 {
4483 /* DVPOS == 0 means move to the start of the screen line. */
4484 move_it_vertically_backward (it, 0);
4485 xassert (it->current_x == 0 && it->hpos == 0);
4486 }
4487 else if (dvpos > 0)
4488 {
4489 /* If there are no continuation lines, and if there is no
4490 selective display, try the simple method of moving forward
4491 DVPOS newlines, then see where we are. */
4492 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4493 {
4494 int shortage = 0, charpos;
4495
4496 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4497 charpos = IT_CHARPOS (*it) + 1;
4498 else
4499 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4500 &shortage, 0);
4501
4502 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4503 {
4504 struct text_pos pos;
4505 CHARPOS (pos) = charpos;
4506 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4507 reseat (it, pos, 1);
4508 it->vpos += dvpos - shortage;
4509 it->hpos = it->current_x = 0;
4510 return;
4511 }
4512 }
4513
4514 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4515 }
4516 else
4517 {
4518 struct it it2;
4519 int start_charpos, i;
4520
4521 /* If there are no continuation lines, and if there is no
4522 selective display, try the simple method of moving backward
4523 -DVPOS newlines. */
4524 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4525 {
4526 int shortage;
4527 int charpos = IT_CHARPOS (*it);
4528 int bytepos = IT_BYTEPOS (*it);
4529
4530 /* If in the middle of a line, go to its start. */
4531 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4532 {
4533 charpos = find_next_newline_no_quit (charpos, -1);
4534 bytepos = CHAR_TO_BYTE (charpos);
4535 }
4536
4537 if (charpos == BEGV)
4538 {
4539 struct text_pos pos;
4540 CHARPOS (pos) = charpos;
4541 BYTEPOS (pos) = bytepos;
4542 reseat (it, pos, 1);
4543 it->hpos = it->current_x = 0;
4544 return;
4545 }
4546 else
4547 {
4548 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4549 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4550 {
4551 struct text_pos pos;
4552 CHARPOS (pos) = charpos;
4553 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4554 reseat (it, pos, 1);
4555 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4556 it->hpos = it->current_x = 0;
4557 return;
4558 }
4559 }
4560 }
4561
4562 /* Go back -DVPOS visible lines and reseat the iterator there. */
4563 start_charpos = IT_CHARPOS (*it);
4564 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4565 back_to_previous_visible_line_start (it);
4566 reseat (it, it->current.pos, 1);
4567 it->current_x = it->hpos = 0;
4568
4569 /* Above call may have moved too far if continuation lines
4570 are involved. Scan forward and see if it did. */
4571 it2 = *it;
4572 it2.vpos = it2.current_y = 0;
4573 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4574 it->vpos -= it2.vpos;
4575 it->current_y -= it2.current_y;
4576 it->current_x = it->hpos = 0;
4577
4578 /* If we moved too far, move IT some lines forward. */
4579 if (it2.vpos > -dvpos)
4580 {
4581 int delta = it2.vpos + dvpos;
4582 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4583 }
4584 }
4585 }
4586
4587
4588 \f
4589 /***********************************************************************
4590 Messages
4591 ***********************************************************************/
4592
4593
4594 /* Output a newline in the *Messages* buffer if "needs" one. */
4595
4596 void
4597 message_log_maybe_newline ()
4598 {
4599 if (message_log_need_newline)
4600 message_dolog ("", 0, 1, 0);
4601 }
4602
4603
4604 /* Add a string M of length LEN to the message log, optionally
4605 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4606 nonzero, means interpret the contents of M as multibyte. This
4607 function calls low-level routines in order to bypass text property
4608 hooks, etc. which might not be safe to run. */
4609
4610 void
4611 message_dolog (m, len, nlflag, multibyte)
4612 char *m;
4613 int len, nlflag, multibyte;
4614 {
4615 if (!NILP (Vmessage_log_max))
4616 {
4617 struct buffer *oldbuf;
4618 Lisp_Object oldpoint, oldbegv, oldzv;
4619 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4620 int point_at_end = 0;
4621 int zv_at_end = 0;
4622 Lisp_Object old_deactivate_mark, tem;
4623 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4624
4625 old_deactivate_mark = Vdeactivate_mark;
4626 oldbuf = current_buffer;
4627 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4628 current_buffer->undo_list = Qt;
4629
4630 oldpoint = Fpoint_marker ();
4631 oldbegv = Fpoint_min_marker ();
4632 oldzv = Fpoint_max_marker ();
4633 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4634
4635 if (PT == Z)
4636 point_at_end = 1;
4637 if (ZV == Z)
4638 zv_at_end = 1;
4639
4640 BEGV = BEG;
4641 BEGV_BYTE = BEG_BYTE;
4642 ZV = Z;
4643 ZV_BYTE = Z_BYTE;
4644 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4645
4646 /* Insert the string--maybe converting multibyte to single byte
4647 or vice versa, so that all the text fits the buffer. */
4648 if (multibyte
4649 && NILP (current_buffer->enable_multibyte_characters))
4650 {
4651 int i, c, nbytes;
4652 unsigned char work[1];
4653
4654 /* Convert a multibyte string to single-byte
4655 for the *Message* buffer. */
4656 for (i = 0; i < len; i += nbytes)
4657 {
4658 c = string_char_and_length (m + i, len - i, &nbytes);
4659 work[0] = (SINGLE_BYTE_CHAR_P (c)
4660 ? c
4661 : multibyte_char_to_unibyte (c, Qnil));
4662 insert_1_both (work, 1, 1, 1, 0, 0);
4663 }
4664 }
4665 else if (! multibyte
4666 && ! NILP (current_buffer->enable_multibyte_characters))
4667 {
4668 int i, c, nbytes;
4669 unsigned char *msg = (unsigned char *) m;
4670 unsigned char *str, work[4];
4671 /* Convert a single-byte string to multibyte
4672 for the *Message* buffer. */
4673 for (i = 0; i < len; i++)
4674 {
4675 c = unibyte_char_to_multibyte (msg[i]);
4676 nbytes = CHAR_STRING (c, work, str);
4677 insert_1_both (work, 1, nbytes, 1, 0, 0);
4678 }
4679 }
4680 else if (len)
4681 insert_1 (m, len, 1, 0, 0);
4682
4683 if (nlflag)
4684 {
4685 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4686 insert_1 ("\n", 1, 1, 0, 0);
4687
4688 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4689 this_bol = PT;
4690 this_bol_byte = PT_BYTE;
4691
4692 if (this_bol > BEG)
4693 {
4694 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4695 prev_bol = PT;
4696 prev_bol_byte = PT_BYTE;
4697
4698 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4699 this_bol, this_bol_byte);
4700 if (dup)
4701 {
4702 del_range_both (prev_bol, prev_bol_byte,
4703 this_bol, this_bol_byte, 0);
4704 if (dup > 1)
4705 {
4706 char dupstr[40];
4707 int duplen;
4708
4709 /* If you change this format, don't forget to also
4710 change message_log_check_duplicate. */
4711 sprintf (dupstr, " [%d times]", dup);
4712 duplen = strlen (dupstr);
4713 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4714 insert_1 (dupstr, duplen, 1, 0, 1);
4715 }
4716 }
4717 }
4718
4719 if (NATNUMP (Vmessage_log_max))
4720 {
4721 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4722 -XFASTINT (Vmessage_log_max) - 1, 0);
4723 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4724 }
4725 }
4726 BEGV = XMARKER (oldbegv)->charpos;
4727 BEGV_BYTE = marker_byte_position (oldbegv);
4728
4729 if (zv_at_end)
4730 {
4731 ZV = Z;
4732 ZV_BYTE = Z_BYTE;
4733 }
4734 else
4735 {
4736 ZV = XMARKER (oldzv)->charpos;
4737 ZV_BYTE = marker_byte_position (oldzv);
4738 }
4739
4740 if (point_at_end)
4741 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4742 else
4743 /* We can't do Fgoto_char (oldpoint) because it will run some
4744 Lisp code. */
4745 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4746 XMARKER (oldpoint)->bytepos);
4747
4748 UNGCPRO;
4749 free_marker (oldpoint);
4750 free_marker (oldbegv);
4751 free_marker (oldzv);
4752
4753 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4754 set_buffer_internal (oldbuf);
4755 if (NILP (tem))
4756 windows_or_buffers_changed = old_windows_or_buffers_changed;
4757 message_log_need_newline = !nlflag;
4758 Vdeactivate_mark = old_deactivate_mark;
4759 }
4760 }
4761
4762
4763 /* We are at the end of the buffer after just having inserted a newline.
4764 (Note: We depend on the fact we won't be crossing the gap.)
4765 Check to see if the most recent message looks a lot like the previous one.
4766 Return 0 if different, 1 if the new one should just replace it, or a
4767 value N > 1 if we should also append " [N times]". */
4768
4769 static int
4770 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4771 int prev_bol, this_bol;
4772 int prev_bol_byte, this_bol_byte;
4773 {
4774 int i;
4775 int len = Z_BYTE - 1 - this_bol_byte;
4776 int seen_dots = 0;
4777 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4778 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4779
4780 for (i = 0; i < len; i++)
4781 {
4782 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4783 && p1[i] != '\n')
4784 seen_dots = 1;
4785 if (p1[i] != p2[i])
4786 return seen_dots;
4787 }
4788 p1 += len;
4789 if (*p1 == '\n')
4790 return 2;
4791 if (*p1++ == ' ' && *p1++ == '[')
4792 {
4793 int n = 0;
4794 while (*p1 >= '0' && *p1 <= '9')
4795 n = n * 10 + *p1++ - '0';
4796 if (strncmp (p1, " times]\n", 8) == 0)
4797 return n+1;
4798 }
4799 return 0;
4800 }
4801
4802
4803 /* Display an echo area message M with a specified length of LEN
4804 chars. The string may include null characters. If M is 0, clear
4805 out any existing message, and let the mini-buffer text show through.
4806
4807 The buffer M must continue to exist until after the echo area gets
4808 cleared or some other message gets displayed there. This means do
4809 not pass text that is stored in a Lisp string; do not pass text in
4810 a buffer that was alloca'd. */
4811
4812 void
4813 message2 (m, len, multibyte)
4814 char *m;
4815 int len;
4816 int multibyte;
4817 {
4818 /* First flush out any partial line written with print. */
4819 message_log_maybe_newline ();
4820 if (m)
4821 message_dolog (m, len, 1, multibyte);
4822 message2_nolog (m, len, multibyte);
4823 }
4824
4825
4826 /* The non-logging counterpart of message2. */
4827
4828 void
4829 message2_nolog (m, len, multibyte)
4830 char *m;
4831 int len;
4832 {
4833 message_enable_multibyte = multibyte;
4834
4835 if (noninteractive)
4836 {
4837 if (noninteractive_need_newline)
4838 putc ('\n', stderr);
4839 noninteractive_need_newline = 0;
4840 if (m)
4841 fwrite (m, len, 1, stderr);
4842 if (cursor_in_echo_area == 0)
4843 fprintf (stderr, "\n");
4844 fflush (stderr);
4845 }
4846 /* A null message buffer means that the frame hasn't really been
4847 initialized yet. Error messages get reported properly by
4848 cmd_error, so this must be just an informative message; toss it. */
4849 else if (INTERACTIVE
4850 && selected_frame->glyphs_initialized_p
4851 && FRAME_MESSAGE_BUF (selected_frame))
4852 {
4853 Lisp_Object mini_window;
4854 struct frame *f;
4855
4856 /* Get the frame containing the mini-buffer
4857 that the selected frame is using. */
4858 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4859 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4860
4861 FRAME_SAMPLE_VISIBILITY (f);
4862 if (FRAME_VISIBLE_P (selected_frame)
4863 && ! FRAME_VISIBLE_P (f))
4864 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4865
4866 if (m)
4867 {
4868 echo_area_glyphs = m;
4869 echo_area_glyphs_length = len;
4870 echo_area_message = Qnil;
4871
4872 if (minibuffer_auto_raise)
4873 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4874 }
4875 else
4876 {
4877 echo_area_glyphs = previous_echo_glyphs = NULL;
4878 echo_area_message = previous_echo_area_message = Qnil;
4879 }
4880
4881 do_pending_window_change ();
4882 echo_area_display (1);
4883 do_pending_window_change ();
4884 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4885 (*frame_up_to_date_hook) (f);
4886 }
4887 }
4888
4889
4890 /* Display an echo area message M with a specified length of LEN
4891 chars. The string may include null characters. If M is not a
4892 string, clear out any existing message, and let the mini-buffer
4893 text show through. */
4894
4895 void
4896 message3 (m, len, multibyte)
4897 Lisp_Object m;
4898 int len;
4899 int multibyte;
4900 {
4901 struct gcpro gcpro1;
4902
4903 GCPRO1 (m);
4904
4905 /* First flush out any partial line written with print. */
4906 message_log_maybe_newline ();
4907 if (STRINGP (m))
4908 message_dolog (XSTRING (m)->data, len, 1, multibyte);
4909 message3_nolog (m, len, multibyte);
4910
4911 UNGCPRO;
4912 }
4913
4914
4915 /* The non-logging version of message3. */
4916
4917 void
4918 message3_nolog (m, len, multibyte)
4919 Lisp_Object m;
4920 int len, multibyte;
4921 {
4922 message_enable_multibyte = multibyte;
4923
4924 if (noninteractive)
4925 {
4926 if (noninteractive_need_newline)
4927 putc ('\n', stderr);
4928 noninteractive_need_newline = 0;
4929 if (STRINGP (m))
4930 fwrite (XSTRING (m)->data, len, 1, stderr);
4931 if (cursor_in_echo_area == 0)
4932 fprintf (stderr, "\n");
4933 fflush (stderr);
4934 }
4935 /* A null message buffer means that the frame hasn't really been
4936 initialized yet. Error messages get reported properly by
4937 cmd_error, so this must be just an informative message; toss it. */
4938 else if (INTERACTIVE
4939 && selected_frame->glyphs_initialized_p
4940 && FRAME_MESSAGE_BUF (selected_frame))
4941 {
4942 Lisp_Object mini_window;
4943 struct frame *f;
4944
4945 /* Get the frame containing the mini-buffer
4946 that the selected frame is using. */
4947 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4948 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4949
4950 FRAME_SAMPLE_VISIBILITY (f);
4951 if (FRAME_VISIBLE_P (selected_frame)
4952 && ! FRAME_VISIBLE_P (f))
4953 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4954
4955 if (STRINGP (m))
4956 {
4957 echo_area_glyphs = NULL;
4958 echo_area_message = m;
4959 echo_area_glyphs_length = len;
4960
4961 if (minibuffer_auto_raise)
4962 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4963 }
4964 else
4965 {
4966 echo_area_glyphs = previous_echo_glyphs = NULL;
4967 echo_area_message = previous_echo_area_message = Qnil;
4968 }
4969
4970 do_pending_window_change ();
4971 echo_area_display (1);
4972 do_pending_window_change ();
4973 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4974 (*frame_up_to_date_hook) (f);
4975 }
4976 }
4977
4978
4979 /* Display a null-terminated echo area message M. If M is 0, clear
4980 out any existing message, and let the mini-buffer text show through.
4981
4982 The buffer M must continue to exist until after the echo area gets
4983 cleared or some other message gets displayed there. Do not pass
4984 text that is stored in a Lisp string. Do not pass text in a buffer
4985 that was alloca'd. */
4986
4987 void
4988 message1 (m)
4989 char *m;
4990 {
4991 message2 (m, (m ? strlen (m) : 0), 0);
4992 }
4993
4994
4995 /* The non-logging counterpart of message1. */
4996
4997 void
4998 message1_nolog (m)
4999 char *m;
5000 {
5001 message2_nolog (m, (m ? strlen (m) : 0), 0);
5002 }
5003
5004 /* Display a message M which contains a single %s
5005 which gets replaced with STRING. */
5006
5007 void
5008 message_with_string (m, string, log)
5009 char *m;
5010 Lisp_Object string;
5011 int log;
5012 {
5013 if (noninteractive)
5014 {
5015 if (m)
5016 {
5017 if (noninteractive_need_newline)
5018 putc ('\n', stderr);
5019 noninteractive_need_newline = 0;
5020 fprintf (stderr, m, XSTRING (string)->data);
5021 if (cursor_in_echo_area == 0)
5022 fprintf (stderr, "\n");
5023 fflush (stderr);
5024 }
5025 }
5026 else if (INTERACTIVE)
5027 {
5028 /* The frame whose minibuffer we're going to display the message on.
5029 It may be larger than the selected frame, so we need
5030 to use its buffer, not the selected frame's buffer. */
5031 Lisp_Object mini_window;
5032 FRAME_PTR f;
5033
5034 /* Get the frame containing the minibuffer
5035 that the selected frame is using. */
5036 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5037 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5038
5039 /* A null message buffer means that the frame hasn't really been
5040 initialized yet. Error messages get reported properly by
5041 cmd_error, so this must be just an informative message; toss it. */
5042 if (FRAME_MESSAGE_BUF (f))
5043 {
5044 int len;
5045 char *a[1];
5046 a[0] = (char *) XSTRING (string)->data;
5047
5048 len = doprnt (FRAME_MESSAGE_BUF (f),
5049 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5050
5051 if (log)
5052 message2 (FRAME_MESSAGE_BUF (f), len,
5053 STRING_MULTIBYTE (string));
5054 else
5055 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5056 STRING_MULTIBYTE (string));
5057
5058 /* Print should start at the beginning of the message
5059 buffer next time. */
5060 message_buf_print = 0;
5061 }
5062 }
5063 }
5064
5065
5066 /* Truncate what will be displayed in the echo area
5067 the next time we display it--but don't redisplay it now. */
5068
5069 void
5070 truncate_echo_area (len)
5071 int len;
5072 {
5073 /* A null message buffer means that the frame hasn't really been
5074 initialized yet. Error messages get reported properly by
5075 cmd_error, so this must be just an informative message; toss it. */
5076 if (!noninteractive && INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame))
5077 echo_area_glyphs_length = len;
5078 }
5079
5080
5081 /* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by
5082 print; zero if being used by message. */
5083
5084 int message_buf_print;
5085
5086
5087 /* Dump an informative message to the minibuf. If M is 0, clear out
5088 any existing message, and let the mini-buffer text show through. */
5089
5090 /* VARARGS 1 */
5091 void
5092 message (m, a1, a2, a3)
5093 char *m;
5094 EMACS_INT a1, a2, a3;
5095 {
5096 if (noninteractive)
5097 {
5098 if (m)
5099 {
5100 if (noninteractive_need_newline)
5101 putc ('\n', stderr);
5102 noninteractive_need_newline = 0;
5103 fprintf (stderr, m, a1, a2, a3);
5104 if (cursor_in_echo_area == 0)
5105 fprintf (stderr, "\n");
5106 fflush (stderr);
5107 }
5108 }
5109 else if (INTERACTIVE)
5110 {
5111 /* The frame whose mini-buffer we're going to display the message
5112 on. It may be larger than the selected frame, so we need to
5113 use its buffer, not the selected frame's buffer. */
5114 Lisp_Object mini_window;
5115 struct frame *f;
5116
5117 /* Get the frame containing the mini-buffer
5118 that the selected frame is using. */
5119 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5120 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5121
5122 /* A null message buffer means that the frame hasn't really been
5123 initialized yet. Error messages get reported properly by
5124 cmd_error, so this must be just an informative message; toss
5125 it. */
5126 if (FRAME_MESSAGE_BUF (f))
5127 {
5128 if (m)
5129 {
5130 int len;
5131 #ifdef NO_ARG_ARRAY
5132 char *a[3];
5133 a[0] = (char *) a1;
5134 a[1] = (char *) a2;
5135 a[2] = (char *) a3;
5136
5137 len = doprnt (FRAME_MESSAGE_BUF (f),
5138 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5139 #else
5140 len = doprnt (FRAME_MESSAGE_BUF (f),
5141 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5142 (char **) &a1);
5143 #endif /* NO_ARG_ARRAY */
5144
5145 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5146 }
5147 else
5148 message1 (0);
5149
5150 /* Print should start at the beginning of the message
5151 buffer next time. */
5152 message_buf_print = 0;
5153 }
5154 }
5155 }
5156
5157
5158 /* The non-logging version of message. */
5159
5160 void
5161 message_nolog (m, a1, a2, a3)
5162 char *m;
5163 EMACS_INT a1, a2, a3;
5164 {
5165 Lisp_Object old_log_max;
5166 old_log_max = Vmessage_log_max;
5167 Vmessage_log_max = Qnil;
5168 message (m, a1, a2, a3);
5169 Vmessage_log_max = old_log_max;
5170 }
5171
5172
5173 /* Display echo_area_message or echo_area_glyphs in the current
5174 mini-buffer. */
5175
5176 void
5177 update_echo_area ()
5178 {
5179 if (STRINGP (echo_area_message))
5180 message3 (echo_area_message, echo_area_glyphs_length,
5181 !NILP (current_buffer->enable_multibyte_characters));
5182 else
5183 message2 (echo_area_glyphs, echo_area_glyphs_length,
5184 !NILP (current_buffer->enable_multibyte_characters));
5185 }
5186
5187
5188 /* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
5189 non-zero update selected_frame. */
5190
5191 static void
5192 echo_area_display (update_frame_p)
5193 int update_frame_p;
5194 {
5195 Lisp_Object mini_window;
5196 struct window *w;
5197 struct frame *f;
5198
5199 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5200 w = XWINDOW (mini_window);
5201 f = XFRAME (WINDOW_FRAME (w));
5202
5203 /* Don't display if frame is invisible or not yet initialized. */
5204 if (!FRAME_VISIBLE_P (f)
5205 || !f->glyphs_initialized_p)
5206 return;
5207
5208 /* When Emacs starts, selected_frame may be a visible terminal
5209 frame, even if we run under a window system. If we let this
5210 through, a message would be displayed on the terminal. */
5211 #ifdef HAVE_WINDOW_SYSTEM
5212 if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
5213 return;
5214 #endif /* HAVE_WINDOW_SYSTEM */
5215
5216 /* Redraw garbaged frames. */
5217 if (frame_garbaged)
5218 {
5219 /* Old redisplay called redraw_garbaged_frames here which in
5220 turn called redraw_frame which in turn called clear_frame.
5221 The call to clear_frame is a source of flickering. After
5222 checking the places where SET_FRAME_GARBAGED is called, I
5223 believe a clear_frame is not necessary. It should suffice in
5224 the new redisplay to invalidate all current matrices, and
5225 ensure a complete redisplay of all windows. */
5226 Lisp_Object tail, frame;
5227
5228 FOR_EACH_FRAME (tail, frame)
5229 {
5230 struct frame *f = XFRAME (frame);
5231
5232 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5233 {
5234 clear_current_matrices (f);
5235 f->garbaged = 0;
5236 }
5237 }
5238
5239 frame_garbaged = 0;
5240 ++windows_or_buffers_changed;
5241 }
5242
5243 if (echo_area_glyphs
5244 || STRINGP (echo_area_message)
5245 || minibuf_level == 0)
5246 {
5247 struct it it;
5248
5249 echo_area_window = mini_window;
5250 clear_glyph_matrix (w->desired_matrix);
5251 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, DEFAULT_FACE_ID);
5252
5253 if (STRINGP (echo_area_message)
5254 && echo_area_glyphs_length)
5255 {
5256 prepare_desired_row (it.glyph_row);
5257 display_string (NULL, echo_area_message, Qnil, 0, 0,
5258 &it, -1, echo_area_glyphs_length, 0,
5259 message_enable_multibyte);
5260 it.glyph_row->truncated_on_right_p = 0;
5261 compute_line_metrics (&it);
5262 }
5263 else if (echo_area_glyphs
5264 && echo_area_glyphs_length)
5265 {
5266 prepare_desired_row (it.glyph_row);
5267 display_string (echo_area_glyphs, Qnil, Qnil, 0, 0, &it,
5268 -1, echo_area_glyphs_length, 0,
5269 message_enable_multibyte);
5270 it.glyph_row->truncated_on_right_p = 0;
5271 compute_line_metrics (&it);
5272 }
5273 else
5274 blank_row (w, it.glyph_row, 0);
5275
5276 it.glyph_row->y = it.current_y;
5277 it.current_y += it.glyph_row->height;
5278
5279 /* Clear the rest of the lines. */
5280 while (it.current_y < it.last_visible_y)
5281 {
5282 ++it.glyph_row;
5283 blank_row (w, it.glyph_row, it.current_y);
5284 it.current_y += it.glyph_row->height;
5285 }
5286
5287 w->must_be_updated_p = 1;
5288 if (update_frame_p)
5289 {
5290 /* Calling update_single_window is faster when we can use
5291 window-based redisplay. */
5292 if (FRAME_WINDOW_P (f))
5293 {
5294 update_single_window (w, 1);
5295 rif->flush_display (f);
5296 }
5297 else
5298 update_frame (f, 1, 1);
5299 }
5300 }
5301 else if (!EQ (mini_window, selected_window))
5302 windows_or_buffers_changed++;
5303
5304 /* Prevent redisplay optimization in redisplay_internal by resetting
5305 this_line_start_pos. This is done because the mini-buffer now
5306 displays the message instead of its buffer text. */
5307 if (EQ (mini_window, selected_window))
5308 CHARPOS (this_line_start_pos) = 0;
5309
5310 previous_echo_glyphs = echo_area_glyphs;
5311 previous_echo_area_message = echo_area_message;
5312 previous_echo_glyphs_length = echo_area_glyphs_length;
5313 }
5314
5315
5316 \f
5317 /***********************************************************************
5318 Frame Titles
5319 ***********************************************************************/
5320
5321
5322 #ifdef HAVE_WINDOW_SYSTEM
5323
5324 /* A buffer for constructing frame titles in it; allocated from the
5325 heap in init_xdisp and resized as needed in store_frame_title_char. */
5326
5327 static char *frame_title_buf;
5328
5329 /* The buffer's end, and a current output position in it. */
5330
5331 static char *frame_title_buf_end;
5332 static char *frame_title_ptr;
5333
5334
5335 /* Store a single character C for the frame title in frame_title_buf.
5336 Re-allocate frame_title_buf if necessary. */
5337
5338 static void
5339 store_frame_title_char (c)
5340 char c;
5341 {
5342 /* If output position has reached the end of the allocated buffer,
5343 double the buffer's size. */
5344 if (frame_title_ptr == frame_title_buf_end)
5345 {
5346 int len = frame_title_ptr - frame_title_buf;
5347 int new_size = 2 * len * sizeof *frame_title_buf;
5348 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
5349 frame_title_buf_end = frame_title_buf + new_size;
5350 frame_title_ptr = frame_title_buf + len;
5351 }
5352
5353 *frame_title_ptr++ = c;
5354 }
5355
5356
5357 /* Store part of a frame title in frame_title_buf, beginning at
5358 frame_title_ptr. STR is the string to store. Do not copy more
5359 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
5360 the whole string. Pad with spaces until FIELD_WIDTH number of
5361 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
5362 Called from display_mode_element when it is used to build a frame
5363 title. */
5364
5365 static int
5366 store_frame_title (str, field_width, precision)
5367 unsigned char *str;
5368 int field_width, precision;
5369 {
5370 int n = 0;
5371
5372 /* Copy at most PRECISION chars from STR. */
5373 while ((precision <= 0 || n < precision)
5374 && *str)
5375 {
5376 store_frame_title_char (*str++);
5377 ++n;
5378 }
5379
5380 /* Fill up with spaces until FIELD_WIDTH reached. */
5381 while (field_width > 0
5382 && n < field_width)
5383 {
5384 store_frame_title_char (' ');
5385 ++n;
5386 }
5387
5388 return n;
5389 }
5390
5391
5392 /* Set the title of FRAME, if it has changed. The title format is
5393 Vicon_title_format if FRAME is iconified, otherwise it is
5394 frame_title_format. */
5395
5396 static void
5397 x_consider_frame_title (frame)
5398 Lisp_Object frame;
5399 {
5400 struct frame *f = XFRAME (frame);
5401
5402 if (FRAME_WINDOW_P (f)
5403 || FRAME_MINIBUF_ONLY_P (f)
5404 || f->explicit_name)
5405 {
5406 /* Do we have more than one visible frame on this X display? */
5407 Lisp_Object tail;
5408 Lisp_Object fmt;
5409 struct buffer *obuf;
5410 int len;
5411 struct it it;
5412
5413 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
5414 {
5415 struct frame *tf = XFRAME (XCONS (tail)->car);
5416
5417 if (tf != f
5418 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
5419 && !FRAME_MINIBUF_ONLY_P (tf)
5420 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
5421 break;
5422 }
5423
5424 /* Set global variable indicating that multiple frames exist. */
5425 multiple_frames = CONSP (tail);
5426
5427 /* Switch to the buffer of selected window of the frame. Set up
5428 frame_title_ptr so that display_mode_element will output into it;
5429 then display the title. */
5430 obuf = current_buffer;
5431 Fset_buffer (XWINDOW (f->selected_window)->buffer);
5432 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
5433 frame_title_ptr = frame_title_buf;
5434 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
5435 NULL, DEFAULT_FACE_ID);
5436 len = display_mode_element (&it, 0, -1, -1, fmt);
5437 frame_title_ptr = NULL;
5438 set_buffer_internal (obuf);
5439
5440 /* Set the title only if it's changed. This avoids consing in
5441 the common case where it hasn't. (If it turns out that we've
5442 already wasted too much time by walking through the list with
5443 display_mode_element, then we might need to optimize at a
5444 higher level than this.) */
5445 if (! STRINGP (f->name)
5446 || STRING_BYTES (XSTRING (f->name)) != len
5447 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
5448 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
5449 }
5450 }
5451
5452 #else /* not HAVE_WINDOW_SYSTEM */
5453
5454 #define frame_title_ptr ((char *)0)
5455 #define store_frame_title(str, mincol, maxcol) 0
5456
5457 #endif /* not HAVE_WINDOW_SYSTEM */
5458
5459
5460
5461 \f
5462 /***********************************************************************
5463 Menu Bars
5464 ***********************************************************************/
5465
5466
5467 /* Prepare for redisplay by updating menu-bar item lists when
5468 appropriate. This can call eval. */
5469
5470 void
5471 prepare_menu_bars ()
5472 {
5473 int all_windows;
5474 struct gcpro gcpro1, gcpro2;
5475 struct frame *f;
5476 struct frame *tooltip_frame;
5477
5478 #ifdef HAVE_X_WINDOWS
5479 tooltip_frame = tip_frame;
5480 #else
5481 tooltip_frame = NULL;
5482 #endif
5483
5484 /* Update all frame titles based on their buffer names, etc. We do
5485 this before the menu bars so that the buffer-menu will show the
5486 up-to-date frame titles. */
5487 #ifdef HAVE_WINDOW_SYSTEM
5488 if (windows_or_buffers_changed || update_mode_lines)
5489 {
5490 Lisp_Object tail, frame;
5491
5492 FOR_EACH_FRAME (tail, frame)
5493 {
5494 f = XFRAME (frame);
5495 if (f != tooltip_frame
5496 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
5497 x_consider_frame_title (frame);
5498 }
5499 }
5500 #endif /* HAVE_WINDOW_SYSTEM */
5501
5502 /* Update the menu bar item lists, if appropriate. This has to be
5503 done before any actual redisplay or generation of display lines. */
5504 all_windows = (update_mode_lines
5505 || buffer_shared > 1
5506 || windows_or_buffers_changed);
5507 if (all_windows)
5508 {
5509 Lisp_Object tail, frame;
5510 int count = specpdl_ptr - specpdl;
5511
5512 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5513
5514 FOR_EACH_FRAME (tail, frame)
5515 {
5516 f = XFRAME (frame);
5517
5518 /* Ignore tooltip frame. */
5519 if (f == tooltip_frame)
5520 continue;
5521
5522 /* If a window on this frame changed size, report that to
5523 the user and clear the size-change flag. */
5524 if (FRAME_WINDOW_SIZES_CHANGED (f))
5525 {
5526 Lisp_Object functions;
5527
5528 /* Clear flag first in case we get an error below. */
5529 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
5530 functions = Vwindow_size_change_functions;
5531 GCPRO2 (tail, functions);
5532
5533 while (CONSP (functions))
5534 {
5535 call1 (XCAR (functions), frame);
5536 functions = XCDR (functions);
5537 }
5538 UNGCPRO;
5539 }
5540
5541 GCPRO1 (tail);
5542 update_menu_bar (f, 0);
5543 #ifdef HAVE_WINDOW_SYSTEM
5544 update_toolbar (f, 0);
5545 #endif
5546 UNGCPRO;
5547 }
5548
5549 unbind_to (count, Qnil);
5550 }
5551 else
5552 {
5553 update_menu_bar (selected_frame, 1);
5554 #ifdef HAVE_WINDOW_SYSTEM
5555 update_toolbar (selected_frame, 1);
5556 #endif
5557 }
5558
5559 /* Motif needs this. See comment in xmenu.c. Turn it off when
5560 pending_menu_activation is not defined. */
5561 #ifdef USE_X_TOOLKIT
5562 pending_menu_activation = 0;
5563 #endif
5564 }
5565
5566
5567 /* Update the menu bar item list for frame F. This has to be done
5568 before we start to fill in any display lines, because it can call
5569 eval.
5570
5571 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
5572
5573 static void
5574 update_menu_bar (f, save_match_data)
5575 struct frame *f;
5576 int save_match_data;
5577 {
5578 Lisp_Object window;
5579 register struct window *w;
5580
5581 window = FRAME_SELECTED_WINDOW (f);
5582 w = XWINDOW (window);
5583
5584 if (update_mode_lines)
5585 w->update_mode_line = Qt;
5586
5587 if (FRAME_WINDOW_P (f)
5588 ?
5589 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5590 FRAME_EXTERNAL_MENU_BAR (f)
5591 #else
5592 FRAME_MENU_BAR_LINES (f) > 0
5593 #endif
5594 : FRAME_MENU_BAR_LINES (f) > 0)
5595 {
5596 /* If the user has switched buffers or windows, we need to
5597 recompute to reflect the new bindings. But we'll
5598 recompute when update_mode_lines is set too; that means
5599 that people can use force-mode-line-update to request
5600 that the menu bar be recomputed. The adverse effect on
5601 the rest of the redisplay algorithm is about the same as
5602 windows_or_buffers_changed anyway. */
5603 if (windows_or_buffers_changed
5604 || !NILP (w->update_mode_line)
5605 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
5606 < BUF_MODIFF (XBUFFER (w->buffer)))
5607 != !NILP (w->last_had_star))
5608 || ((!NILP (Vtransient_mark_mode)
5609 && !NILP (XBUFFER (w->buffer)->mark_active))
5610 != !NILP (w->region_showing)))
5611 {
5612 struct buffer *prev = current_buffer;
5613 int count = specpdl_ptr - specpdl;
5614
5615 set_buffer_internal_1 (XBUFFER (w->buffer));
5616 if (save_match_data)
5617 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5618 if (NILP (Voverriding_local_map_menu_flag))
5619 {
5620 specbind (Qoverriding_terminal_local_map, Qnil);
5621 specbind (Qoverriding_local_map, Qnil);
5622 }
5623
5624 /* Run the Lucid hook. */
5625 call1 (Vrun_hooks, Qactivate_menubar_hook);
5626
5627 /* If it has changed current-menubar from previous value,
5628 really recompute the menu-bar from the value. */
5629 if (! NILP (Vlucid_menu_bar_dirty_flag))
5630 call0 (Qrecompute_lucid_menubar);
5631
5632 safe_run_hooks (Qmenu_bar_update_hook);
5633 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
5634
5635 /* Redisplay the menu bar in case we changed it. */
5636 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5637 if (FRAME_WINDOW_P (f))
5638 set_frame_menubar (f, 0, 0);
5639 else
5640 /* On a terminal screen, the menu bar is an ordinary screen
5641 line, and this makes it get updated. */
5642 w->update_mode_line = Qt;
5643 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5644 /* In the non-toolkit version, the menu bar is an ordinary screen
5645 line, and this makes it get updated. */
5646 w->update_mode_line = Qt;
5647 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5648
5649 unbind_to (count, Qnil);
5650 set_buffer_internal_1 (prev);
5651 }
5652 }
5653 }
5654
5655
5656 \f
5657 /***********************************************************************
5658 Toolbars
5659 ***********************************************************************/
5660
5661 #ifdef HAVE_WINDOW_SYSTEM
5662
5663 /* Update the toolbar item list for frame F. This has to be done
5664 before we start to fill in any display lines. Called from
5665 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
5666 and restore it here. */
5667
5668 static void
5669 update_toolbar (f, save_match_data)
5670 struct frame *f;
5671 int save_match_data;
5672 {
5673 if (WINDOWP (f->toolbar_window)
5674 && XFASTINT (XWINDOW (f->toolbar_window)->height) > 0)
5675 {
5676 Lisp_Object window;
5677 struct window *w;
5678
5679 window = FRAME_SELECTED_WINDOW (f);
5680 w = XWINDOW (window);
5681
5682 /* If the user has switched buffers or windows, we need to
5683 recompute to reflect the new bindings. But we'll
5684 recompute when update_mode_lines is set too; that means
5685 that people can use force-mode-line-update to request
5686 that the menu bar be recomputed. The adverse effect on
5687 the rest of the redisplay algorithm is about the same as
5688 windows_or_buffers_changed anyway. */
5689 if (windows_or_buffers_changed
5690 || !NILP (w->update_mode_line)
5691 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
5692 < BUF_MODIFF (XBUFFER (w->buffer)))
5693 != !NILP (w->last_had_star))
5694 || ((!NILP (Vtransient_mark_mode)
5695 && !NILP (XBUFFER (w->buffer)->mark_active))
5696 != !NILP (w->region_showing)))
5697 {
5698 struct buffer *prev = current_buffer;
5699 int count = specpdl_ptr - specpdl;
5700
5701 /* Set current_buffer to the buffer of the selected
5702 window of the frame, so that we get the right local
5703 keymaps. */
5704 set_buffer_internal_1 (XBUFFER (w->buffer));
5705
5706 /* Save match data, if we must. */
5707 if (save_match_data)
5708 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5709
5710 /* Make sure that we don't accidentally use bogus keymaps. */
5711 if (NILP (Voverriding_local_map_menu_flag))
5712 {
5713 specbind (Qoverriding_terminal_local_map, Qnil);
5714 specbind (Qoverriding_local_map, Qnil);
5715 }
5716
5717 /* Build desired toolbar items from keymaps. */
5718 f->desired_toolbar_items
5719 = toolbar_items (f->desired_toolbar_items,
5720 &f->n_desired_toolbar_items);
5721
5722 /* Redisplay the toolbar in case we changed it. */
5723 w->update_mode_line = Qt;
5724
5725 unbind_to (count, Qnil);
5726 set_buffer_internal_1 (prev);
5727 }
5728 }
5729 }
5730
5731
5732 /* Set F->desired_toolbar_string to a Lisp string representing frame
5733 F's desired toolbar contents. F->desired_toolbar_items must have
5734 been set up previously by calling prepare_menu_bars. */
5735
5736 static void
5737 build_desired_toolbar_string (f)
5738 struct frame *f;
5739 {
5740 int i, size, size_needed, string_idx;
5741 struct gcpro gcpro1, gcpro2, gcpro3;
5742 Lisp_Object image, plist, props;
5743
5744 image = plist = props = Qnil;
5745 GCPRO3 (image, plist, props);
5746
5747 /* Prepare F->desired_toolbar_string. If we can reuse it, do so.
5748 Otherwise, make a new string. */
5749
5750 /* The size of the string we might be able to reuse. */
5751 size = (STRINGP (f->desired_toolbar_string)
5752 ? XSTRING (f->desired_toolbar_string)->size
5753 : 0);
5754
5755 /* Each image in the string we build is preceded by a space,
5756 and there is a space at the end. */
5757 size_needed = f->n_desired_toolbar_items + 1;
5758
5759 /* Reuse f->desired_toolbar_string, if possible. */
5760 if (size < size_needed)
5761 f->desired_toolbar_string = Fmake_string (make_number (size_needed), ' ');
5762 else
5763 {
5764 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
5765 Fremove_text_properties (make_number (0), make_number (size),
5766 props, f->desired_toolbar_string);
5767 }
5768
5769 /* Put a `display' property on the string for the images to display,
5770 put a `menu_item' property on toolbar items with a value that
5771 is the index of the item in F's toolbar item vector. */
5772 for (i = 0, string_idx = 0;
5773 i < f->n_desired_toolbar_items;
5774 ++i, string_idx += 1)
5775 {
5776 #define PROP(IDX) \
5777 (XVECTOR (f->desired_toolbar_items) \
5778 ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
5779
5780 int enabled_p = !NILP (PROP (TOOLBAR_ITEM_ENABLED_P));
5781 int selected_p = !NILP (PROP (TOOLBAR_ITEM_SELECTED_P));
5782 int margin, relief;
5783 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
5784 extern Lisp_Object Qlaplace;
5785
5786 /* If image is a vector, choose the image according to the
5787 button state. */
5788 image = PROP (TOOLBAR_ITEM_IMAGES);
5789 if (VECTORP (image))
5790 {
5791 enum toolbar_item_image idx;
5792
5793 if (enabled_p)
5794 idx = (selected_p
5795 ? TOOLBAR_IMAGE_ENABLED_SELECTED
5796 : TOOLBAR_IMAGE_ENABLED_DESELECTED);
5797 else
5798 idx = (selected_p
5799 ? TOOLBAR_IMAGE_DISABLED_SELECTED
5800 : TOOLBAR_IMAGE_DISABLED_DESELECTED);
5801
5802 xassert (XVECTOR (image)->size >= idx);
5803 image = XVECTOR (image)->contents[idx];
5804 }
5805
5806 /* Ignore invalid image specifications. */
5807 if (!valid_image_p (image))
5808 continue;
5809
5810 /* Display the toolbar button pressed, or depressed. */
5811 plist = Fcopy_sequence (XCDR (image));
5812
5813 /* Compute margin and relief to draw. */
5814 relief = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
5815 margin = relief + max (0, toolbar_button_margin);
5816
5817 if (auto_raise_toolbar_buttons_p)
5818 {
5819 /* Add a `:relief' property to the image spec if the item is
5820 selected. */
5821 if (selected_p)
5822 {
5823 plist = Fplist_put (plist, QCrelief, make_number (-relief));
5824 margin -= relief;
5825 }
5826 }
5827 else
5828 {
5829 /* If image is selected, display it pressed, i.e. with a
5830 negative relief. If it's not selected, display it with a
5831 raised relief. */
5832 plist = Fplist_put (plist, QCrelief,
5833 (selected_p
5834 ? make_number (-relief)
5835 : make_number (relief)));
5836 margin -= relief;
5837 }
5838
5839 /* Put a margin around the image. */
5840 if (margin)
5841 plist = Fplist_put (plist, QCmargin, make_number (margin));
5842
5843 /* If button is not enabled, make the image appear disabled by
5844 applying an appropriate algorithm to it. */
5845 if (!enabled_p)
5846 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
5847
5848 /* Put a `display' text property on the string for the image to
5849 display. Put a `menu-item' property on the string that gives
5850 the start of this item's properties in the toolbar items
5851 vector. */
5852 image = Fcons (Qimage, plist);
5853 props = list4 (Qdisplay, image,
5854 Qmenu_item, make_number (i * TOOLBAR_ITEM_NSLOTS)),
5855 Fadd_text_properties (make_number (string_idx),
5856 make_number (string_idx + 1),
5857 props, f->desired_toolbar_string);
5858 #undef PROP
5859 }
5860
5861 UNGCPRO;
5862 }
5863
5864
5865 /* Display one line of the toolbar of frame IT->f. */
5866
5867 static void
5868 display_toolbar_line (it)
5869 struct it *it;
5870 {
5871 struct glyph_row *row = it->glyph_row;
5872 int max_x = it->last_visible_x;
5873 struct glyph *last;
5874
5875 prepare_desired_row (row);
5876 row->y = it->current_y;
5877
5878 while (it->current_x < max_x)
5879 {
5880 int x_before, x, n_glyphs_before, i, nglyphs;
5881
5882 /* Get the next display element. */
5883 if (!get_next_display_element (it))
5884 break;
5885
5886 /* Produce glyphs. */
5887 x_before = it->current_x;
5888 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
5889 PRODUCE_GLYPHS (it);
5890
5891 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
5892 i = 0;
5893 x = x_before;
5894 while (i < nglyphs)
5895 {
5896 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
5897
5898 if (x + glyph->pixel_width > max_x)
5899 {
5900 /* Glyph doesn't fit on line. */
5901 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
5902 it->current_x = x;
5903 goto out;
5904 }
5905
5906 ++it->hpos;
5907 x += glyph->pixel_width;
5908 ++i;
5909 }
5910
5911 /* Stop at line ends. */
5912 if (ITERATOR_AT_END_OF_LINE_P (it))
5913 break;
5914
5915 set_iterator_to_next (it);
5916 }
5917
5918 out:;
5919
5920 row->displays_text_p = row->used[TEXT_AREA] != 0;
5921 extend_face_to_end_of_line (it);
5922 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
5923 last->right_box_line_p = 1;
5924 compute_line_metrics (it);
5925
5926 /* If line is empty, make it occupy the rest of the toolbar. */
5927 if (!row->displays_text_p)
5928 {
5929 row->height = row->phys_height = it->last_visible_y - row->y;
5930 row->ascent = row->phys_ascent = 0;
5931 }
5932
5933 row->full_width_p = 1;
5934 row->continued_p = 0;
5935 row->truncated_on_left_p = 0;
5936 row->truncated_on_right_p = 0;
5937
5938 it->current_x = it->hpos = 0;
5939 it->current_y += row->height;
5940 ++it->vpos;
5941 ++it->glyph_row;
5942 }
5943
5944
5945 /* Value is the number of screen lines needed to make all toolbar
5946 items of frame F visible. */
5947
5948 static int
5949 toolbar_lines_needed (f)
5950 struct frame *f;
5951 {
5952 struct window *w = XWINDOW (f->toolbar_window);
5953 struct it it;
5954
5955 /* Initialize an iterator for iteration over F->desired_toolbar_string
5956 in the toolbar window of frame F. */
5957 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
5958 it.first_visible_x = 0;
5959 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
5960 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
5961
5962 while (!ITERATOR_AT_END_P (&it))
5963 {
5964 it.glyph_row = w->desired_matrix->rows;
5965 clear_glyph_row (it.glyph_row);
5966 display_toolbar_line (&it);
5967 }
5968
5969 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
5970 }
5971
5972
5973 /* Display the toolbar of frame F. Value is non-zero if toolbar's
5974 height should be changed. */
5975
5976 static int
5977 redisplay_toolbar (f)
5978 struct frame *f;
5979 {
5980 struct window *w;
5981 struct it it;
5982 struct glyph_row *row;
5983 int change_height_p = 0;
5984
5985 /* If frame hasn't a toolbar window or if it is zero-height, don't
5986 do anything. This means you must start with toolbar-lines
5987 non-zero to get the auto-sizing effect. Or in other words, you
5988 can turn off toolbars by specifying toolbar-lines zero. */
5989 if (!WINDOWP (f->toolbar_window)
5990 || (w = XWINDOW (f->toolbar_window),
5991 XFASTINT (w->height) == 0))
5992 return 0;
5993
5994 /* Set up an iterator for the toolbar window. */
5995 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
5996 it.first_visible_x = 0;
5997 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
5998 row = it.glyph_row;
5999
6000 /* Build a string that represents the contents of the toolbar. */
6001 build_desired_toolbar_string (f);
6002 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
6003
6004 /* Display as many lines as needed to display all toolbar items. */
6005 while (it.current_y < it.last_visible_y)
6006 display_toolbar_line (&it);
6007
6008 /* It doesn't make much sense to try scrolling in the toolbar
6009 window, so don't do it. */
6010 w->desired_matrix->no_scrolling_p = 1;
6011 w->must_be_updated_p = 1;
6012
6013 if (auto_resize_toolbars_p)
6014 {
6015 int nlines;
6016
6017 /* If there are blank lines at the end, except for a partially
6018 visible blank line at the end that is smaller than
6019 CANON_Y_UNIT, change the toolbar's height. */
6020 row = it.glyph_row - 1;
6021 if (!row->displays_text_p
6022 && row->height >= CANON_Y_UNIT (f))
6023 change_height_p = 1;
6024
6025 /* If row displays toolbar items, but is partially visible,
6026 change the toolbar's height. */
6027 if (row->displays_text_p
6028 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6029 change_height_p = 1;
6030
6031 /* Resize windows as needed by changing the `toolbar-lines'
6032 frame parameter. */
6033 if (change_height_p
6034 && (nlines = toolbar_lines_needed (f),
6035 nlines != XFASTINT (w->height)))
6036 {
6037 extern Lisp_Object Qtoolbar_lines;
6038 Lisp_Object frame;
6039
6040 XSETFRAME (frame, f);
6041 clear_glyph_matrix (w->desired_matrix);
6042 Fmodify_frame_parameters (frame,
6043 Fcons (Fcons (Qtoolbar_lines,
6044 make_number (nlines)),
6045 Qnil));
6046 fonts_changed_p = 1;
6047 }
6048 }
6049
6050 return change_height_p;
6051 }
6052
6053
6054 /* Get information about the toolbar item which is displayed in GLYPH
6055 on frame F. Return in *PROP_IDX the index where toolbar item
6056 properties start in F->current_toolbar_items. Value is zero if
6057 GLYPH doesn't display a toolbar item. */
6058
6059 int
6060 toolbar_item_info (f, glyph, prop_idx)
6061 struct frame *f;
6062 struct glyph *glyph;
6063 int *prop_idx;
6064 {
6065 Lisp_Object prop;
6066 int success_p;
6067
6068 /* Get the text property `menu-item' at pos. The value of that
6069 property is the start index of this item's properties in
6070 F->current_toolbar_items. */
6071 prop = Fget_text_property (make_number (glyph->charpos),
6072 Qmenu_item, f->current_toolbar_string);
6073 if (INTEGERP (prop))
6074 {
6075 *prop_idx = XINT (prop);
6076 success_p = 1;
6077 }
6078 else
6079 success_p = 0;
6080
6081 return success_p;
6082 }
6083
6084 #endif /* HAVE_WINDOW_SYSTEM */
6085
6086
6087 \f
6088 /************************************************************************
6089 Horizontal scrolling
6090 ************************************************************************/
6091
6092 static int hscroll_window_tree P_ ((Lisp_Object));
6093 static int hscroll_windows P_ ((Lisp_Object));
6094
6095 /* For all leaf windows in the window tree rooted at WINDOW, set their
6096 hscroll value so that PT is (i) visible in the window, and (ii) so
6097 that it is not within a certain margin at the window's left and
6098 right border. Value is non-zero if any window's hscroll has been
6099 changed. */
6100
6101 static int
6102 hscroll_window_tree (window)
6103 Lisp_Object window;
6104 {
6105 int hscrolled_p = 0;
6106
6107 while (WINDOWP (window))
6108 {
6109 struct window *w = XWINDOW (window);
6110
6111 if (WINDOWP (w->hchild))
6112 hscrolled_p |= hscroll_window_tree (w->hchild);
6113 else if (WINDOWP (w->vchild))
6114 hscrolled_p |= hscroll_window_tree (w->vchild);
6115 else if (w->cursor.vpos >= 0)
6116 {
6117 int hscroll_margin, text_area_x, text_area_y;
6118 int text_area_width, text_area_height;
6119 struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
6120 w->cursor.vpos);
6121
6122 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6123 &text_area_width, &text_area_height);
6124
6125 /* Scroll when cursor is inside this scroll margin. */
6126 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6127
6128 if ((XFASTINT (w->hscroll)
6129 && w->cursor.x < hscroll_margin)
6130 || (cursor_row->truncated_on_right_p
6131 && (w->cursor.x > text_area_width - hscroll_margin)))
6132 {
6133 struct it it;
6134 int hscroll;
6135 struct buffer *saved_current_buffer;
6136 int pt;
6137
6138 /* Find point in a display of infinite width. */
6139 saved_current_buffer = current_buffer;
6140 current_buffer = XBUFFER (w->buffer);
6141
6142 if (w == XWINDOW (selected_window))
6143 pt = BUF_PT (current_buffer);
6144 else
6145 {
6146 pt = marker_position (w->pointm);
6147 pt = max (BEGV, pt);
6148 pt = min (ZV, pt);
6149 }
6150
6151 /* Move iterator to pt starting at cursor_row->start in
6152 a line with infinite width. */
6153 init_to_row_start (&it, w, cursor_row);
6154 it.last_visible_x = INFINITY;
6155 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6156 current_buffer = saved_current_buffer;
6157
6158 /* Center cursor in window. */
6159 hscroll = (max (0, it.current_x - text_area_width / 2)
6160 / CANON_X_UNIT (it.f));
6161
6162 /* Don't call Fset_window_hscroll if value hasn't
6163 changed because it will prevent redisplay
6164 optimizations. */
6165 if (XFASTINT (w->hscroll) != hscroll)
6166 {
6167 Fset_window_hscroll (window, make_number (hscroll));
6168 hscrolled_p = 1;
6169 }
6170 }
6171 }
6172
6173 window = w->next;
6174 }
6175
6176 /* Value is non-zero if hscroll of any leaf window has been changed. */
6177 return hscrolled_p;
6178 }
6179
6180
6181 /* Set hscroll so that cursor is visible and not inside horizontal
6182 scroll margins for all windows in the tree rooted at WINDOW. See
6183 also hscroll_window_tree above. Value is non-zero if any window's
6184 hscroll has been changed. If it has, desired matrices on the frame
6185 of WINDOW are cleared. */
6186
6187 static int
6188 hscroll_windows (window)
6189 Lisp_Object window;
6190 {
6191 int hscrolled_p = hscroll_window_tree (window);
6192 if (hscrolled_p)
6193 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6194 return hscrolled_p;
6195 }
6196
6197
6198 \f
6199 /************************************************************************
6200 Redisplay
6201 ************************************************************************/
6202
6203 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6204 to a non-zero value. This is sometimes handy to have in a debugger
6205 session. */
6206
6207 #if GLYPH_DEBUG
6208
6209 /* Values of beg_unchanged and end_unchanged as of last call to
6210 try_window_id. */
6211
6212 int debug_beg_unchanged, debug_end_unchanged;
6213
6214 /* First and last unchanged row for try_window_id. */
6215
6216 int debug_first_unchanged_at_end_vpos;
6217 int debug_last_unchanged_at_beg_vpos;
6218
6219 /* Delta vpos and y. */
6220
6221 int debug_dvpos, debug_dy;
6222
6223 /* Delta in characters and bytes for try_window_id. */
6224
6225 int debug_delta, debug_delta_bytes;
6226
6227 /* Values of window_end_pos and window_end_vpos at the end of
6228 try_window_id. */
6229
6230 int debug_end_pos, debug_end_vpos;
6231
6232 /* Append a string to W->desired_matrix->method. FMT is a printf
6233 format string. A1...A9 are a supplement for a variable-length
6234 argument list. If trace_redisplay_p is non-zero also printf the
6235 resulting string to stderr. */
6236
6237 static void
6238 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
6239 struct window *w;
6240 char *fmt;
6241 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
6242 {
6243 char buffer[512];
6244 char *method = w->desired_matrix->method;
6245 int len = strlen (method);
6246 int size = sizeof w->desired_matrix->method;
6247 int remaining = size - len - 1;
6248
6249 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
6250 if (len && remaining)
6251 {
6252 method[len] = '|';
6253 --remaining, ++len;
6254 }
6255
6256 strncpy (method + len, buffer, remaining);
6257
6258 if (trace_redisplay_p)
6259 fprintf (stderr, "%p (%s): %s\n",
6260 w,
6261 ((BUFFERP (w->buffer)
6262 && STRINGP (XBUFFER (w->buffer)->name))
6263 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
6264 : "no buffer"),
6265 buffer);
6266 }
6267
6268 #endif /* GLYPH_DEBUG */
6269
6270
6271 /* This counter is used to clear the face cache every once in a while
6272 in redisplay_internal. It is incremented for each redisplay.
6273 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
6274 cleared. */
6275
6276 #define CLEAR_FACE_CACHE_COUNT 10000
6277 static int clear_face_cache_count;
6278
6279 /* Record the previous terminal frame we displayed. */
6280
6281 static struct frame *previous_terminal_frame;
6282
6283 /* Non-zero while redisplay_internal is in progress. */
6284
6285 int redisplaying_p;
6286
6287
6288 /* Value is non-zero if all changes in window W, which displays
6289 current_buffer, are in the text between START and END. START is a
6290 buffer position, END is given as a distance from Z. Used in
6291 redisplay_internal for display optimization. */
6292
6293 static INLINE int
6294 text_outside_line_unchanged_p (w, start, end)
6295 struct window *w;
6296 int start, end;
6297 {
6298 int unchanged_p = 1;
6299
6300 /* If text or overlays have changed, see where. */
6301 if (XFASTINT (w->last_modified) < MODIFF
6302 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
6303 {
6304 /* Gap in the line? */
6305 if (GPT < start || Z - GPT < end)
6306 unchanged_p = 0;
6307
6308 /* Changes start in front of the line, or end after it? */
6309 if (unchanged_p
6310 && (beg_unchanged < start - 1
6311 || end_unchanged < end))
6312 unchanged_p = 0;
6313
6314 /* If selective display, can't optimize if changes start at the
6315 beginning of the line. */
6316 if (unchanged_p
6317 && INTEGERP (current_buffer->selective_display)
6318 && XINT (current_buffer->selective_display) > 0
6319 && (beg_unchanged < start || GPT <= start))
6320 unchanged_p = 0;
6321 }
6322
6323 return unchanged_p;
6324 }
6325
6326
6327 /* Do a frame update, taking possible shortcuts into account. This is
6328 the main external entry point for redisplay.
6329
6330 If the last redisplay displayed an echo area message and that message
6331 is no longer requested, we clear the echo area or bring back the
6332 mini-buffer if that is in use. */
6333
6334 void
6335 redisplay ()
6336 {
6337 redisplay_internal (0);
6338 }
6339
6340
6341 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
6342 response to any user action; therefore, we should preserve the echo
6343 area. (Actually, our caller does that job.) Perhaps in the future
6344 avoid recentering windows if it is not necessary; currently that
6345 causes some problems. */
6346
6347 static void
6348 redisplay_internal (preserve_echo_area)
6349 int preserve_echo_area;
6350 {
6351 struct window *w = XWINDOW (selected_window);
6352 struct frame *f = XFRAME (w->frame);
6353 int pause;
6354 int must_finish = 0;
6355 struct text_pos tlbufpos, tlendpos;
6356 int number_of_visible_frames;
6357
6358 /* Non-zero means redisplay has to consider all windows on all
6359 frames. Zero means, only selected_window is considered. */
6360 int consider_all_windows_p;
6361
6362 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
6363
6364 /* No redisplay if running in batch mode or frame is not yet fully
6365 initialized, or redisplay is explicitly turned off by setting
6366 Vinhibit_redisplay. */
6367 if (noninteractive
6368 || !NILP (Vinhibit_redisplay)
6369 || !f->glyphs_initialized_p)
6370 return;
6371
6372 /* The flag redisplay_performed_directly_p is set by
6373 direct_output_for_insert when it already did the whole screen
6374 update necessary. */
6375 if (redisplay_performed_directly_p)
6376 {
6377 redisplay_performed_directly_p = 0;
6378 if (!hscroll_windows (selected_window))
6379 return;
6380 }
6381
6382 #ifdef USE_X_TOOLKIT
6383 if (popup_activated ())
6384 return;
6385 #endif
6386
6387 if (redisplaying_p)
6388 return;
6389 ++redisplaying_p;
6390
6391 retry:
6392
6393 /* If new fonts have been loaded that make a glyph matrix adjustment
6394 necessary, do it. */
6395 if (fonts_changed_p)
6396 {
6397 adjust_glyphs (NULL);
6398 ++windows_or_buffers_changed;
6399 fonts_changed_p = 0;
6400 }
6401
6402 if (! FRAME_WINDOW_P (selected_frame)
6403 && previous_terminal_frame != selected_frame)
6404 {
6405 /* Since frames on an ASCII terminal share the same display
6406 area, displaying a different frame means redisplay the whole
6407 thing. */
6408 windows_or_buffers_changed++;
6409 SET_FRAME_GARBAGED (selected_frame);
6410 XSETFRAME (Vterminal_frame, selected_frame);
6411 }
6412 previous_terminal_frame = selected_frame;
6413
6414 /* Set the visible flags for all frames. Do this before checking
6415 for resized or garbaged frames; they want to know if their frames
6416 are visible. See the comment in frame.h for
6417 FRAME_SAMPLE_VISIBILITY. */
6418 {
6419 Lisp_Object tail, frame;
6420
6421 number_of_visible_frames = 0;
6422
6423 FOR_EACH_FRAME (tail, frame)
6424 {
6425 struct frame *f = XFRAME (frame);
6426
6427 FRAME_SAMPLE_VISIBILITY (f);
6428 if (FRAME_VISIBLE_P (f))
6429 ++number_of_visible_frames;
6430 clear_desired_matrices (f);
6431 }
6432 }
6433
6434 /* Notice any pending interrupt request to change frame size. */
6435 do_pending_window_change ();
6436
6437 /* Clear frames marked as garbaged. */
6438 if (frame_garbaged)
6439 {
6440 /* Old redisplay called redraw_garbaged_frames here which in
6441 turn called redraw_frame which in turn called clear_frame.
6442 The call to clear_frame is a source of flickering. After
6443 checking the places where SET_FRAME_GARBAGED is called, I
6444 believe a clear_frame is not necessary. It should suffice in
6445 the new redisplay to invalidate all current matrices, and
6446 ensure a complete redisplay of all windows. */
6447 Lisp_Object tail, frame;
6448
6449 FOR_EACH_FRAME (tail, frame)
6450 {
6451 struct frame *f = XFRAME (frame);
6452
6453 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
6454 {
6455 clear_current_matrices (f);
6456 f->garbaged = 0;
6457 }
6458 }
6459
6460 frame_garbaged = 0;
6461 ++windows_or_buffers_changed;
6462 }
6463
6464 /* Build menubar and toolbar items. */
6465 prepare_menu_bars ();
6466
6467 if (windows_or_buffers_changed)
6468 update_mode_lines++;
6469
6470 /* Detect case that we need to write or remove a star in the mode line. */
6471 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
6472 {
6473 w->update_mode_line = Qt;
6474 if (buffer_shared > 1)
6475 update_mode_lines++;
6476 }
6477
6478 /* If %c is in the mode line, update it if needed. */
6479 if (!NILP (w->column_number_displayed)
6480 /* This alternative quickly identifies a common case
6481 where no change is needed. */
6482 && !(PT == XFASTINT (w->last_point)
6483 && XFASTINT (w->last_modified) >= MODIFF
6484 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
6485 && XFASTINT (w->column_number_displayed) != current_column ())
6486 w->update_mode_line = Qt;
6487
6488 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
6489
6490 /* The variable buffer_shared is set in redisplay_window and
6491 indicates that we redisplay a buffer in different windows. See
6492 there. */
6493 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
6494
6495 /* If specs for an arrow have changed, do thorough redisplay
6496 to ensure we remove any arrow that should no longer exist. */
6497 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
6498 || ! EQ (Voverlay_arrow_string, last_arrow_string))
6499 consider_all_windows_p = windows_or_buffers_changed = 1;
6500
6501 /* Normally the message* functions will have already displayed and
6502 updated the echo area, but the frame may have been trashed, or
6503 the update may have been preempted, so display the echo area
6504 again here. */
6505 if (echo_area_glyphs
6506 || STRINGP (echo_area_message)
6507 || previous_echo_glyphs
6508 || STRINGP (previous_echo_area_message))
6509 {
6510 echo_area_display (0);
6511 must_finish = 1;
6512 }
6513
6514 /* If showing the region, and mark has changed, we must redisplay
6515 the whole window. The assignment to this_line_start_pos prevents
6516 the optimization directly below this if-statement. */
6517 if (((!NILP (Vtransient_mark_mode)
6518 && !NILP (XBUFFER (w->buffer)->mark_active))
6519 != !NILP (w->region_showing))
6520 || (!NILP (w->region_showing)
6521 && !EQ (w->region_showing,
6522 Fmarker_position (XBUFFER (w->buffer)->mark))))
6523 CHARPOS (this_line_start_pos) = 0;
6524
6525 /* Optimize the case that only the line containing the cursor in the
6526 selected window has changed. Variables starting with this_ are
6527 set in display_line and record information about the line
6528 containing the cursor. */
6529 tlbufpos = this_line_start_pos;
6530 tlendpos = this_line_end_pos;
6531 if (!consider_all_windows_p
6532 && CHARPOS (tlbufpos) > 0
6533 && NILP (w->update_mode_line)
6534 && !current_buffer->clip_changed
6535 && FRAME_VISIBLE_P (XFRAME (w->frame))
6536 && !FRAME_OBSCURED_P (XFRAME (w->frame))
6537 /* Make sure recorded data applies to current buffer, etc. */
6538 && this_line_buffer == current_buffer
6539 && current_buffer == XBUFFER (w->buffer)
6540 && NILP (w->force_start)
6541 /* Point must be on the line that we have info recorded about. */
6542 && PT >= CHARPOS (tlbufpos)
6543 && PT <= Z - CHARPOS (tlendpos)
6544 /* All text outside that line, including its final newline,
6545 must be unchanged */
6546 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
6547 CHARPOS (tlendpos)))
6548 {
6549 if (CHARPOS (tlbufpos) > BEGV
6550 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
6551 && (CHARPOS (tlbufpos) == ZV
6552 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
6553 /* Former continuation line has disappeared by becoming empty */
6554 goto cancel;
6555 else if (XFASTINT (w->last_modified) < MODIFF
6556 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
6557 || MINI_WINDOW_P (w))
6558 {
6559 /* We have to handle the case of continuation around a
6560 wide-column character (See the comment in indent.c around
6561 line 885).
6562
6563 For instance, in the following case:
6564
6565 -------- Insert --------
6566 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
6567 J_I_ ==> J_I_ `^^' are cursors.
6568 ^^ ^^
6569 -------- --------
6570
6571 As we have to redraw the line above, we should goto cancel. */
6572
6573 struct it it;
6574 int line_height_before = this_line_pixel_height;
6575
6576 /* Note that start_display will handle the case that the
6577 line starting at tlbufpos is a continuation lines. */
6578 start_display (&it, w, tlbufpos);
6579
6580 /* Implementation note: It this still necessary? */
6581 if (it.current_x != this_line_start_x)
6582 goto cancel;
6583
6584 TRACE ((stderr, "trying display optimization 1\n"));
6585 w->cursor.vpos = -1;
6586 overlay_arrow_seen = 0;
6587 it.vpos = this_line_vpos;
6588 it.current_y = this_line_y;
6589 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
6590 display_line (&it);
6591
6592 /* If line contains point, is not continued,
6593 and ends at same distance from eob as before, we win */
6594 if (w->cursor.vpos >= 0
6595 /* Line is not continued, otherwise this_line_start_pos
6596 would have been set to 0 in display_line. */
6597 && CHARPOS (this_line_start_pos)
6598 /* Line ends as before. */
6599 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
6600 /* Line has same height as before. Otherwise other lines
6601 would have to be shifted up or down. */
6602 && this_line_pixel_height == line_height_before)
6603 {
6604 /* If this is not the window's last line, we must adjust
6605 the charstarts of the lines below. */
6606 if (it.current_y < it.last_visible_y)
6607 {
6608 struct glyph_row *row
6609 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
6610 int delta, delta_bytes;
6611
6612 if (Z - CHARPOS (tlendpos) == ZV)
6613 {
6614 /* This line ends at end of (accessible part of)
6615 buffer. There is no newline to count. */
6616 delta = (Z
6617 - CHARPOS (tlendpos)
6618 - MATRIX_ROW_START_CHARPOS (row));
6619 delta_bytes = (Z_BYTE
6620 - BYTEPOS (tlendpos)
6621 - MATRIX_ROW_START_BYTEPOS (row));
6622 }
6623 else
6624 {
6625 /* This line ends in a newline. Must take
6626 account of the newline and the rest of the
6627 text that follows. */
6628 delta = (Z
6629 - CHARPOS (tlendpos)
6630 - MATRIX_ROW_START_CHARPOS (row));
6631 delta_bytes = (Z_BYTE
6632 - BYTEPOS (tlendpos)
6633 - MATRIX_ROW_START_BYTEPOS (row));
6634 }
6635
6636 increment_glyph_matrix_buffer_positions (w->current_matrix,
6637 this_line_vpos + 1,
6638 w->current_matrix->nrows,
6639 delta, delta_bytes);
6640 }
6641
6642 /* If this row displays text now but previously didn't,
6643 or vice versa, w->window_end_vpos may have to be
6644 adjusted. */
6645 if ((it.glyph_row - 1)->displays_text_p)
6646 {
6647 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
6648 XSETINT (w->window_end_vpos, this_line_vpos);
6649 }
6650 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
6651 && this_line_vpos > 0)
6652 XSETINT (w->window_end_vpos, this_line_vpos - 1);
6653 w->window_end_valid = Qnil;
6654
6655 /* Update hint: No need to try to scroll in update_window. */
6656 w->desired_matrix->no_scrolling_p = 1;
6657
6658 #if GLYPH_DEBUG
6659 *w->desired_matrix->method = 0;
6660 debug_method_add (w, "optimization 1");
6661 #endif
6662 goto update;
6663 }
6664 else
6665 goto cancel;
6666 }
6667 else if (/* Cursor position hasn't changed. */
6668 PT == XFASTINT (w->last_point)
6669 /* Make sure the cursor was last displayed
6670 in this window. Otherwise we have to reposition it. */
6671 && 0 <= w->cursor.vpos
6672 && XINT (w->height) > w->cursor.vpos)
6673 {
6674 if (!must_finish)
6675 {
6676 do_pending_window_change ();
6677
6678 /* We used to always goto end_of_redisplay here, but this
6679 isn't enough if we have a blinking cursor. */
6680 if (w->cursor_off_p == w->last_cursor_off_p)
6681 goto end_of_redisplay;
6682 }
6683 goto update;
6684 }
6685 /* If highlighting the region, or if the cursor is in the echo area,
6686 then we can't just move the cursor. */
6687 else if (! (!NILP (Vtransient_mark_mode)
6688 && !NILP (current_buffer->mark_active))
6689 && (w == XWINDOW (current_buffer->last_selected_window)
6690 || highlight_nonselected_windows)
6691 && NILP (w->region_showing)
6692 && !cursor_in_echo_area)
6693 {
6694 struct it it;
6695 struct glyph_row *row;
6696
6697 /* Skip from tlbufpos to PT and see where it is. Note that
6698 PT may be in invisible text. If so, we will end at the
6699 next visible position. */
6700 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
6701 NULL, DEFAULT_FACE_ID);
6702 it.current_x = this_line_start_x;
6703 it.current_y = this_line_y;
6704 it.vpos = this_line_vpos;
6705
6706 /* The call to move_it_to stops in front of PT, but
6707 moves over before-strings. */
6708 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6709
6710 if (it.vpos == this_line_vpos
6711 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
6712 row->enabled_p))
6713 {
6714 xassert (this_line_vpos == it.vpos);
6715 xassert (this_line_y == it.current_y);
6716 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
6717 goto update;
6718 }
6719 else
6720 goto cancel;
6721 }
6722
6723 cancel:
6724 /* Text changed drastically or point moved off of line. */
6725 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
6726 }
6727
6728 CHARPOS (this_line_start_pos) = 0;
6729 consider_all_windows_p |= buffer_shared > 1;
6730 ++clear_face_cache_count;
6731
6732
6733 /* Build desired matrices. If consider_all_windows_p is non-zero,
6734 do it for all windows on all frames. Otherwise do it for
6735 selected_window, only. */
6736
6737 if (consider_all_windows_p)
6738 {
6739 Lisp_Object tail, frame;
6740
6741 /* Clear the face cache eventually. */
6742 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
6743 {
6744 clear_face_cache (0);
6745 clear_face_cache_count = 0;
6746 }
6747
6748 /* Recompute # windows showing selected buffer. This will be
6749 incremented each time such a window is displayed. */
6750 buffer_shared = 0;
6751
6752 FOR_EACH_FRAME (tail, frame)
6753 {
6754 struct frame *f = XFRAME (frame);
6755 if (FRAME_WINDOW_P (f) || f == selected_frame)
6756 {
6757 /* Mark all the scroll bars to be removed; we'll redeem
6758 the ones we want when we redisplay their windows. */
6759 if (condemn_scroll_bars_hook)
6760 (*condemn_scroll_bars_hook) (f);
6761
6762 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
6763 redisplay_windows (FRAME_ROOT_WINDOW (f));
6764
6765 /* Any scroll bars which redisplay_windows should have
6766 nuked should now go away. */
6767 if (judge_scroll_bars_hook)
6768 (*judge_scroll_bars_hook) (f);
6769 }
6770 }
6771 }
6772 else if (FRAME_VISIBLE_P (selected_frame)
6773 && !FRAME_OBSCURED_P (selected_frame))
6774 redisplay_window (selected_window, 1);
6775
6776
6777 /* Compare desired and current matrices, perform output. */
6778
6779 update:
6780
6781 /* If fonts changed, display again. */
6782 if (fonts_changed_p)
6783 goto retry;
6784
6785 /* Prevent various kinds of signals during display update.
6786 stdio is not robust about handling signals,
6787 which can cause an apparent I/O error. */
6788 if (interrupt_input)
6789 unrequest_sigio ();
6790 stop_polling ();
6791
6792 if (consider_all_windows_p)
6793 {
6794 Lisp_Object tail;
6795
6796 pause = 0;
6797
6798 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
6799 {
6800 struct frame *f;
6801
6802 if (!FRAMEP (XCONS (tail)->car))
6803 continue;
6804
6805 f = XFRAME (XCONS (tail)->car);
6806
6807 if ((FRAME_WINDOW_P (f) || f == selected_frame)
6808 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
6809 {
6810 /* Mark all windows as to be updated. */
6811 set_window_update_flags (XWINDOW (f->root_window), 1);
6812 pause |= update_frame (f, 0, 0);
6813 if (!pause)
6814 {
6815 if (hscroll_windows (f->root_window))
6816 goto retry;
6817
6818 mark_window_display_accurate (f->root_window, 1);
6819 if (frame_up_to_date_hook != 0)
6820 (*frame_up_to_date_hook) (f);
6821 }
6822 }
6823 }
6824 }
6825 else
6826 {
6827 if (FRAME_VISIBLE_P (selected_frame)
6828 && !FRAME_OBSCURED_P (selected_frame))
6829 {
6830 XWINDOW (selected_window)->must_be_updated_p = 1;
6831 pause = update_frame (selected_frame, 0, 0);
6832 if (!pause && hscroll_windows (selected_window))
6833 goto retry;
6834 }
6835 else
6836 pause = 0;
6837
6838 /* We may have called echo_area_display at the top of this
6839 function. If the echo area is on another frame, that may
6840 have put text on a frame other than the selected one, so the
6841 above call to update_frame would not have caught it. Catch
6842 it here. */
6843 {
6844 Lisp_Object mini_window;
6845 struct frame *mini_frame;
6846
6847 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
6848 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6849
6850 if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
6851 {
6852 XWINDOW (mini_window)->must_be_updated_p = 1;
6853 pause |= update_frame (mini_frame, 0, 0);
6854 if (!pause && hscroll_windows (mini_window))
6855 goto retry;
6856 }
6857 }
6858 }
6859
6860 /* If display was paused because of pending input, make sure we do a
6861 thorough update the next time. */
6862 if (pause)
6863 {
6864 /* Prevent the optimization at the beginning of
6865 redisplay_internal that tries a single-line update of the
6866 line containing the cursor in the selected window. */
6867 CHARPOS (this_line_start_pos) = 0;
6868
6869 /* Let the overlay arrow be updated the next time. */
6870 if (!NILP (last_arrow_position))
6871 {
6872 last_arrow_position = Qt;
6873 last_arrow_string = Qt;
6874 }
6875
6876 /* If we pause after scrolling, some rows in the current
6877 matrices of some windows are not valid. */
6878 if (!WINDOW_FULL_WIDTH_P (w)
6879 && !FRAME_WINDOW_P (XFRAME (w->frame)))
6880 update_mode_lines = 1;
6881 }
6882
6883 /* Now text on frame agrees with windows, so put info into the
6884 windows for partial redisplay to follow. */
6885 if (!pause)
6886 {
6887 register struct buffer *b = XBUFFER (w->buffer);
6888
6889 unchanged_modified = BUF_MODIFF (b);
6890 overlay_unchanged_modified = BUF_OVERLAY_MODIFF (b);
6891 beg_unchanged = BUF_GPT (b) - BUF_BEG (b);
6892 end_unchanged = BUF_Z (b) - BUF_GPT (b);
6893
6894 if (consider_all_windows_p)
6895 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
6896 else
6897 {
6898 XSETFASTINT (w->last_point, BUF_PT (b));
6899 w->last_cursor = w->cursor;
6900 w->last_cursor_off_p = w->cursor_off_p;
6901
6902 b->clip_changed = 0;
6903 w->update_mode_line = Qnil;
6904 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
6905 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
6906 w->last_had_star
6907 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6908 ? Qt : Qnil);
6909
6910 /* Record if we are showing a region, so can make sure to
6911 update it fully at next redisplay. */
6912 w->region_showing = (!NILP (Vtransient_mark_mode)
6913 && (w == XWINDOW (current_buffer->last_selected_window)
6914 || highlight_nonselected_windows)
6915 && !NILP (XBUFFER (w->buffer)->mark_active)
6916 ? Fmarker_position (XBUFFER (w->buffer)->mark)
6917 : Qnil);
6918
6919 w->window_end_valid = w->buffer;
6920 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
6921 last_arrow_string = Voverlay_arrow_string;
6922 if (frame_up_to_date_hook != 0)
6923 (*frame_up_to_date_hook) (selected_frame);
6924 }
6925
6926 update_mode_lines = 0;
6927 windows_or_buffers_changed = 0;
6928 }
6929
6930 /* Start SIGIO interrupts coming again. Having them off during the
6931 code above makes it less likely one will discard output, but not
6932 impossible, since there might be stuff in the system buffer here.
6933 But it is much hairier to try to do anything about that. */
6934 if (interrupt_input)
6935 request_sigio ();
6936 start_polling ();
6937
6938 /* If a frame has become visible which was not before, redisplay
6939 again, so that we display it. Expose events for such a frame
6940 (which it gets when becoming visible) don't call the parts of
6941 redisplay constructing glyphs, so simply exposing a frame won't
6942 display anything in this case. So, we have to display these
6943 frames here explicitly. */
6944 if (!pause)
6945 {
6946 Lisp_Object tail, frame;
6947 int new_count = 0;
6948
6949 FOR_EACH_FRAME (tail, frame)
6950 {
6951 int this_is_visible = 0;
6952
6953 if (XFRAME (frame)->visible)
6954 this_is_visible = 1;
6955 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
6956 if (XFRAME (frame)->visible)
6957 this_is_visible = 1;
6958
6959 if (this_is_visible)
6960 new_count++;
6961 }
6962
6963 if (new_count != number_of_visible_frames)
6964 windows_or_buffers_changed++;
6965 }
6966
6967 /* Change frame size now if a change is pending. */
6968 do_pending_window_change ();
6969
6970 /* If we just did a pending size change, or have additional
6971 visible frames, redisplay again. */
6972 if (windows_or_buffers_changed && !pause)
6973 goto retry;
6974
6975 end_of_redisplay:;
6976
6977 if (--redisplaying_p < 0)
6978 redisplaying_p = 0;
6979 }
6980
6981
6982 /* Redisplay, but leave alone any recent echo area message unless
6983 another message has been requested in its place.
6984
6985 This is useful in situations where you need to redisplay but no
6986 user action has occurred, making it inappropriate for the message
6987 area to be cleared. See tracking_off and
6988 wait_reading_process_input for examples of these situations. */
6989
6990 void
6991 redisplay_preserve_echo_area ()
6992 {
6993 if (!echo_area_glyphs
6994 && !STRINGP (echo_area_message)
6995 && (previous_echo_glyphs
6996 || STRINGP (previous_echo_area_message)))
6997 {
6998 echo_area_glyphs = previous_echo_glyphs;
6999 echo_area_message = previous_echo_area_message;
7000 echo_area_glyphs_length = previous_echo_glyphs_length;
7001 redisplay_internal (1);
7002 echo_area_glyphs = NULL;
7003 echo_area_message = Qnil;
7004 }
7005 else
7006 redisplay_internal (1);
7007 }
7008
7009
7010 /* Mark the display of windows in the window tree rooted at WINDOW as
7011 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7012 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7013 the next time redisplay_internal is called. */
7014
7015 void
7016 mark_window_display_accurate (window, accurate_p)
7017 Lisp_Object window;
7018 int accurate_p;
7019 {
7020 struct window *w;
7021
7022 for (; !NILP (window); window = w->next)
7023 {
7024 w = XWINDOW (window);
7025
7026 if (BUFFERP (w->buffer))
7027 {
7028 struct buffer *b = XBUFFER (w->buffer);
7029
7030 XSETFASTINT (w->last_modified,
7031 accurate_p ? BUF_MODIFF (b) : 0);
7032 XSETFASTINT (w->last_overlay_modified,
7033 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7034 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7035 ? Qt : Qnil);
7036
7037 #if 0 /* I don't think this is necessary because display_line does it.
7038 Let's check it. */
7039 /* Record if we are showing a region, so can make sure to
7040 update it fully at next redisplay. */
7041 w->region_showing
7042 = (!NILP (Vtransient_mark_mode)
7043 && (w == XWINDOW (current_buffer->last_selected_window)
7044 || highlight_nonselected_windows)
7045 && (!NILP (b->mark_active)
7046 ? Fmarker_position (b->mark)
7047 : Qnil));
7048 #endif
7049
7050 if (accurate_p)
7051 {
7052 b->clip_changed = 0;
7053 w->last_cursor = w->cursor;
7054 w->last_cursor_off_p = w->cursor_off_p;
7055 if (w == XWINDOW (selected_window))
7056 w->last_point = BUF_PT (b);
7057 else
7058 w->last_point = XMARKER (w->pointm)->charpos;
7059 }
7060 }
7061
7062 w->window_end_valid = w->buffer;
7063 w->update_mode_line = Qnil;
7064
7065 if (!NILP (w->vchild))
7066 mark_window_display_accurate (w->vchild, accurate_p);
7067 if (!NILP (w->hchild))
7068 mark_window_display_accurate (w->hchild, accurate_p);
7069 }
7070
7071 if (accurate_p)
7072 {
7073 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7074 last_arrow_string = Voverlay_arrow_string;
7075 }
7076 else
7077 {
7078 /* Force a thorough redisplay the next time by setting
7079 last_arrow_position and last_arrow_string to t, which is
7080 unequal to any useful value of Voverlay_arrow_... */
7081 last_arrow_position = Qt;
7082 last_arrow_string = Qt;
7083 }
7084 }
7085
7086
7087 /* Return value in display table DP (Lisp_Char_Table *) for character
7088 C. Since a display table doesn't have any parent, we don't have to
7089 follow parent. Do not call this function directly but use the
7090 macro DISP_CHAR_VECTOR. */
7091
7092 Lisp_Object
7093 disp_char_vector (dp, c)
7094 struct Lisp_Char_Table *dp;
7095 int c;
7096 {
7097 int code[4], i;
7098 Lisp_Object val;
7099
7100 if (SINGLE_BYTE_CHAR_P (c))
7101 return (dp->contents[c]);
7102
7103 SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
7104 if (code[0] != CHARSET_COMPOSITION)
7105 {
7106 if (code[1] < 32)
7107 code[1] = -1;
7108 else if (code[2] < 32)
7109 code[2] = -1;
7110 }
7111
7112 /* Here, the possible range of code[0] (== charset ID) is
7113 128..max_charset. Since the top level char table contains data
7114 for multibyte characters after 256th element, we must increment
7115 code[0] by 128 to get a correct index. */
7116 code[0] += 128;
7117 code[3] = -1; /* anchor */
7118
7119 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
7120 {
7121 val = dp->contents[code[i]];
7122 if (!SUB_CHAR_TABLE_P (val))
7123 return (NILP (val) ? dp->defalt : val);
7124 }
7125
7126 /* Here, val is a sub char table. We return the default value of
7127 it. */
7128 return (dp->defalt);
7129 }
7130
7131
7132 \f
7133 /***********************************************************************
7134 Window Redisplay
7135 ***********************************************************************/
7136
7137 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
7138
7139 static void
7140 redisplay_windows (window)
7141 Lisp_Object window;
7142 {
7143 while (!NILP (window))
7144 {
7145 struct window *w = XWINDOW (window);
7146
7147 if (!NILP (w->hchild))
7148 redisplay_windows (w->hchild);
7149 else if (!NILP (w->vchild))
7150 redisplay_windows (w->vchild);
7151 else
7152 redisplay_window (window, 0);
7153
7154 window = w->next;
7155 }
7156 }
7157
7158
7159 /* Set cursor position of W. PT is assumed to be displayed in ROW.
7160 DELTA is the number of bytes by which positions recorded in ROW
7161 differ from current buffer positions. */
7162
7163 void
7164 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
7165 struct window *w;
7166 struct glyph_row *row;
7167 struct glyph_matrix *matrix;
7168 int delta, delta_bytes, dy, dvpos;
7169 {
7170 struct glyph *glyph = row->glyphs[TEXT_AREA];
7171 struct glyph *end = glyph + row->used[TEXT_AREA];
7172 int x = row->x;
7173 int pt_old = PT - delta;
7174
7175 /* Skip over glyphs not having an object at the start of the row.
7176 These are special glyphs like truncation marks on terminal
7177 frames. */
7178 if (row->displays_text_p)
7179 while (glyph < end
7180 && !glyph->object
7181 && glyph->charpos < 0)
7182 {
7183 x += glyph->pixel_width;
7184 ++glyph;
7185 }
7186
7187 while (glyph < end
7188 && glyph->object
7189 && (!BUFFERP (glyph->object)
7190 || glyph->charpos < pt_old))
7191 {
7192 x += glyph->pixel_width;
7193 ++glyph;
7194 }
7195
7196 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
7197 w->cursor.x = x;
7198 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
7199 w->cursor.y = row->y + dy;
7200
7201 if (w == XWINDOW (selected_window))
7202 {
7203 if (!row->continued_p
7204 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
7205 && row->x == 0)
7206 {
7207 this_line_buffer = XBUFFER (w->buffer);
7208
7209 CHARPOS (this_line_start_pos)
7210 = MATRIX_ROW_START_CHARPOS (row) + delta;
7211 BYTEPOS (this_line_start_pos)
7212 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
7213
7214 CHARPOS (this_line_end_pos)
7215 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
7216 BYTEPOS (this_line_end_pos)
7217 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
7218
7219 this_line_y = w->cursor.y;
7220 this_line_pixel_height = row->height;
7221 this_line_vpos = w->cursor.vpos;
7222 this_line_start_x = row->x;
7223 }
7224 else
7225 CHARPOS (this_line_start_pos) = 0;
7226 }
7227 }
7228
7229
7230 /* Run window scroll functions, if any, for WINDOW with new window
7231 start STARTP. Sets the window start of WINDOW to that position. */
7232
7233 static INLINE struct text_pos
7234 run_window_scroll_functions (window, startp)
7235 Lisp_Object window;
7236 struct text_pos startp;
7237 {
7238 struct window *w = XWINDOW (window);
7239 SET_MARKER_FROM_TEXT_POS (w->start, startp);
7240
7241 if (!NILP (Vwindow_scroll_functions))
7242 {
7243 run_hook_with_args_2 (Qwindow_scroll_functions, window,
7244 make_number (CHARPOS (startp)));
7245 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7246 }
7247
7248 return startp;
7249 }
7250
7251
7252 /* Modify the desired matrix of window W and W->vscroll so that the
7253 line containing the cursor is fully visible. */
7254
7255 static void
7256 make_cursor_line_fully_visible (w)
7257 struct window *w;
7258 {
7259 struct glyph_matrix *matrix;
7260 struct glyph_row *row;
7261 int top_line_height;
7262
7263 /* It's not always possible to find the cursor, e.g, when a window
7264 is full of overlay strings. Don't do anything in that case. */
7265 if (w->cursor.vpos < 0)
7266 return;
7267
7268 matrix = w->desired_matrix;
7269 row = MATRIX_ROW (matrix, w->cursor.vpos);
7270
7271 /* If row->y == top y of window display area, the window isn't tall
7272 enough to display a single line. There is nothing we can do
7273 about it. */
7274 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
7275 if (row->y == top_line_height)
7276 return;
7277
7278 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
7279 {
7280 int dy = row->height - row->visible_height;
7281 w->vscroll = 0;
7282 w->cursor.y += dy;
7283 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7284 }
7285 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
7286 {
7287 int dy = - (row->height - row->visible_height);
7288 w->vscroll = dy;
7289 w->cursor.y += dy;
7290 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7291 }
7292
7293 /* When we change the cursor y-position of the selected window,
7294 change this_line_y as well so that the display optimization for
7295 the cursor line of the selected window in redisplay_internal uses
7296 the correct y-position. */
7297 if (w == XWINDOW (selected_window))
7298 this_line_y = w->cursor.y;
7299 }
7300
7301
7302 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
7303 non-zero means only WINDOW is redisplayed in redisplay_internal.
7304 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
7305 in redisplay_window to bring a partially visible line into view in
7306 the case that only the cursor has moved.
7307
7308 Value is
7309
7310 1 if scrolling succeeded
7311
7312 0 if scrolling didn't find point.
7313
7314 -1 if new fonts have been loaded so that we must interrupt
7315 redisplay, adjust glyph matrices, and try again. */
7316
7317 static int
7318 try_scrolling (window, just_this_one_p, scroll_conservatively,
7319 scroll_step, temp_scroll_step)
7320 Lisp_Object window;
7321 int just_this_one_p;
7322 int scroll_conservatively, scroll_step;
7323 int temp_scroll_step;
7324 {
7325 struct window *w = XWINDOW (window);
7326 struct frame *f = XFRAME (w->frame);
7327 struct text_pos scroll_margin_pos;
7328 struct text_pos pos;
7329 struct text_pos startp;
7330 struct it it;
7331 Lisp_Object window_end;
7332 int this_scroll_margin;
7333 int dy = 0;
7334 int scroll_max;
7335 int line_height, rc;
7336 int amount_to_scroll = 0;
7337 Lisp_Object aggressive;
7338 int height;
7339
7340 #if GLYPH_DEBUG
7341 debug_method_add (w, "try_scrolling");
7342 #endif
7343
7344 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7345
7346 /* Compute scroll margin height in pixels. We scroll when point is
7347 within this distance from the top or bottom of the window. */
7348 if (scroll_margin > 0)
7349 {
7350 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
7351 this_scroll_margin *= CANON_Y_UNIT (f);
7352 }
7353 else
7354 this_scroll_margin = 0;
7355
7356 /* Compute how much we should try to scroll maximally to bring point
7357 into view. */
7358 if (scroll_step)
7359 scroll_max = scroll_step;
7360 else if (scroll_conservatively)
7361 scroll_max = scroll_conservatively;
7362 else if (temp_scroll_step)
7363 scroll_max = temp_scroll_step;
7364 else if (NUMBERP (current_buffer->scroll_down_aggressively)
7365 || NUMBERP (current_buffer->scroll_up_aggressively))
7366 /* We're trying to scroll because of aggressive scrolling
7367 but no scroll_step is set. Choose an arbitrary one. Maybe
7368 there should be a variable for this. */
7369 scroll_max = 10;
7370 else
7371 scroll_max = 0;
7372 scroll_max *= CANON_Y_UNIT (f);
7373
7374 /* Decide whether we have to scroll down. Start at the window end
7375 and move this_scroll_margin up to find the position of the scroll
7376 margin. */
7377 window_end = Fwindow_end (window, Qt);
7378 CHARPOS (scroll_margin_pos) = XINT (window_end);
7379 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
7380 if (this_scroll_margin)
7381 {
7382 start_display (&it, w, scroll_margin_pos);
7383 move_it_vertically (&it, - this_scroll_margin);
7384 scroll_margin_pos = it.current.pos;
7385 }
7386
7387 if (PT >= CHARPOS (scroll_margin_pos))
7388 {
7389 int y0;
7390
7391 /* Point is in the scroll margin at the bottom of the window, or
7392 below. Compute a new window start that makes point visible. */
7393
7394 /* Compute the distance from the scroll margin to PT.
7395 Give up if the distance is greater than scroll_max. */
7396 start_display (&it, w, scroll_margin_pos);
7397 y0 = it.current_y;
7398 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7399 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7400 line_height = (it.max_ascent + it.max_descent
7401 ? it.max_ascent + it.max_descent
7402 : last_height);
7403 dy = it.current_y + line_height - y0;
7404 if (dy > scroll_max)
7405 return 0;
7406
7407 /* Move the window start down. If scrolling conservatively,
7408 move it just enough down to make point visible. If
7409 scroll_step is set, move it down by scroll_step. */
7410 start_display (&it, w, startp);
7411
7412 if (scroll_conservatively)
7413 amount_to_scroll = dy;
7414 else if (scroll_step || temp_scroll_step)
7415 amount_to_scroll = scroll_max;
7416 else
7417 {
7418 aggressive = current_buffer->scroll_down_aggressively;
7419 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7420 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7421 if (NUMBERP (aggressive))
7422 amount_to_scroll = XFLOATINT (aggressive) * height;
7423 }
7424
7425 if (amount_to_scroll <= 0)
7426 return 0;
7427
7428 move_it_vertically (&it, amount_to_scroll);
7429 startp = it.current.pos;
7430 }
7431 else
7432 {
7433 /* See if point is inside the scroll margin at the top of the
7434 window. */
7435 scroll_margin_pos = startp;
7436 if (this_scroll_margin)
7437 {
7438 start_display (&it, w, startp);
7439 move_it_vertically (&it, this_scroll_margin);
7440 scroll_margin_pos = it.current.pos;
7441 }
7442
7443 if (PT < CHARPOS (scroll_margin_pos))
7444 {
7445 /* Point is in the scroll margin at the top of the window or
7446 above what is displayed in the window. */
7447 int y0;
7448
7449 /* Compute the vertical distance from PT to the scroll
7450 margin position. Give up if distance is greater than
7451 scroll_max. */
7452 SET_TEXT_POS (pos, PT, PT_BYTE);
7453 start_display (&it, w, pos);
7454 y0 = it.current_y;
7455 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
7456 it.last_visible_y, -1,
7457 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7458 dy = it.current_y - y0;
7459 if (dy > scroll_max)
7460 return 0;
7461
7462 /* Compute new window start. */
7463 start_display (&it, w, startp);
7464
7465 if (scroll_conservatively)
7466 amount_to_scroll = dy;
7467 else if (scroll_step || temp_scroll_step)
7468 amount_to_scroll = scroll_max;
7469 else
7470 {
7471 aggressive = current_buffer->scroll_up_aggressively;
7472 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7473 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7474 if (NUMBERP (aggressive))
7475 amount_to_scroll = XFLOATINT (aggressive) * height;
7476 }
7477
7478 if (amount_to_scroll <= 0)
7479 return 0;
7480
7481 move_it_vertically (&it, - amount_to_scroll);
7482 startp = it.current.pos;
7483 }
7484 }
7485
7486 /* Run window scroll functions. */
7487 startp = run_window_scroll_functions (window, startp);
7488
7489 /* Display the window. Give up if new fonts are loaded, or if point
7490 doesn't appear. */
7491 if (!try_window (window, startp))
7492 rc = -1;
7493 else if (w->cursor.vpos < 0)
7494 {
7495 clear_glyph_matrix (w->desired_matrix);
7496 rc = 0;
7497 }
7498 else
7499 {
7500 /* Maybe forget recorded base line for line number display. */
7501 if (!just_this_one_p
7502 || current_buffer->clip_changed
7503 || beg_unchanged < CHARPOS (startp))
7504 w->base_line_number = Qnil;
7505
7506 /* If cursor ends up on a partially visible line, shift display
7507 lines up or down. */
7508 make_cursor_line_fully_visible (w);
7509 rc = 1;
7510 }
7511
7512 return rc;
7513 }
7514
7515
7516 /* Compute a suitable window start for window W if display of W starts
7517 on a continuation line. Value is non-zero if a new window start
7518 was computed.
7519
7520 The new window start will be computed, based on W's width, starting
7521 from the start of the continued line. It is the start of the
7522 screen line with the minimum distance from the old start W->start. */
7523
7524 static int
7525 compute_window_start_on_continuation_line (w)
7526 struct window *w;
7527 {
7528 struct text_pos pos, start_pos;
7529 int window_start_changed_p = 0;
7530
7531 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
7532
7533 /* If window start is on a continuation line... Window start may be
7534 < BEGV in case there's invisible text at the start of the
7535 buffer (M-x rmail, for example). */
7536 if (CHARPOS (start_pos) > BEGV
7537 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
7538 {
7539 struct it it;
7540 struct glyph_row *row;
7541
7542 /* Find the start of the continued line. This should be fast
7543 because scan_buffer is fast (newline cache). */
7544 row = w->desired_matrix->rows + (WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0);
7545 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
7546 row, DEFAULT_FACE_ID);
7547 reseat_at_previous_visible_line_start (&it);
7548
7549 /* If the line start is "too far" away from the window start,
7550 say it takes too much time to compute a new window start. */
7551 if (CHARPOS (start_pos) - IT_CHARPOS (it)
7552 < XFASTINT (w->height) * XFASTINT (w->width))
7553 {
7554 int min_distance, distance;
7555
7556 /* Move forward by display lines to find the new window
7557 start. If window width was enlarged, the new start can
7558 be expected to be > the old start. If window width was
7559 decreased, the new window start will be < the old start.
7560 So, we're looking for the display line start with the
7561 minimum distance from the old window start. */
7562 pos = it.current.pos;
7563 min_distance = INFINITY;
7564 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
7565 distance < min_distance)
7566 {
7567 min_distance = distance;
7568 pos = it.current.pos;
7569 move_it_by_lines (&it, 1, 0);
7570 }
7571
7572 /* Set the window start there. */
7573 SET_MARKER_FROM_TEXT_POS (w->start, pos);
7574 window_start_changed_p = 1;
7575 }
7576 }
7577
7578 return window_start_changed_p;
7579 }
7580
7581
7582 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
7583 selected_window is redisplayed. */
7584
7585 static void
7586 redisplay_window (window, just_this_one_p)
7587 Lisp_Object window;
7588 int just_this_one_p;
7589 {
7590 struct window *w = XWINDOW (window);
7591 struct frame *f = XFRAME (w->frame);
7592 struct buffer *buffer = XBUFFER (w->buffer);
7593 struct buffer *old = current_buffer;
7594 struct text_pos lpoint, opoint, startp;
7595 int update_mode_line;
7596 int tem;
7597 struct it it;
7598 /* Record it now because it's overwritten. */
7599 int current_matrix_up_to_date_p = 0;
7600 int really_switched_buffer = 0;
7601 int temp_scroll_step = 0;
7602 int count = specpdl_ptr - specpdl;
7603
7604 SET_TEXT_POS (lpoint, PT, PT_BYTE);
7605 opoint = lpoint;
7606
7607 /* W must be a leaf window here. */
7608 xassert (!NILP (w->buffer));
7609 #if GLYPH_DEBUG
7610 *w->desired_matrix->method = 0;
7611 #endif
7612
7613 specbind (Qinhibit_point_motion_hooks, Qt);
7614
7615 /* Has the mode line to be updated? */
7616 update_mode_line = (!NILP (w->update_mode_line)
7617 || update_mode_lines
7618 || buffer->clip_changed);
7619
7620 if (MINI_WINDOW_P (w))
7621 {
7622 if (w == XWINDOW (echo_area_window)
7623 && (echo_area_glyphs
7624 || STRINGP (echo_area_message)))
7625 {
7626 if (update_mode_line)
7627 /* We may have to update a tty frame's menu bar or a
7628 toolbar. Example `M-x C-h C-h C-g'. */
7629 goto finish_menu_bars;
7630 else
7631 /* We've already displayed the echo area glyphs in this window. */
7632 goto finish_scroll_bars;
7633 }
7634 else if (w != XWINDOW (minibuf_window))
7635 {
7636 /* W is a mini-buffer window, but it's not the currently
7637 active one, so clear it. */
7638 int yb = window_text_bottom_y (w);
7639 struct glyph_row *row;
7640 int y;
7641
7642 for (y = 0, row = w->desired_matrix->rows;
7643 y < yb;
7644 y += row->height, ++row)
7645 blank_row (w, row, y);
7646 goto finish_scroll_bars;
7647 }
7648 }
7649
7650 /* Otherwise set up data on this window; select its buffer and point
7651 value. */
7652 if (update_mode_line)
7653 {
7654 /* Really select the buffer, for the sake of buffer-local
7655 variables. */
7656 set_buffer_internal_1 (XBUFFER (w->buffer));
7657 really_switched_buffer = 1;
7658 }
7659 else
7660 set_buffer_temp (XBUFFER (w->buffer));
7661 SET_TEXT_POS (opoint, PT, PT_BYTE);
7662
7663 current_matrix_up_to_date_p
7664 = (!NILP (w->window_end_valid)
7665 && !current_buffer->clip_changed
7666 && XFASTINT (w->last_modified) >= MODIFF
7667 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
7668
7669 /* When windows_or_buffers_changed is non-zero, we can't rely on
7670 the window end being valid, so set it to nil there. */
7671 if (windows_or_buffers_changed)
7672 {
7673 /* If window starts on a continuation line, maybe adjust the
7674 window start in case the window's width changed. */
7675 if (XMARKER (w->start)->buffer == current_buffer)
7676 compute_window_start_on_continuation_line (w);
7677
7678 w->window_end_valid = Qnil;
7679 }
7680
7681 /* Some sanity checks. */
7682 CHECK_WINDOW_END (w);
7683 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
7684 abort ();
7685 if (BYTEPOS (opoint) < CHARPOS (opoint))
7686 abort ();
7687
7688 /* If %c is in mode line, update it if needed. */
7689 if (!NILP (w->column_number_displayed)
7690 /* This alternative quickly identifies a common case
7691 where no change is needed. */
7692 && !(PT == XFASTINT (w->last_point)
7693 && XFASTINT (w->last_modified) >= MODIFF
7694 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
7695 && XFASTINT (w->column_number_displayed) != current_column ())
7696 update_mode_line = 1;
7697
7698 /* Count number of windows showing the selected buffer. An indirect
7699 buffer counts as its base buffer. */
7700 if (!just_this_one_p)
7701 {
7702 struct buffer *current_base, *window_base;
7703 current_base = current_buffer;
7704 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
7705 if (current_base->base_buffer)
7706 current_base = current_base->base_buffer;
7707 if (window_base->base_buffer)
7708 window_base = window_base->base_buffer;
7709 if (current_base == window_base)
7710 buffer_shared++;
7711 }
7712
7713 /* Point refers normally to the selected window. For any other
7714 window, set up appropriate value. */
7715 if (!EQ (window, selected_window))
7716 {
7717 int new_pt = XMARKER (w->pointm)->charpos;
7718 int new_pt_byte = marker_byte_position (w->pointm);
7719 if (new_pt < BEGV)
7720 {
7721 new_pt = BEGV;
7722 new_pt_byte = BEGV_BYTE;
7723 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
7724 }
7725 else if (new_pt > (ZV - 1))
7726 {
7727 new_pt = ZV;
7728 new_pt_byte = ZV_BYTE;
7729 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
7730 }
7731
7732 /* We don't use SET_PT so that the point-motion hooks don't run. */
7733 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
7734 }
7735
7736 /* If any of the character widths specified in the display table
7737 have changed, invalidate the width run cache. It's true that
7738 this may be a bit late to catch such changes, but the rest of
7739 redisplay goes (non-fatally) haywire when the display table is
7740 changed, so why should we worry about doing any better? */
7741 if (current_buffer->width_run_cache)
7742 {
7743 struct Lisp_Char_Table *disptab = buffer_display_table ();
7744
7745 if (! disptab_matches_widthtab (disptab,
7746 XVECTOR (current_buffer->width_table)))
7747 {
7748 invalidate_region_cache (current_buffer,
7749 current_buffer->width_run_cache,
7750 BEG, Z);
7751 recompute_width_table (current_buffer, disptab);
7752 }
7753 }
7754
7755 /* If window-start is screwed up, choose a new one. */
7756 if (XMARKER (w->start)->buffer != current_buffer)
7757 goto recenter;
7758
7759 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7760
7761 /* If someone specified a new starting point but did not insist,
7762 check whether it can be used. */
7763 if (!NILP (w->optional_new_start))
7764 {
7765 w->optional_new_start = Qnil;
7766 /* This takes a mini-buffer prompt into account. */
7767 start_display (&it, w, startp);
7768 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7769 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7770 if (IT_CHARPOS (it) == PT)
7771 w->force_start = Qt;
7772 }
7773
7774 /* Handle case where place to start displaying has been specified,
7775 unless the specified location is outside the accessible range. */
7776 if (!NILP (w->force_start))
7777 {
7778 w->force_start = Qnil;
7779 w->vscroll = 0;
7780 w->window_end_valid = Qnil;
7781
7782 /* Forget any recorded base line for line number display. */
7783 if (!current_matrix_up_to_date_p
7784 || current_buffer->clip_changed)
7785 w->base_line_number = Qnil;
7786
7787 /* Redisplay the mode line. Select the buffer properly for that.
7788 Also, run the hook window-scroll-functions
7789 because we have scrolled. */
7790 /* Note, we do this after clearing force_start because
7791 if there's an error, it is better to forget about force_start
7792 than to get into an infinite loop calling the hook functions
7793 and having them get more errors. */
7794 if (!update_mode_line
7795 || ! NILP (Vwindow_scroll_functions))
7796 {
7797 if (!really_switched_buffer)
7798 {
7799 set_buffer_temp (old);
7800 set_buffer_internal_1 (XBUFFER (w->buffer));
7801 really_switched_buffer = 1;
7802 }
7803
7804 update_mode_line = 1;
7805 w->update_mode_line = Qt;
7806 startp = run_window_scroll_functions (window, startp);
7807 }
7808
7809 XSETFASTINT (w->last_modified, 0);
7810 XSETFASTINT (w->last_overlay_modified, 0);
7811 if (CHARPOS (startp) < BEGV)
7812 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
7813 else if (CHARPOS (startp) > ZV)
7814 SET_TEXT_POS (startp, ZV, ZV_BYTE);
7815
7816 /* Redisplay, then check if cursor has been set during the
7817 redisplay. Give up if new fonts were loaded. */
7818 if (!try_window (window, startp))
7819 {
7820 w->force_start = Qt;
7821 clear_glyph_matrix (w->desired_matrix);
7822 goto restore_buffers;
7823 }
7824
7825 if (w->cursor.vpos < 0)
7826 {
7827 /* If point does not appear, or on a line that is not fully
7828 visible, move point so it does appear. The desired
7829 matrix has been built above, so we can use it. */
7830 int height = window_box_height (w) / 2;
7831 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
7832
7833 while (row->y < height)
7834 ++row;
7835
7836 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
7837 MATRIX_ROW_START_BYTEPOS (row));
7838
7839 if (w != XWINDOW (selected_window))
7840 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
7841 else if (current_buffer == old)
7842 SET_TEXT_POS (lpoint, PT, PT_BYTE);
7843
7844 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
7845
7846 /* If we are highlighting the region, then we just changed
7847 the region, so redisplay to show it. */
7848 if (!NILP (Vtransient_mark_mode)
7849 && !NILP (current_buffer->mark_active))
7850 {
7851 clear_glyph_matrix (w->desired_matrix);
7852 if (!try_window (window, startp))
7853 goto restore_buffers;
7854 }
7855 }
7856
7857 make_cursor_line_fully_visible (w);
7858 #if GLYPH_DEBUG
7859 debug_method_add (w, "forced window start");
7860 #endif
7861 goto done;
7862 }
7863
7864 /* Handle case where text has not changed, only point, and it has
7865 not moved off the frame. */
7866 if (current_matrix_up_to_date_p
7867 /* Point may be in this window. */
7868 && PT >= CHARPOS (startp)
7869 /* If we don't check this, we are called to move the cursor in a
7870 horizontally split window with a current matrix that doesn't
7871 fit the display. */
7872 && !windows_or_buffers_changed
7873 /* Selective display hasn't changed. */
7874 && !current_buffer->clip_changed
7875 /* If force-mode-line-update was called, really redisplay;
7876 that's how redisplay is forced after e.g. changing
7877 buffer-invisibility-spec. */
7878 && NILP (w->update_mode_line)
7879 /* Can't use this case if highlighting a region. When a
7880 region exists, cursor movement has to do more than just
7881 set the cursor. */
7882 && !(!NILP (Vtransient_mark_mode)
7883 && !NILP (current_buffer->mark_active))
7884 && NILP (w->region_showing)
7885 /* Right after splitting windows, last_point may be nil. */
7886 && INTEGERP (w->last_point)
7887 /* This code is not used for mini-buffer for the sake of the case
7888 of redisplaying to replace an echo area message; since in
7889 that case the mini-buffer contents per se are usually
7890 unchanged. This code is of no real use in the mini-buffer
7891 since the handling of this_line_start_pos, etc., in redisplay
7892 handles the same cases. */
7893 && !EQ (window, minibuf_window)
7894 /* When splitting windows or for new windows, it happens that
7895 redisplay is called with a nil window_end_vpos or one being
7896 larger than the window. This should really be fixed in
7897 window.c. I don't have this on my list, now, so we do
7898 approximately the same as the old redisplay code. --gerd. */
7899 && INTEGERP (w->window_end_vpos)
7900 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
7901 && (FRAME_WINDOW_P (f)
7902 || !MARKERP (Voverlay_arrow_position)
7903 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
7904 {
7905 int this_scroll_margin;
7906 struct glyph_row *row;
7907 int scroll_p;
7908
7909 #if GLYPH_DEBUG
7910 debug_method_add (w, "cursor movement");
7911 #endif
7912
7913 /* Scroll if point within this distance from the top or bottom
7914 of the window. This is a pixel value. */
7915 this_scroll_margin = max (0, scroll_margin);
7916 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
7917 this_scroll_margin *= CANON_Y_UNIT (f);
7918
7919 /* Start with the row the cursor was displayed during the last
7920 not paused redisplay. Give up if that row is not valid. */
7921 if (w->last_cursor.vpos >= w->current_matrix->nrows)
7922 goto try_to_scroll;
7923 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
7924 if (row->mode_line_p)
7925 ++row;
7926 if (!row->enabled_p)
7927 goto try_to_scroll;
7928
7929 scroll_p = 0;
7930 if (PT > XFASTINT (w->last_point))
7931 {
7932 /* Point has moved forward. */
7933 int last_y = window_text_bottom_y (w) - this_scroll_margin;
7934
7935 while ((MATRIX_ROW_END_CHARPOS (row) < PT
7936 /* The end position of a row equals the start
7937 position of the next row. If PT is there, we
7938 would rather display it in the next line, except
7939 when this line ends in ZV. */
7940 || (MATRIX_ROW_END_CHARPOS (row) == PT
7941 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
7942 || !row->ends_at_zv_p)))
7943 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
7944 {
7945 xassert (row->enabled_p);
7946 ++row;
7947 }
7948
7949 /* If within the scroll margin, scroll. Note that
7950 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
7951 next line would be drawn, and that this_scroll_margin can
7952 be zero. */
7953 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
7954 || PT > MATRIX_ROW_END_CHARPOS (row)
7955 /* Line is completely visible last line in window and PT
7956 is to be set in the next line. */
7957 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
7958 && PT == MATRIX_ROW_END_CHARPOS (row)
7959 && !row->ends_at_zv_p
7960 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
7961 scroll_p = 1;
7962 }
7963 else if (PT < XFASTINT (w->last_point))
7964 {
7965 /* Cursor has to be moved backward. Note that PT >=
7966 CHARPOS (startp) because of the outer if-statement. */
7967 while (!row->mode_line_p
7968 && (MATRIX_ROW_START_CHARPOS (row) > PT
7969 || (MATRIX_ROW_START_CHARPOS (row) == PT
7970 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
7971 && (row->y > this_scroll_margin
7972 || CHARPOS (startp) == BEGV))
7973 {
7974 xassert (row->enabled_p);
7975 --row;
7976 }
7977
7978 /* Consider the following case: Window starts at BEGV, there
7979 is invisible, intangible text at BEGV, so that display
7980 starts at some point START > BEGV. It can happen that
7981 we are called with PT somewhere between BEGV and START.
7982 Try to handle that case. */
7983 if (row < w->current_matrix->rows
7984 || row->mode_line_p)
7985 {
7986 row = w->current_matrix->rows;
7987 if (row->mode_line_p)
7988 ++row;
7989 }
7990
7991 /* Due to newlines in overlay strings, we may have to skip
7992 forward over overlay strings. */
7993 while (MATRIX_ROW_END_CHARPOS (row) == PT
7994 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
7995 && !row->ends_at_zv_p)
7996 ++row;
7997
7998 /* If within the scroll margin, scroll. */
7999 if (row->y < this_scroll_margin
8000 && CHARPOS (startp) != BEGV)
8001 scroll_p = 1;
8002 }
8003
8004 /* if PT is not in the glyph row, give up. */
8005 if (PT < MATRIX_ROW_START_CHARPOS (row)
8006 || PT > MATRIX_ROW_END_CHARPOS (row))
8007 goto try_to_scroll;
8008
8009 /* If we end up in a partially visible line, let's make it fully
8010 visible. This can be done most easily by using the existing
8011 scrolling code. */
8012 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8013 {
8014 temp_scroll_step = 1;
8015 goto try_to_scroll;
8016 }
8017 else if (scroll_p)
8018 goto try_to_scroll;
8019
8020 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8021 goto done;
8022 }
8023
8024 /* If current starting point was originally the beginning of a line
8025 but no longer is, find a new starting point. */
8026 else if (!NILP (w->start_at_line_beg)
8027 && !(CHARPOS (startp) <= BEGV
8028 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
8029 {
8030 #if GLYPH_DEBUG
8031 debug_method_add (w, "recenter 1");
8032 #endif
8033 goto recenter;
8034 }
8035
8036 /* Try scrolling with try_window_id. */
8037 else if (!windows_or_buffers_changed
8038 /* Window must be either use window-based redisplay or
8039 be full width. */
8040 && (FRAME_WINDOW_P (f)
8041 || ((line_ins_del_ok && WINDOW_FULL_WIDTH_P (w))
8042 && just_this_one_p))
8043 && !MINI_WINDOW_P (w)
8044 /* Point is not known NOT to appear in window. */
8045 && PT >= CHARPOS (startp)
8046 && XFASTINT (w->last_modified)
8047 /* Window is not hscrolled. */
8048 && XFASTINT (w->hscroll) == 0
8049 /* Selective display has not changed. */
8050 && !current_buffer->clip_changed
8051 /* Current matrix is up to date. */
8052 && !NILP (w->window_end_valid)
8053 /* Can't use this case if highlighting a region because
8054 a cursor movement will do more than just set the cursor. */
8055 && !(!NILP (Vtransient_mark_mode)
8056 && !NILP (current_buffer->mark_active))
8057 && NILP (w->region_showing)
8058 /* Overlay arrow position and string not changed. */
8059 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
8060 && EQ (last_arrow_string, Voverlay_arrow_string)
8061 /* Value is > 0 if update has been done, it is -1 if we
8062 know that the same window start will not work. It is 0
8063 if unsuccessful for some other reason. */
8064 && (tem = try_window_id (w)) != 0)
8065 {
8066 #if GLYPH_DEBUG
8067 debug_method_add (w, "try_window_id");
8068 #endif
8069
8070 if (fonts_changed_p)
8071 goto restore_buffers;
8072 if (tem > 0)
8073 goto done;
8074 /* Otherwise try_window_id has returned -1 which means that we
8075 don't want the alternative below this comment to execute. */
8076 }
8077 else if (CHARPOS (startp) >= BEGV
8078 && CHARPOS (startp) <= ZV
8079 && PT >= CHARPOS (startp)
8080 && (CHARPOS (startp) < ZV
8081 /* Avoid starting at end of buffer. */
8082 || CHARPOS (startp) == BEGV
8083 || (XFASTINT (w->last_modified) >= MODIFF
8084 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
8085 {
8086 #if GLYPH_DEBUG
8087 debug_method_add (w, "same window start");
8088 #endif
8089
8090 /* Try to redisplay starting at same place as before.
8091 If point has not moved off frame, accept the results. */
8092 if (!current_matrix_up_to_date_p
8093 /* Don't use try_window_reusing_current_matrix in this case
8094 because it can have changed the buffer. */
8095 || !NILP (Vwindow_scroll_functions)
8096 || MINI_WINDOW_P (w)
8097 || !try_window_reusing_current_matrix (w))
8098 {
8099 IF_DEBUG (debug_method_add (w, "1"));
8100 try_window (window, startp);
8101 }
8102
8103 if (fonts_changed_p)
8104 goto restore_buffers;
8105
8106 if (w->cursor.vpos >= 0)
8107 {
8108 if (!just_this_one_p
8109 || current_buffer->clip_changed
8110 || beg_unchanged < CHARPOS (startp))
8111 /* Forget any recorded base line for line number display. */
8112 w->base_line_number = Qnil;
8113
8114 make_cursor_line_fully_visible (w);
8115 goto done;
8116 }
8117 else
8118 clear_glyph_matrix (w->desired_matrix);
8119 }
8120
8121 try_to_scroll:
8122
8123 XSETFASTINT (w->last_modified, 0);
8124 XSETFASTINT (w->last_overlay_modified, 0);
8125
8126 /* Redisplay the mode line. Select the buffer properly for that. */
8127 if (!update_mode_line)
8128 {
8129 if (!really_switched_buffer)
8130 {
8131 set_buffer_temp (old);
8132 set_buffer_internal_1 (XBUFFER (w->buffer));
8133 really_switched_buffer = 1;
8134 }
8135 update_mode_line = 1;
8136 w->update_mode_line = Qt;
8137 }
8138
8139 /* Try to scroll by specified few lines. */
8140 if ((scroll_conservatively
8141 || scroll_step
8142 || temp_scroll_step
8143 || NUMBERP (current_buffer->scroll_up_aggressively)
8144 || NUMBERP (current_buffer->scroll_down_aggressively))
8145 && !current_buffer->clip_changed
8146 && CHARPOS (startp) >= BEGV
8147 && CHARPOS (startp) <= ZV)
8148 {
8149 /* The function returns -1 if new fonts were loaded, 1 if
8150 successful, 0 if not successful. */
8151 int rc = try_scrolling (window, just_this_one_p,
8152 scroll_conservatively,
8153 scroll_step,
8154 temp_scroll_step);
8155 if (rc > 0)
8156 goto done;
8157 else if (rc < 0)
8158 goto restore_buffers;
8159 }
8160
8161 /* Finally, just choose place to start which centers point */
8162
8163 recenter:
8164
8165 #if GLYPH_DEBUG
8166 debug_method_add (w, "recenter");
8167 #endif
8168
8169 /* w->vscroll = 0; */
8170
8171 /* Forget any previously recorded base line for line number display. */
8172 if (!current_matrix_up_to_date_p
8173 || current_buffer->clip_changed)
8174 w->base_line_number = Qnil;
8175
8176 /* Move backward half the height of the window. */
8177 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8178 it.current_y = it.last_visible_y;
8179 move_it_vertically_backward (&it, it.last_visible_y / 2);
8180 xassert (IT_CHARPOS (it) >= BEGV);
8181
8182 /* The function move_it_vertically_backward may move over more
8183 than the specified y-distance. If it->w is small, e.g. a
8184 mini-buffer window, we may end up in front of the window's
8185 display area. Start displaying at the start of the line
8186 containing PT in this case. */
8187 if (it.current_y <= 0)
8188 {
8189 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8190 move_it_vertically (&it, 0);
8191 xassert (IT_CHARPOS (it) <= PT);
8192 it.current_y = 0;
8193 }
8194
8195 it.current_x = it.hpos = 0;
8196
8197 /* Set startp here explicitly in case that helps avoid an infinite loop
8198 in case the window-scroll-functions functions get errors. */
8199 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
8200
8201 /* Run scroll hooks. */
8202 startp = run_window_scroll_functions (window, it.current.pos);
8203
8204 /* Redisplay the window. */
8205 if (!current_matrix_up_to_date_p
8206 || windows_or_buffers_changed
8207 /* Don't use try_window_reusing_current_matrix in this case
8208 because it can have changed the buffer. */
8209 || !NILP (Vwindow_scroll_functions)
8210 || !just_this_one_p
8211 || MINI_WINDOW_P (w)
8212 || !try_window_reusing_current_matrix (w))
8213 try_window (window, startp);
8214
8215 /* If new fonts have been loaded (due to fontsets), give up. We
8216 have to start a new redisplay since we need to re-adjust glyph
8217 matrices. */
8218 if (fonts_changed_p)
8219 goto restore_buffers;
8220
8221 /* If cursor did not appear assume that the middle of the window is
8222 in the first line of the window. Do it again with the next line.
8223 (Imagine a window of height 100, displaying two lines of height
8224 60. Moving back 50 from it->last_visible_y will end in the first
8225 line.) */
8226 if (w->cursor.vpos < 0)
8227 {
8228 if (!NILP (w->window_end_valid)
8229 && PT >= Z - XFASTINT (w->window_end_pos))
8230 {
8231 clear_glyph_matrix (w->desired_matrix);
8232 move_it_by_lines (&it, 1, 0);
8233 try_window (window, it.current.pos);
8234 }
8235 else if (PT < IT_CHARPOS (it))
8236 {
8237 clear_glyph_matrix (w->desired_matrix);
8238 move_it_by_lines (&it, -1, 0);
8239 try_window (window, it.current.pos);
8240 }
8241 else
8242 {
8243 /* Not much we can do about it. */
8244 }
8245 }
8246
8247 /* Consider the following case: Window starts at BEGV, there is
8248 invisible, intangible text at BEGV, so that display starts at
8249 some point START > BEGV. It can happen that we are called with
8250 PT somewhere between BEGV and START. Try to handle that case. */
8251 if (w->cursor.vpos < 0)
8252 {
8253 struct glyph_row *row = w->current_matrix->rows;
8254 if (row->mode_line_p)
8255 ++row;
8256 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8257 }
8258
8259 make_cursor_line_fully_visible (w);
8260
8261 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8262 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
8263 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
8264 ? Qt : Qnil);
8265
8266 done:
8267
8268 /* Display the mode line, if we must. */
8269 if ((update_mode_line
8270 /* If window not full width, must redo its mode line
8271 if (a) the window to its side is being redone and
8272 (b) we do a frame-based redisplay. This is a consequence
8273 of how inverted lines are drawn in frame-based redisplay. */
8274 || (!just_this_one_p
8275 && !FRAME_WINDOW_P (f)
8276 && !WINDOW_FULL_WIDTH_P (w))
8277 /* Line number to display. */
8278 || INTEGERP (w->base_line_pos)
8279 /* Column number is displayed and different from the one displayed. */
8280 || (!NILP (w->column_number_displayed)
8281 && XFASTINT (w->column_number_displayed) != current_column ()))
8282 /* This means that the window has a mode line. */
8283 && (WINDOW_WANTS_MODELINE_P (w)
8284 || WINDOW_WANTS_TOP_LINE_P (w)))
8285 {
8286 display_mode_lines (w);
8287
8288 /* If mode line height has changed, arrange for a thorough
8289 immediate redisplay using the correct mode line height. */
8290 if (WINDOW_WANTS_MODELINE_P (w)
8291 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
8292 {
8293 fonts_changed_p = 1;
8294 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
8295 = DESIRED_MODE_LINE_HEIGHT (w);
8296 }
8297
8298 /* If top line height has changed, arrange for a thorough
8299 immediate redisplay using the correct mode line height. */
8300 if (WINDOW_WANTS_TOP_LINE_P (w)
8301 && CURRENT_TOP_LINE_HEIGHT (w) != DESIRED_TOP_LINE_HEIGHT (w))
8302 {
8303 fonts_changed_p = 1;
8304 MATRIX_TOP_LINE_ROW (w->current_matrix)->height
8305 = DESIRED_TOP_LINE_HEIGHT (w);
8306 }
8307
8308 if (fonts_changed_p)
8309 goto restore_buffers;
8310 }
8311
8312 if (!line_number_displayed
8313 && !BUFFERP (w->base_line_pos))
8314 {
8315 w->base_line_pos = Qnil;
8316 w->base_line_number = Qnil;
8317 }
8318
8319 finish_menu_bars:
8320
8321 /* When we reach a frame's selected window, redo the frame's menu bar. */
8322 if (update_mode_line
8323 && EQ (FRAME_SELECTED_WINDOW (f), window))
8324 {
8325 int redisplay_menu_p = 0;
8326
8327 if (FRAME_WINDOW_P (f))
8328 {
8329 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
8330 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
8331 #else
8332 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
8333 #endif
8334 }
8335 else
8336 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
8337
8338 if (redisplay_menu_p)
8339 display_menu_bar (w);
8340
8341 #ifdef HAVE_WINDOW_SYSTEM
8342 if (WINDOWP (f->toolbar_window)
8343 && (FRAME_TOOLBAR_LINES (f) > 0
8344 || auto_resize_toolbars_p))
8345 redisplay_toolbar (f);
8346 #endif
8347 }
8348
8349 finish_scroll_bars:
8350
8351 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
8352 {
8353 int start, end, whole;
8354
8355 /* Calculate the start and end positions for the current window.
8356 At some point, it would be nice to choose between scrollbars
8357 which reflect the whole buffer size, with special markers
8358 indicating narrowing, and scrollbars which reflect only the
8359 visible region.
8360
8361 Note that mini-buffers sometimes aren't displaying any text. */
8362 if (! MINI_WINDOW_P (w)
8363 || (w == XWINDOW (minibuf_window)
8364 && !echo_area_glyphs
8365 && !STRINGP (echo_area_message)))
8366 {
8367 whole = ZV - BEGV;
8368 start = marker_position (w->start) - BEGV;
8369 /* I don't think this is guaranteed to be right. For the
8370 moment, we'll pretend it is. */
8371 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
8372
8373 if (end < start)
8374 end = start;
8375 if (whole < (end - start))
8376 whole = end - start;
8377 }
8378 else
8379 start = end = whole = 0;
8380
8381 /* Indicate what this scroll bar ought to be displaying now. */
8382 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
8383
8384 /* Note that we actually used the scroll bar attached to this
8385 window, so it shouldn't be deleted at the end of redisplay. */
8386 (*redeem_scroll_bar_hook) (w);
8387 }
8388
8389 restore_buffers:
8390
8391 /* Restore current_buffer and value of point in it. */
8392 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
8393 if (really_switched_buffer)
8394 set_buffer_internal_1 (old);
8395 else
8396 set_buffer_temp (old);
8397 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
8398
8399 unbind_to (count, Qnil);
8400 }
8401
8402
8403 /* Build the complete desired matrix of WINDOW with a window start
8404 buffer position POS. Value is non-zero if successful. It is zero
8405 if fonts were loaded during redisplay which makes re-adjusting
8406 glyph matrices necessary. */
8407
8408 int
8409 try_window (window, pos)
8410 Lisp_Object window;
8411 struct text_pos pos;
8412 {
8413 struct window *w = XWINDOW (window);
8414 struct it it;
8415 struct glyph_row *last_text_row = NULL;
8416
8417 /* Make POS the new window start. */
8418 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
8419
8420 /* Mark cursor position as unknown. No overlay arrow seen. */
8421 w->cursor.vpos = -1;
8422 overlay_arrow_seen = 0;
8423
8424 /* Initialize iterator and info to start at POS. */
8425 start_display (&it, w, pos);
8426
8427 /* Display all lines of W. */
8428 while (it.current_y < it.last_visible_y)
8429 {
8430 if (display_line (&it))
8431 last_text_row = it.glyph_row - 1;
8432 if (fonts_changed_p)
8433 return 0;
8434 }
8435
8436 /* If bottom moved off end of frame, change mode line percentage. */
8437 if (XFASTINT (w->window_end_pos) <= 0
8438 && Z != IT_CHARPOS (it))
8439 w->update_mode_line = Qt;
8440
8441 /* Set window_end_pos to the offset of the last character displayed
8442 on the window from the end of current_buffer. Set
8443 window_end_vpos to its row number. */
8444 if (last_text_row)
8445 {
8446 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
8447 w->window_end_bytepos
8448 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8449 XSETFASTINT (w->window_end_pos,
8450 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8451 XSETFASTINT (w->window_end_vpos,
8452 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8453 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
8454 ->displays_text_p);
8455 }
8456 else
8457 {
8458 w->window_end_bytepos = 0;
8459 XSETFASTINT (w->window_end_pos, 0);
8460 XSETFASTINT (w->window_end_vpos, 0);
8461 }
8462
8463 /* But that is not valid info until redisplay finishes. */
8464 w->window_end_valid = Qnil;
8465 return 1;
8466 }
8467
8468
8469 \f
8470 /************************************************************************
8471 Window redisplay reusing current matrix when buffer has not changed
8472 ************************************************************************/
8473
8474 /* Try redisplay of window W showing an unchanged buffer with a
8475 different window start than the last time it was displayed by
8476 reusing its current matrix. Value is non-zero if successful.
8477 W->start is the new window start. */
8478
8479 static int
8480 try_window_reusing_current_matrix (w)
8481 struct window *w;
8482 {
8483 struct frame *f = XFRAME (w->frame);
8484 struct glyph_row *row, *bottom_row;
8485 struct it it;
8486 struct run run;
8487 struct text_pos start, new_start;
8488 int nrows_scrolled, i;
8489 struct glyph_row *last_text_row;
8490 struct glyph_row *last_reused_text_row;
8491 struct glyph_row *start_row;
8492 int start_vpos, min_y, max_y;
8493
8494 /* Right now this function doesn't handle terminal frames. */
8495 if (!FRAME_WINDOW_P (f))
8496 return 0;
8497
8498 /* Can't do this if region may have changed. */
8499 if ((!NILP (Vtransient_mark_mode)
8500 && !NILP (current_buffer->mark_active))
8501 || !NILP (w->region_showing))
8502 return 0;
8503
8504 /* If top-line visibility has changed, give up. */
8505 if (WINDOW_WANTS_TOP_LINE_P (w)
8506 != MATRIX_TOP_LINE_ROW (w->current_matrix)->mode_line_p)
8507 return 0;
8508
8509 /* Give up if old or new display is scrolled vertically. We could
8510 make this function handle this, but right now it doesn't. */
8511 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8512 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
8513 return 0;
8514
8515 /* The variable new_start now holds the new window start. The old
8516 start `start' can be determined from the current matrix. */
8517 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
8518 start = start_row->start.pos;
8519 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
8520
8521 /* Clear the desired matrix for the display below. */
8522 clear_glyph_matrix (w->desired_matrix);
8523
8524 if (CHARPOS (new_start) <= CHARPOS (start))
8525 {
8526 int first_row_y;
8527
8528 IF_DEBUG (debug_method_add (w, "twu1"));
8529
8530 /* Display up to a row that can be reused. The variable
8531 last_text_row is set to the last row displayed that displays
8532 text. */
8533 start_display (&it, w, new_start);
8534 first_row_y = it.current_y;
8535 w->cursor.vpos = -1;
8536 last_text_row = last_reused_text_row = NULL;
8537 while (it.current_y < it.last_visible_y
8538 && IT_CHARPOS (it) < CHARPOS (start)
8539 && !fonts_changed_p)
8540 if (display_line (&it))
8541 last_text_row = it.glyph_row - 1;
8542
8543 /* A value of current_y < last_visible_y means that we stopped
8544 at the previous window start, which in turn means that we
8545 have at least one reusable row. */
8546 if (it.current_y < it.last_visible_y)
8547 {
8548 nrows_scrolled = it.vpos;
8549
8550 /* Find PT if not already found in the lines displayed. */
8551 if (w->cursor.vpos < 0)
8552 {
8553 int dy = it.current_y - first_row_y;
8554
8555 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8556 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8557 {
8558 if (PT >= MATRIX_ROW_START_CHARPOS (row)
8559 && PT < MATRIX_ROW_END_CHARPOS (row))
8560 {
8561 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
8562 dy, nrows_scrolled);
8563 break;
8564 }
8565
8566 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
8567 break;
8568
8569 ++row;
8570 }
8571
8572 /* Give up if point was not found. This shouldn't
8573 happen often; not more often than with try_window
8574 itself. */
8575 if (w->cursor.vpos < 0)
8576 {
8577 clear_glyph_matrix (w->desired_matrix);
8578 return 0;
8579 }
8580 }
8581
8582 /* Scroll the display. Do it before the current matrix is
8583 changed. The problem here is that update has not yet
8584 run, i.e. part of the current matrix is not up to date.
8585 scroll_run_hook will clear the cursor, and use the
8586 current matrix to get the height of the row the cursor is
8587 in. */
8588 run.current_y = first_row_y;
8589 run.desired_y = it.current_y;
8590 run.height = it.last_visible_y - it.current_y;
8591 if (run.height > 0)
8592 {
8593 update_begin (f);
8594 rif->update_window_begin_hook (w);
8595 rif->scroll_run_hook (w, &run);
8596 rif->update_window_end_hook (w, 0);
8597 update_end (f);
8598 }
8599
8600 /* Shift current matrix down by nrows_scrolled lines. */
8601 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
8602 rotate_matrix (w->current_matrix,
8603 start_vpos,
8604 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
8605 nrows_scrolled);
8606
8607 /* Disable lines not reused. */
8608 for (i = 0; i < it.vpos; ++i)
8609 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
8610
8611 /* Re-compute Y positions. */
8612 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
8613 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8614 max_y = it.last_visible_y;
8615 while (row < bottom_row)
8616 {
8617 row->y = it.current_y;
8618
8619 if (row->y < min_y)
8620 row->visible_height = row->height - (min_y - row->y);
8621 else if (row->y + row->height > max_y)
8622 row->visible_height
8623 = row->height - (row->y + row->height - max_y);
8624 else
8625 row->visible_height = row->height;
8626
8627 it.current_y += row->height;
8628 ++it.vpos;
8629
8630 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8631 last_reused_text_row = row;
8632 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
8633 break;
8634 ++row;
8635 }
8636 }
8637
8638 /* Update window_end_pos etc.; last_reused_text_row is the last
8639 reused row from the current matrix containing text, if any.
8640 The value of last_text_row is the last displayed line
8641 containing text. */
8642 if (last_reused_text_row)
8643 {
8644 w->window_end_bytepos
8645 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
8646 XSETFASTINT (w->window_end_pos,
8647 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
8648 XSETFASTINT (w->window_end_vpos,
8649 MATRIX_ROW_VPOS (last_reused_text_row,
8650 w->current_matrix));
8651 }
8652 else if (last_text_row)
8653 {
8654 w->window_end_bytepos
8655 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8656 XSETFASTINT (w->window_end_pos,
8657 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8658 XSETFASTINT (w->window_end_vpos,
8659 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8660 }
8661 else
8662 {
8663 /* This window must be completely empty. */
8664 w->window_end_bytepos = 0;
8665 XSETFASTINT (w->window_end_pos, 0);
8666 XSETFASTINT (w->window_end_vpos, 0);
8667 }
8668 w->window_end_valid = Qnil;
8669
8670 /* Update hint: don't try scrolling again in update_window. */
8671 w->desired_matrix->no_scrolling_p = 1;
8672
8673 #if GLYPH_DEBUG
8674 debug_method_add (w, "try_window_reusing_current_matrix 1");
8675 #endif
8676 return 1;
8677 }
8678 else if (CHARPOS (new_start) > CHARPOS (start))
8679 {
8680 struct glyph_row *pt_row, *row;
8681 struct glyph_row *first_reusable_row;
8682 struct glyph_row *first_row_to_display;
8683 int dy;
8684 int yb = window_text_bottom_y (w);
8685
8686 IF_DEBUG (debug_method_add (w, "twu2"));
8687
8688 /* Find the row starting at new_start, if there is one. Don't
8689 reuse a partially visible line at the end. */
8690 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8691 while (first_reusable_row->enabled_p
8692 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
8693 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
8694 < CHARPOS (new_start)))
8695 ++first_reusable_row;
8696
8697 /* Give up if there is no row to reuse. */
8698 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
8699 || !first_reusable_row->enabled_p)
8700 return 0;
8701
8702 /* The row we found must start at new_start, or else something
8703 is broken. */
8704 xassert (MATRIX_ROW_START_CHARPOS (first_reusable_row)
8705 == CHARPOS (new_start));
8706
8707 /* We can reuse fully visible rows beginning with
8708 first_reusable_row to the end of the window. Set
8709 first_row_to_display to the first row that cannot be reused.
8710 Set pt_row to the row containing point, if there is any. */
8711 first_row_to_display = first_reusable_row;
8712 pt_row = NULL;
8713 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
8714 {
8715 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
8716 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
8717 pt_row = first_row_to_display;
8718
8719 ++first_row_to_display;
8720 }
8721
8722 /* Start displaying at the start of first_row_to_display. */
8723 xassert (first_row_to_display->y < yb);
8724 init_to_row_start (&it, w, first_row_to_display);
8725 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
8726 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
8727 - nrows_scrolled);
8728 it.current_y = first_row_to_display->y - first_reusable_row->y;
8729
8730 /* Display lines beginning with first_row_to_display in the
8731 desired matrix. Set last_text_row to the last row displayed
8732 that displays text. */
8733 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
8734 if (pt_row == NULL)
8735 w->cursor.vpos = -1;
8736 last_text_row = NULL;
8737 while (it.current_y < it.last_visible_y && !fonts_changed_p)
8738 if (display_line (&it))
8739 last_text_row = it.glyph_row - 1;
8740
8741 /* Give up If point isn't in a row displayed or reused. */
8742 if (w->cursor.vpos < 0)
8743 {
8744 clear_glyph_matrix (w->desired_matrix);
8745 return 0;
8746 }
8747
8748 /* If point is in a reused row, adjust y and vpos of the cursor
8749 position. */
8750 if (pt_row)
8751 {
8752 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
8753 w->current_matrix);
8754 w->cursor.y -= first_reusable_row->y;
8755 }
8756
8757 /* Scroll the display. */
8758 run.current_y = first_reusable_row->y;
8759 run.desired_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8760 run.height = it.last_visible_y - run.current_y;
8761 if (run.height)
8762 {
8763 struct frame *f = XFRAME (WINDOW_FRAME (w));
8764 update_begin (f);
8765 rif->update_window_begin_hook (w);
8766 rif->scroll_run_hook (w, &run);
8767 rif->update_window_end_hook (w, 0);
8768 update_end (f);
8769 }
8770
8771 /* Adjust Y positions of reused rows. */
8772 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
8773 row = first_reusable_row;
8774 dy = first_reusable_row->y;
8775 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8776 max_y = it.last_visible_y;
8777 while (row < first_row_to_display)
8778 {
8779 row->y -= dy;
8780 if (row->y < min_y)
8781 row->visible_height = row->height - (min_y - row->y);
8782 else if (row->y + row->height > max_y)
8783 row->visible_height
8784 = row->height - (row->y + row->height - max_y);
8785 else
8786 row->visible_height = row->height;
8787 ++row;
8788 }
8789
8790 /* Disable rows not reused. */
8791 while (row < bottom_row)
8792 {
8793 row->enabled_p = 0;
8794 ++row;
8795 }
8796
8797 /* Scroll the current matrix. */
8798 xassert (nrows_scrolled > 0);
8799 rotate_matrix (w->current_matrix,
8800 start_vpos,
8801 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
8802 -nrows_scrolled);
8803
8804 /* Adjust window end. A null value of last_text_row means that
8805 the window end is in reused rows which in turn means that
8806 only its vpos can have changed. */
8807 if (last_text_row)
8808 {
8809 w->window_end_bytepos
8810 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8811 XSETFASTINT (w->window_end_pos,
8812 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8813 XSETFASTINT (w->window_end_vpos,
8814 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8815 }
8816 else
8817 {
8818 XSETFASTINT (w->window_end_vpos,
8819 XFASTINT (w->window_end_vpos) - nrows_scrolled);
8820 }
8821
8822 w->window_end_valid = Qnil;
8823 w->desired_matrix->no_scrolling_p = 1;
8824
8825 #if GLYPH_DEBUG
8826 debug_method_add (w, "try_window_reusing_current_matrix 2");
8827 #endif
8828 return 1;
8829 }
8830
8831 return 0;
8832 }
8833
8834
8835 \f
8836 /************************************************************************
8837 Window redisplay reusing current matrix when buffer has changed
8838 ************************************************************************/
8839
8840 static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
8841 static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
8842 int *, int *));
8843 static struct glyph_row *
8844 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
8845 struct glyph_row *));
8846
8847
8848 /* Return the last row in MATRIX displaying text. If row START is
8849 non-null, start searching with that row. IT gives the dimensions
8850 of the display. Value is null if matrix is empty; otherwise it is
8851 a pointer to the row found. */
8852
8853 static struct glyph_row *
8854 find_last_row_displaying_text (matrix, it, start)
8855 struct glyph_matrix *matrix;
8856 struct it *it;
8857 struct glyph_row *start;
8858 {
8859 struct glyph_row *row, *row_found;
8860
8861 /* Set row_found to the last row in IT->w's current matrix
8862 displaying text. The loop looks funny but think of partially
8863 visible lines. */
8864 row_found = NULL;
8865 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
8866 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8867 {
8868 xassert (row->enabled_p);
8869 row_found = row;
8870 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
8871 break;
8872 ++row;
8873 }
8874
8875 return row_found;
8876 }
8877
8878
8879 /* Return the last row in the current matrix of W that is not affected
8880 by changes at the start of current_buffer that occurred since the
8881 last time W was redisplayed. Value is null if no such row exists.
8882
8883 The global variable beg_unchanged has to contain the number of
8884 bytes unchanged at the start of current_buffer. BEG +
8885 beg_unchanged is the buffer position of the first changed byte in
8886 current_buffer. Characters at positions < BEG + beg_unchanged are
8887 at the same buffer positions as they were when the current matrix
8888 was built. */
8889
8890 static struct glyph_row *
8891 get_last_unchanged_at_beg_row (w)
8892 struct window *w;
8893 {
8894 int first_changed_pos = BEG + beg_unchanged;
8895 struct glyph_row *row;
8896 struct glyph_row *row_found = NULL;
8897 int yb = window_text_bottom_y (w);
8898
8899 /* Find the last row displaying unchanged text. */
8900 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8901 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
8902 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
8903 {
8904 if (/* If row ends before first_changed_pos, it is unchanged,
8905 except in some case. */
8906 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
8907 /* When row ends in ZV and we write at ZV it is not
8908 unchanged. */
8909 && !row->ends_at_zv_p
8910 /* When first_changed_pos is the end of a continued line,
8911 row is not unchanged because it may be no longer
8912 continued. */
8913 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
8914 && row->continued_p))
8915 row_found = row;
8916
8917 /* Stop if last visible row. */
8918 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
8919 break;
8920
8921 ++row;
8922 }
8923
8924 return row_found;
8925 }
8926
8927
8928 /* Find the first glyph row in the current matrix of W that is not
8929 affected by changes at the end of current_buffer since the last
8930 time the window was redisplayed. Return in *DELTA the number of
8931 bytes by which buffer positions in unchanged text at the end of
8932 current_buffer must be adjusted. Value is null if no such row
8933 exists, i.e. all rows are affected by changes.
8934
8935 The global variable end_unchanged is assumed to contain the number
8936 of unchanged bytes at the end of current_buffer. The buffer
8937 position of the last changed byte in current_buffer is then Z -
8938 end_unchanged. */
8939
8940 static struct glyph_row *
8941 get_first_unchanged_at_end_row (w, delta, delta_bytes)
8942 struct window *w;
8943 int *delta, *delta_bytes;
8944 {
8945 struct glyph_row *row;
8946 struct glyph_row *row_found = NULL;
8947
8948 *delta = *delta_bytes = 0;
8949
8950 /* A value of window_end_pos >= end_unchanged means that the window
8951 end is in the range of changed text. If so, there is no
8952 unchanged row at the end of W's current matrix. */
8953 xassert (!NILP (w->window_end_valid));
8954 if (XFASTINT (w->window_end_pos) >= end_unchanged)
8955 return NULL;
8956
8957 /* Set row to the last row in W's current matrix displaying text. */
8958 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
8959
8960 /* End vpos should always be on text, except in an entirely empty
8961 matrix. */
8962 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row)
8963 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0);
8964
8965 /* If matrix is entirely empty, no unchanged row exists. */
8966 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8967 {
8968 /* The value of row is the last glyph row in the matrix having a
8969 meaningful buffer position in it. The end position of row
8970 corresponds to window_end_pos. This allows us to translate
8971 buffer positions in the current matrix to current buffer
8972 positions for characters not in changed text. */
8973 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
8974 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
8975 int last_unchanged_pos, last_unchanged_pos_old;
8976 struct glyph_row *first_text_row
8977 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8978
8979 *delta = Z - Z_old;
8980 *delta_bytes = Z_BYTE - Z_BYTE_old;
8981
8982 /* Set last_unchanged_pos to the buffer position of the last
8983 character in the buffer that has not been changed. Z is the
8984 index + 1 of the last byte in current_buffer, i.e. by
8985 subtracting end_unchanged we get the index of the last
8986 unchanged character, and we have to add BEG to get its buffer
8987 position. */
8988 last_unchanged_pos = Z - end_unchanged + BEG;
8989 last_unchanged_pos_old = last_unchanged_pos - *delta;
8990
8991 /* Search backward from ROW for a row displaying a line that
8992 starts at a minimum position >= last_unchanged_pos_old. */
8993 while (row >= first_text_row)
8994 {
8995 xassert (row->enabled_p);
8996 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
8997
8998 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
8999 row_found = row;
9000 --row;
9001 }
9002 }
9003
9004 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9005 return row_found;
9006 }
9007
9008
9009 /* Make sure that glyph rows in the current matrix of window W
9010 reference the same glyph memory as corresponding rows in the
9011 frame's frame matrix. This function is called after scrolling W's
9012 current matrix on a terminal frame in try_window_id and
9013 try_window_reusing_current_matrix. */
9014
9015 static void
9016 sync_frame_with_window_matrix_rows (w)
9017 struct window *w;
9018 {
9019 struct frame *f = XFRAME (w->frame);
9020 struct glyph_row *window_row, *window_row_end, *frame_row;
9021
9022 /* Preconditions: W must be a leaf window and full-width. Its frame
9023 must have a frame matrix. */
9024 xassert (NILP (w->hchild) && NILP (w->vchild));
9025 xassert (WINDOW_FULL_WIDTH_P (w));
9026 xassert (!FRAME_WINDOW_P (f));
9027
9028 /* If W is a full-width window, glyph pointers in W's current matrix
9029 have, by definition, to be the same as glyph pointers in the
9030 corresponding frame matrix. */
9031 window_row = w->current_matrix->rows;
9032 window_row_end = window_row + w->current_matrix->nrows;
9033 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9034 while (window_row < window_row_end)
9035 {
9036 int area;
9037 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9038 frame_row->glyphs[area] = window_row->glyphs[area];
9039 ++window_row, ++frame_row;
9040 }
9041 }
9042
9043
9044 /* Try to redisplay window W by reusing its existing display. W's
9045 current matrix must be up to date when this function is called,
9046 i.e. window_end_valid must not be nil.
9047
9048 Value is
9049
9050 1 if display has been updated
9051 0 if otherwise unsuccessful
9052 -1 if redisplay with same window start is known not to succeed
9053
9054 The following steps are performed:
9055
9056 1. Find the last row in the current matrix of W that is not
9057 affected by changes at the start of current_buffer. If no such row
9058 is found, give up.
9059
9060 2. Find the first row in W's current matrix that is not affected by
9061 changes at the end of current_buffer. Maybe there is no such row.
9062
9063 3. Display lines beginning with the row + 1 found in step 1 to the
9064 row found in step 2 or, if step 2 didn't find a row, to the end of
9065 the window.
9066
9067 4. If cursor is not known to appear on the window, give up.
9068
9069 5. If display stopped at the row found in step 2, scroll the
9070 display and current matrix as needed.
9071
9072 6. Maybe display some lines at the end of W, if we must. This can
9073 happen under various circumstances, like a partially visible line
9074 becoming fully visible, or because newly displayed lines are displayed
9075 in smaller font sizes.
9076
9077 7. Update W's window end information. */
9078
9079 /* Check that window end is what we expect it to be. */
9080
9081 static int
9082 try_window_id (w)
9083 struct window *w;
9084 {
9085 struct frame *f = XFRAME (w->frame);
9086 struct glyph_matrix *current_matrix = w->current_matrix;
9087 struct glyph_matrix *desired_matrix = w->desired_matrix;
9088 struct glyph_row *last_unchanged_at_beg_row;
9089 struct glyph_row *first_unchanged_at_end_row;
9090 struct glyph_row *row;
9091 struct glyph_row *bottom_row;
9092 int bottom_vpos;
9093 struct it it;
9094 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
9095 struct text_pos start_pos;
9096 struct run run;
9097 int first_unchanged_at_end_vpos = 0;
9098 struct glyph_row *last_text_row, *last_text_row_at_end;
9099 struct text_pos start;
9100
9101 SET_TEXT_POS_FROM_MARKER (start, w->start);
9102
9103 /* Check pre-conditions. Window end must be valid, otherwise
9104 the current matrix would not be up to date. */
9105 xassert (!NILP (w->window_end_valid));
9106 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
9107 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
9108
9109 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
9110 only if buffer has really changed. The reason is that the gap is
9111 initially at Z for freshly visited files. The code below would
9112 set end_unchanged to 0 in that case. */
9113 if (MODIFF > SAVE_MODIFF)
9114 {
9115 if (GPT - BEG < beg_unchanged)
9116 beg_unchanged = GPT - BEG;
9117 if (Z - GPT < end_unchanged)
9118 end_unchanged = Z - GPT;
9119 }
9120
9121 /* If window starts after a line end, and the last change is in
9122 front of that newline, then changes don't affect the display.
9123 This case happens with stealth-fontification. */
9124 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9125 if (CHARPOS (start) > BEGV
9126 && Z - end_unchanged < CHARPOS (start) - 1
9127 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
9128 && PT < MATRIX_ROW_END_CHARPOS (row))
9129 {
9130 /* We have to update window end positions because the buffer's
9131 size has changed. */
9132 w->window_end_pos
9133 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9134 w->window_end_bytepos
9135 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9136 return 1;
9137 }
9138
9139 /* Return quickly if changes are all below what is displayed in the
9140 window, and if PT is in the window. */
9141 if (beg_unchanged > MATRIX_ROW_END_CHARPOS (row)
9142 && PT < MATRIX_ROW_END_CHARPOS (row))
9143 {
9144 /* We have to update window end positions because the buffer's
9145 size has changed. */
9146 w->window_end_pos
9147 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9148 w->window_end_bytepos
9149 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9150 return 1;
9151 }
9152
9153 /* Check that window start agrees with the start of the first glyph
9154 row in its current matrix. Check this after we know the window
9155 start is not in changed text, otherwise positions would not be
9156 comparable. */
9157 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9158 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
9159 return 0;
9160
9161 /* Remember beg_unchanged and end_unchanged for debugging purposes. */
9162 IF_DEBUG (debug_beg_unchanged = beg_unchanged;
9163 debug_end_unchanged = end_unchanged);
9164
9165 /* Compute the position at which we have to start displaying new
9166 lines. Some of the lines at the top of the window might be
9167 reusable because they are not displaying changed text. Find the
9168 last row in W's current matrix not affected by changes at the
9169 start of current_buffer. Value is null if changes start in the
9170 first line of window. */
9171 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
9172 if (last_unchanged_at_beg_row)
9173 {
9174 init_to_row_end (&it, w, last_unchanged_at_beg_row);
9175 start_pos = it.current.pos;
9176
9177 /* Start displaying new lines in the desired matrix at the same
9178 vpos we would use in the current matrix, i.e. below
9179 last_unchanged_at_beg_row. */
9180 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
9181 current_matrix);
9182 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9183 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
9184
9185 xassert (it.hpos == 0 && it.current_x == 0);
9186 }
9187 else
9188 {
9189 /* There are no reusable lines at the start of the window.
9190 Start displaying in the first line. */
9191 start_display (&it, w, start);
9192 start_pos = it.current.pos;
9193 }
9194
9195 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
9196 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
9197
9198 /* Find the first row that is not affected by changes at the end of
9199 the buffer. Value will be null if there is no unchanged row, in
9200 which case we must redisplay to the end of the window. delta
9201 will be set to the value by which buffer positions beginning with
9202 first_unchanged_at_end_row have to be adjusted due to text
9203 changes. */
9204 first_unchanged_at_end_row
9205 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
9206 IF_DEBUG (debug_delta = delta);
9207 IF_DEBUG (debug_delta_bytes = delta_bytes);
9208
9209 /* Set stop_pos to the buffer position up to which we will have to
9210 display new lines. If first_unchanged_at_end_row != NULL, this
9211 is the buffer position of the start of the line displayed in that
9212 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
9213 that we don't stop at a buffer position. */
9214 stop_pos = 0;
9215 if (first_unchanged_at_end_row)
9216 {
9217 xassert (last_unchanged_at_beg_row == NULL
9218 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
9219
9220 /* If this is a continuation line, move forward to the next one
9221 that isn't. Changes in lines above affect this line.
9222 Caution: this may move first_unchanged_at_end_row to a row
9223 not displaying text. */
9224 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
9225 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9226 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9227 < it.last_visible_y))
9228 ++first_unchanged_at_end_row;
9229
9230 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9231 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9232 >= it.last_visible_y))
9233 first_unchanged_at_end_row = NULL;
9234 else
9235 {
9236 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
9237 + delta);
9238 first_unchanged_at_end_vpos
9239 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
9240 xassert (stop_pos >= Z - end_unchanged);
9241 }
9242 }
9243 else if (last_unchanged_at_beg_row == NULL)
9244 return 0;
9245
9246
9247 #if GLYPH_DEBUG
9248
9249 /* Either there is no unchanged row at the end, or the one we have
9250 now displays text. This is a necessary condition for the window
9251 end pos calculation at the end of this function. */
9252 xassert (first_unchanged_at_end_row == NULL
9253 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
9254
9255 debug_last_unchanged_at_beg_vpos
9256 = (last_unchanged_at_beg_row
9257 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
9258 : -1);
9259 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
9260
9261 #endif /* GLYPH_DEBUG != 0 */
9262
9263
9264 /* Display new lines. Set last_text_row to the last new line
9265 displayed which has text on it, i.e. might end up as being the
9266 line where the window_end_vpos is. */
9267 w->cursor.vpos = -1;
9268 last_text_row = NULL;
9269 overlay_arrow_seen = 0;
9270 while (it.current_y < it.last_visible_y
9271 && !fonts_changed_p
9272 && (first_unchanged_at_end_row == NULL
9273 || IT_CHARPOS (it) < stop_pos))
9274 {
9275 if (display_line (&it))
9276 last_text_row = it.glyph_row - 1;
9277 }
9278
9279 if (fonts_changed_p)
9280 return -1;
9281
9282
9283 /* Compute differences in buffer positions, y-positions etc. for
9284 lines reused at the bottom of the window. Compute what we can
9285 scroll. */
9286 if (first_unchanged_at_end_row)
9287 {
9288 dvpos = (it.vpos
9289 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
9290 current_matrix));
9291 dy = it.current_y - first_unchanged_at_end_row->y;
9292 run.current_y = first_unchanged_at_end_row->y;
9293 run.desired_y = run.current_y + dy;
9294 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
9295 }
9296 else
9297 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
9298 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
9299
9300
9301 /* Find the cursor if not already found. We have to decide whether
9302 PT will appear on this window (it sometimes doesn't, but this is
9303 not a very frequent case.) This decision has to be made before
9304 the current matrix is altered. A value of cursor.vpos < 0 means
9305 that PT is either in one of the lines beginning at
9306 first_unchanged_at_end_row or below the window. Don't care for
9307 lines that might be displayed later at the window end; as
9308 mentioned, this is not a frequent case. */
9309 if (w->cursor.vpos < 0)
9310 {
9311 int last_y = min (it.last_visible_y, it.last_visible_y + dy);
9312
9313 /* Cursor in unchanged rows at the top? */
9314 if (PT < CHARPOS (start_pos)
9315 && last_unchanged_at_beg_row)
9316 {
9317 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9318 while (row <= last_unchanged_at_beg_row
9319 && MATRIX_ROW_END_CHARPOS (row) <= PT)
9320 ++row;
9321 xassert (row <= last_unchanged_at_beg_row);
9322 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9323 }
9324
9325 /* Start from first_unchanged_at_end_row looking for PT. */
9326 else if (first_unchanged_at_end_row)
9327 {
9328 row = first_unchanged_at_end_row;
9329 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9330 {
9331 if (PT - delta >= MATRIX_ROW_START_CHARPOS (row)
9332 && PT - delta < MATRIX_ROW_END_CHARPOS (row))
9333 {
9334 set_cursor_from_row (w, row, w->current_matrix, delta,
9335 delta_bytes, dy, dvpos);
9336 break;
9337 }
9338 else if (MATRIX_ROW_BOTTOM_Y (row) >= last_y)
9339 break;
9340 ++row;
9341 }
9342 }
9343
9344 /* Give up if cursor was not found. */
9345 if (w->cursor.vpos < 0)
9346 {
9347 clear_glyph_matrix (w->desired_matrix);
9348 return -1;
9349 }
9350 }
9351
9352 /* Don't let the cursor end in the scroll margins. */
9353 {
9354 int this_scroll_margin, cursor_height;
9355
9356 this_scroll_margin = max (0, scroll_margin);
9357 this_scroll_margin = min (this_scroll_margin,
9358 XFASTINT (w->height) / 4);
9359 this_scroll_margin *= CANON_Y_UNIT (it.f);
9360 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
9361
9362 if ((w->cursor.y < this_scroll_margin
9363 && CHARPOS (start) > BEGV)
9364 /* Don't take scroll margin into account at the bottom because
9365 old redisplay didn't do it either. */
9366 || w->cursor.y + cursor_height > it.last_visible_y)
9367 {
9368 w->cursor.vpos = -1;
9369 clear_glyph_matrix (w->desired_matrix);
9370 return -1;
9371 }
9372 }
9373
9374 /* Scroll the display. Do it before changing the current matrix so
9375 that xterm.c doesn't get confused about where the cursor glyph is
9376 found. */
9377 if (dy)
9378 {
9379 update_begin (f);
9380
9381 if (FRAME_WINDOW_P (f))
9382 {
9383 rif->update_window_begin_hook (w);
9384 rif->scroll_run_hook (w, &run);
9385 rif->update_window_end_hook (w, 0);
9386 }
9387 else
9388 {
9389 /* Terminal frame. In this case, dvpos gives the number of
9390 lines to scroll by; dvpos < 0 means scroll up. */
9391 int first_unchanged_at_end_vpos
9392 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
9393 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
9394 int end = XFASTINT (w->top) + window_internal_height (w);
9395
9396 /* Perform the operation on the screen. */
9397 if (dvpos > 0)
9398 {
9399 /* Scroll last_unchanged_at_beg_row to the end of the
9400 window down dvpos lines. */
9401 set_terminal_window (end);
9402
9403 /* On dumb terminals delete dvpos lines at the end
9404 before inserting dvpos empty lines. */
9405 if (!scroll_region_ok)
9406 ins_del_lines (end - dvpos, -dvpos);
9407
9408 /* Insert dvpos empty lines in front of
9409 last_unchanged_at_beg_row. */
9410 ins_del_lines (from, dvpos);
9411 }
9412 else if (dvpos < 0)
9413 {
9414 /* Scroll up last_unchanged_at_beg_vpos to the end of
9415 the window to last_unchanged_at_beg_vpos - |dvpos|. */
9416 set_terminal_window (end);
9417
9418 /* Delete dvpos lines in front of
9419 last_unchanged_at_beg_vpos. ins_del_lines will set
9420 the cursor to the given vpos and emit |dvpos| delete
9421 line sequences. */
9422 ins_del_lines (from + dvpos, dvpos);
9423
9424 /* On a dumb terminal insert dvpos empty lines at the
9425 end. */
9426 if (!scroll_region_ok)
9427 ins_del_lines (end + dvpos, -dvpos);
9428 }
9429
9430 set_terminal_window (0);
9431 }
9432
9433 update_end (f);
9434 }
9435
9436 /* Shift reused rows of the current matrix to the right position. */
9437 if (dvpos < 0)
9438 {
9439 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
9440 bottom_vpos, dvpos);
9441 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
9442 bottom_vpos, 0);
9443 }
9444 else if (dvpos > 0)
9445 {
9446 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
9447 bottom_vpos, dvpos);
9448 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
9449 first_unchanged_at_end_vpos + dvpos, 0);
9450 }
9451
9452 /* For frame-based redisplay, make sure that current frame and window
9453 matrix are in sync with respect to glyph memory. */
9454 if (!FRAME_WINDOW_P (f))
9455 sync_frame_with_window_matrix_rows (w);
9456
9457 /* Adjust buffer positions in reused rows. */
9458 if (delta)
9459 increment_glyph_matrix_buffer_positions (current_matrix,
9460 first_unchanged_at_end_vpos + dvpos,
9461 bottom_vpos, delta, delta_bytes);
9462
9463 /* Adjust Y positions. */
9464 if (dy)
9465 shift_glyph_matrix (w, current_matrix,
9466 first_unchanged_at_end_vpos + dvpos,
9467 bottom_vpos, dy);
9468
9469 if (first_unchanged_at_end_row)
9470 first_unchanged_at_end_row += dvpos;
9471
9472 /* If scrolling up, there may be some lines to display at the end of
9473 the window. */
9474 last_text_row_at_end = NULL;
9475 if (dy < 0)
9476 {
9477 /* Set last_row to the glyph row in the current matrix where the
9478 window end line is found. It has been moved up or down in
9479 the matrix by dvpos. */
9480 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
9481 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
9482
9483 /* If last_row is the window end line, it should display text. */
9484 xassert (last_row->displays_text_p);
9485
9486 /* If window end line was partially visible before, begin
9487 displaying at that line. Otherwise begin displaying with the
9488 line following it. */
9489 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
9490 {
9491 init_to_row_start (&it, w, last_row);
9492 it.vpos = last_vpos;
9493 it.current_y = last_row->y;
9494 }
9495 else
9496 {
9497 init_to_row_end (&it, w, last_row);
9498 it.vpos = 1 + last_vpos;
9499 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
9500 ++last_row;
9501 }
9502
9503 /* We may start in a continuation line. If so, we have to get
9504 the right continuation_lines_width and current_x. */
9505 it.continuation_lines_width = last_row->continuation_lines_width;
9506 it.hpos = it.current_x = 0;
9507
9508 /* Display the rest of the lines at the window end. */
9509 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9510 while (it.current_y < it.last_visible_y
9511 && !fonts_changed_p)
9512 {
9513 /* Is it always sure that the display agrees with lines in
9514 the current matrix? I don't think so, so we mark rows
9515 displayed invalid in the current matrix by setting their
9516 enabled_p flag to zero. */
9517 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
9518 if (display_line (&it))
9519 last_text_row_at_end = it.glyph_row - 1;
9520 }
9521 }
9522
9523 /* Update window_end_pos and window_end_vpos. */
9524 if (first_unchanged_at_end_row
9525 && first_unchanged_at_end_row->y < it.last_visible_y
9526 && !last_text_row_at_end)
9527 {
9528 /* Window end line if one of the preserved rows from the current
9529 matrix. Set row to the last row displaying text in current
9530 matrix starting at first_unchanged_at_end_row, after
9531 scrolling. */
9532 xassert (first_unchanged_at_end_row->displays_text_p);
9533 row = find_last_row_displaying_text (w->current_matrix, &it,
9534 first_unchanged_at_end_row);
9535 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
9536
9537 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
9538 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
9539 XSETFASTINT (w->window_end_vpos,
9540 MATRIX_ROW_VPOS (row, w->current_matrix));
9541 }
9542 else if (last_text_row_at_end)
9543 {
9544 XSETFASTINT (w->window_end_pos,
9545 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
9546 w->window_end_bytepos
9547 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
9548 XSETFASTINT (w->window_end_vpos,
9549 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
9550 }
9551 else if (last_text_row)
9552 {
9553 /* We have displayed either to the end of the window or at the
9554 end of the window, i.e. the last row with text is to be found
9555 in the desired matrix. */
9556 XSETFASTINT (w->window_end_pos,
9557 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9558 w->window_end_bytepos
9559 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9560 XSETFASTINT (w->window_end_vpos,
9561 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
9562 }
9563 else if (first_unchanged_at_end_row == NULL
9564 && last_text_row == NULL
9565 && last_text_row_at_end == NULL)
9566 {
9567 /* Displayed to end of window, but no line containing text was
9568 displayed. Lines were deleted at the end of the window. */
9569 int vpos;
9570 int top_line_p = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
9571
9572 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
9573 if ((w->desired_matrix->rows[vpos + top_line_p].enabled_p
9574 && w->desired_matrix->rows[vpos + top_line_p].displays_text_p)
9575 || (!w->desired_matrix->rows[vpos + top_line_p].enabled_p
9576 && w->current_matrix->rows[vpos + top_line_p].displays_text_p))
9577 break;
9578
9579 w->window_end_vpos = make_number (vpos);
9580 }
9581 else
9582 abort ();
9583
9584 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
9585 debug_end_vpos = XFASTINT (w->window_end_vpos));
9586
9587 /* Record that display has not been completed. */
9588 w->window_end_valid = Qnil;
9589 w->desired_matrix->no_scrolling_p = 1;
9590 return 1;
9591 }
9592
9593
9594 \f
9595 /***********************************************************************
9596 More debugging support
9597 ***********************************************************************/
9598
9599 #if GLYPH_DEBUG
9600
9601 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
9602 static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
9603
9604
9605 /* Dump the contents of glyph matrix MATRIX on stderr. If
9606 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
9607
9608 void
9609 dump_glyph_matrix (matrix, with_glyphs_p)
9610 struct glyph_matrix *matrix;
9611 int with_glyphs_p;
9612 {
9613 int i;
9614 for (i = 0; i < matrix->nrows; ++i)
9615 dump_glyph_row (matrix, i, with_glyphs_p);
9616 }
9617
9618
9619 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
9620 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
9621
9622 void
9623 dump_glyph_row (matrix, vpos, with_glyphs_p)
9624 struct glyph_matrix *matrix;
9625 int vpos, with_glyphs_p;
9626 {
9627 struct glyph_row *row;
9628
9629 if (vpos < 0 || vpos >= matrix->nrows)
9630 return;
9631
9632 row = MATRIX_ROW (matrix, vpos);
9633
9634 fprintf (stderr, "Row Start End Used oEI><O\\CTZF X Y W\n");
9635 fprintf (stderr, "=============================================\n");
9636
9637 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 %4d %4d %4d\n",
9638 row - matrix->rows,
9639 MATRIX_ROW_START_CHARPOS (row),
9640 MATRIX_ROW_END_CHARPOS (row),
9641 row->used[TEXT_AREA],
9642 row->contains_overlapping_glyphs_p,
9643 row->enabled_p,
9644 row->inverse_p,
9645 row->truncated_on_left_p,
9646 row->truncated_on_right_p,
9647 row->overlay_arrow_p,
9648 row->continued_p,
9649 MATRIX_ROW_CONTINUATION_LINE_P (row),
9650 row->displays_text_p,
9651 row->ends_at_zv_p,
9652 row->fill_line_p,
9653 row->x,
9654 row->y,
9655 row->pixel_width);
9656 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
9657 row->end.overlay_string_index);
9658 fprintf (stderr, "%9d %5d\n",
9659 CHARPOS (row->start.string_pos),
9660 CHARPOS (row->end.string_pos));
9661 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
9662 row->end.dpvec_index);
9663
9664 if (with_glyphs_p)
9665 {
9666 struct glyph *glyph, *glyph_end;
9667 int prev_had_glyphs_p;
9668
9669 glyph = row->glyphs[TEXT_AREA];
9670 glyph_end = glyph + row->used[TEXT_AREA];
9671
9672 /* Glyph for a line end in text. */
9673 if (glyph == glyph_end && glyph->charpos > 0)
9674 ++glyph_end;
9675
9676 if (glyph < glyph_end)
9677 {
9678 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
9679 prev_had_glyphs_p = 1;
9680 }
9681 else
9682 prev_had_glyphs_p = 0;
9683
9684 while (glyph < glyph_end)
9685 {
9686 if (glyph->type == CHAR_GLYPH)
9687 {
9688 fprintf (stderr,
9689 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9690 glyph - row->glyphs[TEXT_AREA],
9691 'C',
9692 glyph->charpos,
9693 glyph->pixel_width,
9694 glyph->u.ch.code,
9695 (glyph->u.ch.code < 0x80 && glyph->u.ch.code >= ' '
9696 ? glyph->u.ch.code
9697 : '.'),
9698 glyph->u.ch.face_id,
9699 glyph->left_box_line_p,
9700 glyph->right_box_line_p);
9701 }
9702 else if (glyph->type == STRETCH_GLYPH)
9703 {
9704 fprintf (stderr,
9705 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9706 glyph - row->glyphs[TEXT_AREA],
9707 'S',
9708 glyph->charpos,
9709 glyph->pixel_width,
9710 0,
9711 '.',
9712 glyph->u.stretch.face_id,
9713 glyph->left_box_line_p,
9714 glyph->right_box_line_p);
9715 }
9716 else if (glyph->type == IMAGE_GLYPH)
9717 {
9718 fprintf (stderr,
9719 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9720 glyph - row->glyphs[TEXT_AREA],
9721 'I',
9722 glyph->charpos,
9723 glyph->pixel_width,
9724 glyph->u.img.id,
9725 '.',
9726 glyph->u.img.face_id,
9727 glyph->left_box_line_p,
9728 glyph->right_box_line_p);
9729 }
9730 ++glyph;
9731 }
9732 }
9733 }
9734
9735
9736 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
9737 Sdump_glyph_matrix, 0, 1, "p",
9738 "Dump the current matrix of the selected window to stderr.\n\
9739 Shows contents of glyph row structures. With non-nil optional\n\
9740 parameter WITH-GLYPHS-P, dump glyphs as well.")
9741 (with_glyphs_p)
9742 {
9743 struct window *w = XWINDOW (selected_window);
9744 struct buffer *buffer = XBUFFER (w->buffer);
9745
9746 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
9747 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
9748 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
9749 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
9750 fprintf (stderr, "=============================================\n");
9751 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
9752 return Qnil;
9753 }
9754
9755
9756 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
9757 "Dump glyph row ROW to stderr.")
9758 (row)
9759 Lisp_Object row;
9760 {
9761 CHECK_NUMBER (row, 0);
9762 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
9763 return Qnil;
9764 }
9765
9766
9767 DEFUN ("dump-toolbar-row", Fdump_toolbar_row, Sdump_toolbar_row,
9768 0, 0, "", "")
9769 ()
9770 {
9771 struct glyph_matrix *m = (XWINDOW (selected_frame->toolbar_window)
9772 ->current_matrix);
9773 dump_glyph_row (m, 0, 1);
9774 return Qnil;
9775 }
9776
9777
9778 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
9779 Strace_redisplay_toggle, 0, 0, "",
9780 "Toggle tracing of redisplay.")
9781 ()
9782 {
9783 trace_redisplay_p = !trace_redisplay_p;
9784 return Qnil;
9785 }
9786
9787
9788 #endif /* GLYPH_DEBUG */
9789
9790
9791 \f
9792 /***********************************************************************
9793 Building Desired Matrix Rows
9794 ***********************************************************************/
9795
9796 /* Return a temporary glyph row holding the glyphs of an overlay
9797 arrow. Only used for non-window-redisplay windows. */
9798
9799 static struct glyph_row *
9800 get_overlay_arrow_glyph_row (w)
9801 struct window *w;
9802 {
9803 struct frame *f = XFRAME (WINDOW_FRAME (w));
9804 struct buffer *buffer = XBUFFER (w->buffer);
9805 struct buffer *old = current_buffer;
9806 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
9807 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
9808 unsigned char *arrow_end = arrow_string + arrow_len;
9809 unsigned char *p;
9810 struct it it;
9811 int multibyte_p;
9812 int n_glyphs_before;
9813
9814 set_buffer_temp (buffer);
9815 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
9816 it.glyph_row->used[TEXT_AREA] = 0;
9817 SET_TEXT_POS (it.position, 0, 0);
9818
9819 multibyte_p = !NILP (buffer->enable_multibyte_characters);
9820 p = arrow_string;
9821 while (p < arrow_end)
9822 {
9823 Lisp_Object face, ilisp;
9824
9825 /* Get the next character. */
9826 if (multibyte_p)
9827 it.c = string_char_and_length (p, arrow_len, &it.len);
9828 else
9829 it.c = *p, it.len = 1;
9830 p += it.len;
9831
9832 /* Get its face. */
9833 XSETFASTINT (ilisp, p - arrow_string);
9834 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
9835 it.face_id = compute_char_face (f, it.c, face);
9836
9837 /* Compute its width, get its glyphs. */
9838 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
9839 PRODUCE_GLYPHS (&it);
9840
9841 /* If this character doesn't fit any more in the line, we have
9842 to remove some glyphs. */
9843 if (it.current_x > it.last_visible_x)
9844 {
9845 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
9846 break;
9847 }
9848 }
9849
9850 set_buffer_temp (old);
9851 return it.glyph_row;
9852 }
9853
9854
9855 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
9856 glyphs are only inserted for terminal frames since we can't really
9857 win with truncation glyphs when partially visible glyphs are
9858 involved. Which glyphs to insert is determined by
9859 produce_special_glyphs. */
9860
9861 static void
9862 insert_left_trunc_glyphs (it)
9863 struct it *it;
9864 {
9865 struct it truncate_it;
9866 struct glyph *from, *end, *to, *toend;
9867
9868 xassert (!FRAME_WINDOW_P (it->f));
9869
9870 /* Get the truncation glyphs. */
9871 truncate_it = *it;
9872 truncate_it.charset = -1;
9873 truncate_it.current_x = 0;
9874 truncate_it.face_id = DEFAULT_FACE_ID;
9875 truncate_it.glyph_row = &scratch_glyph_row;
9876 truncate_it.glyph_row->used[TEXT_AREA] = 0;
9877 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
9878 truncate_it.object = 0;
9879 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
9880
9881 /* Overwrite glyphs from IT with truncation glyphs. */
9882 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
9883 end = from + truncate_it.glyph_row->used[TEXT_AREA];
9884 to = it->glyph_row->glyphs[TEXT_AREA];
9885 toend = to + it->glyph_row->used[TEXT_AREA];
9886
9887 while (from < end)
9888 *to++ = *from++;
9889
9890 /* There may be padding glyphs left over. Remove them. */
9891 from = to;
9892 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
9893 ++from;
9894 while (from < toend)
9895 *to++ = *from++;
9896
9897 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
9898 }
9899
9900
9901 /* Compute the pixel height and width of IT->glyph_row.
9902
9903 Most of the time, ascent and height of a display line will be equal
9904 to the max_ascent and max_height values of the display iterator
9905 structure. This is not the case if
9906
9907 1. We hit ZV without displaying anything. In this case, max_ascent
9908 and max_height will be zero.
9909
9910 2. We have some glyphs that don't contribute to the line height.
9911 (The glyph row flag contributes_to_line_height_p is for future
9912 pixmap extensions).
9913
9914 The first case is easily covered by using default values because in
9915 these cases, the line height does not really matter, except that it
9916 must not be zero. */
9917
9918 static void
9919 compute_line_metrics (it)
9920 struct it *it;
9921 {
9922 struct glyph_row *row = it->glyph_row;
9923 int area, i;
9924
9925 if (FRAME_WINDOW_P (it->f))
9926 {
9927 int i, top_line_height;
9928
9929 /* The line may consist of one space only, that was added to
9930 place the cursor on it. If so, the row's height hasn't been
9931 computed yet. */
9932 if (row->height == 0)
9933 {
9934 if (it->max_ascent + it->max_descent == 0)
9935 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
9936 row->ascent = it->max_ascent;
9937 row->height = it->max_ascent + it->max_descent;
9938 row->phys_ascent = it->max_phys_ascent;
9939 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
9940 }
9941
9942 /* Compute the width of this line. */
9943 row->pixel_width = row->x;
9944 for (i = 0; i < row->used[TEXT_AREA]; ++i)
9945 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
9946
9947 xassert (row->pixel_width >= 0);
9948 xassert (row->ascent >= 0 && row->height > 0);
9949
9950 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
9951 || MATRIX_ROW_OVERLAPS_PRED_P (row));
9952
9953 /* If first line's physical ascent is larger than its logical
9954 ascent, use the physical ascent, and make the row taller.
9955 This makes accented characters fully visible. */
9956 if (row == it->w->desired_matrix->rows
9957 && row->phys_ascent > row->ascent)
9958 {
9959 row->height += row->phys_ascent - row->ascent;
9960 row->ascent = row->phys_ascent;
9961 }
9962
9963 /* Compute how much of the line is visible. */
9964 row->visible_height = row->height;
9965
9966 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w);
9967 if (row->y < top_line_height)
9968 row->visible_height -= top_line_height - row->y;
9969 else
9970 {
9971 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
9972 if (row->y + row->height > max_y)
9973 row->visible_height -= row->y + row->height - max_y;
9974 }
9975 }
9976 else
9977 {
9978 row->pixel_width = row->used[TEXT_AREA];
9979 row->ascent = row->phys_ascent = 0;
9980 row->height = row->phys_height = row->visible_height = 1;
9981 }
9982
9983 /* Compute a hash code for this row. */
9984 row->hash = 0;
9985 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
9986 for (i = 0; i < row->used[area]; ++i)
9987 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
9988 + row->glyphs[area][i].u.val
9989 + (row->glyphs[area][i].type << 2));
9990
9991 it->max_ascent = it->max_descent = 0;
9992 it->max_phys_ascent = it->max_phys_descent = 0;
9993 }
9994
9995
9996 /* Append one space to the glyph row of iterator IT if doing a
9997 window-based redisplay. DEFAULT_FACE_P non-zero means let the
9998 space have the default face, otherwise let it have the same face as
9999 IT->face_id. This function is called to make sure that there is
10000 always one glyph at the end of a glyph row that the cursor can be
10001 set on under window-systems. (If there weren't such a glyph we
10002 would not know how wide and tall the cursor should be displayed). */
10003
10004 static void
10005 append_space (it, default_face_p)
10006 struct it *it;
10007 int default_face_p;
10008 {
10009 if (FRAME_WINDOW_P (it->f))
10010 {
10011 int n = it->glyph_row->used[TEXT_AREA];
10012
10013 if (it->glyph_row->glyphs[TEXT_AREA] + n
10014 < it->glyph_row->glyphs[1 + TEXT_AREA])
10015 {
10016 /* Save some values that must not be changed. */
10017 int saved_x = it->current_x;
10018 struct text_pos saved_pos;
10019 int saved_what = it->what;
10020 int saved_face_id = it->face_id;
10021 int saved_charset = it->charset;
10022 Lisp_Object saved_object;
10023
10024 saved_object = it->object;
10025 saved_pos = it->position;
10026
10027 it->what = IT_CHARACTER;
10028 bzero (&it->position, sizeof it->position);
10029 it->object = 0;
10030 it->c = ' ';
10031 it->len = 1;
10032 it->charset = CHARSET_ASCII;
10033
10034 if (default_face_p)
10035 it->face_id = DEFAULT_FACE_ID;
10036 if (it->multibyte_p)
10037 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, CHARSET_ASCII);
10038 else
10039 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, -1);
10040
10041 PRODUCE_GLYPHS (it);
10042
10043 it->current_x = saved_x;
10044 it->object = saved_object;
10045 it->position = saved_pos;
10046 it->what = saved_what;
10047 it->face_id = saved_face_id;
10048 it->charset = saved_charset;
10049 }
10050 }
10051 }
10052
10053
10054 /* Extend the face of the last glyph in the text area of IT->glyph_row
10055 to the end of the display line. Called from display_line.
10056 If the glyph row is empty, add a space glyph to it so that we
10057 know the face to draw. Set the glyph row flag fill_line_p. */
10058
10059 static void
10060 extend_face_to_end_of_line (it)
10061 struct it *it;
10062 {
10063 struct face *face;
10064 struct frame *f = it->f;
10065
10066 /* If line is already filled, do nothing. */
10067 if (it->current_x >= it->last_visible_x)
10068 return;
10069
10070 /* Face extension extends the background and box of IT->face_id
10071 to the end of the line. If the background equals the background
10072 of the frame, we haven't to do anything. */
10073 face = FACE_FROM_ID (f, it->face_id);
10074 if (FRAME_WINDOW_P (f)
10075 && face->box == FACE_NO_BOX
10076 && face->background == FRAME_BACKGROUND_PIXEL (f)
10077 && !face->stipple)
10078 return;
10079
10080 /* Set the glyph row flag indicating that the face of the last glyph
10081 in the text area has to be drawn to the end of the text area. */
10082 it->glyph_row->fill_line_p = 1;
10083
10084 /* If current charset of IT is not ASCII, make sure we have the
10085 ASCII face. This will be automatically undone the next time
10086 get_next_display_element returns a character from a different
10087 charset. Note that the charset will always be ASCII in unibyte
10088 text. */
10089 if (it->charset != CHARSET_ASCII)
10090 {
10091 it->charset = CHARSET_ASCII;
10092 it->face_id = FACE_FOR_CHARSET (f, it->face_id, CHARSET_ASCII);
10093 }
10094
10095 if (FRAME_WINDOW_P (f))
10096 {
10097 /* If the row is empty, add a space with the current face of IT,
10098 so that we know which face to draw. */
10099 if (it->glyph_row->used[TEXT_AREA] == 0)
10100 {
10101 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
10102 it->glyph_row->glyphs[TEXT_AREA][0].u.ch.face_id = it->face_id;
10103 it->glyph_row->used[TEXT_AREA] = 1;
10104 }
10105 }
10106 else
10107 {
10108 /* Save some values that must not be changed. */
10109 int saved_x = it->current_x;
10110 struct text_pos saved_pos;
10111 Lisp_Object saved_object;
10112 int saved_what = it->what;
10113
10114 saved_object = it->object;
10115 saved_pos = it->position;
10116
10117 it->what = IT_CHARACTER;
10118 bzero (&it->position, sizeof it->position);
10119 it->object = 0;
10120 it->c = ' ';
10121 it->len = 1;
10122
10123 PRODUCE_GLYPHS (it);
10124
10125 while (it->current_x <= it->last_visible_x)
10126 PRODUCE_GLYPHS (it);
10127
10128 /* Don't count these blanks really. It would let us insert a left
10129 truncation glyph below and make us set the cursor on them, maybe. */
10130 it->current_x = saved_x;
10131 it->object = saved_object;
10132 it->position = saved_pos;
10133 it->what = saved_what;
10134 }
10135 }
10136
10137
10138 /* Value is non-zero if text starting at CHARPOS in current_buffer is
10139 trailing whitespace. */
10140
10141 static int
10142 trailing_whitespace_p (charpos)
10143 int charpos;
10144 {
10145 int bytepos = CHAR_TO_BYTE (charpos);
10146 int c = 0;
10147
10148 while (bytepos < ZV_BYTE
10149 && (c = FETCH_CHAR (bytepos),
10150 c == ' ' || c == '\t'))
10151 ++bytepos;
10152
10153 return bytepos >= ZV_BYTE || c == '\n' || c == '\r';
10154 }
10155
10156
10157 /* Highlight trailing whitespace, if any, in ROW. */
10158
10159 void
10160 highlight_trailing_whitespace (f, row)
10161 struct frame *f;
10162 struct glyph_row *row;
10163 {
10164 int used = row->used[TEXT_AREA];
10165
10166 if (used)
10167 {
10168 struct glyph *start = row->glyphs[TEXT_AREA];
10169 struct glyph *glyph = start + used - 1;
10170
10171 /* Skip over the space glyph inserted to display the
10172 cursor at the end of a line. */
10173 if (glyph->type == CHAR_GLYPH
10174 && glyph->u.ch.code == ' '
10175 && glyph->object == 0)
10176 --glyph;
10177
10178 /* If last glyph is a space or stretch, and it's trailing
10179 whitespace, set the face of all trailing whitespace glyphs in
10180 IT->glyph_row to `trailing-whitespace'. */
10181 if (glyph >= start
10182 && BUFFERP (glyph->object)
10183 && (glyph->type == STRETCH_GLYPH
10184 || (glyph->type == CHAR_GLYPH
10185 && glyph->u.ch.code == ' '))
10186 && trailing_whitespace_p (glyph->charpos))
10187 {
10188 int face_id = lookup_named_face (f, Qtrailing_whitespace,
10189 CHARSET_ASCII);
10190
10191 while (glyph >= start
10192 && BUFFERP (glyph->object)
10193 && (glyph->type == STRETCH_GLYPH
10194 || (glyph->type == CHAR_GLYPH
10195 && glyph->u.ch.code == ' ')))
10196 {
10197 if (glyph->type == STRETCH_GLYPH)
10198 glyph->u.stretch.face_id = face_id;
10199 else
10200 glyph->u.ch.face_id = face_id;
10201 --glyph;
10202 }
10203 }
10204 }
10205 }
10206
10207
10208
10209 /* Construct the glyph row IT->glyph_row in the desired matrix of
10210 IT->w from text at the current position of IT. See dispextern.h
10211 for an overview of struct it. Value is non-zero if
10212 IT->glyph_row displays text, as opposed to a line displaying ZV
10213 only. */
10214
10215 static int
10216 display_line (it)
10217 struct it *it;
10218 {
10219 struct glyph_row *row = it->glyph_row;
10220
10221 /* We always start displaying at hpos zero even if hscrolled. */
10222 xassert (it->hpos == 0 && it->current_x == 0);
10223
10224 /* We must not display in a row that's not a text row. */
10225 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
10226 < it->w->desired_matrix->nrows);
10227
10228 /* Is IT->w showing the region? */
10229 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
10230
10231 /* Clear the result glyph row and enable it. */
10232 prepare_desired_row (row);
10233
10234 row->y = it->current_y;
10235 row->start = it->current;
10236 row->continuation_lines_width = it->continuation_lines_width;
10237 row->displays_text_p = 1;
10238
10239 /* Arrange the overlays nicely for our purposes. Usually, we call
10240 display_line on only one line at a time, in which case this
10241 can't really hurt too much, or we call it on lines which appear
10242 one after another in the buffer, in which case all calls to
10243 recenter_overlay_lists but the first will be pretty cheap. */
10244 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
10245
10246 #if NO_PROMPT_IN_BUFFER
10247 /* Show mini-buffer prompt, if at the beginning of a mini-buffer
10248 window. */
10249 if (MINI_WINDOW_P (it->w)
10250 && MATRIX_ROW_START_CHARPOS (row) == BEG
10251 && it->vpos == 0)
10252 {
10253 if (NILP (minibuf_prompt))
10254 minibuf_prompt_width = minibuf_prompt_pixel_width = 0;
10255 else
10256 {
10257 /* We would like to truncate the prompt a little bit before
10258 the right margin of the window, so that user input can
10259 start on the first line. Set max_x to this position. */
10260 int max_x = (it->last_visible_x - 4 * CANON_X_UNIT (it->f));
10261
10262 /* We use a temporary iterator different from IT so that
10263 IT's settings are not overwritten when displaying
10264 the prompt. */
10265 struct it ti;
10266
10267 ti = *it;
10268
10269 /* Display the prompt. Set minibuf_prompt_width to the
10270 number of glyphs generated for the prompt, set
10271 minibuf_prompt_pixel_width to its width in pixels. */
10272 xassert (it->current_x == 0);
10273 display_string (NULL, minibuf_prompt, Qnil, 0, 0, &ti,
10274 0, 0, max_x, -1);
10275 minibuf_prompt_width = ti.hpos;
10276 minibuf_prompt_pixel_width = ti.current_x;
10277
10278 /* Transfer pixel and hpos information to IT. */
10279 it->hpos = ti.hpos;
10280 it->current_x = ti.current_x;
10281 }
10282 }
10283 #endif /* NO_PROMPT_IN_BUFFER */
10284
10285 /* Move over display elements that are not visible because we are
10286 hscrolled. This may stop at an x-position < IT->first_visible_x
10287 if the first glyph is partially visible or if we hit a line end. */
10288 if (it->current_x < it->first_visible_x)
10289 move_it_in_display_line_to (it, ZV, it->first_visible_x,
10290 MOVE_TO_POS | MOVE_TO_X);
10291
10292 /* Get the initial row height. This is either the height of the
10293 text hscrolled, if there is any, or zero. */
10294 row->ascent = it->max_ascent;
10295 row->height = it->max_ascent + it->max_descent;
10296 row->phys_ascent = it->max_phys_ascent;
10297 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
10298
10299 /* Loop generating characters. The loop is left with IT on the next
10300 character to display. */
10301 while (1)
10302 {
10303 int n_glyphs_before, hpos_before, x_before;
10304 int x, i, nglyphs;
10305
10306 /* Retrieve the next thing to display. Value is zero if end of
10307 buffer reached. */
10308 if (!get_next_display_element (it))
10309 {
10310 /* Maybe add a space at the end of this line that is used to
10311 display the cursor there under X. */
10312 append_space (it, 1);
10313
10314 /* The position -1 below indicates a blank line not
10315 corresponding to any text, as opposed to an empty line
10316 corresponding to a line end. */
10317 if (row->used[TEXT_AREA] <= 1)
10318 {
10319 row->glyphs[TEXT_AREA]->charpos = -1;
10320 row->displays_text_p = 0;
10321
10322 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
10323 row->indicate_empty_line_p = 1;
10324 }
10325
10326 it->continuation_lines_width = 0;
10327 row->ends_at_zv_p = 1;
10328 break;
10329 }
10330
10331 /* Now, get the metrics of what we want to display. This also
10332 generates glyphs in `row' (which is IT->glyph_row). */
10333 n_glyphs_before = row->used[TEXT_AREA];
10334 x = it->current_x;
10335 PRODUCE_GLYPHS (it);
10336
10337 /* If this display element was in marginal areas, continue with
10338 the next one. */
10339 if (it->area != TEXT_AREA)
10340 {
10341 row->ascent = max (row->ascent, it->max_ascent);
10342 row->height = max (row->height, it->max_ascent + it->max_descent);
10343 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10344 row->phys_height = max (row->phys_height,
10345 it->max_phys_ascent + it->max_phys_descent);
10346 set_iterator_to_next (it);
10347 continue;
10348 }
10349
10350 /* Does the display element fit on the line? If we truncate
10351 lines, we should draw past the right edge of the window. If
10352 we don't truncate, we want to stop so that we can display the
10353 continuation glyph before the right margin. If lines are
10354 continued, there are two possible strategies for characters
10355 resulting in more than 1 glyph (e.g. tabs): Display as many
10356 glyphs as possible in this line and leave the rest for the
10357 continuation line, or display the whole element in the next
10358 line. Original redisplay did the former, so we do it also. */
10359 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10360 hpos_before = it->hpos;
10361 x_before = x;
10362
10363 if (nglyphs == 1
10364 && it->current_x < it->last_visible_x)
10365 {
10366 ++it->hpos;
10367 row->ascent = max (row->ascent, it->max_ascent);
10368 row->height = max (row->height, it->max_ascent + it->max_descent);
10369 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10370 row->phys_height = max (row->phys_height,
10371 it->max_phys_ascent + it->max_phys_descent);
10372 if (it->current_x - it->pixel_width < it->first_visible_x)
10373 row->x = x - it->first_visible_x;
10374 }
10375 else
10376 {
10377 int new_x;
10378 struct glyph *glyph;
10379
10380 for (i = 0; i < nglyphs; ++i, x = new_x)
10381 {
10382 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10383 new_x = x + glyph->pixel_width;
10384
10385 if (/* Lines are continued. */
10386 !it->truncate_lines_p
10387 && (/* Glyph doesn't fit on the line. */
10388 new_x > it->last_visible_x
10389 /* Or it fits exactly on a window system frame. */
10390 || (new_x == it->last_visible_x
10391 && FRAME_WINDOW_P (it->f))))
10392 {
10393 /* End of a continued line. */
10394
10395 if (it->hpos == 0
10396 || (new_x == it->last_visible_x
10397 && FRAME_WINDOW_P (it->f)))
10398 {
10399 /* Current glyph fits exactly on the line. We
10400 must continue the line because we can't draw
10401 the cursor after the glyph. */
10402 row->continued_p = 1;
10403 it->current_x = new_x;
10404 it->continuation_lines_width += new_x;
10405 ++it->hpos;
10406 if (i == nglyphs - 1)
10407 set_iterator_to_next (it);
10408 }
10409 else
10410 {
10411 /* Display element draws past the right edge of
10412 the window. Restore positions to values
10413 before the element. The next line starts
10414 with current_x before the glyph that could
10415 not be displayed, so that TAB works right. */
10416 row->used[TEXT_AREA] = n_glyphs_before + i;
10417
10418 /* Display continuation glyphs. */
10419 if (!FRAME_WINDOW_P (it->f))
10420 produce_special_glyphs (it, IT_CONTINUATION);
10421 row->continued_p = 1;
10422
10423 it->current_x = x;
10424 it->continuation_lines_width += x;
10425 }
10426 break;
10427 }
10428 else if (new_x > it->first_visible_x)
10429 {
10430 /* Increment number of glyphs actually displayed. */
10431 ++it->hpos;
10432
10433 if (x < it->first_visible_x)
10434 /* Glyph is partially visible, i.e. row starts at
10435 negative X position. */
10436 row->x = x - it->first_visible_x;
10437 }
10438 else
10439 {
10440 /* Glyph is completely off the left margin of the
10441 window. This should not happen because of the
10442 move_it_in_display_line at the start of
10443 this function. */
10444 abort ();
10445 }
10446 }
10447
10448 row->ascent = max (row->ascent, it->max_ascent);
10449 row->height = max (row->height, it->max_ascent + it->max_descent);
10450 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10451 row->phys_height = max (row->phys_height,
10452 it->max_phys_ascent + it->max_phys_descent);
10453
10454 /* End of this display line if row is continued. */
10455 if (row->continued_p)
10456 break;
10457 }
10458
10459 /* Is this a line end? If yes, we're also done, after making
10460 sure that a non-default face is extended up to the right
10461 margin of the window. */
10462 if (ITERATOR_AT_END_OF_LINE_P (it))
10463 {
10464 int used_before = row->used[TEXT_AREA];
10465
10466 /* Add a space at the end of the line that is used to
10467 display the cursor there. */
10468 append_space (it, 0);
10469
10470 /* Extend the face to the end of the line. */
10471 extend_face_to_end_of_line (it);
10472
10473 /* Make sure we have the position. */
10474 if (used_before == 0)
10475 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
10476
10477 /* Consume the line end. This skips over invisible lines. */
10478 set_iterator_to_next (it);
10479 it->continuation_lines_width = 0;
10480 break;
10481 }
10482
10483 /* Proceed with next display element. Note that this skips
10484 over lines invisible because of selective display. */
10485 set_iterator_to_next (it);
10486
10487 /* If we truncate lines, we are done when the last displayed
10488 glyphs reach past the right margin of the window. */
10489 if (it->truncate_lines_p
10490 && (FRAME_WINDOW_P (it->f)
10491 ? (it->current_x >= it->last_visible_x)
10492 : (it->current_x > it->last_visible_x)))
10493 {
10494 /* Maybe add truncation glyphs. */
10495 if (!FRAME_WINDOW_P (it->f))
10496 {
10497 --it->glyph_row->used[TEXT_AREA];
10498 produce_special_glyphs (it, IT_TRUNCATION);
10499 }
10500
10501 row->truncated_on_right_p = 1;
10502 it->continuation_lines_width = 0;
10503 reseat_at_next_visible_line_start (it, 0);
10504 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
10505 it->hpos = hpos_before;
10506 it->current_x = x_before;
10507 break;
10508 }
10509 }
10510
10511 /* If line is not empty and hscrolled, maybe insert truncation glyphs
10512 at the left window margin. */
10513 if (it->first_visible_x
10514 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
10515 {
10516 if (!FRAME_WINDOW_P (it->f))
10517 insert_left_trunc_glyphs (it);
10518 row->truncated_on_left_p = 1;
10519 }
10520
10521 /* If the start of this line is the overlay arrow-position, then
10522 mark this glyph row as the one containing the overlay arrow.
10523 This is clearly a mess with variable size fonts. It would be
10524 better to let it be displayed like cursors under X. */
10525 if (MARKERP (Voverlay_arrow_position)
10526 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
10527 && (MATRIX_ROW_START_CHARPOS (row)
10528 == marker_position (Voverlay_arrow_position))
10529 && STRINGP (Voverlay_arrow_string)
10530 && ! overlay_arrow_seen)
10531 {
10532 /* Overlay arrow in window redisplay is a bitmap. */
10533 if (!FRAME_WINDOW_P (it->f))
10534 {
10535 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
10536 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
10537 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
10538 struct glyph *p = row->glyphs[TEXT_AREA];
10539 struct glyph *p2, *end;
10540
10541 /* Copy the arrow glyphs. */
10542 while (glyph < arrow_end)
10543 *p++ = *glyph++;
10544
10545 /* Throw away padding glyphs. */
10546 p2 = p;
10547 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
10548 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
10549 ++p2;
10550 if (p2 > p)
10551 {
10552 while (p2 < end)
10553 *p++ = *p2++;
10554 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
10555 }
10556 }
10557
10558 overlay_arrow_seen = 1;
10559 row->overlay_arrow_p = 1;
10560 }
10561
10562 /* Compute pixel dimensions of this line. */
10563 compute_line_metrics (it);
10564
10565 /* Remember the position at which this line ends. */
10566 row->end = it->current;
10567
10568 /* Maybe set the cursor. If you change this, it's probably a good
10569 idea to also change the code in redisplay_window for cursor
10570 movement in an unchanged window. */
10571 if (it->w->cursor.vpos < 0
10572 && PT >= MATRIX_ROW_START_CHARPOS (row)
10573 && MATRIX_ROW_END_CHARPOS (row) >= PT
10574 && !(MATRIX_ROW_END_CHARPOS (row) == PT
10575 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
10576 || !row->ends_at_zv_p)))
10577 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
10578
10579 /* Highlight trailing whitespace. */
10580 if (it->show_trailing_whitespace_p)
10581 highlight_trailing_whitespace (it->f, it->glyph_row);
10582
10583 /* Prepare for the next line. This line starts horizontally at (X
10584 HPOS) = (0 0). Vertical positions are incremented. As a
10585 convenience for the caller, IT->glyph_row is set to the next
10586 row to be used. */
10587 it->current_x = it->hpos = 0;
10588 it->current_y += row->height;
10589 ++it->vpos;
10590 ++it->glyph_row;
10591 return row->displays_text_p;
10592 }
10593
10594
10595 \f
10596 /***********************************************************************
10597 Menu Bar
10598 ***********************************************************************/
10599
10600 /* Redisplay the menu bar in the frame for window W.
10601
10602 The menu bar of X frames that don't have X toolkit support is
10603 displayed in a special window W->frame->menu_bar_window.
10604
10605 The menu bar of terminal frames is treated specially as far as
10606 glyph matrices are concerned. Menu bar lines are not part of
10607 windows, so the update is done directly on the frame matrix rows
10608 for the menu bar. */
10609
10610 static void
10611 display_menu_bar (w)
10612 struct window *w;
10613 {
10614 struct frame *f = XFRAME (WINDOW_FRAME (w));
10615 struct it it;
10616 Lisp_Object items;
10617 int i;
10618
10619 /* Don't do all this for graphical frames. */
10620 #ifdef HAVE_NTGUI
10621 if (!NILP (Vwindow_system))
10622 return;
10623 #endif
10624 #ifdef USE_X_TOOLKIT
10625 if (FRAME_X_P (f))
10626 return;
10627 #endif
10628
10629 #ifdef USE_X_TOOLKIT
10630 xassert (!FRAME_WINDOW_P (f));
10631 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
10632 it.first_visible_x = 0;
10633 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
10634 #else /* not USE_X_TOOLKIT */
10635 if (FRAME_WINDOW_P (f))
10636 {
10637 /* Menu bar lines are displayed in the desired matrix of the
10638 dummy window menu_bar_window. */
10639 struct window *menu_w;
10640 xassert (WINDOWP (f->menu_bar_window));
10641 menu_w = XWINDOW (f->menu_bar_window);
10642 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
10643 MODE_LINE_FACE_ID);
10644 it.first_visible_x = 0;
10645 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
10646 }
10647 else
10648 {
10649 /* This is a TTY frame, i.e. character hpos/vpos are used as
10650 pixel x/y. */
10651 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
10652 MODE_LINE_FACE_ID);
10653 it.first_visible_x = 0;
10654 it.last_visible_x = FRAME_WIDTH (f);
10655 }
10656 #endif /* not USE_X_TOOLKIT */
10657
10658 /* Clear all rows of the menu bar. */
10659 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
10660 {
10661 struct glyph_row *row = it.glyph_row + i;
10662 clear_glyph_row (row);
10663 row->enabled_p = 1;
10664 row->full_width_p = 1;
10665 }
10666
10667 /* Make the first line of the menu bar appear in reverse video. */
10668 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
10669
10670 /* Display all items of the menu bar. */
10671 items = FRAME_MENU_BAR_ITEMS (it.f);
10672 for (i = 0; i < XVECTOR (items)->size; i += 4)
10673 {
10674 Lisp_Object string;
10675
10676 /* Stop at nil string. */
10677 string = XVECTOR (items)->contents[i + 1];
10678 if (NILP (string))
10679 break;
10680
10681 /* Remember where item was displayed. */
10682 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
10683
10684 /* Display the item, pad with one space. */
10685 if (it.current_x < it.last_visible_x)
10686 display_string (NULL, string, Qnil, 0, 0, &it,
10687 XSTRING (string)->size + 1, 0, 0, -1);
10688 }
10689
10690 /* Fill out the line with spaces. */
10691 if (it.current_x < it.last_visible_x)
10692 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
10693
10694 /* Compute the total height of the lines. */
10695 compute_line_metrics (&it);
10696 }
10697
10698
10699 \f
10700 /***********************************************************************
10701 Mode Line
10702 ***********************************************************************/
10703
10704 /* Display the mode and/or top line of window W. */
10705
10706 static void
10707 display_mode_lines (w)
10708 struct window *w;
10709 {
10710 /* These will be set while the mode line specs are processed. */
10711 line_number_displayed = 0;
10712 w->column_number_displayed = Qnil;
10713
10714 if (WINDOW_WANTS_MODELINE_P (w))
10715 display_mode_line (w, MODE_LINE_FACE_ID, current_buffer->mode_line_format);
10716
10717 if (WINDOW_WANTS_TOP_LINE_P (w))
10718 display_mode_line (w, TOP_LINE_FACE_ID, current_buffer->top_line_format);
10719 }
10720
10721
10722 /* Display mode or top line of window W. FACE_ID specifies which line
10723 to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
10724 FORMAT is the mode line format to display. */
10725
10726 static void
10727 display_mode_line (w, face_id, format)
10728 struct window *w;
10729 enum face_id face_id;
10730 Lisp_Object format;
10731 {
10732 struct it it;
10733 struct face *face;
10734
10735 init_iterator (&it, w, -1, -1, NULL, face_id);
10736 prepare_desired_row (it.glyph_row);
10737
10738 /* Temporarily make frame's keyboard the current kboard so that
10739 kboard-local variables in the mode_line_format will get the right
10740 values. */
10741 push_frame_kboard (it.f);
10742 display_mode_element (&it, 0, 0, 0, format);
10743 pop_frame_kboard ();
10744
10745 /* Fill up with spaces. */
10746 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
10747
10748 compute_line_metrics (&it);
10749 it.glyph_row->full_width_p = 1;
10750 it.glyph_row->mode_line_p = 1;
10751 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
10752 it.glyph_row->continued_p = 0;
10753 it.glyph_row->truncated_on_left_p = 0;
10754 it.glyph_row->truncated_on_right_p = 0;
10755
10756 /* Make a 3D mode-line have a shadow at its right end. */
10757 face = FACE_FROM_ID (it.f, face_id);
10758 extend_face_to_end_of_line (&it);
10759 if (face->box != FACE_NO_BOX)
10760 {
10761 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
10762 + it.glyph_row->used[TEXT_AREA] - 1);
10763 last->right_box_line_p = 1;
10764 }
10765 }
10766
10767
10768 /* Contribute ELT to the mode line for window IT->w. How it
10769 translates into text depends on its data type.
10770
10771 IT describes the display environment in which we display, as usual.
10772
10773 DEPTH is the depth in recursion. It is used to prevent
10774 infinite recursion here.
10775
10776 FIELD_WIDTH is the number of characters the display of ELT should
10777 occupy in the mode line, and PRECISION is the maximum number of
10778 characters to display from ELT's representation. See
10779 display_string for details. *
10780
10781 Returns the hpos of the end of the text generated by ELT. */
10782
10783 static int
10784 display_mode_element (it, depth, field_width, precision, elt)
10785 struct it *it;
10786 int depth;
10787 int field_width, precision;
10788 Lisp_Object elt;
10789 {
10790 int n = 0, field, prec;
10791
10792 tail_recurse:
10793 if (depth > 10)
10794 goto invalid;
10795
10796 depth++;
10797
10798 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
10799 {
10800 case Lisp_String:
10801 {
10802 /* A string: output it and check for %-constructs within it. */
10803 unsigned char c;
10804 unsigned char *this = XSTRING (elt)->data;
10805 unsigned char *lisp_string = this;
10806
10807 while ((precision <= 0 || n < precision)
10808 && *this
10809 && (frame_title_ptr
10810 || it->current_x < it->last_visible_x))
10811 {
10812 unsigned char *last = this;
10813
10814 /* Advance to end of string or next format specifier. */
10815 while ((c = *this++) != '\0' && c != '%')
10816 ;
10817
10818 if (this - 1 != last)
10819 {
10820 /* Output to end of string or up to '%'. Field width
10821 is length of string. Don't output more than
10822 PRECISION allows us. */
10823 prec = --this - last;
10824 if (precision > 0 && prec > precision - n)
10825 prec = precision - n;
10826
10827 if (frame_title_ptr)
10828 n += store_frame_title (last, prec, prec);
10829 else
10830 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
10831 it, 0, prec, 0, -1);
10832 }
10833 else /* c == '%' */
10834 {
10835 unsigned char *percent_position = this;
10836
10837 /* Get the specified minimum width. Zero means
10838 don't pad. */
10839 field = 0;
10840 while ((c = *this++) >= '0' && c <= '9')
10841 field = field * 10 + c - '0';
10842
10843 /* Don't pad beyond the total padding allowed. */
10844 if (field_width - n > 0 && field > field_width - n)
10845 field = field_width - n;
10846
10847 /* Note that either PRECISION <= 0 or N < PRECISION. */
10848 prec = precision - n;
10849
10850 if (c == 'M')
10851 n += display_mode_element (it, depth, field, prec,
10852 Vglobal_mode_string);
10853 else if (c != 0)
10854 {
10855 unsigned char *spec
10856 = decode_mode_spec (it->w, c, field, prec);
10857
10858 if (frame_title_ptr)
10859 n += store_frame_title (spec, field, prec);
10860 else
10861 {
10862 int nglyphs_before
10863 = it->glyph_row->used[TEXT_AREA];
10864 int charpos
10865 = percent_position - XSTRING (elt)->data;
10866 int nwritten
10867 = display_string (spec, Qnil, elt, charpos, 0, it,
10868 field, prec, 0, -1);
10869
10870 /* Assign to the glyphs written above the
10871 string where the `%x' came from, position
10872 of the `%'. */
10873 if (nwritten > 0)
10874 {
10875 struct glyph *glyph
10876 = (it->glyph_row->glyphs[TEXT_AREA]
10877 + nglyphs_before);
10878 int i;
10879
10880 for (i = 0; i < nwritten; ++i)
10881 {
10882 glyph[i].object = elt;
10883 glyph[i].charpos = charpos;
10884 }
10885
10886 n += nwritten;
10887 }
10888 }
10889 }
10890 }
10891 }
10892 }
10893 break;
10894
10895 case Lisp_Symbol:
10896 /* A symbol: process the value of the symbol recursively
10897 as if it appeared here directly. Avoid error if symbol void.
10898 Special case: if value of symbol is a string, output the string
10899 literally. */
10900 {
10901 register Lisp_Object tem;
10902 tem = Fboundp (elt);
10903 if (!NILP (tem))
10904 {
10905 tem = Fsymbol_value (elt);
10906 /* If value is a string, output that string literally:
10907 don't check for % within it. */
10908 if (STRINGP (tem))
10909 {
10910 prec = XSTRING (tem)->size;
10911 if (precision > 0 && prec > precision - n)
10912 prec = precision - n;
10913 if (frame_title_ptr)
10914 n += store_frame_title (XSTRING (tem)->data, -1, prec);
10915 else
10916 n += display_string (NULL, tem, Qnil, 0, 0, it,
10917 0, prec, 0, -1);
10918 }
10919 else if (!EQ (tem, elt))
10920 {
10921 /* Give up right away for nil or t. */
10922 elt = tem;
10923 goto tail_recurse;
10924 }
10925 }
10926 }
10927 break;
10928
10929 case Lisp_Cons:
10930 {
10931 register Lisp_Object car, tem;
10932
10933 /* A cons cell: three distinct cases.
10934 If first element is a string or a cons, process all the elements
10935 and effectively concatenate them.
10936 If first element is a negative number, truncate displaying cdr to
10937 at most that many characters. If positive, pad (with spaces)
10938 to at least that many characters.
10939 If first element is a symbol, process the cadr or caddr recursively
10940 according to whether the symbol's value is non-nil or nil. */
10941 car = XCONS (elt)->car;
10942 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
10943 {
10944 /* An element of the form (:eval FORM) means evaluate FORM
10945 and use the result as mode line elements. */
10946 struct gcpro gcpro1;
10947 Lisp_Object spec;
10948
10949 spec = eval_form (XCAR (XCDR (elt)));
10950 GCPRO1 (spec);
10951 n += display_mode_element (it, depth, field_width - n,
10952 precision - n, spec);
10953 UNGCPRO;
10954 }
10955 else if (SYMBOLP (car))
10956 {
10957 tem = Fboundp (car);
10958 elt = XCONS (elt)->cdr;
10959 if (!CONSP (elt))
10960 goto invalid;
10961 /* elt is now the cdr, and we know it is a cons cell.
10962 Use its car if CAR has a non-nil value. */
10963 if (!NILP (tem))
10964 {
10965 tem = Fsymbol_value (car);
10966 if (!NILP (tem))
10967 { elt = XCONS (elt)->car; goto tail_recurse; }
10968 }
10969 /* Symbol's value is nil (or symbol is unbound)
10970 Get the cddr of the original list
10971 and if possible find the caddr and use that. */
10972 elt = XCONS (elt)->cdr;
10973 if (NILP (elt))
10974 break;
10975 else if (!CONSP (elt))
10976 goto invalid;
10977 elt = XCONS (elt)->car;
10978 goto tail_recurse;
10979 }
10980 else if (INTEGERP (car))
10981 {
10982 register int lim = XINT (car);
10983 elt = XCONS (elt)->cdr;
10984 if (lim < 0)
10985 {
10986 /* Negative int means reduce maximum width. */
10987 if (precision <= 0)
10988 precision = -lim;
10989 else
10990 precision = min (precision, -lim);
10991 }
10992 else if (lim > 0)
10993 {
10994 /* Padding specified. Don't let it be more than
10995 current maximum. */
10996 if (precision > 0)
10997 lim = min (precision, lim);
10998
10999 /* If that's more padding than already wanted, queue it.
11000 But don't reduce padding already specified even if
11001 that is beyond the current truncation point. */
11002 field_width = max (lim, field_width);
11003 }
11004 goto tail_recurse;
11005 }
11006 else if (STRINGP (car) || CONSP (car))
11007 {
11008 register int limit = 50;
11009 /* Limit is to protect against circular lists. */
11010 while (CONSP (elt)
11011 && --limit > 0
11012 && (precision <= 0 || n < precision))
11013 {
11014 n += display_mode_element (it, depth, field_width - n,
11015 precision - n, XCONS (elt)->car);
11016 elt = XCONS (elt)->cdr;
11017 }
11018 }
11019 }
11020 break;
11021
11022 default:
11023 invalid:
11024 if (frame_title_ptr)
11025 n += store_frame_title ("*invalid*", 0, precision - n);
11026 else
11027 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
11028 precision - n, 0, 0);
11029 return n;
11030 }
11031
11032 /* Pad to FIELD_WIDTH. */
11033 if (field_width > 0 && n < field_width)
11034 {
11035 if (frame_title_ptr)
11036 n += store_frame_title ("", field_width - n, 0);
11037 else
11038 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
11039 0, 0, 0);
11040 }
11041
11042 return n;
11043 }
11044
11045
11046 /* Write a null-terminated, right justified decimal representation of
11047 the positive integer D to BUF using a minimal field width WIDTH. */
11048
11049 static void
11050 pint2str (buf, width, d)
11051 register char *buf;
11052 register int width;
11053 register int d;
11054 {
11055 register char *p = buf;
11056
11057 if (d <= 0)
11058 *p++ = '0';
11059 else
11060 {
11061 while (d > 0)
11062 {
11063 *p++ = d % 10 + '0';
11064 d /= 10;
11065 }
11066 }
11067
11068 for (width -= (int) (p - buf); width > 0; --width)
11069 *p++ = ' ';
11070 *p-- = '\0';
11071 while (p > buf)
11072 {
11073 d = *buf;
11074 *buf++ = *p;
11075 *p-- = d;
11076 }
11077 }
11078
11079 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
11080 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
11081 type of CODING_SYSTEM. Return updated pointer into BUF. */
11082
11083 static unsigned char invalid_eol_type[] = "(*invalid*)";
11084
11085 static char *
11086 decode_mode_spec_coding (coding_system, buf, eol_flag)
11087 Lisp_Object coding_system;
11088 register char *buf;
11089 int eol_flag;
11090 {
11091 Lisp_Object val;
11092 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
11093 unsigned char *eol_str;
11094 int eol_str_len;
11095 /* The EOL conversion we are using. */
11096 Lisp_Object eoltype;
11097
11098 val = coding_system;
11099
11100 if (NILP (val)) /* Not yet decided. */
11101 {
11102 if (multibyte)
11103 *buf++ = '-';
11104 if (eol_flag)
11105 eoltype = eol_mnemonic_undecided;
11106 /* Don't mention EOL conversion if it isn't decided. */
11107 }
11108 else
11109 {
11110 Lisp_Object eolvalue;
11111
11112 eolvalue = Fget (coding_system, Qeol_type);
11113
11114 while (!NILP (val) && SYMBOLP (val))
11115 {
11116 val = Fget (val, Qcoding_system);
11117 if (NILP (eolvalue))
11118 eolvalue = Fget (val, Qeol_type);
11119 }
11120
11121 if (multibyte)
11122 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
11123
11124 if (eol_flag)
11125 {
11126 /* The EOL conversion that is normal on this system. */
11127
11128 if (NILP (eolvalue)) /* Not yet decided. */
11129 eoltype = eol_mnemonic_undecided;
11130 else if (VECTORP (eolvalue)) /* Not yet decided. */
11131 eoltype = eol_mnemonic_undecided;
11132 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
11133 eoltype = (XFASTINT (eolvalue) == 0
11134 ? eol_mnemonic_unix
11135 : (XFASTINT (eolvalue) == 1
11136 ? eol_mnemonic_dos : eol_mnemonic_mac));
11137 }
11138 }
11139
11140 if (eol_flag)
11141 {
11142 /* Mention the EOL conversion if it is not the usual one. */
11143 if (STRINGP (eoltype))
11144 {
11145 eol_str = XSTRING (eoltype)->data;
11146 eol_str_len = XSTRING (eoltype)->size;
11147 }
11148 else if (INTEGERP (eoltype)
11149 && CHAR_VALID_P (XINT (eoltype), 0))
11150 {
11151 int c = XINT (eoltype);
11152 unsigned char work[4];
11153
11154 eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
11155 }
11156 else
11157 {
11158 eol_str = invalid_eol_type;
11159 eol_str_len = sizeof (invalid_eol_type) - 1;
11160 }
11161 bcopy (eol_str, buf, eol_str_len);
11162 buf += eol_str_len;
11163 }
11164
11165 return buf;
11166 }
11167
11168 /* Return a string for the output of a mode line %-spec for window W,
11169 generated by character C. PRECISION >= 0 means don't return a
11170 string longer than that value. FIELD_WIDTH > 0 means pad the
11171 string returned with spaces to that value. */
11172
11173 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
11174
11175 static char *
11176 decode_mode_spec (w, c, field_width, precision)
11177 struct window *w;
11178 register char c;
11179 int field_width, precision;
11180 {
11181 Lisp_Object obj;
11182 struct frame *f = XFRAME (WINDOW_FRAME (w));
11183 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
11184 struct buffer *b = XBUFFER (w->buffer);
11185
11186 obj = Qnil;
11187
11188 switch (c)
11189 {
11190 case '*':
11191 if (!NILP (b->read_only))
11192 return "%";
11193 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11194 return "*";
11195 return "-";
11196
11197 case '+':
11198 /* This differs from %* only for a modified read-only buffer. */
11199 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11200 return "*";
11201 if (!NILP (b->read_only))
11202 return "%";
11203 return "-";
11204
11205 case '&':
11206 /* This differs from %* in ignoring read-only-ness. */
11207 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11208 return "*";
11209 return "-";
11210
11211 case '%':
11212 return "%";
11213
11214 case '[':
11215 {
11216 int i;
11217 char *p;
11218
11219 if (command_loop_level > 5)
11220 return "[[[... ";
11221 p = decode_mode_spec_buf;
11222 for (i = 0; i < command_loop_level; i++)
11223 *p++ = '[';
11224 *p = 0;
11225 return decode_mode_spec_buf;
11226 }
11227
11228 case ']':
11229 {
11230 int i;
11231 char *p;
11232
11233 if (command_loop_level > 5)
11234 return " ...]]]";
11235 p = decode_mode_spec_buf;
11236 for (i = 0; i < command_loop_level; i++)
11237 *p++ = ']';
11238 *p = 0;
11239 return decode_mode_spec_buf;
11240 }
11241
11242 case '-':
11243 {
11244 register int i;
11245
11246 /* Let lots_of_dashes be a string of infinite length. */
11247 if (field_width <= 0
11248 || field_width > sizeof (lots_of_dashes))
11249 {
11250 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
11251 decode_mode_spec_buf[i] = '-';
11252 decode_mode_spec_buf[i] = '\0';
11253 return decode_mode_spec_buf;
11254 }
11255 else
11256 return lots_of_dashes;
11257 }
11258
11259 case 'b':
11260 obj = b->name;
11261 break;
11262
11263 case 'c':
11264 {
11265 int col = current_column ();
11266 XSETFASTINT (w->column_number_displayed, col);
11267 pint2str (decode_mode_spec_buf, field_width, col);
11268 return decode_mode_spec_buf;
11269 }
11270
11271 case 'F':
11272 /* %F displays the frame name. */
11273 if (!NILP (f->title))
11274 return (char *) XSTRING (f->title)->data;
11275 if (f->explicit_name || ! FRAME_WINDOW_P (f))
11276 return (char *) XSTRING (f->name)->data;
11277 return "Emacs";
11278
11279 case 'f':
11280 obj = b->filename;
11281 break;
11282
11283 case 'l':
11284 {
11285 int startpos = XMARKER (w->start)->charpos;
11286 int startpos_byte = marker_byte_position (w->start);
11287 int line, linepos, linepos_byte, topline;
11288 int nlines, junk;
11289 int height = XFASTINT (w->height);
11290
11291 /* If we decided that this buffer isn't suitable for line numbers,
11292 don't forget that too fast. */
11293 if (EQ (w->base_line_pos, w->buffer))
11294 goto no_value;
11295 /* But do forget it, if the window shows a different buffer now. */
11296 else if (BUFFERP (w->base_line_pos))
11297 w->base_line_pos = Qnil;
11298
11299 /* If the buffer is very big, don't waste time. */
11300 if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit)
11301 {
11302 w->base_line_pos = Qnil;
11303 w->base_line_number = Qnil;
11304 goto no_value;
11305 }
11306
11307 if (!NILP (w->base_line_number)
11308 && !NILP (w->base_line_pos)
11309 && XFASTINT (w->base_line_pos) <= startpos)
11310 {
11311 line = XFASTINT (w->base_line_number);
11312 linepos = XFASTINT (w->base_line_pos);
11313 linepos_byte = buf_charpos_to_bytepos (b, linepos);
11314 }
11315 else
11316 {
11317 line = 1;
11318 linepos = BUF_BEGV (b);
11319 linepos_byte = BUF_BEGV_BYTE (b);
11320 }
11321
11322 /* Count lines from base line to window start position. */
11323 nlines = display_count_lines (linepos, linepos_byte,
11324 startpos_byte,
11325 startpos, &junk);
11326
11327 topline = nlines + line;
11328
11329 /* Determine a new base line, if the old one is too close
11330 or too far away, or if we did not have one.
11331 "Too close" means it's plausible a scroll-down would
11332 go back past it. */
11333 if (startpos == BUF_BEGV (b))
11334 {
11335 XSETFASTINT (w->base_line_number, topline);
11336 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
11337 }
11338 else if (nlines < height + 25 || nlines > height * 3 + 50
11339 || linepos == BUF_BEGV (b))
11340 {
11341 int limit = BUF_BEGV (b);
11342 int limit_byte = BUF_BEGV_BYTE (b);
11343 int position;
11344 int distance = (height * 2 + 30) * 200;
11345
11346 if (startpos - distance > limit)
11347 {
11348 limit = startpos - distance;
11349 limit_byte = CHAR_TO_BYTE (limit);
11350 }
11351
11352 nlines = display_count_lines (startpos, startpos_byte,
11353 limit_byte,
11354 - (height * 2 + 30),
11355 &position);
11356 /* If we couldn't find the lines we wanted within
11357 200 chars per line,
11358 give up on line numbers for this window. */
11359 if (position == limit_byte && limit == startpos - distance)
11360 {
11361 w->base_line_pos = w->buffer;
11362 w->base_line_number = Qnil;
11363 goto no_value;
11364 }
11365
11366 XSETFASTINT (w->base_line_number, topline - nlines);
11367 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
11368 }
11369
11370 /* Now count lines from the start pos to point. */
11371 nlines = display_count_lines (startpos, startpos_byte,
11372 PT_BYTE, PT, &junk);
11373
11374 /* Record that we did display the line number. */
11375 line_number_displayed = 1;
11376
11377 /* Make the string to show. */
11378 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
11379 return decode_mode_spec_buf;
11380 no_value:
11381 {
11382 char* p = decode_mode_spec_buf;
11383 int pad = field_width - 2;
11384 while (pad-- > 0)
11385 *p++ = ' ';
11386 *p++ = '?';
11387 *p = '?';
11388 return decode_mode_spec_buf;
11389 }
11390 }
11391 break;
11392
11393 case 'm':
11394 obj = b->mode_name;
11395 break;
11396
11397 case 'n':
11398 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
11399 return " Narrow";
11400 break;
11401
11402 case 'p':
11403 {
11404 int pos = marker_position (w->start);
11405 int total = BUF_ZV (b) - BUF_BEGV (b);
11406
11407 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
11408 {
11409 if (pos <= BUF_BEGV (b))
11410 return "All";
11411 else
11412 return "Bottom";
11413 }
11414 else if (pos <= BUF_BEGV (b))
11415 return "Top";
11416 else
11417 {
11418 if (total > 1000000)
11419 /* Do it differently for a large value, to avoid overflow. */
11420 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11421 else
11422 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
11423 /* We can't normally display a 3-digit number,
11424 so get us a 2-digit number that is close. */
11425 if (total == 100)
11426 total = 99;
11427 sprintf (decode_mode_spec_buf, "%2d%%", total);
11428 return decode_mode_spec_buf;
11429 }
11430 }
11431
11432 /* Display percentage of size above the bottom of the screen. */
11433 case 'P':
11434 {
11435 int toppos = marker_position (w->start);
11436 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
11437 int total = BUF_ZV (b) - BUF_BEGV (b);
11438
11439 if (botpos >= BUF_ZV (b))
11440 {
11441 if (toppos <= BUF_BEGV (b))
11442 return "All";
11443 else
11444 return "Bottom";
11445 }
11446 else
11447 {
11448 if (total > 1000000)
11449 /* Do it differently for a large value, to avoid overflow. */
11450 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11451 else
11452 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
11453 /* We can't normally display a 3-digit number,
11454 so get us a 2-digit number that is close. */
11455 if (total == 100)
11456 total = 99;
11457 if (toppos <= BUF_BEGV (b))
11458 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
11459 else
11460 sprintf (decode_mode_spec_buf, "%2d%%", total);
11461 return decode_mode_spec_buf;
11462 }
11463 }
11464
11465 case 's':
11466 /* status of process */
11467 obj = Fget_buffer_process (w->buffer);
11468 if (NILP (obj))
11469 return "no process";
11470 #ifdef subprocesses
11471 obj = Fsymbol_name (Fprocess_status (obj));
11472 #endif
11473 break;
11474
11475 case 't': /* indicate TEXT or BINARY */
11476 #ifdef MODE_LINE_BINARY_TEXT
11477 return MODE_LINE_BINARY_TEXT (b);
11478 #else
11479 return "T";
11480 #endif
11481
11482 case 'z':
11483 /* coding-system (not including end-of-line format) */
11484 case 'Z':
11485 /* coding-system (including end-of-line type) */
11486 {
11487 int eol_flag = (c == 'Z');
11488 char *p = decode_mode_spec_buf;
11489
11490 if (! FRAME_WINDOW_P (f))
11491 {
11492 /* No need to mention EOL here--the terminal never needs
11493 to do EOL conversion. */
11494 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
11495 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
11496 }
11497 p = decode_mode_spec_coding (b->buffer_file_coding_system,
11498 p, eol_flag);
11499
11500 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
11501 #ifdef subprocesses
11502 obj = Fget_buffer_process (Fcurrent_buffer ());
11503 if (PROCESSP (obj))
11504 {
11505 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
11506 p, eol_flag);
11507 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
11508 p, eol_flag);
11509 }
11510 #endif /* subprocesses */
11511 #endif /* 0 */
11512 *p = 0;
11513 return decode_mode_spec_buf;
11514 }
11515 }
11516
11517 if (STRINGP (obj))
11518 return (char *) XSTRING (obj)->data;
11519 else
11520 return "";
11521 }
11522
11523
11524 /* Count up to COUNT lines starting from START / START_BYTE.
11525 But don't go beyond LIMIT_BYTE.
11526 Return the number of lines thus found (always nonnegative).
11527
11528 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
11529
11530 static int
11531 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
11532 int start, start_byte, limit_byte, count;
11533 int *byte_pos_ptr;
11534 {
11535 register unsigned char *cursor;
11536 unsigned char *base;
11537
11538 register int ceiling;
11539 register unsigned char *ceiling_addr;
11540 int orig_count = count;
11541
11542 /* If we are not in selective display mode,
11543 check only for newlines. */
11544 int selective_display = (!NILP (current_buffer->selective_display)
11545 && !INTEGERP (current_buffer->selective_display));
11546
11547 if (count > 0)
11548 {
11549 while (start_byte < limit_byte)
11550 {
11551 ceiling = BUFFER_CEILING_OF (start_byte);
11552 ceiling = min (limit_byte - 1, ceiling);
11553 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
11554 base = (cursor = BYTE_POS_ADDR (start_byte));
11555 while (1)
11556 {
11557 if (selective_display)
11558 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
11559 ;
11560 else
11561 while (*cursor != '\n' && ++cursor != ceiling_addr)
11562 ;
11563
11564 if (cursor != ceiling_addr)
11565 {
11566 if (--count == 0)
11567 {
11568 start_byte += cursor - base + 1;
11569 *byte_pos_ptr = start_byte;
11570 return orig_count;
11571 }
11572 else
11573 if (++cursor == ceiling_addr)
11574 break;
11575 }
11576 else
11577 break;
11578 }
11579 start_byte += cursor - base;
11580 }
11581 }
11582 else
11583 {
11584 while (start_byte > limit_byte)
11585 {
11586 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
11587 ceiling = max (limit_byte, ceiling);
11588 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
11589 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
11590 while (1)
11591 {
11592 if (selective_display)
11593 while (--cursor != ceiling_addr
11594 && *cursor != '\n' && *cursor != 015)
11595 ;
11596 else
11597 while (--cursor != ceiling_addr && *cursor != '\n')
11598 ;
11599
11600 if (cursor != ceiling_addr)
11601 {
11602 if (++count == 0)
11603 {
11604 start_byte += cursor - base + 1;
11605 *byte_pos_ptr = start_byte;
11606 /* When scanning backwards, we should
11607 not count the newline posterior to which we stop. */
11608 return - orig_count - 1;
11609 }
11610 }
11611 else
11612 break;
11613 }
11614 /* Here we add 1 to compensate for the last decrement
11615 of CURSOR, which took it past the valid range. */
11616 start_byte += cursor - base + 1;
11617 }
11618 }
11619
11620 *byte_pos_ptr = limit_byte;
11621
11622 if (count < 0)
11623 return - orig_count + count;
11624 return orig_count - count;
11625
11626 }
11627
11628
11629 \f
11630 /***********************************************************************
11631 Displaying strings
11632 ***********************************************************************/
11633
11634 /* Display a NUL-terminated string, starting with index START.
11635
11636 If STRING is non-null, display that C string. Otherwise, the Lisp
11637 string LISP_STRING is displayed.
11638
11639 If FACE_STRING is not nil, FACE_STRING_POS is a position in
11640 FACE_STRING. Display STRING or LISP_STRING with the face at
11641 FACE_STRING_POS in FACE_STRING:
11642
11643 Display the string in the environment given by IT, but use the
11644 standard display table, temporarily.
11645
11646 FIELD_WIDTH is the minimum number of output glyphs to produce.
11647 If STRING has fewer characters than FIELD_WIDTH, pad to the right
11648 with spaces. If STRING has more characters, more than FIELD_WIDTH
11649 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
11650
11651 PRECISION is the maximum number of characters to output from
11652 STRING. PRECISION < 0 means don't truncate the string.
11653
11654 This is roughly equivalent to printf format specifiers:
11655
11656 FIELD_WIDTH PRECISION PRINTF
11657 ----------------------------------------
11658 -1 -1 %s
11659 -1 10 %.10s
11660 10 -1 %10s
11661 20 10 %20.10s
11662
11663 MULTIBYTE zero means do not display multibyte chars, > 0 means do
11664 display them, and < 0 means obey the current buffer's value of
11665 enable_multibyte_characters.
11666
11667 Value is the number of glyphs produced. */
11668
11669 static int
11670 display_string (string, lisp_string, face_string, face_string_pos,
11671 start, it, field_width, precision, max_x, multibyte)
11672 unsigned char *string;
11673 Lisp_Object lisp_string;
11674 int start;
11675 struct it *it;
11676 int field_width, precision, max_x;
11677 int multibyte;
11678 {
11679 int hpos_at_start = it->hpos;
11680 int saved_face_id = it->face_id;
11681 struct glyph_row *row = it->glyph_row;
11682
11683 /* Initialize the iterator IT for iteration over STRING beginning
11684 with index START. We assume that IT may be modified here (which
11685 means that display_line has to do something when displaying a
11686 mini-buffer prompt, which it does). */
11687 reseat_to_string (it, string, lisp_string, start,
11688 precision, field_width, multibyte);
11689
11690 /* If displaying STRING, set up the face of the iterator
11691 from LISP_STRING, if that's given. */
11692 if (STRINGP (face_string))
11693 {
11694 int endptr;
11695 struct face *face;
11696
11697 it->face_id
11698 = face_at_string_position (it->w, face_string, face_string_pos,
11699 0, it->region_beg_charpos,
11700 it->region_end_charpos,
11701 &endptr, it->base_face_id);
11702 face = FACE_FROM_ID (it->f, it->face_id);
11703 it->face_box_p = face->box != FACE_NO_BOX;
11704 }
11705
11706 /* Set max_x to the maximum allowed X position. Don't let it go
11707 beyond the right edge of the window. */
11708 if (max_x <= 0)
11709 max_x = it->last_visible_x;
11710 else
11711 max_x = min (max_x, it->last_visible_x);
11712
11713 /* Skip over display elements that are not visible. because IT->w is
11714 hscrolled. */
11715 if (it->current_x < it->first_visible_x)
11716 move_it_in_display_line_to (it, 100000, it->first_visible_x,
11717 MOVE_TO_POS | MOVE_TO_X);
11718
11719 row->ascent = it->max_ascent;
11720 row->height = it->max_ascent + it->max_descent;
11721 row->phys_ascent = it->max_phys_ascent;
11722 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11723
11724 /* This condition is for the case that we are called with current_x
11725 past last_visible_x. */
11726 while (it->current_x < max_x)
11727 {
11728 int x_before, x, n_glyphs_before, i, nglyphs;
11729
11730 /* Get the next display element. */
11731 if (!get_next_display_element (it))
11732 break;
11733
11734 /* Produce glyphs. */
11735 x_before = it->current_x;
11736 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
11737 PRODUCE_GLYPHS (it);
11738
11739 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
11740 i = 0;
11741 x = x_before;
11742 while (i < nglyphs)
11743 {
11744 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11745
11746 if (!it->truncate_lines_p
11747 && x + glyph->pixel_width > max_x)
11748 {
11749 /* End of continued line or max_x reached. */
11750 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
11751 it->current_x = x;
11752 break;
11753 }
11754 else if (x + glyph->pixel_width > it->first_visible_x)
11755 {
11756 /* Glyph is at least partially visible. */
11757 ++it->hpos;
11758 if (x < it->first_visible_x)
11759 it->glyph_row->x = x - it->first_visible_x;
11760 }
11761 else
11762 {
11763 /* Glyph is off the left margin of the display area.
11764 Should not happen. */
11765 abort ();
11766 }
11767
11768 row->ascent = max (row->ascent, it->max_ascent);
11769 row->height = max (row->height, it->max_ascent + it->max_descent);
11770 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11771 row->phys_height = max (row->phys_height,
11772 it->max_phys_ascent + it->max_phys_descent);
11773 x += glyph->pixel_width;
11774 ++i;
11775 }
11776
11777 /* Stop if max_x reached. */
11778 if (i < nglyphs)
11779 break;
11780
11781 /* Stop at line ends. */
11782 if (ITERATOR_AT_END_OF_LINE_P (it))
11783 {
11784 it->continuation_lines_width = 0;
11785 break;
11786 }
11787
11788 set_iterator_to_next (it);
11789
11790 /* Stop if truncating at the right edge. */
11791 if (it->truncate_lines_p
11792 && it->current_x >= it->last_visible_x)
11793 {
11794 /* Add truncation mark, but don't do it if the line is
11795 truncated at a padding space. */
11796 if (IT_CHARPOS (*it) < it->string_nchars)
11797 {
11798 if (!FRAME_WINDOW_P (it->f))
11799 produce_special_glyphs (it, IT_TRUNCATION);
11800 it->glyph_row->truncated_on_right_p = 1;
11801 }
11802 break;
11803 }
11804 }
11805
11806 /* Maybe insert a truncation at the left. */
11807 if (it->first_visible_x
11808 && IT_CHARPOS (*it) > 0)
11809 {
11810 if (!FRAME_WINDOW_P (it->f))
11811 insert_left_trunc_glyphs (it);
11812 it->glyph_row->truncated_on_left_p = 1;
11813 }
11814
11815 it->face_id = saved_face_id;
11816
11817 /* Value is number of columns displayed. */
11818 return it->hpos - hpos_at_start;
11819 }
11820
11821
11822 \f
11823 /* This is like a combination of memq and assq. Return 1 if PROPVAL
11824 appears as an element of LIST or as the car of an element of LIST.
11825 If PROPVAL is a list, compare each element against LIST in that
11826 way, and return 1 if any element of PROPVAL is found in LIST.
11827 Otherwise return 0. This function cannot quit. */
11828
11829 int
11830 invisible_p (propval, list)
11831 register Lisp_Object propval;
11832 Lisp_Object list;
11833 {
11834 register Lisp_Object tail, proptail;
11835 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11836 {
11837 register Lisp_Object tem;
11838 tem = XCONS (tail)->car;
11839 if (EQ (propval, tem))
11840 return 1;
11841 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
11842 return 1;
11843 }
11844 if (CONSP (propval))
11845 for (proptail = propval; CONSP (proptail);
11846 proptail = XCONS (proptail)->cdr)
11847 {
11848 Lisp_Object propelt;
11849 propelt = XCONS (proptail)->car;
11850 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11851 {
11852 register Lisp_Object tem;
11853 tem = XCONS (tail)->car;
11854 if (EQ (propelt, tem))
11855 return 1;
11856 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
11857 return 1;
11858 }
11859 }
11860 return 0;
11861 }
11862
11863
11864 /* Return 1 if PROPVAL appears as the car of an element of LIST and
11865 the cdr of that element is non-nil. If PROPVAL is a list, check
11866 each element of PROPVAL in that way, and the first time some
11867 element is found, return 1 if the cdr of that element is non-nil.
11868 Otherwise return 0. This function cannot quit. */
11869
11870 int
11871 invisible_ellipsis_p (propval, list)
11872 register Lisp_Object propval;
11873 Lisp_Object list;
11874 {
11875 register Lisp_Object tail, proptail;
11876 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11877 {
11878 register Lisp_Object tem;
11879 tem = XCONS (tail)->car;
11880 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
11881 return ! NILP (XCONS (tem)->cdr);
11882 }
11883 if (CONSP (propval))
11884 for (proptail = propval; CONSP (proptail);
11885 proptail = XCONS (proptail)->cdr)
11886 {
11887 Lisp_Object propelt;
11888 propelt = XCONS (proptail)->car;
11889 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11890 {
11891 register Lisp_Object tem;
11892 tem = XCONS (tail)->car;
11893 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
11894 return ! NILP (XCONS (tem)->cdr);
11895 }
11896 }
11897 return 0;
11898 }
11899
11900
11901 \f
11902 /***********************************************************************
11903 Initialization
11904 ***********************************************************************/
11905
11906 void
11907 syms_of_xdisp ()
11908 {
11909 echo_area_message = previous_echo_area_message = Qnil;
11910 staticpro (&echo_area_message);
11911 staticpro (&previous_echo_area_message);
11912
11913 staticpro (&Qinhibit_redisplay);
11914 Qinhibit_redisplay = intern ("inhibit-redisplay");
11915
11916 #if GLYPH_DEBUG
11917 defsubr (&Sdump_glyph_matrix);
11918 defsubr (&Sdump_glyph_row);
11919 defsubr (&Sdump_toolbar_row);
11920 defsubr (&Strace_redisplay_toggle);
11921 #endif
11922
11923 staticpro (&Qmenu_bar_update_hook);
11924 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
11925
11926 staticpro (&Qoverriding_terminal_local_map);
11927 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
11928
11929 staticpro (&Qoverriding_local_map);
11930 Qoverriding_local_map = intern ("overriding-local-map");
11931
11932 staticpro (&Qwindow_scroll_functions);
11933 Qwindow_scroll_functions = intern ("window-scroll-functions");
11934
11935 staticpro (&Qredisplay_end_trigger_functions);
11936 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
11937
11938 staticpro (&Qinhibit_point_motion_hooks);
11939 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
11940
11941 staticpro (&Qdisplay);
11942 Qdisplay = intern ("display");
11943 staticpro (&Qleft_margin);
11944 Qspace_width = intern ("space-width");
11945 staticpro (&Qspace_width);
11946 Qheight = intern ("height");
11947 staticpro (&Qheight);
11948 Qraise = intern ("raise");
11949 staticpro (&Qraise);
11950 Qspace = intern ("space");
11951 staticpro (&Qspace);
11952 Qleft_margin = intern ("left-margin");
11953 staticpro (&Qright_margin);
11954 Qright_margin = intern ("right-margin");
11955 Qalign_to = intern ("align-to");
11956 staticpro (&Qalign_to);
11957 QCalign_to = intern (":align-to");
11958 staticpro (&QCalign_to);
11959 Qwidth = intern ("width");
11960 staticpro (&Qwidth);
11961 Qrelative_width = intern ("relative-width");
11962 staticpro (&Qrelative_width);
11963 QCrelative_width = intern (":relative-width");
11964 staticpro (&QCrelative_width);
11965 QCrelative_height = intern (":relative-height");
11966 staticpro (&QCrelative_height);
11967 QCeval = intern (":eval");
11968 staticpro (&QCeval);
11969 QCwhen = intern (":when");
11970 staticpro (&QCwhen);
11971 Qfontified = intern ("fontified");
11972 staticpro (&Qfontified);
11973 Qfontification_functions = intern ("fontification-functions");
11974 staticpro (&Qfontification_functions);
11975 Qshow_trailing_whitespace = intern ("show-trailing-whitespace");
11976 staticpro (&Qshow_trailing_whitespace);
11977 Qtrailing_whitespace = intern ("trailing-whitespace");
11978 staticpro (&Qtrailing_whitespace);
11979 Qimage = intern ("image");
11980 staticpro (&Qimage);
11981
11982 staticpro (&last_arrow_position);
11983 staticpro (&last_arrow_string);
11984 last_arrow_position = Qnil;
11985 last_arrow_string = Qnil;
11986
11987 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
11988 "Non-nil means don't actually do any redisplay.\n\
11989 This is used for internal purposes.");
11990 Vinhibit_redisplay = Qnil;
11991
11992 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
11993 "String (or mode line construct) included (normally) in `mode-line-format'.");
11994 Vglobal_mode_string = Qnil;
11995
11996 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
11997 "Marker for where to display an arrow on top of the buffer text.\n\
11998 This must be the beginning of a line in order to work.\n\
11999 See also `overlay-arrow-string'.");
12000 Voverlay_arrow_position = Qnil;
12001
12002 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
12003 "String to display as an arrow. See also `overlay-arrow-position'.");
12004 Voverlay_arrow_string = Qnil;
12005
12006 DEFVAR_INT ("scroll-step", &scroll_step,
12007 "*The number of lines to try scrolling a window by when point moves out.\n\
12008 If that fails to bring point back on frame, point is centered instead.\n\
12009 If this is zero, point is always centered after it moves off frame.");
12010
12011 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
12012 "*Scroll up to this many lines, to bring point back on screen.");
12013 scroll_conservatively = 0;
12014
12015 DEFVAR_INT ("scroll-margin", &scroll_margin,
12016 "*Number of lines of margin at the top and bottom of a window.\n\
12017 Recenter the window whenever point gets within this many lines\n\
12018 of the top or bottom of the window.");
12019 scroll_margin = 0;
12020
12021 #if GLYPH_DEBUG
12022 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
12023 #endif
12024
12025 DEFVAR_BOOL ("truncate-partial-width-windows",
12026 &truncate_partial_width_windows,
12027 "*Non-nil means truncate lines in all windows less than full frame wide.");
12028 truncate_partial_width_windows = 1;
12029
12030 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
12031 "*Non-nil means use inverse video for the mode line.");
12032 mode_line_inverse_video = 1;
12033
12034 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
12035 "*Maximum buffer size for which line number should be displayed.\n\
12036 If the buffer is bigger than this, the line number does not appear\n\
12037 in the mode line.");
12038 line_number_display_limit = 1000000;
12039
12040 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
12041 "*Non-nil means highlight region even in nonselected windows.");
12042 highlight_nonselected_windows = 0;
12043
12044 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
12045 "Non-nil if more than one frame is visible on this display.\n\
12046 Minibuffer-only frames don't count, but iconified frames do.\n\
12047 This variable is not guaranteed to be accurate except while processing\n\
12048 `frame-title-format' and `icon-title-format'.");
12049
12050 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
12051 "Template for displaying the title bar of visible frames.\n\
12052 \(Assuming the window manager supports this feature.)\n\
12053 This variable has the same structure as `mode-line-format' (which see),\n\
12054 and is used only on frames for which no explicit name has been set\n\
12055 \(see `modify-frame-parameters').");
12056 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
12057 "Template for displaying the title bar of an iconified frame.\n\
12058 \(Assuming the window manager supports this feature.)\n\
12059 This variable has the same structure as `mode-line-format' (which see),\n\
12060 and is used only on frames for which no explicit name has been set\n\
12061 \(see `modify-frame-parameters').");
12062 Vicon_title_format
12063 = Vframe_title_format
12064 = Fcons (intern ("multiple-frames"),
12065 Fcons (build_string ("%b"),
12066 Fcons (Fcons (build_string (""),
12067 Fcons (intern ("invocation-name"),
12068 Fcons (build_string ("@"),
12069 Fcons (intern ("system-name"),
12070 Qnil)))),
12071 Qnil)));
12072
12073 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
12074 "Maximum number of lines to keep in the message log buffer.\n\
12075 If nil, disable message logging. If t, log messages but don't truncate\n\
12076 the buffer when it becomes large.");
12077 XSETFASTINT (Vmessage_log_max, 50);
12078
12079 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
12080 "Functions called before redisplay, if window sizes have changed.\n\
12081 The value should be a list of functions that take one argument.\n\
12082 Just before redisplay, for each frame, if any of its windows have changed\n\
12083 size since the last redisplay, or have been split or deleted,\n\
12084 all the functions in the list are called, with the frame as argument.");
12085 Vwindow_size_change_functions = Qnil;
12086
12087 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
12088 "List of Functions to call before redisplaying a window with scrolling.\n\
12089 Each function is called with two arguments, the window\n\
12090 and its new display-start position. Note that the value of `window-end'\n\
12091 is not valid when these functions are called.");
12092 Vwindow_scroll_functions = Qnil;
12093
12094 DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p,
12095 "*Non-nil means automatically resize toolbars.\n\
12096 This increases a toolbar's height if not all toolbar items are visible.\n\
12097 It decreases a toolbar's height when it would display blank lines\n\
12098 otherwise.");
12099 auto_resize_toolbars_p = 1;
12100
12101 DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p,
12102 "*Non-nil means raise toolbar buttons when the mouse moves over them.");
12103 auto_raise_toolbar_buttons_p = 1;
12104
12105 DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin,
12106 "*Margin around toolbar buttons in pixels.");
12107 toolbar_button_margin = 1;
12108
12109 DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief,
12110 "Relief thickness of toolbar buttons.");
12111 toolbar_button_relief = 3;
12112
12113 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
12114 "List of functions to call to fontify regions of text.\n\
12115 Each function is called with one argument POS. Functions must\n\
12116 fontify a region starting at POS in the current buffer, and give\n\
12117 fontified regions the property `fontified'.\n\
12118 This variable automatically becomes buffer-local when set.");
12119 Vfontification_functions = Qnil;
12120 Fmake_local_variable (Qfontification_functions);
12121
12122 DEFVAR_BOOL ("unibyte-display-via-language-environment",
12123 &unibyte_display_via_language_environment,
12124 "*Non-nil means display unibyte text according to language environment.\n\
12125 Specifically this means that unibyte non-ASCII characters\n\
12126 are displayed by converting them to the equivalent multibyte characters\n\
12127 according to the current language environment. As a result, they are\n\
12128 displayed according to the current fontset.");
12129 unibyte_display_via_language_environment = 0;
12130 }
12131
12132
12133 /* Initialize this module when Emacs starts. */
12134
12135 void
12136 init_xdisp ()
12137 {
12138 Lisp_Object root_window;
12139 struct window *mini_w;
12140
12141 CHARPOS (this_line_start_pos) = 0;
12142
12143 mini_w = XWINDOW (minibuf_window);
12144 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
12145
12146 echo_area_glyphs = 0;
12147 previous_echo_glyphs = 0;
12148 echo_area_message = previous_echo_area_message = Qnil;
12149
12150 if (!noninteractive)
12151 {
12152 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
12153 int i;
12154
12155 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
12156 set_window_height (root_window,
12157 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
12158 0);
12159 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
12160 set_window_height (minibuf_window, 1, 0);
12161
12162 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
12163 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
12164
12165 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
12166 scratch_glyph_row.glyphs[TEXT_AREA + 1]
12167 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
12168
12169 /* The default ellipsis glyphs `...'. */
12170 for (i = 0; i < 3; ++i)
12171 XSETFASTINT (default_invis_vector[i], '.');
12172 }
12173
12174 #ifdef HAVE_WINDOW_SYSTEM
12175 {
12176 /* Allocate the buffer for frame titles. */
12177 int size = 100;
12178 frame_title_buf = (char *) xmalloc (size);
12179 frame_title_buf_end = frame_title_buf + size;
12180 frame_title_ptr = NULL;
12181 }
12182 #endif /* HAVE_WINDOW_SYSTEM */
12183 }
12184
12185