Remove references to echo_area_glyphs
[bpt/emacs.git] / src / xdisp.c
CommitLineData
a2889657 1/* Display generation from window structure and buffer text.
5f5c8ee5
GM
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99
3 Free Software Foundation, Inc.
a2889657
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
b1d1124b 9the Free Software Foundation; either version 2, or (at your option)
a2889657
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a2889657 21
5f5c8ee5
GM
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. */
a2889657 169
18160b98 170#include <config.h>
a2889657 171#include <stdio.h>
5f5c8ee5
GM
172#ifdef STDC_HEADERS
173#include <stdlib.h>
174#endif
a2889657 175#include "lisp.h"
44fa5b1e 176#include "frame.h"
a2889657
JB
177#include "window.h"
178#include "termchar.h"
179#include "dispextern.h"
180#include "buffer.h"
1c9241f5 181#include "charset.h"
a2889657
JB
182#include "indent.h"
183#include "commands.h"
184#include "macros.h"
185#include "disptab.h"
30c566e4 186#include "termhooks.h"
b0a0fbda 187#include "intervals.h"
fe8b0cf8 188#include "keyboard.h"
1c9241f5
KH
189#include "coding.h"
190#include "process.h"
dfcf069d
AS
191#include "region-cache.h"
192
6d55d620 193#ifdef HAVE_X_WINDOWS
dfcf069d
AS
194#include "xterm.h"
195#endif
a2889657 196
5f5c8ee5
GM
197#define min(a, b) ((a) < (b) ? (a) : (b))
198#define max(a, b) ((a) > (b) ? (a) : (b))
199
200#define INFINITY 10000000
201
8f3343d0 202#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
76412d64 203extern void set_frame_menubar ();
cd6dfed6 204extern int pending_menu_activation;
76412d64
RS
205#endif
206
a2889657
JB
207extern int interrupt_input;
208extern int command_loop_level;
209
b6436d4e
RS
210extern int minibuffer_auto_raise;
211
c4628384
RS
212extern Lisp_Object Qface;
213
399164b4
KH
214extern Lisp_Object Voverriding_local_map;
215extern Lisp_Object Voverriding_local_map_menu_flag;
5f5c8ee5 216extern Lisp_Object Qmenu_item;
399164b4 217
d46fb96a 218Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
75c43375 219Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
e0bfbde6 220Lisp_Object Qredisplay_end_trigger_functions;
2e54982e 221Lisp_Object Qinhibit_point_motion_hooks;
5f5c8ee5
GM
222Lisp_Object QCeval, QCwhen;
223Lisp_Object Qfontified;
224
225/* Functions called to fontify regions of text. */
226
227Lisp_Object Vfontification_functions;
228Lisp_Object Qfontification_functions;
229
230/* Non-zero means draw toolbar buttons raised when the mouse moves
231 over them. */
232
233int auto_raise_toolbar_buttons_p;
234
235/* Margin around toolbar buttons in pixels. */
236
237int toolbar_button_margin;
238
239/* Thickness of shadow to draw around toolbar buttons. */
240
241int 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
246int auto_resize_toolbars_p;
399164b4 247
735c094c
KH
248/* Non-nil means don't actually do any redisplay. */
249
250Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
251
5f5c8ee5
GM
252/* Names of text properties relevant for redisplay. */
253
254Lisp_Object Qdisplay, Qrelative_width, Qwidth, Qalign_to;
255extern Lisp_Object Qface, Qinvisible, Qimage;
256
257/* Symbols used in text property values. */
258
259Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
260Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qheight, Qraise;
261
8f897821 262/* Non-nil means highlight trailing whitespace. */
5f5c8ee5 263
8f897821 264Lisp_Object Vshow_trailing_whitespace;
5f5c8ee5
GM
265
266/* Name of the face used to highlight trailing whitespace. */
267
268Lisp_Object Qtrailing_whitespace;
269
270/* The symbol `image' which is the car of the lists used to represent
271 images in Lisp. */
272
273Lisp_Object Qimage;
274
275/* Non-zero means print newline to stdout before next mini-buffer
276 message. */
a2889657
JB
277
278int noninteractive_need_newline;
279
5f5c8ee5 280/* Non-zero means print newline to message log before next message. */
f88eb0b6 281
3c6595e0 282static int message_log_need_newline;
f88eb0b6 283
5f5c8ee5
GM
284\f
285/* The buffer position of the first character appearing entirely or
286 partially on the line of the selected window which contains the
287 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
288 redisplay optimization in redisplay_internal. */
a2889657 289
5f5c8ee5 290static struct text_pos this_line_start_pos;
a2889657 291
5f5c8ee5
GM
292/* Number of characters past the end of the line above, including the
293 terminating newline. */
294
295static struct text_pos this_line_end_pos;
296
297/* The vertical positions and the height of this line. */
a2889657 298
a2889657 299static int this_line_vpos;
5f5c8ee5
GM
300static int this_line_y;
301static int this_line_pixel_height;
302
303/* X position at which this display line starts. Usually zero;
304 negative if first character is partially visible. */
305
306static int this_line_start_x;
a2889657 307
5f5c8ee5 308/* Buffer that this_line_.* variables are referring to. */
a2889657 309
a2889657
JB
310static struct buffer *this_line_buffer;
311
5f5c8ee5
GM
312/* Nonzero means truncate lines in all windows less wide than the
313 frame. */
a2889657 314
a2889657
JB
315int truncate_partial_width_windows;
316
7bbe686f 317/* A flag to control how to display unibyte 8-bit character. */
5f5c8ee5 318
7bbe686f 319int unibyte_display_via_language_environment;
5f5c8ee5
GM
320
321/* Nonzero means we have more than one non-mini-buffer-only frame.
322 Not guaranteed to be accurate except while parsing
323 frame-title-format. */
7bbe686f 324
d39b6696
KH
325int multiple_frames;
326
a2889657
JB
327Lisp_Object Vglobal_mode_string;
328
329/* Marker for where to display an arrow on top of the buffer text. */
5f5c8ee5 330
a2889657
JB
331Lisp_Object Voverlay_arrow_position;
332
5f5c8ee5
GM
333/* String to display for the arrow. Only used on terminal frames. */
334
a2889657
JB
335Lisp_Object Voverlay_arrow_string;
336
5f5c8ee5
GM
337/* Values of those variables at last redisplay. However, if
338 Voverlay_arrow_position is a marker, last_arrow_position is its
339 numerical position. */
340
d45de95b
RS
341static Lisp_Object last_arrow_position, last_arrow_string;
342
5f5c8ee5
GM
343/* Like mode-line-format, but for the title bar on a visible frame. */
344
d39b6696
KH
345Lisp_Object Vframe_title_format;
346
5f5c8ee5
GM
347/* Like mode-line-format, but for the title bar on an iconified frame. */
348
d39b6696
KH
349Lisp_Object Vicon_title_format;
350
08b610e4
RS
351/* List of functions to call when a window's size changes. These
352 functions get one arg, a frame on which one or more windows' sizes
353 have changed. */
5f5c8ee5 354
08b610e4
RS
355static Lisp_Object Vwindow_size_change_functions;
356
cf074754
RS
357Lisp_Object Qmenu_bar_update_hook;
358
a2889657 359/* Nonzero if overlay arrow has been displayed once in this window. */
a2889657 360
5f5c8ee5 361static int overlay_arrow_seen;
ca26e1c8 362
fba9ce76 363/* Nonzero means highlight the region even in nonselected windows. */
fba9ce76 364
5f5c8ee5
GM
365int highlight_nonselected_windows;
366
367/* If cursor motion alone moves point off frame, try scrolling this
368 many lines up or down if that will bring it back. */
369
14510fee 370static int scroll_step;
a2889657 371
5f5c8ee5
GM
372/* Non-0 means scroll just far enough to bring point back on the
373 screen, when appropriate. */
374
0789adb2
RS
375static int scroll_conservatively;
376
5f5c8ee5
GM
377/* Recenter the window whenever point gets within this many lines of
378 the top or bottom of the window. This value is translated into a
379 pixel value by multiplying it with CANON_Y_UNIT, which means that
380 there is really a fixed pixel height scroll margin. */
381
9afd2168
RS
382int scroll_margin;
383
5f5c8ee5
GM
384/* Number of characters of overlap to show, when scrolling a one-line
385 window such as a minibuffer. */
386
010494d0
KH
387static int minibuffer_scroll_overlap;
388
5f5c8ee5
GM
389/* Number of windows showing the buffer of the selected window (or
390 another buffer with the same base buffer). keyboard.c refers to
391 this. */
a2889657 392
a2889657
JB
393int buffer_shared;
394
5f5c8ee5 395/* Vector containing glyphs for an ellipsis `...'. */
a2889657 396
5f5c8ee5 397static Lisp_Object default_invis_vector[3];
a2889657 398
5f5c8ee5 399/* Nonzero means display mode line highlighted. */
a2889657 400
a2889657
JB
401int mode_line_inverse_video;
402
5f5c8ee5
GM
403/* Prompt to display in front of the mini-buffer contents. */
404
8c5b6a0a 405Lisp_Object minibuf_prompt;
a2889657 406
5f5c8ee5
GM
407/* Width of current mini-buffer prompt. Only set after display_line
408 of the line that contains the prompt. */
409
a2889657 410int minibuf_prompt_width;
5f5c8ee5
GM
411int minibuf_prompt_pixel_width;
412
413/* Message to display instead of mini-buffer contents. This is what
414 the functions error and message make, and command echoing uses it
415 as well. It overrides the minibuf_prompt as well as the buffer. */
a2889657 416
a2889657
JB
417char *echo_area_glyphs;
418
5f5c8ee5
GM
419/* A Lisp string to display instead of mini-buffer contents, analogous
420 to echo_area_glyphs. If this is a string, display that string.
421 Otherwise, if echo_area_glyphs is non-null, display that. */
422
423Lisp_Object echo_area_message;
424
425/* This is the length of the message in echo_area_glyphs or
426 echo_area_message. */
427
90adcf20
RS
428int echo_area_glyphs_length;
429
5f5c8ee5
GM
430/* Value of echo_area_glyphs when it was last acted on. If this is
431 nonzero, there is a message on the frame in the mini-buffer and it
432 should be erased as soon as it is no longer requested to appear. */
433
434char *previous_echo_glyphs;
435Lisp_Object previous_echo_area_message;
436static int previous_echo_glyphs_length;
437
438/* This is the window where the echo area message was displayed. It
439 is always a mini-buffer window, but it may not be the same window
440 currently active as a mini-buffer. */
441
73af359d
RS
442Lisp_Object echo_area_window;
443
a3788d53
RS
444/* Nonzero means multibyte characters were enabled when the echo area
445 message was specified. */
5f5c8ee5 446
a3788d53
RS
447int message_enable_multibyte;
448
5f5c8ee5
GM
449/* True if we should redraw the mode lines on the next redisplay. */
450
a2889657
JB
451int update_mode_lines;
452
5f5c8ee5
GM
453/* Smallest number of characters before the gap at any time since last
454 redisplay that finished. Valid for current buffer when
455 try_window_id can be called. */
456
a2889657
JB
457int beg_unchanged;
458
5f5c8ee5
GM
459/* Smallest number of characters after the gap at any time since last
460 redisplay that finished. Valid for current buffer when
461 try_window_id can be called. */
462
a2889657
JB
463int end_unchanged;
464
5f5c8ee5
GM
465/* MODIFF as of last redisplay that finished; if it matches MODIFF,
466 and overlay_unchanged_modified matches OVERLAY_MODIFF, that means
467 beg_unchanged and end_unchanged contain no useful information. */
468
a2889657
JB
469int unchanged_modified;
470
8850a573 471/* OVERLAY_MODIFF as of last redisplay that finished. */
5f5c8ee5 472
8850a573
RS
473int overlay_unchanged_modified;
474
5f5c8ee5
GM
475/* Nonzero if window sizes or contents have changed since last
476 redisplay that finished */
477
a2889657
JB
478int windows_or_buffers_changed;
479
5f5c8ee5
GM
480/* Nonzero after display_mode_line if %l was used and it displayed a
481 line number. */
482
aa6d10fa
RS
483int line_number_displayed;
484
485/* Maximum buffer size for which to display line numbers. */
5f5c8ee5 486
14510fee 487static int line_number_display_limit;
5992c4f7 488
5d121aec
KH
489/* line width to consider when repostioning for line number display */
490
491static int line_number_display_limit_width;
492
5f5c8ee5
GM
493/* Number of lines to keep in the message log buffer. t means
494 infinite. nil means don't log at all. */
495
5992c4f7 496Lisp_Object Vmessage_log_max;
d45de95b 497
5f5c8ee5
GM
498/* A scratch glyph row with contents used for generating truncation
499 glyphs. Also used in direct_output_for_insert. */
12adba34 500
5f5c8ee5
GM
501#define MAX_SCRATCH_GLYPHS 100
502struct glyph_row scratch_glyph_row;
503static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
1adc55de 504
5f5c8ee5
GM
505/* Ascent and height of the last line processed by move_it_to. */
506
507static int last_max_ascent, last_height;
508
509/* The maximum distance to look ahead for text properties. Values
510 that are too small let us call compute_char_face and similar
511 functions too often which is expensive. Values that are too large
512 let us call compute_char_face and alike too often because we
513 might not be interested in text properties that far away. */
514
515#define TEXT_PROP_DISTANCE_LIMIT 100
516
517/* Non-zero means print traces of redisplay if compiled with
518 GLYPH_DEBUG != 0. */
519
520#if GLYPH_DEBUG
521int trace_redisplay_p;
522#endif
523
524/* Value returned from text property handlers (see below). */
525
526enum prop_handled
3c6595e0 527{
5f5c8ee5
GM
528 HANDLED_NORMALLY,
529 HANDLED_RECOMPUTE_PROPS,
530 HANDLED_OVERLAY_STRING_CONSUMED,
531 HANDLED_RETURN
532};
3c6595e0 533
5f5c8ee5
GM
534/* A description of text properties that redisplay is interested
535 in. */
3c6595e0 536
5f5c8ee5
GM
537struct props
538{
539 /* The name of the property. */
540 Lisp_Object *name;
90adcf20 541
5f5c8ee5
GM
542 /* A unique index for the property. */
543 enum prop_idx idx;
544
545 /* A handler function called to set up iterator IT from the property
546 at IT's current position. Value is used to steer handle_stop. */
547 enum prop_handled (*handler) P_ ((struct it *it));
548};
549
550static enum prop_handled handle_face_prop P_ ((struct it *));
551static enum prop_handled handle_invisible_prop P_ ((struct it *));
552static enum prop_handled handle_display_prop P_ ((struct it *));
553static enum prop_handled handle_overlay_change P_ ((struct it *));
554static enum prop_handled handle_fontified_prop P_ ((struct it *));
555
556/* Properties handled by iterators. */
557
558static struct props it_props[] =
5992c4f7 559{
5f5c8ee5
GM
560 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
561 /* Handle `face' before `display' because some sub-properties of
562 `display' need to know the face. */
563 {&Qface, FACE_PROP_IDX, handle_face_prop},
564 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
565 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
566 {NULL, 0, NULL}
567};
5992c4f7 568
5f5c8ee5
GM
569/* Value is the position described by X. If X is a marker, value is
570 the marker_position of X. Otherwise, value is X. */
12adba34 571
5f5c8ee5 572#define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
12adba34 573
5f5c8ee5 574/* Enumeration returned by some move_it_.* functions internally. */
12adba34 575
5f5c8ee5
GM
576enum move_it_result
577{
578 /* Not used. Undefined value. */
579 MOVE_UNDEFINED,
bab29e15 580
5f5c8ee5
GM
581 /* Move ended at the requested buffer position or ZV. */
582 MOVE_POS_MATCH_OR_ZV,
bab29e15 583
5f5c8ee5
GM
584 /* Move ended at the requested X pixel position. */
585 MOVE_X_REACHED,
12adba34 586
5f5c8ee5
GM
587 /* Move within a line ended at the end of a line that must be
588 continued. */
589 MOVE_LINE_CONTINUED,
590
591 /* Move within a line ended at the end of a line that would
592 be displayed truncated. */
593 MOVE_LINE_TRUNCATED,
ff6c30e5 594
5f5c8ee5
GM
595 /* Move within a line ended at a line end. */
596 MOVE_NEWLINE_OR_CR
597};
12adba34 598
ff6c30e5 599
5f5c8ee5
GM
600\f
601/* Function prototypes. */
602
28514cd9 603static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
4fdb80f2 604static int string_char_and_length P_ ((unsigned char *, int, int *));
5f5c8ee5
GM
605static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
606 struct text_pos));
607static int compute_window_start_on_continuation_line P_ ((struct window *));
608static Lisp_Object eval_handler P_ ((Lisp_Object));
609static Lisp_Object eval_form P_ ((Lisp_Object));
610static void insert_left_trunc_glyphs P_ ((struct it *));
611static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
612static void extend_face_to_end_of_line P_ ((struct it *));
613static void append_space P_ ((struct it *, int));
614static void make_cursor_line_fully_visible P_ ((struct window *));
615static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
616static int trailing_whitespace_p P_ ((int));
617static int message_log_check_duplicate P_ ((int, int, int, int));
618int invisible_p P_ ((Lisp_Object, Lisp_Object));
619int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
620static void push_it P_ ((struct it *));
621static void pop_it P_ ((struct it *));
622static void sync_frame_with_window_matrix_rows P_ ((struct window *));
623static void redisplay_internal P_ ((int));
624static void echo_area_display P_ ((int));
625static void redisplay_windows P_ ((Lisp_Object));
626static void redisplay_window P_ ((Lisp_Object, int));
627static void update_menu_bar P_ ((struct frame *, int));
628static int try_window_reusing_current_matrix P_ ((struct window *));
629static int try_window_id P_ ((struct window *));
630static int display_line P_ ((struct it *));
631static void display_mode_lines P_ ((struct window *));
632static void display_mode_line P_ ((struct window *, enum face_id,
633 Lisp_Object));
634static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
635static char *decode_mode_spec P_ ((struct window *, char, int, int));
636static void display_menu_bar P_ ((struct window *));
637static int display_count_lines P_ ((int, int, int, int, int *));
638static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
639 int, int, struct it *, int, int, int, int));
640static void compute_line_metrics P_ ((struct it *));
641static void run_redisplay_end_trigger_hook P_ ((struct it *));
642static int get_overlay_strings P_ ((struct it *));
643static void next_overlay_string P_ ((struct it *));
644void set_iterator_to_next P_ ((struct it *));
645static void reseat P_ ((struct it *, struct text_pos, int));
646static void reseat_1 P_ ((struct it *, struct text_pos, int));
647static void back_to_previous_visible_line_start P_ ((struct it *));
648static void reseat_at_previous_visible_line_start P_ ((struct it *));
312246d1 649static void reseat_at_next_visible_line_start P_ ((struct it *, int));
5f5c8ee5
GM
650static int next_element_from_display_vector P_ ((struct it *));
651static int next_element_from_string P_ ((struct it *));
652static int next_element_from_c_string P_ ((struct it *));
653static int next_element_from_buffer P_ ((struct it *));
654static int next_element_from_image P_ ((struct it *));
655static int next_element_from_stretch P_ ((struct it *));
656static void load_overlay_strings P_ ((struct it *));
657static void init_from_display_pos P_ ((struct it *, struct window *,
658 struct display_pos *));
659static void reseat_to_string P_ ((struct it *, unsigned char *,
660 Lisp_Object, int, int, int, int));
661static int charset_at_position P_ ((struct text_pos));
662static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
663 int, int, int));
664void move_it_vertically_backward P_ ((struct it *, int));
665static void init_to_row_start P_ ((struct it *, struct window *,
666 struct glyph_row *));
667static void init_to_row_end P_ ((struct it *, struct window *,
668 struct glyph_row *));
669static void back_to_previous_line_start P_ ((struct it *));
670static void forward_to_next_line_start P_ ((struct it *));
671static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
672 Lisp_Object, int));
673static struct text_pos string_pos P_ ((int, Lisp_Object));
674static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
675static int number_of_chars P_ ((unsigned char *, int));
676static void compute_stop_pos P_ ((struct it *));
677static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
678 Lisp_Object));
679static int face_before_or_after_it_pos P_ ((struct it *, int));
680static int next_overlay_change P_ ((int));
681static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
682 Lisp_Object, struct text_pos *));
683
684#define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
685#define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
ff6c30e5 686
5f5c8ee5 687#ifdef HAVE_WINDOW_SYSTEM
12adba34 688
5f5c8ee5
GM
689static void update_toolbar P_ ((struct frame *, int));
690static void build_desired_toolbar_string P_ ((struct frame *f));
691static int redisplay_toolbar P_ ((struct frame *));
692static void display_toolbar_line P_ ((struct it *));
12adba34 693
5f5c8ee5 694#endif /* HAVE_WINDOW_SYSTEM */
12adba34 695
5f5c8ee5
GM
696\f
697/***********************************************************************
698 Window display dimensions
699 ***********************************************************************/
12adba34 700
5f5c8ee5
GM
701/* Return the window-relative maximum y + 1 for glyph rows displaying
702 text in window W. This is the height of W minus the height of a
703 mode line, if any. */
704
705INLINE int
706window_text_bottom_y (w)
707 struct window *w;
708{
709 struct frame *f = XFRAME (w->frame);
710 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
711
712 if (WINDOW_WANTS_MODELINE_P (w))
713 height -= CURRENT_MODE_LINE_HEIGHT (w);
714 return height;
f88eb0b6
KH
715}
716
f82aff7c 717
5f5c8ee5
GM
718/* Return the pixel width of display area AREA of window W. AREA < 0
719 means return the total width of W, not including bitmap areas to
720 the left and right of the window. */
ff6c30e5 721
5f5c8ee5
GM
722INLINE int
723window_box_width (w, area)
724 struct window *w;
725 int area;
726{
727 struct frame *f = XFRAME (w->frame);
728 int width = XFASTINT (w->width);
729
730 if (!w->pseudo_window_p)
ff6c30e5 731 {
5f5c8ee5
GM
732 width -= FRAME_SCROLL_BAR_WIDTH (f) + 2 * FRAME_FLAGS_AREA_COLS (f);
733
734 if (area == TEXT_AREA)
735 {
736 if (INTEGERP (w->left_margin_width))
737 width -= XFASTINT (w->left_margin_width);
738 if (INTEGERP (w->right_margin_width))
739 width -= XFASTINT (w->right_margin_width);
740 }
741 else if (area == LEFT_MARGIN_AREA)
742 width = (INTEGERP (w->left_margin_width)
743 ? XFASTINT (w->left_margin_width) : 0);
744 else if (area == RIGHT_MARGIN_AREA)
745 width = (INTEGERP (w->right_margin_width)
746 ? XFASTINT (w->right_margin_width) : 0);
ff6c30e5 747 }
5f5c8ee5
GM
748
749 return width * CANON_X_UNIT (f);
ff6c30e5 750}
1adc55de 751
1adc55de 752
5f5c8ee5
GM
753/* Return the pixel height of the display area of window W, not
754 including mode lines of W, if any.. */
f88eb0b6 755
5f5c8ee5
GM
756INLINE int
757window_box_height (w)
758 struct window *w;
f88eb0b6 759{
5f5c8ee5
GM
760 struct frame *f = XFRAME (w->frame);
761 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
762
763 if (WINDOW_WANTS_MODELINE_P (w))
764 height -= CURRENT_MODE_LINE_HEIGHT (w);
765
766 if (WINDOW_WANTS_TOP_LINE_P (w))
767 height -= CURRENT_TOP_LINE_HEIGHT (w);
768
769 return height;
5992c4f7
KH
770}
771
772
5f5c8ee5
GM
773/* Return the frame-relative coordinate of the left edge of display
774 area AREA of window W. AREA < 0 means return the left edge of the
775 whole window, to the right of any bitmap area at the left side of
776 W. */
5992c4f7 777
5f5c8ee5
GM
778INLINE int
779window_box_left (w, area)
780 struct window *w;
781 int area;
90adcf20 782{
5f5c8ee5
GM
783 struct frame *f = XFRAME (w->frame);
784 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
a3788d53 785
5f5c8ee5 786 if (!w->pseudo_window_p)
90adcf20 787 {
5f5c8ee5
GM
788 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
789 + FRAME_FLAGS_AREA_WIDTH (f));
790
791 if (area == TEXT_AREA)
792 x += window_box_width (w, LEFT_MARGIN_AREA);
793 else if (area == RIGHT_MARGIN_AREA)
794 x += (window_box_width (w, LEFT_MARGIN_AREA)
795 + window_box_width (w, TEXT_AREA));
90adcf20 796 }
73af359d 797
5f5c8ee5
GM
798 return x;
799}
90adcf20 800
b6436d4e 801
5f5c8ee5
GM
802/* Return the frame-relative coordinate of the right edge of display
803 area AREA of window W. AREA < 0 means return the left edge of the
804 whole window, to the left of any bitmap area at the right side of
805 W. */
ded34426 806
5f5c8ee5
GM
807INLINE int
808window_box_right (w, area)
809 struct window *w;
810 int area;
811{
812 return window_box_left (w, area) + window_box_width (w, area);
813}
814
815
816/* Get the bounding box of the display area AREA of window W, without
817 mode lines, in frame-relative coordinates. AREA < 0 means the
818 whole window, not including bitmap areas to the left and right of
819 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
820 coordinates of the upper-left corner of the box. Return in
821 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
822
823INLINE void
824window_box (w, area, box_x, box_y, box_width, box_height)
825 struct window *w;
826 int area;
827 int *box_x, *box_y, *box_width, *box_height;
828{
829 struct frame *f = XFRAME (w->frame);
830
831 *box_width = window_box_width (w, area);
832 *box_height = window_box_height (w);
833 *box_x = window_box_left (w, area);
834 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
835 + XFASTINT (w->top) * CANON_Y_UNIT (f));
836 if (WINDOW_WANTS_TOP_LINE_P (w))
837 *box_y += CURRENT_TOP_LINE_HEIGHT (w);
ded34426 838}
1adc55de 839
1adc55de 840
5f5c8ee5
GM
841/* Get the bounding box of the display area AREA of window W, without
842 mode lines. AREA < 0 means the whole window, not including bitmap
843 areas to the left and right of the window. Return in *TOP_LEFT_X
844 and TOP_LEFT_Y the frame-relative pixel coordinates of the
845 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
846 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
847 box. */
ded34426 848
5f5c8ee5
GM
849INLINE void
850window_box_edges (w, area, top_left_x, top_left_y,
851 bottom_right_x, bottom_right_y)
852 struct window *w;
853 int area;
854 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
48ae5f0a 855{
5f5c8ee5
GM
856 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
857 bottom_right_y);
858 *bottom_right_x += *top_left_x;
859 *bottom_right_y += *top_left_y;
48ae5f0a
KH
860}
861
5f5c8ee5
GM
862
863\f
864/***********************************************************************
865 Utilities
866 ***********************************************************************/
867
4fdb80f2
GM
868/* Return the next character from STR which is MAXLEN bytes long.
869 Return in *LEN the length of the character. This is like
870 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
871 we find one, we return a `?', but with the length of the illegal
872 character. */
873
874static INLINE int
7a5b8a93 875string_char_and_length (str, maxlen, len)
4fdb80f2 876 unsigned char *str;
7a5b8a93 877 int maxlen, *len;
4fdb80f2
GM
878{
879 int c;
880
881 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
882 if (!CHAR_VALID_P (c, 1))
883 /* We may not change the length here because other places in Emacs
884 don't use this function, i.e. they silently accept illegal
885 characters. */
886 c = '?';
887
888 return c;
889}
890
891
892
5f5c8ee5
GM
893/* Given a position POS containing a valid character and byte position
894 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
895
896static struct text_pos
897string_pos_nchars_ahead (pos, string, nchars)
898 struct text_pos pos;
899 Lisp_Object string;
900 int nchars;
0b1005ef 901{
5f5c8ee5
GM
902 xassert (STRINGP (string) && nchars >= 0);
903
904 if (STRING_MULTIBYTE (string))
905 {
906 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
907 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
908 int len;
909
910 while (nchars--)
911 {
4fdb80f2 912 string_char_and_length (p, rest, &len);
5f5c8ee5
GM
913 p += len, rest -= len;
914 xassert (rest >= 0);
915 CHARPOS (pos) += 1;
916 BYTEPOS (pos) += len;
917 }
918 }
919 else
920 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
921
922 return pos;
0a9dc68b
RS
923}
924
0a9dc68b 925
5f5c8ee5
GM
926/* Value is the text position, i.e. character and byte position,
927 for character position CHARPOS in STRING. */
928
929static INLINE struct text_pos
930string_pos (charpos, string)
931 int charpos;
0a9dc68b 932 Lisp_Object string;
0a9dc68b 933{
5f5c8ee5
GM
934 struct text_pos pos;
935 xassert (STRINGP (string));
936 xassert (charpos >= 0);
937 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
938 return pos;
939}
940
941
942/* Value is a text position, i.e. character and byte position, for
943 character position CHARPOS in C string S. MULTIBYTE_P non-zero
944 means recognize multibyte characters. */
945
946static struct text_pos
947c_string_pos (charpos, s, multibyte_p)
948 int charpos;
949 unsigned char *s;
950 int multibyte_p;
951{
952 struct text_pos pos;
953
954 xassert (s != NULL);
955 xassert (charpos >= 0);
956
957 if (multibyte_p)
0a9dc68b 958 {
5f5c8ee5
GM
959 int rest = strlen (s), len;
960
961 SET_TEXT_POS (pos, 0, 0);
962 while (charpos--)
0a9dc68b 963 {
4fdb80f2 964 string_char_and_length (s, rest, &len);
5f5c8ee5
GM
965 s += len, rest -= len;
966 xassert (rest >= 0);
967 CHARPOS (pos) += 1;
968 BYTEPOS (pos) += len;
0a9dc68b
RS
969 }
970 }
5f5c8ee5
GM
971 else
972 SET_TEXT_POS (pos, charpos, charpos);
0a9dc68b 973
5f5c8ee5
GM
974 return pos;
975}
0a9dc68b 976
0a9dc68b 977
5f5c8ee5
GM
978/* Value is the number of characters in C string S. MULTIBYTE_P
979 non-zero means recognize multibyte characters. */
0a9dc68b 980
5f5c8ee5
GM
981static int
982number_of_chars (s, multibyte_p)
983 unsigned char *s;
984 int multibyte_p;
985{
986 int nchars;
987
988 if (multibyte_p)
989 {
990 int rest = strlen (s), len;
991 unsigned char *p = (unsigned char *) s;
0a9dc68b 992
5f5c8ee5
GM
993 for (nchars = 0; rest > 0; ++nchars)
994 {
4fdb80f2 995 string_char_and_length (p, rest, &len);
5f5c8ee5 996 rest -= len, p += len;
0a9dc68b
RS
997 }
998 }
5f5c8ee5
GM
999 else
1000 nchars = strlen (s);
1001
1002 return nchars;
0b1005ef
KH
1003}
1004
5f5c8ee5
GM
1005
1006/* Compute byte position NEWPOS->bytepos corresponding to
1007 NEWPOS->charpos. POS is a known position in string STRING.
1008 NEWPOS->charpos must be >= POS.charpos. */
76412d64 1009
5f5c8ee5
GM
1010static void
1011compute_string_pos (newpos, pos, string)
1012 struct text_pos *newpos, pos;
1013 Lisp_Object string;
76412d64 1014{
5f5c8ee5
GM
1015 xassert (STRINGP (string));
1016 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1017
1018 if (STRING_MULTIBYTE (string))
1019 *newpos = string_pos_nchars_ahead (pos, CHARPOS (*newpos) - CHARPOS (pos),
1020 string);
1021 else
1022 BYTEPOS (*newpos) = CHARPOS (*newpos);
76412d64
RS
1023}
1024
9c74a0dd 1025
5f5c8ee5
GM
1026/* Return the charset of the character at position POS in
1027 current_buffer. */
1adc55de 1028
5f5c8ee5
GM
1029static int
1030charset_at_position (pos)
1031 struct text_pos pos;
a2889657 1032{
5f5c8ee5
GM
1033 int c, multibyte_p;
1034 unsigned char *p = BYTE_POS_ADDR (BYTEPOS (pos));
1035
1036 multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1037 if (multibyte_p)
a2889657 1038 {
5f5c8ee5
GM
1039 int maxlen = ((BYTEPOS (pos) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
1040 - BYTEPOS (pos));
1041 int len;
4fdb80f2 1042 c = string_char_and_length (p, maxlen, &len);
a2889657 1043 }
5f5c8ee5
GM
1044 else
1045 c = *p;
1046
1047 return CHAR_CHARSET (c);
1048}
1049
1050
1051\f
1052/***********************************************************************
1053 Lisp form evaluation
1054 ***********************************************************************/
1055
1056/* Error handler for eval_form. */
1057
1058static Lisp_Object
1059eval_handler (arg)
1060 Lisp_Object arg;
1061{
1062 return Qnil;
1063}
1064
1065
1066/* Evaluate SEXPR and return the result, or nil if something went
1067 wrong. */
1068
1069static Lisp_Object
1070eval_form (sexpr)
1071 Lisp_Object sexpr;
1072{
1073 int count = specpdl_ptr - specpdl;
1074 Lisp_Object val;
1075 specbind (Qinhibit_redisplay, Qt);
1076 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1077 return unbind_to (count, val);
1078}
1079
1080
1081\f
1082/***********************************************************************
1083 Debugging
1084 ***********************************************************************/
1085
1086#if 0
1087
1088/* Define CHECK_IT to perform sanity checks on iterators.
1089 This is for debugging. It is too slow to do unconditionally. */
1090
1091static void
1092check_it (it)
1093 struct it *it;
1094{
1095 if (it->method == next_element_from_string)
a2889657 1096 {
5f5c8ee5
GM
1097 xassert (STRINGP (it->string));
1098 xassert (IT_STRING_CHARPOS (*it) >= 0);
1099 }
1100 else if (it->method == next_element_from_buffer)
1101 {
1102 /* Check that character and byte positions agree. */
1103 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1104 }
73af359d 1105
5f5c8ee5
GM
1106 if (it->dpvec)
1107 xassert (it->current.dpvec_index >= 0);
1108 else
1109 xassert (it->current.dpvec_index < 0);
1110}
1f40cad2 1111
5f5c8ee5
GM
1112#define CHECK_IT(IT) check_it ((IT))
1113
1114#else /* not 0 */
1115
1116#define CHECK_IT(IT) (void) 0
1117
1118#endif /* not 0 */
1119
1120
1121#if GLYPH_DEBUG
1122
1123/* Check that the window end of window W is what we expect it
1124 to be---the last row in the current matrix displaying text. */
1125
1126static void
1127check_window_end (w)
1128 struct window *w;
1129{
1130 if (!MINI_WINDOW_P (w)
1131 && !NILP (w->window_end_valid))
1132 {
1133 struct glyph_row *row;
1134 xassert ((row = MATRIX_ROW (w->current_matrix,
1135 XFASTINT (w->window_end_vpos)),
1136 !row->enabled_p
1137 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1138 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1139 }
1140}
1141
1142#define CHECK_WINDOW_END(W) check_window_end ((W))
1143
1144#else /* not GLYPH_DEBUG */
1145
1146#define CHECK_WINDOW_END(W) (void) 0
1147
1148#endif /* not GLYPH_DEBUG */
1149
1150
1151\f
1152/***********************************************************************
1153 Iterator initialization
1154 ***********************************************************************/
1155
1156/* Initialize IT for displaying current_buffer in window W, starting
1157 at character position CHARPOS. CHARPOS < 0 means that no buffer
1158 position is specified which is useful when the iterator is assigned
1159 a position later. BYTEPOS is the byte position corresponding to
1160 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1161
1162 If ROW is not null, calls to produce_glyphs with IT as parameter
1163 will produce glyphs in that row.
1164
1165 BASE_FACE_ID is the id of a base face to use. It must be one of
1166 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1167 TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
1168 displaying the toolbar.
1169
1170 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1171 TOP_LINE_FACE_ID, the iterator will be initialized to use the
1172 corresponding mode line glyph row of the desired matrix of W. */
1173
1174void
1175init_iterator (it, w, charpos, bytepos, row, base_face_id)
1176 struct it *it;
1177 struct window *w;
1178 int charpos, bytepos;
1179 struct glyph_row *row;
1180 enum face_id base_face_id;
1181{
1182 int highlight_region_p;
1183 Lisp_Object value;
1184
1185 /* Some precondition checks. */
1186 xassert (w != NULL && it != NULL);
1187 xassert (charpos < 0 || current_buffer == XBUFFER (w->buffer));
1188 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1189
1190 /* If face attributes have been changed since the last redisplay,
1191 free realized faces now because they depend on face definitions
1192 that might have changed. */
1193 if (face_change_count)
1194 {
1195 face_change_count = 0;
1196 free_all_realized_faces (Qnil);
1197 }
1198
1199 /* Use one of the mode line rows of W's desired matrix if
1200 appropriate. */
1201 if (row == NULL)
1202 {
1203 if (base_face_id == MODE_LINE_FACE_ID)
1204 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1205 else if (base_face_id == TOP_LINE_FACE_ID)
1206 row = MATRIX_TOP_LINE_ROW (w->desired_matrix);
1207 }
1208
1209 /* Clear IT. */
1210 bzero (it, sizeof *it);
1211 it->current.overlay_string_index = -1;
1212 it->current.dpvec_index = -1;
1213 it->charset = CHARSET_ASCII;
1214 it->base_face_id = base_face_id;
1215
1216 /* The window in which we iterate over current_buffer: */
1217 XSETWINDOW (it->window, w);
1218 it->w = w;
1219 it->f = XFRAME (w->frame);
1220
1221 /* If realized faces have been removed, e.g. because of face
1222 attribute changes of named faces, recompute them. */
1223 if (FRAME_FACE_CACHE (it->f)->used == 0)
1224 recompute_basic_faces (it->f);
1225
5f5c8ee5
GM
1226 /* Current value of the `space-width', and 'height' properties. */
1227 it->space_width = Qnil;
1228 it->font_height = Qnil;
1229
1230 /* Are control characters displayed as `^C'? */
1231 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1232
1233 /* -1 means everything between a CR and the following line end
1234 is invisible. >0 means lines indented more than this value are
1235 invisible. */
1236 it->selective = (INTEGERP (current_buffer->selective_display)
1237 ? XFASTINT (current_buffer->selective_display)
1238 : (!NILP (current_buffer->selective_display)
1239 ? -1 : 0));
1240 it->selective_display_ellipsis_p
1241 = !NILP (current_buffer->selective_display_ellipses);
1242
1243 /* Display table to use. */
1244 it->dp = window_display_table (w);
1245
1246 /* Are multibyte characters enabled in current_buffer? */
1247 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1248
1249 /* Non-zero if we should highlight the region. */
1250 highlight_region_p
1251 = (!NILP (Vtransient_mark_mode)
1252 && !NILP (current_buffer->mark_active)
1253 && XMARKER (current_buffer->mark)->buffer != 0);
1254
1255 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1256 start and end of a visible region in window IT->w. Set both to
1257 -1 to indicate no region. */
1258 if (highlight_region_p
1259 /* Maybe highlight only in selected window. */
1260 && (/* Either show region everywhere. */
1261 highlight_nonselected_windows
1262 /* Or show region in the selected window. */
1263 || w == XWINDOW (selected_window)
1264 /* Or show the region if we are in the mini-buffer and W is
1265 the window the mini-buffer refers to. */
1266 || (MINI_WINDOW_P (XWINDOW (selected_window))
1267 && w == XWINDOW (Vminibuf_scroll_window))))
1268 {
1269 int charpos = marker_position (current_buffer->mark);
1270 it->region_beg_charpos = min (PT, charpos);
1271 it->region_end_charpos = max (PT, charpos);
1272 }
1273 else
1274 it->region_beg_charpos = it->region_end_charpos = -1;
1275
1276 /* Get the position at which the redisplay_end_trigger hook should
1277 be run, if it is to be run at all. */
1278 if (MARKERP (w->redisplay_end_trigger)
1279 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1280 it->redisplay_end_trigger_charpos
1281 = marker_position (w->redisplay_end_trigger);
1282 else if (INTEGERP (w->redisplay_end_trigger))
1283 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1284
1285 /* Correct bogus values of tab_width. */
1286 it->tab_width = XINT (current_buffer->tab_width);
1287 if (it->tab_width <= 0 || it->tab_width > 1000)
1288 it->tab_width = 8;
1289
1290 /* Are lines in the display truncated? */
1291 it->truncate_lines_p
1292 = (base_face_id != DEFAULT_FACE_ID
1293 || XINT (it->w->hscroll)
1294 || (truncate_partial_width_windows
1295 && !WINDOW_FULL_WIDTH_P (it->w))
1296 || !NILP (current_buffer->truncate_lines));
1297
1298 /* Get dimensions of truncation and continuation glyphs. These are
1299 displayed as bitmaps under X, so we don't need them for such
1300 frames. */
1301 if (!FRAME_WINDOW_P (it->f))
1302 {
1303 if (it->truncate_lines_p)
1304 {
1305 /* We will need the truncation glyph. */
1306 xassert (it->glyph_row == NULL);
1307 produce_special_glyphs (it, IT_TRUNCATION);
1308 it->truncation_pixel_width = it->pixel_width;
1309 }
1310 else
1311 {
1312 /* We will need the continuation glyph. */
1313 xassert (it->glyph_row == NULL);
1314 produce_special_glyphs (it, IT_CONTINUATION);
1315 it->continuation_pixel_width = it->pixel_width;
1316 }
1317
1318 /* Reset these values to zero becaue the produce_special_glyphs
1319 above has changed them. */
1320 it->pixel_width = it->ascent = it->descent = 0;
312246d1 1321 it->phys_ascent = it->phys_descent = 0;
5f5c8ee5
GM
1322 }
1323
1324 /* Set this after getting the dimensions of truncation and
1325 continuation glyphs, so that we don't produce glyphs when calling
1326 produce_special_glyphs, above. */
1327 it->glyph_row = row;
1328 it->area = TEXT_AREA;
1329
1330 /* Get the dimensions of the display area. The display area
1331 consists of the visible window area plus a horizontally scrolled
1332 part to the left of the window. All x-values are relative to the
1333 start of this total display area. */
1334 if (base_face_id != DEFAULT_FACE_ID)
1335 {
1336 /* Mode lines, menu bar in terminal frames. */
1337 it->first_visible_x = 0;
1338 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1339 }
1340 else
1341 {
1342 it->first_visible_x
1343 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1344 it->last_visible_x = (it->first_visible_x
1345 + window_box_width (w, TEXT_AREA));
1346
1347 /* If we truncate lines, leave room for the truncator glyph(s) at
1348 the right margin. Otherwise, leave room for the continuation
1349 glyph(s). Truncation and continuation glyphs are not inserted
1350 for window-based redisplay. */
1351 if (!FRAME_WINDOW_P (it->f))
1352 {
1353 if (it->truncate_lines_p)
1354 it->last_visible_x -= it->truncation_pixel_width;
1355 else
1356 it->last_visible_x -= it->continuation_pixel_width;
1357 }
1358
1359 it->top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
1360 it->current_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w) + w->vscroll;
1361 }
1362
1363 /* Leave room for a border glyph. */
1364 if (!FRAME_WINDOW_P (it->f)
1365 && !WINDOW_RIGHTMOST_P (it->w))
1366 it->last_visible_x -= 1;
1367
1368 it->last_visible_y = window_text_bottom_y (w);
1369
1370 /* For mode lines and alike, arrange for the first glyph having a
1371 left box line if the face specifies a box. */
1372 if (base_face_id != DEFAULT_FACE_ID)
1373 {
1374 struct face *face;
1375
1376 it->face_id = base_face_id;
1377
1378 /* If we have a boxed mode line, make the first character appear
1379 with a left box line. */
1380 face = FACE_FROM_ID (it->f, base_face_id);
1381 if (face->box != FACE_NO_BOX)
1382 it->start_of_box_run_p = 1;
1383 }
1384
1385 /* If a buffer position was specified, set the iterator there,
1386 getting overlays and face properties from that position. */
1387 if (charpos > 0)
1388 {
1389 it->end_charpos = ZV;
1390 it->face_id = -1;
1391 IT_CHARPOS (*it) = charpos;
1392
1393 /* Compute byte position if not specified. */
1394 if (bytepos <= 0)
1395 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1396 else
1397 IT_BYTEPOS (*it) = bytepos;
1398
1399 /* Compute faces etc. */
1400 reseat (it, it->current.pos, 1);
1401 }
1402
1403 CHECK_IT (it);
1404}
1405
1406
1407/* Initialize IT for the display of window W with window start POS. */
1408
1409void
1410start_display (it, w, pos)
1411 struct it *it;
1412 struct window *w;
1413 struct text_pos pos;
1414{
1415 int start_at_line_beg_p;
1416 struct glyph_row *row;
1417 int first_vpos = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
1418 int first_y;
1419
1420 row = w->desired_matrix->rows + first_vpos;
1421 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1422 first_y = it->current_y;
1423
1424 /* If window start is not at a line start, move back to the line
1425 start. This makes sure that we take continuation lines into
1426 account. */
1427 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1428 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1429 if (!start_at_line_beg_p)
1430 reseat_at_previous_visible_line_start (it);
1431
1432#if NO_PROMPT_IN_BUFFER
1433 /* Take the mini-buffer prompt width into account for tab
1434 calculations. */
1435 if (MINI_WINDOW_P (w) && IT_CHARPOS (*it) == BEGV)
1436 {
1437 /* Why is mini-buffer_prompt_width guaranteed to be set here? */
1438 it->prompt_width = minibuf_prompt_pixel_width;
1439 }
1440#endif /* NO_PROMPT_IN_BUFFER */
1441
1442 /* If window start is not at a line start, skip forward to POS to
1443 get the correct continuation_lines_width and current_x. */
1444 if (!start_at_line_beg_p)
1445 {
1446 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1447
1448 /* If lines are continued, this line may end in the middle of a
1449 multi-glyph character (e.g. a control character displayed as
1450 \003, or in the middle of an overlay string). In this case
1451 move_it_to above will not have taken us to the start of
1452 the continuation line but to the end of the continued line. */
1453 if (!it->truncate_lines_p && it->current_x > 0)
1454 {
1455 if (it->current.dpvec_index >= 0
1456 || it->current.overlay_string_index >= 0)
1457 {
1458 set_iterator_to_next (it);
1459 move_it_in_display_line_to (it, -1, -1, 0);
1460 }
1461 it->continuation_lines_width += it->current_x;
1462 }
1463
1464 it->current_y = first_y;
1465 it->vpos = 0;
1466 it->current_x = it->hpos = 0;
1467 }
1468
1469#if 0 /* Don't assert the following because start_display is sometimes
1470 called intentionally with a window start that is not at a
1471 line start. Please leave this code in as a comment. */
1472
1473 /* Window start should be on a line start, now. */
1474 xassert (it->continuation_lines_width
1475 || IT_CHARPOS (it) == BEGV
1476 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1477#endif /* 0 */
1478}
1479
1480
1481/* Initialize IT for stepping through current_buffer in window W,
1482 starting at position POS that includes overlay string and display
1483 vector/ control character translation position information. */
1484
1485static void
1486init_from_display_pos (it, w, pos)
1487 struct it *it;
1488 struct window *w;
1489 struct display_pos *pos;
1490{
1491 /* Keep in mind: the call to reseat in init_iterator skips invisible
1492 text, so we might end up at a position different from POS. This
1493 is only a problem when POS is a row start after a newline and an
1494 overlay starts there with an after-string, and the overlay has an
1495 invisible property. Since we don't skip invisible text in
1496 display_line and elsewhere immediately after consuming the
1497 newline before the row start, such a POS will not be in a string,
1498 but the call to init_iterator below will move us to the
1499 after-string. */
1500 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1501 NULL, DEFAULT_FACE_ID);
1502
1503 /* If position is within an overlay string, set up IT to
1504 the right overlay string. */
1505 if (pos->overlay_string_index >= 0)
1506 {
1507 int relative_index;
1508
1509 /* We already have the first chunk of overlay strings in
1510 IT->overlay_strings. Load more until the one for
1511 pos->overlay_string_index is in IT->overlay_strings. */
1512 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1513 {
1514 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1515 it->current.overlay_string_index = 0;
1516 while (n--)
1517 {
1518 load_overlay_strings (it);
1519 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1520 }
1521 }
1522
1523 it->current.overlay_string_index = pos->overlay_string_index;
1524 relative_index = (it->current.overlay_string_index
1525 % OVERLAY_STRING_CHUNK_SIZE);
1526 it->string = it->overlay_strings[relative_index];
1527 it->current.string_pos = pos->string_pos;
1528 it->method = next_element_from_string;
1529 }
1530 else if (CHARPOS (pos->string_pos) >= 0)
1531 {
1532 /* Recorded position is not in an overlay string, but in another
1533 string. This can only be a string from a `display' property.
1534 IT should already be filled with that string. */
1535 it->current.string_pos = pos->string_pos;
1536 xassert (STRINGP (it->string));
1537 }
1538
1539 /* Restore position in display vector translations or control
1540 character translations. */
1541 if (pos->dpvec_index >= 0)
1542 {
1543 /* This fills IT->dpvec. */
1544 get_next_display_element (it);
1545 xassert (it->dpvec && it->current.dpvec_index == 0);
1546 it->current.dpvec_index = pos->dpvec_index;
1547 }
1548
1549 CHECK_IT (it);
1550}
1551
1552
1553/* Initialize IT for stepping through current_buffer in window W
1554 starting at ROW->start. */
1555
1556static void
1557init_to_row_start (it, w, row)
1558 struct it *it;
1559 struct window *w;
1560 struct glyph_row *row;
1561{
1562 init_from_display_pos (it, w, &row->start);
1563 it->continuation_lines_width = row->continuation_lines_width;
1564 CHECK_IT (it);
1565}
1566
1567
1568/* Initialize IT for stepping through current_buffer in window W
1569 starting in the line following ROW, i.e. starting at ROW->end. */
1570
1571static void
1572init_to_row_end (it, w, row)
1573 struct it *it;
1574 struct window *w;
1575 struct glyph_row *row;
1576{
1577 init_from_display_pos (it, w, &row->end);
1578
1579 if (row->continued_p)
1580 it->continuation_lines_width = (row->continuation_lines_width
1581 + row->pixel_width);
1582 CHECK_IT (it);
1583}
1584
1585
1586
1587\f
1588/***********************************************************************
1589 Text properties
1590 ***********************************************************************/
1591
1592/* Called when IT reaches IT->stop_charpos. Handle text property and
1593 overlay changes. Set IT->stop_charpos to the next position where
1594 to stop. */
1595
1596static void
1597handle_stop (it)
1598 struct it *it;
1599{
1600 enum prop_handled handled;
1601 int handle_overlay_change_p = 1;
1602 struct props *p;
1603
1604 it->dpvec = NULL;
1605 it->current.dpvec_index = -1;
1606
1607 do
1608 {
1609 handled = HANDLED_NORMALLY;
1610
1611 /* Call text property handlers. */
1612 for (p = it_props; p->handler; ++p)
1613 {
1614 handled = p->handler (it);
1615
1616 if (handled == HANDLED_RECOMPUTE_PROPS)
1617 break;
1618 else if (handled == HANDLED_RETURN)
1619 return;
1620 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1621 handle_overlay_change_p = 0;
1622 }
1623
1624 if (handled != HANDLED_RECOMPUTE_PROPS)
1625 {
1626 /* Don't check for overlay strings below when set to deliver
1627 characters from a display vector. */
1628 if (it->method == next_element_from_display_vector)
1629 handle_overlay_change_p = 0;
1630
1631 /* Handle overlay changes. */
1632 if (handle_overlay_change_p)
1633 handled = handle_overlay_change (it);
1634
1635 /* Determine where to stop next. */
1636 if (handled == HANDLED_NORMALLY)
1637 compute_stop_pos (it);
1638 }
1639 }
1640 while (handled == HANDLED_RECOMPUTE_PROPS);
1641}
1642
1643
1644/* Compute IT->stop_charpos from text property and overlay change
1645 information for IT's current position. */
1646
1647static void
1648compute_stop_pos (it)
1649 struct it *it;
1650{
1651 register INTERVAL iv, next_iv;
1652 Lisp_Object object, limit, position;
1653
1654 /* If nowhere else, stop at the end. */
1655 it->stop_charpos = it->end_charpos;
1656
1657 if (STRINGP (it->string))
1658 {
1659 /* Strings are usually short, so don't limit the search for
1660 properties. */
1661 object = it->string;
1662 limit = Qnil;
1663 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1664 }
1665 else
1666 {
1667 int charpos;
1668
1669 /* If next overlay change is in front of the current stop pos
1670 (which is IT->end_charpos), stop there. Note: value of
1671 next_overlay_change is point-max if no overlay change
1672 follows. */
1673 charpos = next_overlay_change (IT_CHARPOS (*it));
1674 if (charpos < it->stop_charpos)
1675 it->stop_charpos = charpos;
1676
1677 /* If showing the region, we have to stop at the region
1678 start or end because the face might change there. */
1679 if (it->region_beg_charpos > 0)
1680 {
1681 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1682 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1683 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1684 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1685 }
1686
1687 /* Set up variables for computing the stop position from text
1688 property changes. */
1689 XSETBUFFER (object, current_buffer);
1690 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1691 XSETFASTINT (position, IT_CHARPOS (*it));
1692
1693 }
1694
1695 /* Get the interval containing IT's position. Value is a null
1696 interval if there isn't such an interval. */
1697 iv = validate_interval_range (object, &position, &position, 0);
1698 if (!NULL_INTERVAL_P (iv))
1699 {
1700 Lisp_Object values_here[LAST_PROP_IDX];
1701 struct props *p;
1702
1703 /* Get properties here. */
1704 for (p = it_props; p->handler; ++p)
1705 values_here[p->idx] = textget (iv->plist, *p->name);
1706
1707 /* Look for an interval following iv that has different
1708 properties. */
1709 for (next_iv = next_interval (iv);
1710 (!NULL_INTERVAL_P (next_iv)
1711 && (NILP (limit)
1712 || XFASTINT (limit) > next_iv->position));
1713 next_iv = next_interval (next_iv))
1714 {
1715 for (p = it_props; p->handler; ++p)
1716 {
1717 Lisp_Object new_value;
1718
1719 new_value = textget (next_iv->plist, *p->name);
1720 if (!EQ (values_here[p->idx], new_value))
1721 break;
1722 }
1723
1724 if (p->handler)
1725 break;
1726 }
1727
1728 if (!NULL_INTERVAL_P (next_iv))
1729 {
1730 if (INTEGERP (limit)
1731 && next_iv->position >= XFASTINT (limit))
1732 /* No text property change up to limit. */
1733 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1734 else
1735 /* Text properties change in next_iv. */
1736 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1737 }
1738 }
1739
1740 xassert (STRINGP (it->string)
1741 || (it->stop_charpos >= BEGV
1742 && it->stop_charpos >= IT_CHARPOS (*it)));
1743}
1744
1745
1746/* Return the position of the next overlay change after POS in
1747 current_buffer. Value is point-max if no overlay change
1748 follows. This is like `next-overlay-change' but doesn't use
1749 xmalloc. */
1750
1751static int
1752next_overlay_change (pos)
1753 int pos;
1754{
1755 int noverlays;
1756 int endpos;
1757 Lisp_Object *overlays;
1758 int len;
1759 int i;
1760
1761 /* Get all overlays at the given position. */
1762 len = 10;
1763 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1764 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1765 if (noverlays > len)
1766 {
1767 len = noverlays;
1768 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1769 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1770 }
1771
1772 /* If any of these overlays ends before endpos,
1773 use its ending point instead. */
1774 for (i = 0; i < noverlays; ++i)
1775 {
1776 Lisp_Object oend;
1777 int oendpos;
1778
1779 oend = OVERLAY_END (overlays[i]);
1780 oendpos = OVERLAY_POSITION (oend);
1781 endpos = min (endpos, oendpos);
1782 }
1783
1784 return endpos;
1785}
1786
1787
1788\f
1789/***********************************************************************
1790 Fontification
1791 ***********************************************************************/
1792
1793/* Handle changes in the `fontified' property of the current buffer by
1794 calling hook functions from Qfontification_functions to fontify
1795 regions of text. */
1796
1797static enum prop_handled
1798handle_fontified_prop (it)
1799 struct it *it;
1800{
1801 Lisp_Object prop, pos;
1802 enum prop_handled handled = HANDLED_NORMALLY;
1803
1804 /* Get the value of the `fontified' property at IT's current buffer
1805 position. (The `fontified' property doesn't have a special
1806 meaning in strings.) If the value is nil, call functions from
1807 Qfontification_functions. */
1808 if (!STRINGP (it->string)
1809 && it->s == NULL
1810 && !NILP (Vfontification_functions)
1811 && (pos = make_number (IT_CHARPOS (*it)),
1812 prop = Fget_char_property (pos, Qfontified, Qnil),
1813 NILP (prop)))
1814 {
1815 Lisp_Object args[2];
1816
1817 /* Run the hook functions. */
1818 args[0] = Qfontification_functions;
1819 args[1] = pos;
1820 Frun_hook_with_args (make_number (2), args);
1821
1822 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1823 something. This avoids an endless loop if they failed to
1824 fontify the text for which reason ever. */
1825 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1826 handled = HANDLED_RECOMPUTE_PROPS;
1827 }
1828
1829 return handled;
1830}
1831
1832
1833\f
1834/***********************************************************************
1835 Faces
1836 ***********************************************************************/
1837
1838/* Set up iterator IT from face properties at its current position.
1839 Called from handle_stop. */
1840
1841static enum prop_handled
1842handle_face_prop (it)
1843 struct it *it;
1844{
1845 int new_face_id, next_stop;
1846
1847 if (!STRINGP (it->string))
1848 {
1849 new_face_id
1850 = face_at_buffer_position (it->w,
1851 IT_CHARPOS (*it),
1852 it->region_beg_charpos,
1853 it->region_end_charpos,
1854 &next_stop,
1855 (IT_CHARPOS (*it)
1856 + TEXT_PROP_DISTANCE_LIMIT),
1857 0);
1858
1859 /* Is this a start of a run of characters with box face?
1860 Caveat: this can be called for a freshly initialized
1861 iterator; face_id is -1 is this case. We know that the new
1862 face will not change until limit, i.e. if the new face has a
1863 box, all characters up to limit will have one. But, as
1864 usual, we don't know whether limit is really the end. */
1865 if (new_face_id != it->face_id)
1866 {
1867 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1868
1869 /* If new face has a box but old face has not, this is
1870 the start of a run of characters with box, i.e. it has
1871 a shadow on the left side. The value of face_id of the
1872 iterator will be -1 if this is the initial call that gets
1873 the face. In this case, we have to look in front of IT's
1874 position and see whether there is a face != new_face_id. */
1875 it->start_of_box_run_p
1876 = (new_face->box != FACE_NO_BOX
1877 && (it->face_id >= 0
1878 || IT_CHARPOS (*it) == BEG
1879 || new_face_id != face_before_it_pos (it)));
1880 it->face_box_p = new_face->box != FACE_NO_BOX;
1881 }
1882 }
1883 else
1884 {
1885 new_face_id
1886 = face_at_string_position (it->w,
1887 it->string,
1888 IT_STRING_CHARPOS (*it),
1889 (it->current.overlay_string_index >= 0
1890 ? IT_CHARPOS (*it)
1891 : 0),
1892 it->region_beg_charpos,
1893 it->region_end_charpos,
1894 &next_stop,
1895 it->base_face_id);
1896
1897#if 0 /* This shouldn't be neccessary. Let's check it. */
1898 /* If IT is used to display a mode line we would really like to
1899 use the mode line face instead of the frame's default face. */
1900 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1901 && new_face_id == DEFAULT_FACE_ID)
1902 new_face_id = MODE_LINE_FACE_ID;
1903#endif
1904
1905 /* Is this a start of a run of characters with box? Caveat:
1906 this can be called for a freshly allocated iterator; face_id
1907 is -1 is this case. We know that the new face will not
1908 change until the next check pos, i.e. if the new face has a
1909 box, all characters up to that position will have a
1910 box. But, as usual, we don't know whether that position
1911 is really the end. */
1912 if (new_face_id != it->face_id)
1913 {
1914 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1915 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1916
1917 /* If new face has a box but old face hasn't, this is the
1918 start of a run of characters with box, i.e. it has a
1919 shadow on the left side. */
1920 it->start_of_box_run_p
1921 = new_face->box && (old_face == NULL || !old_face->box);
1922 it->face_box_p = new_face->box != FACE_NO_BOX;
1923 }
1924 }
1925
1926 it->face_id = new_face_id;
1927 it->charset = CHARSET_ASCII;
1928 return HANDLED_NORMALLY;
1929}
1930
1931
1932/* Compute the face one character before or after the current position
1933 of IT. BEFORE_P non-zero means get the face in front of IT's
1934 position. Value is the id of the face. */
1935
1936static int
1937face_before_or_after_it_pos (it, before_p)
1938 struct it *it;
1939 int before_p;
1940{
1941 int face_id, limit;
1942 int next_check_charpos;
1943 struct text_pos pos;
1944
1945 xassert (it->s == NULL);
1946
1947 if (STRINGP (it->string))
1948 {
1949 /* No face change past the end of the string (for the case
1950 we are padding with spaces). No face change before the
1951 string start. */
1952 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1953 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1954 return it->face_id;
1955
1956 /* Set pos to the position before or after IT's current position. */
1957 if (before_p)
1958 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1959 else
1960 pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string);
1961
1962 /* Get the face for ASCII, or unibyte. */
1963 face_id
1964 = face_at_string_position (it->w,
1965 it->string,
1966 CHARPOS (pos),
1967 (it->current.overlay_string_index >= 0
1968 ? IT_CHARPOS (*it)
1969 : 0),
1970 it->region_beg_charpos,
1971 it->region_end_charpos,
1972 &next_check_charpos,
1973 it->base_face_id);
1974
1975 /* Correct the face for charsets different from ASCII. Do it
1976 for the multibyte case only. The face returned above is
1977 suitable for unibyte text if IT->string is unibyte. */
1978 if (STRING_MULTIBYTE (it->string))
1979 {
1980 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1981 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1982 int c, len, charset;
1983
4fdb80f2 1984 c = string_char_and_length (p, rest, &len);
5f5c8ee5
GM
1985 charset = CHAR_CHARSET (c);
1986 if (charset != CHARSET_ASCII)
1987 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
1988 }
1989 }
1990 else
1991 {
70851746
GM
1992 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1993 || (IT_CHARPOS (*it) <= BEGV && before_p))
1994 return it->face_id;
1995
5f5c8ee5
GM
1996 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1997 pos = it->current.pos;
1998
1999 if (before_p)
2000 DEC_TEXT_POS (pos);
2001 else
2002 INC_TEXT_POS (pos);
70851746 2003
5f5c8ee5
GM
2004 /* Determine face for CHARSET_ASCII, or unibyte. */
2005 face_id = face_at_buffer_position (it->w,
2006 CHARPOS (pos),
2007 it->region_beg_charpos,
2008 it->region_end_charpos,
2009 &next_check_charpos,
2010 limit, 0);
2011
2012 /* Correct the face for charsets different from ASCII. Do it
2013 for the multibyte case only. The face returned above is
2014 suitable for unibyte text if current_buffer is unibyte. */
2015 if (it->multibyte_p)
2016 {
2017 int charset = charset_at_position (pos);
2018 if (charset != CHARSET_ASCII)
2019 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
2020 }
2021 }
2022
2023 return face_id;
2024}
2025
2026
2027\f
2028/***********************************************************************
2029 Invisible text
2030 ***********************************************************************/
2031
2032/* Set up iterator IT from invisible properties at its current
2033 position. Called from handle_stop. */
2034
2035static enum prop_handled
2036handle_invisible_prop (it)
2037 struct it *it;
2038{
2039 enum prop_handled handled = HANDLED_NORMALLY;
2040
2041 if (STRINGP (it->string))
2042 {
2043 extern Lisp_Object Qinvisible;
2044 Lisp_Object prop, end_charpos, limit, charpos;
2045
2046 /* Get the value of the invisible text property at the
2047 current position. Value will be nil if there is no such
2048 property. */
2049 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2050 prop = Fget_text_property (charpos, Qinvisible, it->string);
2051
2052 if (!NILP (prop))
2053 {
2054 handled = HANDLED_RECOMPUTE_PROPS;
2055
2056 /* Get the position at which the next change of the
2057 invisible text property can be found in IT->string.
2058 Value will be nil if the property value is the same for
2059 all the rest of IT->string. */
2060 XSETINT (limit, XSTRING (it->string)->size);
2061 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2062 it->string, limit);
2063
2064 /* Text at current position is invisible. The next
2065 change in the property is at position end_charpos.
2066 Move IT's current position to that position. */
2067 if (INTEGERP (end_charpos)
2068 && XFASTINT (end_charpos) < XFASTINT (limit))
2069 {
2070 struct text_pos old;
2071 old = it->current.string_pos;
2072 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2073 compute_string_pos (&it->current.string_pos, old, it->string);
2074 }
2075 else
2076 {
2077 /* The rest of the string is invisible. If this is an
2078 overlay string, proceed with the next overlay string
2079 or whatever comes and return a character from there. */
2080 if (it->current.overlay_string_index >= 0)
2081 {
2082 next_overlay_string (it);
2083 /* Don't check for overlay strings when we just
2084 finished processing them. */
2085 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2086 }
2087 else
2088 {
2089 struct Lisp_String *s = XSTRING (it->string);
2090 IT_STRING_CHARPOS (*it) = s->size;
2091 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2092 }
2093 }
2094 }
2095 }
2096 else
2097 {
2098 int visible_p, newpos, next_stop;
2099 Lisp_Object pos, prop;
2100
2101 /* First of all, is there invisible text at this position? */
2102 XSETFASTINT (pos, IT_CHARPOS (*it));
2103 prop = Fget_char_property (pos, Qinvisible, it->window);
2104
2105 /* If we are on invisible text, skip over it. */
2106 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2107 {
2108 /* Record whether we have to display an ellipsis for the
2109 invisible text. */
2110 int display_ellipsis_p
2111 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2112
2113 handled = HANDLED_RECOMPUTE_PROPS;
2114
2115 /* Loop skipping over invisible text. The loop is left at
2116 ZV or with IT on the first char being visible again. */
2117 do
2118 {
2119 /* Try to skip some invisible text. Return value is the
2120 position reached which can be equal to IT's position
2121 if there is nothing invisible here. This skips both
2122 over invisible text properties and overlays with
2123 invisible property. */
2124 newpos = skip_invisible (IT_CHARPOS (*it),
2125 &next_stop, ZV, it->window);
2126
2127 /* If we skipped nothing at all we weren't at invisible
2128 text in the first place. If everything to the end of
2129 the buffer was skipped, end the loop. */
2130 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2131 visible_p = 1;
2132 else
2133 {
2134 /* We skipped some characters but not necessarily
2135 all there are. Check if we ended up on visible
2136 text. Fget_char_property returns the property of
2137 the char before the given position, i.e. if we
2138 get visible_p = 1, this means that the char at
2139 newpos is visible. */
2140 XSETFASTINT (pos, newpos);
2141 prop = Fget_char_property (pos, Qinvisible, it->window);
2142 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2143 }
2144
2145 /* If we ended up on invisible text, proceed to
2146 skip starting with next_stop. */
2147 if (!visible_p)
2148 IT_CHARPOS (*it) = next_stop;
2149 }
2150 while (!visible_p);
2151
2152 /* The position newpos is now either ZV or on visible text. */
2153 IT_CHARPOS (*it) = newpos;
2154 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2155
2156 /* Maybe return `...' next for the end of the invisible text. */
2157 if (display_ellipsis_p)
2158 {
2159 if (it->dp
2160 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2161 {
2162 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2163 it->dpvec = v->contents;
2164 it->dpend = v->contents + v->size;
2165 }
2166 else
2167 {
2168 /* Default `...'. */
2169 it->dpvec = default_invis_vector;
2170 it->dpend = default_invis_vector + 3;
2171 }
2172
2173 /* The ellipsis display does not replace the display of
2174 the character at the new position. Indicate this by
2175 setting IT->dpvec_char_len to zero. */
2176 it->dpvec_char_len = 0;
2177
2178 it->current.dpvec_index = 0;
2179 it->method = next_element_from_display_vector;
2180 }
2181 }
2182 }
2183
2184 return handled;
2185}
2186
2187
2188\f
2189/***********************************************************************
2190 'display' property
2191 ***********************************************************************/
2192
2193/* Set up iterator IT from `display' property at its current position.
2194 Called from handle_stop. */
2195
2196static enum prop_handled
2197handle_display_prop (it)
2198 struct it *it;
2199{
2200 Lisp_Object prop, object;
2201 struct text_pos *position;
2202 int space_or_image_found_p;
2203
2204 if (STRINGP (it->string))
2205 {
2206 object = it->string;
2207 position = &it->current.string_pos;
2208 }
2209 else
2210 {
2211 object = Qnil;
2212 position = &it->current.pos;
2213 }
2214
2215 /* Reset those iterator values set from display property values. */
2216 it->font_height = Qnil;
2217 it->space_width = Qnil;
2218 it->voffset = 0;
2219
2220 /* We don't support recursive `display' properties, i.e. string
2221 values that have a string `display' property, that have a string
2222 `display' property etc. */
2223 if (!it->string_from_display_prop_p)
2224 it->area = TEXT_AREA;
2225
2226 prop = Fget_char_property (make_number (position->charpos),
2227 Qdisplay, object);
2228 if (NILP (prop))
2229 return HANDLED_NORMALLY;
2230
2231 space_or_image_found_p = 0;
2232 if (CONSP (prop) && CONSP (XCAR (prop)))
2233 {
2234 while (CONSP (prop))
2235 {
2236 if (handle_single_display_prop (it, XCAR (prop), object, position))
2237 space_or_image_found_p = 1;
2238 prop = XCDR (prop);
2239 }
2240 }
2241 else if (VECTORP (prop))
2242 {
2243 int i;
2244 for (i = 0; i < XVECTOR (prop)->size; ++i)
2245 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2246 object, position))
2247 space_or_image_found_p = 1;
2248 }
2249 else
2250 {
2251 if (handle_single_display_prop (it, prop, object, position))
2252 space_or_image_found_p = 1;
2253 }
2254
2255 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2256}
2257
2258
2259/* Value is the position of the end of the `display' property stating
2260 at START_POS in OBJECT. */
2261
2262static struct text_pos
2263display_prop_end (it, object, start_pos)
2264 struct it *it;
2265 Lisp_Object object;
2266 struct text_pos start_pos;
2267{
2268 Lisp_Object end;
2269 struct text_pos end_pos;
2270
2271 /* Characters having this form of property are not displayed, so
2272 we have to find the end of the property. */
2273 end = Fnext_single_property_change (make_number (start_pos.charpos),
2274 Qdisplay, object, Qnil);
2275 if (NILP (end))
2276 {
2277 /* A nil value of `end' means there are no changes of the
2278 property to the end of the buffer or string. */
2279 if (it->current.overlay_string_index >= 0)
2280 end_pos.charpos = XSTRING (it->string)->size;
2281 else
2282 end_pos.charpos = it->end_charpos;
2283 }
2284 else
2285 end_pos.charpos = XFASTINT (end);
2286
2287 if (STRINGP (it->string))
2288 compute_string_pos (&end_pos, start_pos, it->string);
2289 else
2290 end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
2291
2292 return end_pos;
2293}
2294
2295
2296/* Set up IT from a single `display' sub-property value PROP. OBJECT
2297 is the object in which the `display' property was found. *POSITION
2298 is the position at which it was found.
2299
2300 If PROP is a `space' or `image' sub-property, set *POSITION to the
2301 end position of the `display' property.
2302
2303 Value is non-zero if a `space' or `image' property value was found. */
2304
2305static int
2306handle_single_display_prop (it, prop, object, position)
2307 struct it *it;
2308 Lisp_Object prop;
2309 Lisp_Object object;
2310 struct text_pos *position;
2311{
2312 Lisp_Object value;
2313 int space_or_image_found_p = 0;
2314
2315 Lisp_Object form;
2316
2317 /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
2318 evaluated. If the result is nil, VALUE is ignored. */
2319 form = Qt;
2320 if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
2321 {
2322 prop = XCDR (prop);
2323 if (!CONSP (prop))
2324 return 0;
2325 form = XCAR (prop);
2326 prop = XCDR (prop);
2327 if (!CONSP (prop))
2328 return 0;
2329 prop = XCAR (prop);
2330 }
2331
2332 if (!NILP (form) && !EQ (form, Qt))
2333 {
2334 struct gcpro gcpro1;
2335 struct text_pos end_pos, pt;
2336
2337 end_pos = display_prop_end (it, object, *position);
2338 GCPRO1 (form);
2339
2340 /* Temporarily set point to the end position, and then evaluate
2341 the form. This makes `(eolp)' work as FORM. */
2342 CHARPOS (pt) = PT;
2343 BYTEPOS (pt) = PT_BYTE;
2344 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2345 form = eval_form (form);
2346 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2347 UNGCPRO;
2348 }
2349
2350 if (NILP (form))
2351 return 0;
2352
2353 if (CONSP (prop)
2354 && EQ (XCAR (prop), Qheight)
2355 && CONSP (XCDR (prop)))
2356 {
2357 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2358 return 0;
2359
2360 /* `(height HEIGHT)'. */
2361 it->font_height = XCAR (XCDR (prop));
2362 if (!NILP (it->font_height))
2363 {
2364 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2365 int new_height = -1;
2366
2367 if (CONSP (it->font_height)
2368 && (EQ (XCAR (it->font_height), Qplus)
2369 || EQ (XCAR (it->font_height), Qminus))
2370 && CONSP (XCDR (it->font_height))
2371 && INTEGERP (XCAR (XCDR (it->font_height))))
2372 {
2373 /* `(+ N)' or `(- N)' where N is an integer. */
2374 int steps = XINT (XCAR (XCDR (it->font_height)));
2375 if (EQ (XCAR (it->font_height), Qplus))
2376 steps = - steps;
2377 it->face_id = smaller_face (it->f, it->face_id, steps);
2378 }
2379 else if (SYMBOLP (it->font_height))
2380 {
2381 /* Call function with current height as argument.
2382 Value is the new height. */
2383 Lisp_Object form, height;
2384 struct gcpro gcpro1;
2385
2386 height = face->lface[LFACE_HEIGHT_INDEX];
2387 form = Fcons (it->font_height, Fcons (height, Qnil));
2388 GCPRO1 (form);
2389 height = eval_form (form);
2390 if (NUMBERP (height))
2391 new_height = XFLOATINT (height);
2392 UNGCPRO;
2393 }
2394 else if (NUMBERP (it->font_height))
2395 {
2396 /* Value is a multiple of the canonical char height. */
2397 struct face *face;
2398
2399 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2400 new_height = (XFLOATINT (it->font_height)
2401 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2402 }
2403 else
2404 {
2405 /* Evaluate IT->font_height with `height' bound to the
2406 current specified height to get the new height. */
2407 Lisp_Object value;
2408 int count = specpdl_ptr - specpdl;
2409
2410 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2411 value = eval_form (it->font_height);
2412 unbind_to (count, Qnil);
2413
2414 if (NUMBERP (value))
2415 new_height = XFLOATINT (value);
2416 }
2417
2418 if (new_height > 0)
2419 it->face_id = face_with_height (it->f, it->face_id, new_height);
2420 }
2421 }
2422 else if (CONSP (prop)
2423 && EQ (XCAR (prop), Qspace_width)
2424 && CONSP (XCDR (prop)))
2425 {
2426 /* `(space_width WIDTH)'. */
2427 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2428 return 0;
2429
2430 value = XCAR (XCDR (prop));
2431 if (NUMBERP (value) && XFLOATINT (value) > 0)
2432 it->space_width = value;
2433 }
2434 else if (CONSP (prop)
2435 && EQ (XCAR (prop), Qraise)
2436 && CONSP (XCDR (prop)))
2437 {
2438#ifdef HAVE_WINDOW_SYSTEM
2439 /* `(raise FACTOR)'. */
2440 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2441 return 0;
2442
2443 value = XCAR (XCDR (prop));
2444 if (NUMBERP (value))
2445 {
2446 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2447 it->voffset = - (XFLOATINT (value)
2448 * (face->font->ascent + face->font->descent));
2449 }
2450#endif /* HAVE_WINDOW_SYSTEM */
2451 }
2452 else if (!it->string_from_display_prop_p)
2453 {
2454 /* `(left-margin VALUE)' or `(right-margin VALUE)
2455 or `(nil VALUE)' or VALUE. */
2456 Lisp_Object location, value;
2457 struct text_pos start_pos;
2458 int valid_p;
2459
2460 /* Characters having this form of property are not displayed, so
2461 we have to find the end of the property. */
2462 space_or_image_found_p = 1;
2463 start_pos = *position;
2464 *position = display_prop_end (it, object, start_pos);
2465
2466 /* Let's stop at the new position and assume that all
2467 text properties change there. */
2468 it->stop_charpos = position->charpos;
2469
2470 if (CONSP (prop)
2471 && !EQ (XCAR (prop), Qspace)
2472 && !EQ (XCAR (prop), Qimage))
2473 {
2474 location = XCAR (prop);
2475 value = XCDR (prop);
2476 }
2477 else
2478 {
2479 location = Qnil;
2480 value = prop;
2481 }
2482
2483#ifdef HAVE_WINDOW_SYSTEM
2484 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2485 valid_p = STRINGP (value);
2486 else
2487 valid_p = (STRINGP (value)
2488 || (CONSP (value) && EQ (XCAR (value), Qspace))
2489 || valid_image_p (value));
2490#else /* not HAVE_WINDOW_SYSTEM */
2491 valid_p = STRINGP (value);
2492#endif /* not HAVE_WINDOW_SYSTEM */
2493
2494 if ((EQ (location, Qleft_margin)
2495 || EQ (location, Qright_margin)
2496 || NILP (location))
2497 && valid_p)
2498 {
2499 /* Save current settings of IT so that we can restore them
2500 when we are finished with the glyph property value. */
2501 push_it (it);
2502
2503 if (NILP (location))
2504 it->area = TEXT_AREA;
2505 else if (EQ (location, Qleft_margin))
2506 it->area = LEFT_MARGIN_AREA;
2507 else
2508 it->area = RIGHT_MARGIN_AREA;
2509
2510 if (STRINGP (value))
2511 {
2512 it->string = value;
2513 it->multibyte_p = STRING_MULTIBYTE (it->string);
2514 it->current.overlay_string_index = -1;
2515 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2516 it->end_charpos = it->string_nchars
2517 = XSTRING (it->string)->size;
2518 it->method = next_element_from_string;
2519 it->stop_charpos = 0;
2520 it->string_from_display_prop_p = 1;
2521 }
2522 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2523 {
2524 it->method = next_element_from_stretch;
2525 it->object = value;
2526 it->current.pos = it->position = start_pos;
2527 }
2528#ifdef HAVE_WINDOW_SYSTEM
2529 else
2530 {
2531 it->what = IT_IMAGE;
2532 it->image_id = lookup_image (it->f, value);
2533 it->position = start_pos;
2534 it->object = NILP (object) ? it->w->buffer : object;
2535 it->method = next_element_from_image;
2536
2537 /* Say that we don't have consumed the characters with
2538 `display' property yet. The call to pop_it in
2539 set_iterator_to_next will clean this up. */
2540 *position = start_pos;
2541 }
2542#endif /* HAVE_WINDOW_SYSTEM */
2543 }
2544 }
2545
2546 return space_or_image_found_p;
2547}
2548
2549
2550\f
2551/***********************************************************************
2552 Overlay strings
2553 ***********************************************************************/
2554
2555/* The following structure is used to record overlay strings for
2556 later sorting in load_overlay_strings. */
2557
2558struct overlay_entry
2559{
2560 Lisp_Object string;
2561 int priority;
2562 int after_string_p;
2563};
2564
2565
2566/* Set up iterator IT from overlay strings at its current position.
2567 Called from handle_stop. */
2568
2569static enum prop_handled
2570handle_overlay_change (it)
2571 struct it *it;
2572{
2573 /* Overlays are handled in current_buffer only. */
2574 if (STRINGP (it->string))
2575 return HANDLED_NORMALLY;
2576 else
2577 return (get_overlay_strings (it)
2578 ? HANDLED_RECOMPUTE_PROPS
2579 : HANDLED_NORMALLY);
2580}
2581
2582
2583/* Set up the next overlay string for delivery by IT, if there is an
2584 overlay string to deliver. Called by set_iterator_to_next when the
2585 end of the current overlay string is reached. If there are more
2586 overlay strings to display, IT->string and
2587 IT->current.overlay_string_index are set appropriately here.
2588 Otherwise IT->string is set to nil. */
2589
2590static void
2591next_overlay_string (it)
2592 struct it *it;
2593{
2594 ++it->current.overlay_string_index;
2595 if (it->current.overlay_string_index == it->n_overlay_strings)
2596 {
2597 /* No more overlay strings. Restore IT's settings to what
2598 they were before overlay strings were processed, and
2599 continue to deliver from current_buffer. */
2600 pop_it (it);
2601 xassert (it->stop_charpos >= BEGV
2602 && it->stop_charpos <= it->end_charpos);
2603 it->string = Qnil;
2604 it->current.overlay_string_index = -1;
2605 SET_TEXT_POS (it->current.string_pos, -1, -1);
2606 it->n_overlay_strings = 0;
2607 it->method = next_element_from_buffer;
2608 }
2609 else
2610 {
2611 /* There are more overlay strings to process. If
2612 IT->current.overlay_string_index has advanced to a position
2613 where we must load IT->overlay_strings with more strings, do
2614 it. */
2615 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2616
2617 if (it->current.overlay_string_index && i == 0)
2618 load_overlay_strings (it);
2619
2620 /* Initialize IT to deliver display elements from the overlay
2621 string. */
2622 it->string = it->overlay_strings[i];
2623 it->multibyte_p = STRING_MULTIBYTE (it->string);
2624 SET_TEXT_POS (it->current.string_pos, 0, 0);
2625 it->method = next_element_from_string;
2626 it->stop_charpos = 0;
2627 }
2628
2629 CHECK_IT (it);
2630}
2631
2632
2633/* Compare two overlay_entry structures E1 and E2. Used as a
2634 comparison function for qsort in load_overlay_strings. Overlay
2635 strings for the same position are sorted so that
2636
2637 1. All after-strings come in front of before-strings.
2638
2639 2. Within after-strings, strings are sorted so that overlay strings
2640 from overlays with higher priorities come first.
2641
2642 2. Within before-strings, strings are sorted so that overlay
2643 strings from overlays with higher priorities come last.
2644
2645 Value is analogous to strcmp. */
2646
2647
2648static int
2649compare_overlay_entries (e1, e2)
2650 void *e1, *e2;
2651{
2652 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2653 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2654 int result;
2655
2656 if (entry1->after_string_p != entry2->after_string_p)
2657 /* Let after-strings appear in front of before-strings. */
2658 result = entry1->after_string_p ? -1 : 1;
2659 else if (entry1->after_string_p)
2660 /* After-strings sorted in order of decreasing priority. */
2661 result = entry2->priority - entry1->priority;
2662 else
2663 /* Before-strings sorted in order of increasing priority. */
2664 result = entry1->priority - entry2->priority;
2665
2666 return result;
2667}
2668
2669
2670/* Load the vector IT->overlay_strings with overlay strings from IT's
2671 current buffer position. Set IT->n_overlays to the total number of
2672 overlay strings found.
2673
2674 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2675 a time. On entry into load_overlay_strings,
2676 IT->current.overlay_string_index gives the number of overlay
2677 strings that have already been loaded by previous calls to this
2678 function.
2679
2680 Overlay strings are sorted so that after-string strings come in
2681 front of before-string strings. Within before and after-strings,
2682 strings are sorted by overlay priority. See also function
2683 compare_overlay_entries. */
2684
2685static void
2686load_overlay_strings (it)
2687 struct it *it;
2688{
2689 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2690 Lisp_Object ov, overlay, window, str;
2691 int start, end;
2692 int size = 20;
2693 int n = 0, i, j;
2694 struct overlay_entry *entries
2695 = (struct overlay_entry *) alloca (size * sizeof *entries);
2696
2697 /* Append the overlay string STRING of overlay OVERLAY to vector
2698 `entries' which has size `size' and currently contains `n'
2699 elements. AFTER_P non-zero means STRING is an after-string of
2700 OVERLAY. */
2701#define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2702 do \
2703 { \
2704 Lisp_Object priority; \
2705 \
2706 if (n == size) \
2707 { \
2708 int new_size = 2 * size; \
2709 struct overlay_entry *old = entries; \
2710 entries = \
2711 (struct overlay_entry *) alloca (new_size \
2712 * sizeof *entries); \
2713 bcopy (old, entries, size * sizeof *entries); \
2714 size = new_size; \
2715 } \
2716 \
2717 entries[n].string = (STRING); \
2718 priority = Foverlay_get ((OVERLAY), Qpriority); \
2719 entries[n].priority \
2720 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2721 entries[n].after_string_p = (AFTER_P); \
2722 ++n; \
2723 } \
2724 while (0)
2725
2726 /* Process overlay before the overlay center. */
2727 for (ov = current_buffer->overlays_before;
2728 CONSP (ov);
2729 ov = XCONS (ov)->cdr)
2730 {
2731 overlay = XCONS (ov)->car;
2732 xassert (OVERLAYP (overlay));
2733 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2734 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2735
2736 if (end < IT_CHARPOS (*it))
2737 break;
2738
2739 /* Skip this overlay if it doesn't start or end at IT's current
2740 position. */
2741 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2742 continue;
2743
2744 /* Skip this overlay if it doesn't apply to IT->w. */
2745 window = Foverlay_get (overlay, Qwindow);
2746 if (WINDOWP (window) && XWINDOW (window) != it->w)
2747 continue;
2748
2749 /* If overlay has a non-empty before-string, record it. */
2750 if (start == IT_CHARPOS (*it)
2751 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2752 && XSTRING (str)->size)
2753 RECORD_OVERLAY_STRING (overlay, str, 0);
2754
2755 /* If overlay has a non-empty after-string, record it. */
2756 if (end == IT_CHARPOS (*it)
2757 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2758 && XSTRING (str)->size)
2759 RECORD_OVERLAY_STRING (overlay, str, 1);
2760 }
2761
2762 /* Process overlays after the overlay center. */
2763 for (ov = current_buffer->overlays_after;
2764 CONSP (ov);
2765 ov = XCONS (ov)->cdr)
2766 {
2767 overlay = XCONS (ov)->car;
2768 xassert (OVERLAYP (overlay));
2769 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2770 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2771
2772 if (start > IT_CHARPOS (*it))
2773 break;
2774
2775 /* Skip this overlay if it doesn't start or end at IT's current
2776 position. */
2777 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2778 continue;
2779
2780 /* Skip this overlay if it doesn't apply to IT->w. */
2781 window = Foverlay_get (overlay, Qwindow);
2782 if (WINDOWP (window) && XWINDOW (window) != it->w)
2783 continue;
2784
2785 /* If overlay has a non-empty before-string, record it. */
2786 if (start == IT_CHARPOS (*it)
2787 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2788 && XSTRING (str)->size)
2789 RECORD_OVERLAY_STRING (overlay, str, 0);
2790
2791 /* If overlay has a non-empty after-string, record it. */
2792 if (end == IT_CHARPOS (*it)
2793 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2794 && XSTRING (str)->size)
2795 RECORD_OVERLAY_STRING (overlay, str, 1);
2796 }
2797
2798#undef RECORD_OVERLAY_STRING
2799
2800 /* Sort entries. */
2801 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2802
2803 /* Record the total number of strings to process. */
2804 it->n_overlay_strings = n;
2805
2806 /* IT->current.overlay_string_index is the number of overlay strings
2807 that have already been consumed by IT. Copy some of the
2808 remaining overlay strings to IT->overlay_strings. */
2809 i = 0;
2810 j = it->current.overlay_string_index;
2811 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2812 it->overlay_strings[i++] = entries[j++].string;
2813
2814 CHECK_IT (it);
2815}
2816
2817
2818/* Get the first chunk of overlay strings at IT's current buffer
2819 position. Value is non-zero if at least one overlay string was
2820 found. */
2821
2822static int
2823get_overlay_strings (it)
2824 struct it *it;
2825{
2826 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2827 process. This fills IT->overlay_strings with strings, and sets
2828 IT->n_overlay_strings to the total number of strings to process.
2829 IT->pos.overlay_string_index has to be set temporarily to zero
2830 because load_overlay_strings needs this; it must be set to -1
2831 when no overlay strings are found because a zero value would
2832 indicate a position in the first overlay string. */
2833 it->current.overlay_string_index = 0;
2834 load_overlay_strings (it);
2835
2836 /* If we found overlay strings, set up IT to deliver display
2837 elements from the first one. Otherwise set up IT to deliver
2838 from current_buffer. */
2839 if (it->n_overlay_strings)
2840 {
2841 /* Make sure we know settings in current_buffer, so that we can
2842 restore meaningful values when we're done with the overlay
2843 strings. */
2844 compute_stop_pos (it);
2845 xassert (it->face_id >= 0);
2846
2847 /* Save IT's settings. They are restored after all overlay
2848 strings have been processed. */
2849 xassert (it->sp == 0);
2850 push_it (it);
2851
2852 /* Set up IT to deliver display elements from the first overlay
2853 string. */
2854 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2855 it->stop_charpos = 0;
2856 it->string = it->overlay_strings[0];
2857 it->multibyte_p = STRING_MULTIBYTE (it->string);
2858 xassert (STRINGP (it->string));
2859 it->method = next_element_from_string;
2860 }
2861 else
2862 {
2863 it->string = Qnil;
2864 it->current.overlay_string_index = -1;
2865 it->method = next_element_from_buffer;
2866 }
2867
2868 CHECK_IT (it);
2869
2870 /* Value is non-zero if we found at least one overlay string. */
2871 return STRINGP (it->string);
2872}
2873
2874
2875\f
2876/***********************************************************************
2877 Saving and restoring state
2878 ***********************************************************************/
2879
2880/* Save current settings of IT on IT->stack. Called, for example,
2881 before setting up IT for an overlay string, to be able to restore
2882 IT's settings to what they were after the overlay string has been
2883 processed. */
2884
2885static void
2886push_it (it)
2887 struct it *it;
2888{
2889 struct iterator_stack_entry *p;
2890
2891 xassert (it->sp < 2);
2892 p = it->stack + it->sp;
2893
2894 p->stop_charpos = it->stop_charpos;
2895 xassert (it->face_id >= 0);
2896 p->face_id = it->face_id;
2897 p->string = it->string;
2898 p->pos = it->current;
2899 p->end_charpos = it->end_charpos;
2900 p->string_nchars = it->string_nchars;
2901 p->area = it->area;
2902 p->multibyte_p = it->multibyte_p;
2903 p->space_width = it->space_width;
2904 p->font_height = it->font_height;
2905 p->voffset = it->voffset;
2906 p->string_from_display_prop_p = it->string_from_display_prop_p;
2907 ++it->sp;
2908}
2909
2910
2911/* Restore IT's settings from IT->stack. Called, for example, when no
2912 more overlay strings must be processed, and we return to delivering
2913 display elements from a buffer, or when the end of a string from a
2914 `display' property is reached and we return to delivering display
2915 elements from an overlay string, or from a buffer. */
2916
2917static void
2918pop_it (it)
2919 struct it *it;
2920{
2921 struct iterator_stack_entry *p;
2922
2923 xassert (it->sp > 0);
2924 --it->sp;
2925 p = it->stack + it->sp;
2926 it->stop_charpos = p->stop_charpos;
2927 it->face_id = p->face_id;
2928 it->string = p->string;
2929 it->current = p->pos;
2930 it->end_charpos = p->end_charpos;
2931 it->string_nchars = p->string_nchars;
2932 it->area = p->area;
2933 it->multibyte_p = p->multibyte_p;
2934 it->space_width = p->space_width;
2935 it->font_height = p->font_height;
2936 it->voffset = p->voffset;
2937 it->string_from_display_prop_p = p->string_from_display_prop_p;
2938}
2939
2940
2941\f
2942/***********************************************************************
2943 Moving over lines
2944 ***********************************************************************/
2945
2946/* Set IT's current position to the previous line start. */
2947
2948static void
2949back_to_previous_line_start (it)
2950 struct it *it;
2951{
2952 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
2953 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2954}
2955
2956
2957/* Set IT's current position to the next line start. */
2958
2959static void
2960forward_to_next_line_start (it)
2961 struct it *it;
2962{
2963 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
2964 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2965}
2966
2967
2968/* Set IT's current position to the previous visible line start. Skip
2969 invisible text that is so either due to text properties or due to
2970 selective display. Caution: this does not change IT->current_x and
2971 IT->hpos. */
2972
2973static void
2974back_to_previous_visible_line_start (it)
2975 struct it *it;
2976{
2977 int visible_p = 0;
2978
2979 /* Go back one newline if not on BEGV already. */
2980 if (IT_CHARPOS (*it) > BEGV)
2981 back_to_previous_line_start (it);
2982
2983 /* Move over lines that are invisible because of selective display
2984 or text properties. */
2985 while (IT_CHARPOS (*it) > BEGV
2986 && !visible_p)
2987 {
2988 visible_p = 1;
2989
2990 /* If selective > 0, then lines indented more than that values
2991 are invisible. */
2992 if (it->selective > 0
2993 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
2994 it->selective))
2995 visible_p = 0;
2996#ifdef USE_TEXT_PROPERTIES
2997 else
2998 {
2999 Lisp_Object prop;
3000
3001 prop = Fget_char_property (IT_CHARPOS (*it), Qinvisible, it->window);
3002 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3003 visible_p = 0;
3004 }
3005#endif /* USE_TEXT_PROPERTIES */
3006
3007 /* Back one more newline if the current one is invisible. */
3008 if (!visible_p)
3009 back_to_previous_line_start (it);
3010 }
3011
3012 xassert (IT_CHARPOS (*it) >= BEGV);
3013 xassert (IT_CHARPOS (*it) == BEGV
3014 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3015 CHECK_IT (it);
3016}
3017
3018
3019/* Reseat iterator IT at the previous visible line start. Skip
3020 invisible text that is so either due to text properties or due to
3021 selective display. At the end, update IT's overlay information,
3022 face information etc. */
3023
3024static void
3025reseat_at_previous_visible_line_start (it)
3026 struct it *it;
3027{
3028 back_to_previous_visible_line_start (it);
3029 reseat (it, it->current.pos, 1);
3030 CHECK_IT (it);
3031}
3032
3033
3034/* Reseat iterator IT on the next visible line start in the current
312246d1
GM
3035 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3036 preceding the line start. Skip over invisible text that is so
3037 because of selective display. Compute faces, overlays etc at the
3038 new position. Note that this function does not skip over text that
3039 is invisible because of text properties. */
5f5c8ee5
GM
3040
3041static void
312246d1 3042reseat_at_next_visible_line_start (it, on_newline_p)
5f5c8ee5 3043 struct it *it;
312246d1 3044 int on_newline_p;
5f5c8ee5
GM
3045{
3046 /* Restore the buffer position when currently not delivering display
3047 elements from the current buffer. This is the case, for example,
3048 when called at the end of a truncated overlay string. */
3049 while (it->sp)
3050 pop_it (it);
3051 it->method = next_element_from_buffer;
3052
3053 /* Otherwise, scan_buffer would not work. */
3054 if (IT_CHARPOS (*it) < ZV)
3055 {
3056 /* If on a newline, advance past it. Otherwise, find the next
3057 newline which automatically gives us the position following
3058 the newline. */
3059 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3060 {
3061 ++IT_CHARPOS (*it);
3062 ++IT_BYTEPOS (*it);
3063 }
3064 else
3065 forward_to_next_line_start (it);
3066
3067 /* We must either have reached the end of the buffer or end up
3068 after a newline. */
3069 xassert (IT_CHARPOS (*it) == ZV
3070 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3071
3072 /* Skip over lines that are invisible because they are indented
3073 more than the value of IT->selective. */
3074 if (it->selective > 0)
3075 while (IT_CHARPOS (*it) < ZV
3076 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3077 it->selective))
3078 forward_to_next_line_start (it);
312246d1
GM
3079
3080 /* Position on the newline if we should. */
3081 if (on_newline_p && IT_CHARPOS (*it) > BEGV)
3082 {
3083 --IT_CHARPOS (*it);
3084 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3085 }
5f5c8ee5
GM
3086
3087 /* Set the iterator there. The 0 as the last parameter of
3088 reseat means don't force a text property lookup. The lookup
3089 is then only done if we've skipped past the iterator's
3090 check_charpos'es. This optimization is important because
3091 text property lookups tend to be expensive. */
3092 reseat (it, it->current.pos, 0);
3093 }
3094
3095 CHECK_IT (it);
3096}
3097
3098
3099\f
3100/***********************************************************************
3101 Changing an iterator's position
3102***********************************************************************/
3103
3104/* Change IT's current position to POS in current_buffer. If FORCE_P
3105 is non-zero, always check for text properties at the new position.
3106 Otherwise, text properties are only looked up if POS >=
3107 IT->check_charpos of a property. */
3108
3109static void
3110reseat (it, pos, force_p)
3111 struct it *it;
3112 struct text_pos pos;
3113 int force_p;
3114{
3115 int original_pos = IT_CHARPOS (*it);
3116
3117 reseat_1 (it, pos, 0);
3118
3119 /* Determine where to check text properties. Avoid doing it
3120 where possible because text property lookup is very expensive. */
3121 if (force_p
3122 || CHARPOS (pos) > it->stop_charpos
3123 || CHARPOS (pos) < original_pos)
3124 handle_stop (it);
3125
3126 CHECK_IT (it);
3127}
3128
3129
3130/* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3131 IT->stop_pos to POS, also. */
3132
3133static void
3134reseat_1 (it, pos, set_stop_p)
3135 struct it *it;
3136 struct text_pos pos;
3137 int set_stop_p;
3138{
3139 /* Don't call this function when scanning a C string. */
3140 xassert (it->s == NULL);
3141
3142 /* POS must be a reasonable value. */
3143 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3144
3145 it->current.pos = it->position = pos;
3146 XSETBUFFER (it->object, current_buffer);
3147 it->dpvec = NULL;
3148 it->current.dpvec_index = -1;
3149 it->current.overlay_string_index = -1;
3150 IT_STRING_CHARPOS (*it) = -1;
3151 IT_STRING_BYTEPOS (*it) = -1;
3152 it->string = Qnil;
3153 it->method = next_element_from_buffer;
3154 it->sp = 0;
3155
3156 if (set_stop_p)
3157 it->stop_charpos = CHARPOS (pos);
3158}
3159
3160
3161/* Set up IT for displaying a string, starting at CHARPOS in window W.
3162 If S is non-null, it is a C string to iterate over. Otherwise,
3163 STRING gives a Lisp string to iterate over.
3164
3165 If PRECISION > 0, don't return more then PRECISION number of
3166 characters from the string.
3167
3168 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3169 characters have been returned. FIELD_WIDTH < 0 means an infinite
3170 field width.
3171
3172 MULTIBYTE = 0 means disable processing of multibyte characters,
3173 MULTIBYTE > 0 means enable it,
3174 MULTIBYTE < 0 means use IT->multibyte_p.
3175
3176 IT must be initialized via a prior call to init_iterator before
3177 calling this function. */
3178
3179static void
3180reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3181 struct it *it;
3182 unsigned char *s;
3183 Lisp_Object string;
3184 int charpos;
3185 int precision, field_width, multibyte;
3186{
3187 /* No region in strings. */
3188 it->region_beg_charpos = it->region_end_charpos = -1;
3189
3190 /* No text property checks performed by default, but see below. */
3191 it->stop_charpos = -1;
3192
3193 /* Set iterator position and end position. */
3194 bzero (&it->current, sizeof it->current);
3195 it->current.overlay_string_index = -1;
3196 it->current.dpvec_index = -1;
3197 it->charset = CHARSET_ASCII;
3198 xassert (charpos >= 0);
3199
3200 /* Use the setting of MULTIBYTE if specified. */
3201 if (multibyte >= 0)
3202 it->multibyte_p = multibyte > 0;
3203
3204 if (s == NULL)
3205 {
3206 xassert (STRINGP (string));
3207 it->string = string;
3208 it->s = NULL;
3209 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3210 it->method = next_element_from_string;
3211 it->current.string_pos = string_pos (charpos, string);
3212 }
3213 else
3214 {
3215 it->s = s;
3216 it->string = Qnil;
3217
3218 /* Note that we use IT->current.pos, not it->current.string_pos,
3219 for displaying C strings. */
3220 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3221 if (it->multibyte_p)
3222 {
3223 it->current.pos = c_string_pos (charpos, s, 1);
3224 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3225 }
3226 else
3227 {
3228 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3229 it->end_charpos = it->string_nchars = strlen (s);
3230 }
3231
3232 it->method = next_element_from_c_string;
3233 }
3234
3235 /* PRECISION > 0 means don't return more than PRECISION characters
3236 from the string. */
3237 if (precision > 0 && it->end_charpos - charpos > precision)
3238 it->end_charpos = it->string_nchars = charpos + precision;
3239
3240 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3241 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3242 FIELD_WIDTH < 0 means infinite field width. This is useful for
3243 padding with `-' at the end of a mode line. */
3244 if (field_width < 0)
3245 field_width = INFINITY;
3246 if (field_width > it->end_charpos - charpos)
3247 it->end_charpos = charpos + field_width;
3248
3249 /* Use the standard display table for displaying strings. */
3250 if (DISP_TABLE_P (Vstandard_display_table))
3251 it->dp = XCHAR_TABLE (Vstandard_display_table);
3252
3253 it->stop_charpos = charpos;
3254 CHECK_IT (it);
3255}
3256
3257
3258\f
3259/***********************************************************************
3260 Iteration
3261 ***********************************************************************/
3262
3263/* Load IT's display element fields with information about the next
3264 display element from the current position of IT. Value is zero if
3265 end of buffer (or C string) is reached. */
3266
3267int
3268get_next_display_element (it)
3269 struct it *it;
3270{
3271 /* Non-zero means that we found an display element. Zero means that
3272 we hit the end of what we iterate over. Performance note: the
3273 function pointer `method' used here turns out to be faster than
3274 using a sequence of if-statements. */
3275 int success_p = (*it->method) (it);
3276 int charset;
3277
3278 if (it->what == IT_CHARACTER)
3279 {
3280 /* Map via display table or translate control characters.
3281 IT->c, IT->len etc. have been set to the next character by
3282 the function call above. If we have a display table, and it
3283 contains an entry for IT->c, translate it. Don't do this if
3284 IT->c itself comes from a display table, otherwise we could
3285 end up in an infinite recursion. (An alternative could be to
3286 count the recursion depth of this function and signal an
3287 error when a certain maximum depth is reached.) Is it worth
3288 it? */
3289 if (success_p && it->dpvec == NULL)
3290 {
3291 Lisp_Object dv;
3292
3293 if (it->dp
3294 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3295 VECTORP (dv)))
3296 {
3297 struct Lisp_Vector *v = XVECTOR (dv);
3298
3299 /* Return the first character from the display table
3300 entry, if not empty. If empty, don't display the
3301 current character. */
3302 if (v->size)
3303 {
3304 it->dpvec_char_len = it->len;
3305 it->dpvec = v->contents;
3306 it->dpend = v->contents + v->size;
3307 it->current.dpvec_index = 0;
3308 it->method = next_element_from_display_vector;
3309 }
3310
3311 success_p = get_next_display_element (it);
3312 }
3313
3314 /* Translate control characters into `\003' or `^C' form.
3315 Control characters coming from a display table entry are
3316 currently not translated because we use IT->dpvec to hold
3317 the translation. This could easily be changed but I
3318 don't believe that it is worth doing. */
3319 else if ((it->c < ' '
3320 && (it->area != TEXT_AREA
3321 || (it->c != '\n'
3322 && it->c != '\t'
3323 && it->c != '\r')))
54c85a23 3324 || (it->c >= 127
5f5c8ee5
GM
3325 && it->len == 1))
3326 {
3327 /* IT->c is a control character which must be displayed
3328 either as '\003' or as `^C' where the '\\' and '^'
3329 can be defined in the display table. Fill
3330 IT->ctl_chars with glyphs for what we have to
3331 display. Then, set IT->dpvec to these glyphs. */
3332 GLYPH g;
3333
54c85a23 3334 if (it->c < 128 && it->ctl_arrow_p)
5f5c8ee5
GM
3335 {
3336 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3337 if (it->dp
3338 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3339 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3340 g = XINT (DISP_CTRL_GLYPH (it->dp));
3341 else
3342 g = FAST_MAKE_GLYPH ('^', 0);
3343 XSETINT (it->ctl_chars[0], g);
3344
3345 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3346 XSETINT (it->ctl_chars[1], g);
3347
3348 /* Set up IT->dpvec and return first character from it. */
3349 it->dpvec_char_len = it->len;
3350 it->dpvec = it->ctl_chars;
3351 it->dpend = it->dpvec + 2;
3352 it->current.dpvec_index = 0;
3353 it->method = next_element_from_display_vector;
3354 get_next_display_element (it);
3355 }
3356 else
3357 {
3358 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3359 if (it->dp
3360 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3361 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3362 g = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3363 else
3364 g = FAST_MAKE_GLYPH ('\\', 0);
3365 XSETINT (it->ctl_chars[0], g);
3366
3367 /* Insert three more glyphs into IT->ctl_chars for
3368 the octal display of the character. */
3369 g = FAST_MAKE_GLYPH (((it->c >> 6) & 7) + '0', 0);
3370 XSETINT (it->ctl_chars[1], g);
3371 g = FAST_MAKE_GLYPH (((it->c >> 3) & 7) + '0', 0);
3372 XSETINT (it->ctl_chars[2], g);
3373 g = FAST_MAKE_GLYPH ((it->c & 7) + '0', 0);
3374 XSETINT (it->ctl_chars[3], g);
3375
3376 /* Set up IT->dpvec and return the first character
3377 from it. */
3378 it->dpvec_char_len = it->len;
3379 it->dpvec = it->ctl_chars;
3380 it->dpend = it->dpvec + 4;
3381 it->current.dpvec_index = 0;
3382 it->method = next_element_from_display_vector;
3383 get_next_display_element (it);
3384 }
3385 }
3386 }
3387
3388 /* Adjust face id if charset changes. There are no charset
3389 changes in unibyte text because Emacs' charsets are not
3390 applicable there. */
3391 if (it->multibyte_p
3392 && success_p
3393 && (charset = CHAR_CHARSET (it->c),
3394 charset != it->charset))
3395 {
3396 it->charset = charset;
3397 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, charset);
3398 }
3399 }
3400
3401 /* Is this character the last one of a run of characters with
3402 box? If yes, set IT->end_of_box_run_p to 1. */
3403 if (it->face_box_p
3404 && it->s == NULL)
3405 {
3406 int face_id;
3407 struct face *face;
3408
3409 it->end_of_box_run_p
3410 = ((face_id = face_after_it_pos (it),
3411 face_id != it->face_id)
3412 && (face = FACE_FROM_ID (it->f, face_id),
3413 face->box == FACE_NO_BOX));
3414 }
3415
3416 /* Value is 0 if end of buffer or string reached. */
3417 return success_p;
3418}
3419
3420
3421/* Move IT to the next display element.
3422
3423 Functions get_next_display_element and set_iterator_to_next are
3424 separate because I find this arrangement easier to handle than a
3425 get_next_display_element function that also increments IT's
3426 position. The way it is we can first look at an iterator's current
3427 display element, decide whether it fits on a line, and if it does,
3428 increment the iterator position. The other way around we probably
3429 would either need a flag indicating whether the iterator has to be
3430 incremented the next time, or we would have to implement a
3431 decrement position function which would not be easy to write. */
3432
3433void
3434set_iterator_to_next (it)
3435 struct it *it;
3436{
3437 if (it->method == next_element_from_buffer)
3438 {
3439 /* The current display element of IT is a character from
3440 current_buffer. Advance in the buffer, and maybe skip over
3441 invisible lines that are so because of selective display. */
3442 if (ITERATOR_AT_END_OF_LINE_P (it))
312246d1 3443 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
3444 else
3445 {
3446 xassert (it->len != 0);
3447 IT_BYTEPOS (*it) += it->len;
3448 IT_CHARPOS (*it) += 1;
3449 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3450 }
3451 }
3452 else if (it->method == next_element_from_c_string)
3453 {
3454 /* Current display element of IT is from a C string. */
3455 IT_BYTEPOS (*it) += it->len;
3456 IT_CHARPOS (*it) += 1;
3457 }
3458 else if (it->method == next_element_from_display_vector)
3459 {
3460 /* Current display element of IT is from a display table entry.
3461 Advance in the display table definition. Reset it to null if
3462 end reached, and continue with characters from buffers/
3463 strings. */
286bcbc9
GM
3464 struct face *face;
3465
5f5c8ee5 3466 ++it->current.dpvec_index;
286bcbc9
GM
3467
3468 /* Restore face and charset of the iterator to what they were
3469 before the display vector entry (these entries may contain
3470 faces, and of course characters of different charsets). */
5f5c8ee5 3471 it->face_id = it->saved_face_id;
286bcbc9
GM
3472 it->charset = FACE_FROM_ID (it->f, it->face_id)->charset;
3473
5f5c8ee5
GM
3474 if (it->dpvec + it->current.dpvec_index == it->dpend)
3475 {
3476 if (it->s)
3477 it->method = next_element_from_c_string;
3478 else if (STRINGP (it->string))
3479 it->method = next_element_from_string;
3480 else
3481 it->method = next_element_from_buffer;
3482
3483 it->dpvec = NULL;
3484 it->current.dpvec_index = -1;
3485
312246d1
GM
3486 /* Skip over characters which were displayed via IT->dpvec. */
3487 if (it->dpvec_char_len < 0)
3488 reseat_at_next_visible_line_start (it, 1);
3489 else if (it->dpvec_char_len > 0)
5f5c8ee5
GM
3490 {
3491 it->len = it->dpvec_char_len;
3492 set_iterator_to_next (it);
3493 }
3494 }
3495 }
3496 else if (it->method == next_element_from_string)
3497 {
3498 /* Current display element is a character from a Lisp string. */
3499 xassert (it->s == NULL && STRINGP (it->string));
3500 IT_STRING_BYTEPOS (*it) += it->len;
3501 IT_STRING_CHARPOS (*it) += 1;
3502
3503 consider_string_end:
3504
3505 if (it->current.overlay_string_index >= 0)
3506 {
3507 /* IT->string is an overlay string. Advance to the
3508 next, if there is one. */
3509 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3510 next_overlay_string (it);
3511 }
3512 else
3513 {
3514 /* IT->string is not an overlay string. If we reached
3515 its end, and there is something on IT->stack, proceed
3516 with what is on the stack. This can be either another
3517 string, this time an overlay string, or a buffer. */
3518 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3519 && it->sp > 0)
3520 {
3521 pop_it (it);
3522 if (!STRINGP (it->string))
3523 it->method = next_element_from_buffer;
3524 }
3525 }
3526 }
3527 else if (it->method == next_element_from_image
3528 || it->method == next_element_from_stretch)
3529 {
3530 /* The position etc with which we have to proceed are on
3531 the stack. The position may be at the end of a string,
3532 if the `display' property takes up the whole string. */
3533 pop_it (it);
3534 it->image_id = 0;
3535 if (STRINGP (it->string))
3536 {
3537 it->method = next_element_from_string;
3538 goto consider_string_end;
3539 }
3540 else
3541 it->method = next_element_from_buffer;
3542 }
3543 else
3544 /* There are no other methods defined, so this should be a bug. */
3545 abort ();
3546
3547 /* Reset flags indicating start and end of a sequence of
3548 characters with box. */
3549 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3550
3551 xassert (it->method != next_element_from_string
3552 || (STRINGP (it->string)
3553 && IT_STRING_CHARPOS (*it) >= 0));
3554}
3555
3556
3557/* Load IT's display element fields with information about the next
3558 display element which comes from a display table entry or from the
3559 result of translating a control character to one of the forms `^C'
3560 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3561
3562static int
3563next_element_from_display_vector (it)
3564 struct it *it;
3565{
3566 /* Precondition. */
3567 xassert (it->dpvec && it->current.dpvec_index >= 0);
3568
3569 /* Remember the current face id in case glyphs specify faces.
3570 IT's face is restored in set_iterator_to_next. */
3571 it->saved_face_id = it->face_id;
3572
3573 if (INTEGERP (*it->dpvec)
3574 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3575 {
3576 int lface_id;
3577 GLYPH g;
3578
3579 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3580 it->c = FAST_GLYPH_CHAR (g);
3581 it->len = CHAR_LEN (it->c);
3582
3583 /* The entry may contain a face id to use. Such a face id is
3584 the id of a Lisp face, not a realized face. A face id of
3585 zero means no face. */
3586 lface_id = FAST_GLYPH_FACE (g);
3587 if (lface_id)
3588 {
3589 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3590 if (face_id >= 0)
3591 {
3592 it->face_id = face_id;
3593 it->charset = CHARSET_ASCII;
3594 }
3595 }
3596 }
3597 else
3598 /* Display table entry is invalid. Return a space. */
3599 it->c = ' ', it->len = 1;
3600
3601 /* Don't change position and object of the iterator here. They are
3602 still the values of the character that had this display table
3603 entry or was translated, and that's what we want. */
3604 it->what = IT_CHARACTER;
3605 return 1;
3606}
3607
3608
3609/* Load IT with the next display element from Lisp string IT->string.
3610 IT->current.string_pos is the current position within the string.
3611 If IT->current.overlay_string_index >= 0, the Lisp string is an
3612 overlay string. */
3613
3614static int
3615next_element_from_string (it)
3616 struct it *it;
3617{
3618 struct text_pos position;
3619
3620 xassert (STRINGP (it->string));
3621 xassert (IT_STRING_CHARPOS (*it) >= 0);
3622 position = it->current.string_pos;
3623
3624 /* Time to check for invisible text? */
3625 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3626 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3627 {
3628 handle_stop (it);
3629
3630 /* Since a handler may have changed IT->method, we must
3631 recurse here. */
3632 return get_next_display_element (it);
3633 }
3634
3635 if (it->current.overlay_string_index >= 0)
3636 {
3637 /* Get the next character from an overlay string. In overlay
3638 strings, There is no field width or padding with spaces to
3639 do. */
3640 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3641 {
3642 it->what = IT_EOB;
3643 return 0;
3644 }
3645 else if (STRING_MULTIBYTE (it->string))
3646 {
3647 int remaining = (STRING_BYTES (XSTRING (it->string))
3648 - IT_STRING_BYTEPOS (*it));
3649 unsigned char *s = (XSTRING (it->string)->data
3650 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3651 it->c = string_char_and_length (s, remaining, &it->len);
5f5c8ee5
GM
3652 }
3653 else
3654 {
3655 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3656 it->len = 1;
3657 }
3658 }
3659 else
3660 {
3661 /* Get the next character from a Lisp string that is not an
3662 overlay string. Such strings come from the mode line, for
3663 example. We may have to pad with spaces, or truncate the
3664 string. See also next_element_from_c_string. */
3665 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3666 {
3667 it->what = IT_EOB;
3668 return 0;
3669 }
3670 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3671 {
3672 /* Pad with spaces. */
3673 it->c = ' ', it->len = 1;
3674 CHARPOS (position) = BYTEPOS (position) = -1;
3675 }
3676 else if (STRING_MULTIBYTE (it->string))
3677 {
3678 int maxlen = (STRING_BYTES (XSTRING (it->string))
3679 - IT_STRING_BYTEPOS (*it));
3680 unsigned char *s = (XSTRING (it->string)->data
3681 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3682 it->c = string_char_and_length (s, maxlen, &it->len);
5f5c8ee5
GM
3683 }
3684 else
3685 {
3686 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3687 it->len = 1;
3688 }
3689 }
3690
3691 /* Record what we have and where it came from. Note that we store a
3692 buffer position in IT->position although it could arguably be a
3693 string position. */
3694 it->what = IT_CHARACTER;
3695 it->object = it->string;
3696 it->position = position;
3697 return 1;
3698}
3699
3700
3701/* Load IT with next display element from C string IT->s.
3702 IT->string_nchars is the maximum number of characters to return
3703 from the string. IT->end_charpos may be greater than
3704 IT->string_nchars when this function is called, in which case we
3705 may have to return padding spaces. Value is zero if end of string
3706 reached, including padding spaces. */
3707
3708static int
3709next_element_from_c_string (it)
3710 struct it *it;
3711{
3712 int success_p = 1;
3713
3714 xassert (it->s);
3715 it->what = IT_CHARACTER;
3716 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3717 it->object = Qnil;
3718
3719 /* IT's position can be greater IT->string_nchars in case a field
3720 width or precision has been specified when the iterator was
3721 initialized. */
3722 if (IT_CHARPOS (*it) >= it->end_charpos)
3723 {
3724 /* End of the game. */
3725 it->what = IT_EOB;
3726 success_p = 0;
3727 }
3728 else if (IT_CHARPOS (*it) >= it->string_nchars)
3729 {
3730 /* Pad with spaces. */
3731 it->c = ' ', it->len = 1;
3732 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3733 }
3734 else if (it->multibyte_p)
3735 {
3736 /* Implementation note: The calls to strlen apparently aren't a
3737 performance problem because there is no noticeable performance
3738 difference between Emacs running in unibyte or multibyte mode. */
3739 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
4fdb80f2
GM
3740 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3741 maxlen, &it->len);
5f5c8ee5
GM
3742 }
3743 else
3744 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3745
3746 return success_p;
3747}
3748
3749
3750/* Set up IT to return characters from an ellipsis, if appropriate.
3751 The definition of the ellipsis glyphs may come from a display table
3752 entry. This function Fills IT with the first glyph from the
3753 ellipsis if an ellipsis is to be displayed. */
3754
3755static void
3756next_element_from_ellipsis (it)
3757 struct it *it;
3758{
3759 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3760 {
3761 /* Use the display table definition for `...'. Invalid glyphs
3762 will be handled by the method returning elements from dpvec. */
3763 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3764 it->dpvec_char_len = it->len;
3765 it->dpvec = v->contents;
3766 it->dpend = v->contents + v->size;
3767 it->current.dpvec_index = 0;
3768 it->method = next_element_from_display_vector;
3769 get_next_display_element (it);
3770 }
3771 else if (it->selective_display_ellipsis_p)
3772 {
3773 /* Use default `...' which is stored in default_invis_vector. */
3774 it->dpvec_char_len = it->len;
3775 it->dpvec = default_invis_vector;
3776 it->dpend = default_invis_vector + 3;
3777 it->current.dpvec_index = 0;
3778 it->method = next_element_from_display_vector;
3779 get_next_display_element (it);
3780 }
3781}
3782
3783
3784/* Deliver an image display element. The iterator IT is already
3785 filled with image information (done in handle_display_prop). Value
3786 is always 1. */
3787
3788
3789static int
3790next_element_from_image (it)
3791 struct it *it;
3792{
3793 it->what = IT_IMAGE;
3794 return 1;
3795}
3796
3797
3798/* Fill iterator IT with next display element from a stretch glyph
3799 property. IT->object is the value of the text property. Value is
3800 always 1. */
3801
3802static int
3803next_element_from_stretch (it)
3804 struct it *it;
3805{
3806 it->what = IT_STRETCH;
3807 return 1;
3808}
3809
3810
3811/* Load IT with the next display element from current_buffer. Value
3812 is zero if end of buffer reached. IT->stop_charpos is the next
3813 position at which to stop and check for text properties or buffer
3814 end. */
3815
3816static int
3817next_element_from_buffer (it)
3818 struct it *it;
3819{
3820 int success_p = 1;
3821
3822 /* Check this assumption, otherwise, we would never enter the
3823 if-statement, below. */
3824 xassert (IT_CHARPOS (*it) >= BEGV
3825 && IT_CHARPOS (*it) <= it->stop_charpos);
3826
3827 if (IT_CHARPOS (*it) >= it->stop_charpos)
3828 {
3829 if (IT_CHARPOS (*it) >= it->end_charpos)
3830 {
3831 int overlay_strings_follow_p;
3832
3833 /* End of the game, except when overlay strings follow that
3834 haven't been returned yet. */
3835 if (it->overlay_strings_at_end_processed_p)
3836 overlay_strings_follow_p = 0;
3837 else
3838 {
3839 it->overlay_strings_at_end_processed_p = 1;
3840 overlay_strings_follow_p
3841 = get_overlay_strings (it);
3842 }
3843
3844 if (overlay_strings_follow_p)
3845 success_p = get_next_display_element (it);
3846 else
3847 {
3848 it->what = IT_EOB;
3849 it->position = it->current.pos;
3850 success_p = 0;
3851 }
3852 }
3853 else
3854 {
3855 handle_stop (it);
3856 return get_next_display_element (it);
3857 }
3858 }
3859 else
3860 {
3861 /* No face changes, overlays etc. in sight, so just return a
3862 character from current_buffer. */
3863 unsigned char *p;
3864
3865 /* Maybe run the redisplay end trigger hook. Performance note:
3866 This doesn't seem to cost measurable time. */
3867 if (it->redisplay_end_trigger_charpos
3868 && it->glyph_row
3869 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3870 run_redisplay_end_trigger_hook (it);
3871
3872 /* Get the next character, maybe multibyte. */
3873 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3874 if (it->multibyte_p)
3875 {
3876 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3877 - IT_BYTEPOS (*it));
4fdb80f2 3878 it->c = string_char_and_length (p, maxlen, &it->len);
5f5c8ee5
GM
3879 }
3880 else
3881 it->c = *p, it->len = 1;
3882
3883 /* Record what we have and where it came from. */
3884 it->what = IT_CHARACTER;;
3885 it->object = it->w->buffer;
3886 it->position = it->current.pos;
3887
3888 /* Normally we return the character found above, except when we
3889 really want to return an ellipsis for selective display. */
3890 if (it->selective)
3891 {
3892 if (it->c == '\n')
3893 {
3894 /* A value of selective > 0 means hide lines indented more
3895 than that number of columns. */
3896 if (it->selective > 0
3897 && IT_CHARPOS (*it) + 1 < ZV
3898 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3899 IT_BYTEPOS (*it) + 1,
3900 it->selective))
312246d1
GM
3901 {
3902 next_element_from_ellipsis (it);
3903 it->dpvec_char_len = -1;
3904 }
5f5c8ee5
GM
3905 }
3906 else if (it->c == '\r' && it->selective == -1)
3907 {
3908 /* A value of selective == -1 means that everything from the
3909 CR to the end of the line is invisible, with maybe an
3910 ellipsis displayed for it. */
3911 next_element_from_ellipsis (it);
312246d1 3912 it->dpvec_char_len = -1;
5f5c8ee5
GM
3913 }
3914 }
3915 }
3916
3917 /* Value is zero if end of buffer reached. */
3918 xassert (!success_p || it->len > 0);
3919 return success_p;
3920}
3921
3922
3923/* Run the redisplay end trigger hook for IT. */
3924
3925static void
3926run_redisplay_end_trigger_hook (it)
3927 struct it *it;
3928{
3929 Lisp_Object args[3];
3930
3931 /* IT->glyph_row should be non-null, i.e. we should be actually
3932 displaying something, or otherwise we should not run the hook. */
3933 xassert (it->glyph_row);
3934
3935 /* Set up hook arguments. */
3936 args[0] = Qredisplay_end_trigger_functions;
3937 args[1] = it->window;
3938 XSETINT (args[2], it->redisplay_end_trigger_charpos);
3939 it->redisplay_end_trigger_charpos = 0;
3940
3941 /* Since we are *trying* to run these functions, don't try to run
3942 them again, even if they get an error. */
3943 it->w->redisplay_end_trigger = Qnil;
3944 Frun_hook_with_args (3, args);
3945
3946 /* Notice if it changed the face of the character we are on. */
3947 handle_face_prop (it);
3948}
3949
3950
3951\f
3952/***********************************************************************
3953 Moving an iterator without producing glyphs
3954 ***********************************************************************/
3955
3956/* Move iterator IT to a specified buffer or X position within one
3957 line on the display without producing glyphs.
3958
3959 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
3960 whichever is reached first.
3961
3962 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
3963
3964 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
3965 0 <= TO_X <= IT->last_visible_x. This means in particular, that
3966 TO_X includes the amount by which a window is horizontally
3967 scrolled.
3968
3969 Value is
3970
3971 MOVE_POS_MATCH_OR_ZV
3972 - when TO_POS or ZV was reached.
3973
3974 MOVE_X_REACHED
3975 -when TO_X was reached before TO_POS or ZV were reached.
3976
3977 MOVE_LINE_CONTINUED
3978 - when we reached the end of the display area and the line must
3979 be continued.
3980
3981 MOVE_LINE_TRUNCATED
3982 - when we reached the end of the display area and the line is
3983 truncated.
3984
3985 MOVE_NEWLINE_OR_CR
3986 - when we stopped at a line end, i.e. a newline or a CR and selective
3987 display is on. */
3988
3989enum move_it_result
3990move_it_in_display_line_to (it, to_charpos, to_x, op)
3991 struct it *it;
3992 int to_charpos, to_x, op;
3993{
3994 enum move_it_result result = MOVE_UNDEFINED;
3995 struct glyph_row *saved_glyph_row;
3996
3997 /* Don't produce glyphs in produce_glyphs. */
3998 saved_glyph_row = it->glyph_row;
3999 it->glyph_row = NULL;
4000
4001#if NO_PROMPT_IN_BUFFER
4002 /* Take a mini-buffer prompt into account. */
4003 if (MINI_WINDOW_P (it->w)
4004 && IT_CHARPOS (*it) == BEGV)
4005 {
4006 it->current_x = minibuf_prompt_pixel_width;
4007 it->hpos = minibuf_prompt_width;
4008 }
4009#endif
4010
4011 while (1)
4012 {
4013 int x, i;
4014
4015 /* Stop when ZV or TO_CHARPOS reached. */
4016 if (!get_next_display_element (it)
4017 || ((op & MOVE_TO_POS) != 0
4018 && BUFFERP (it->object)
4019 && IT_CHARPOS (*it) >= to_charpos))
4020 {
4021 result = MOVE_POS_MATCH_OR_ZV;
4022 break;
4023 }
4024
4025 /* The call to produce_glyphs will get the metrics of the
4026 display element IT is loaded with. We record in x the
4027 x-position before this display element in case it does not
4028 fit on the line. */
4029 x = it->current_x;
4030 PRODUCE_GLYPHS (it);
4031
4032 if (it->area != TEXT_AREA)
4033 {
4034 set_iterator_to_next (it);
4035 continue;
4036 }
4037
4038 /* The number of glyphs we get back in IT->nglyphs will normally
4039 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4040 character on a terminal frame, or (iii) a line end. For the
4041 second case, IT->nglyphs - 1 padding glyphs will be present
4042 (on X frames, there is only one glyph produced for a
4043 composite character.
4044
4045 The behavior implemented below means, for continuation lines,
4046 that as many spaces of a TAB as fit on the current line are
4047 displayed there. For terminal frames, as many glyphs of a
4048 multi-glyph character are displayed in the current line, too.
4049 This is what the old redisplay code did, and we keep it that
4050 way. Under X, the whole shape of a complex character must
4051 fit on the line or it will be completely displayed in the
4052 next line.
4053
4054 Note that both for tabs and padding glyphs, all glyphs have
4055 the same width. */
4056 if (it->nglyphs)
4057 {
4058 /* More than one glyph or glyph doesn't fit on line. All
4059 glyphs have the same width. */
4060 int single_glyph_width = it->pixel_width / it->nglyphs;
4061 int new_x;
4062
4063 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4064 {
4065 new_x = x + single_glyph_width;
4066
4067 /* We want to leave anything reaching TO_X to the caller. */
4068 if ((op & MOVE_TO_X) && new_x > to_x)
4069 {
4070 it->current_x = x;
4071 result = MOVE_X_REACHED;
4072 break;
4073 }
4074 else if (/* Lines are continued. */
4075 !it->truncate_lines_p
4076 && (/* And glyph doesn't fit on the line. */
4077 new_x > it->last_visible_x
4078 /* Or it fits exactly and we're on a window
4079 system frame. */
4080 || (new_x == it->last_visible_x
4081 && FRAME_WINDOW_P (it->f))))
4082 {
4083 if (/* IT->hpos == 0 means the very first glyph
4084 doesn't fit on the line, e.g. a wide image. */
4085 it->hpos == 0
4086 || (new_x == it->last_visible_x
4087 && FRAME_WINDOW_P (it->f)))
4088 {
4089 ++it->hpos;
4090 it->current_x = new_x;
4091 if (i == it->nglyphs - 1)
4092 set_iterator_to_next (it);
4093 }
4094 else
4095 it->current_x = x;
4096
4097 result = MOVE_LINE_CONTINUED;
4098 break;
4099 }
4100 else if (new_x > it->first_visible_x)
4101 {
4102 /* Glyph is visible. Increment number of glyphs that
4103 would be displayed. */
4104 ++it->hpos;
4105 }
4106 else
4107 {
4108 /* Glyph is completely off the left margin of the display
4109 area. Nothing to do. */
4110 }
4111 }
4112
4113 if (result != MOVE_UNDEFINED)
4114 break;
4115 }
4116 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4117 {
4118 /* Stop when TO_X specified and reached. This check is
4119 necessary here because of lines consisting of a line end,
4120 only. The line end will not produce any glyphs and we
4121 would never get MOVE_X_REACHED. */
4122 xassert (it->nglyphs == 0);
4123 result = MOVE_X_REACHED;
4124 break;
4125 }
4126
4127 /* Is this a line end? If yes, we're done. */
4128 if (ITERATOR_AT_END_OF_LINE_P (it))
4129 {
4130 result = MOVE_NEWLINE_OR_CR;
4131 break;
4132 }
4133
4134 /* The current display element has been consumed. Advance
4135 to the next. */
4136 set_iterator_to_next (it);
4137
4138 /* Stop if lines are truncated and IT's current x-position is
4139 past the right edge of the window now. */
4140 if (it->truncate_lines_p
4141 && it->current_x >= it->last_visible_x)
4142 {
4143 result = MOVE_LINE_TRUNCATED;
4144 break;
4145 }
4146 }
4147
4148 /* Restore the iterator settings altered at the beginning of this
4149 function. */
4150 it->glyph_row = saved_glyph_row;
4151 return result;
4152}
4153
4154
4155/* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4156 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4157 the description of enum move_operation_enum.
4158
4159 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4160 screen line, this function will set IT to the next position >
4161 TO_CHARPOS. */
4162
4163void
4164move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4165 struct it *it;
4166 int to_charpos, to_x, to_y, to_vpos;
4167 int op;
4168{
4169 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4170 int line_height;
4171
4172 xassert (XBUFFER (it->w->buffer) == current_buffer);
4173
4174 while (1)
4175 {
4176 if (op & MOVE_TO_VPOS)
4177 {
4178 /* If no TO_CHARPOS and no TO_X specified, stop at the
4179 start of the line TO_VPOS. */
4180 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4181 {
4182 if (it->vpos == to_vpos)
4183 break;
4184 skip = move_it_in_display_line_to (it, -1, -1, 0);
4185 }
4186 else
4187 {
4188 /* TO_VPOS >= 0 means stop at TO_X in the line at
4189 TO_VPOS, or at TO_POS, whichever comes first. */
4190 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4191
4192 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4193 break;
4194 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4195 {
4196 /* We have reached TO_X but not in the line we want. */
4197 skip = move_it_in_display_line_to (it, to_charpos,
4198 -1, MOVE_TO_POS);
4199 if (skip == MOVE_POS_MATCH_OR_ZV)
4200 break;
4201 }
4202 }
4203 }
4204 else if (op & MOVE_TO_Y)
4205 {
4206 struct it it_backup;
4207 int done_p;
4208
4209 /* TO_Y specified means stop at TO_X in the line containing
4210 TO_Y---or at TO_CHARPOS if this is reached first. The
4211 problem is that we can't really tell whether the line
4212 contains TO_Y before we have completely scanned it, and
4213 this may skip past TO_X. What we do is to first scan to
4214 TO_X.
4215
4216 If TO_X is not specified, use a TO_X of zero. The reason
4217 is to make the outcome of this function more predictable.
4218 If we didn't use TO_X == 0, we would stop at the end of
4219 the line which is probably not what a caller would expect
4220 to happen. */
4221 skip = move_it_in_display_line_to (it, to_charpos,
4222 ((op & MOVE_TO_X)
4223 ? to_x : 0),
4224 (MOVE_TO_X
4225 | (op & MOVE_TO_POS)));
4226
4227 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4228 if (skip == MOVE_POS_MATCH_OR_ZV)
4229 break;
4230
4231 /* If TO_X was reached, we would like to know whether TO_Y
4232 is in the line. This can only be said if we know the
4233 total line height which requires us to scan the rest of
4234 the line. */
4235 done_p = 0;
4236 if (skip == MOVE_X_REACHED)
4237 {
4238 it_backup = *it;
4239 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4240 op & MOVE_TO_POS);
4241 }
4242
4243 /* Now, decide whether TO_Y is in this line. */
4244 line_height = it->max_ascent + it->max_descent;
4245
4246 if (to_y >= it->current_y
4247 && to_y < it->current_y + line_height)
4248 {
4249 if (skip == MOVE_X_REACHED)
4250 /* If TO_Y is in this line and TO_X was reached above,
4251 we scanned too far. We have to restore IT's settings
4252 to the ones before skipping. */
4253 *it = it_backup;
4254 done_p = 1;
4255 }
4256 else if (skip == MOVE_X_REACHED)
4257 {
4258 skip = skip2;
4259 if (skip == MOVE_POS_MATCH_OR_ZV)
4260 done_p = 1;
4261 }
4262
4263 if (done_p)
4264 break;
4265 }
4266 else
4267 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4268
4269 switch (skip)
4270 {
4271 case MOVE_POS_MATCH_OR_ZV:
4272 return;
4273
4274 case MOVE_NEWLINE_OR_CR:
4275 set_iterator_to_next (it);
4276 it->continuation_lines_width = 0;
4277 break;
4278
4279 case MOVE_LINE_TRUNCATED:
4280 it->continuation_lines_width = 0;
312246d1 4281 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
4282 if ((op & MOVE_TO_POS) != 0
4283 && IT_CHARPOS (*it) > to_charpos)
4284 goto out;
4285 break;
4286
4287 case MOVE_LINE_CONTINUED:
4288 it->continuation_lines_width += it->current_x;
4289 break;
4290
4291 default:
4292 abort ();
4293 }
4294
4295 /* Reset/increment for the next run. */
4296 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4297 it->current_x = it->hpos = 0;
4298 it->current_y += it->max_ascent + it->max_descent;
4299 ++it->vpos;
4300 last_height = it->max_ascent + it->max_descent;
4301 last_max_ascent = it->max_ascent;
4302 it->max_ascent = it->max_descent = 0;
4303 }
4304 out:;
4305}
4306
4307
4308/* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4309
4310 If DY > 0, move IT backward at least that many pixels. DY = 0
4311 means move IT backward to the preceding line start or BEGV. This
4312 function may move over more than DY pixels if IT->current_y - DY
4313 ends up in the middle of a line; in this case IT->current_y will be
4314 set to the top of the line moved to. */
4315
4316void
4317move_it_vertically_backward (it, dy)
4318 struct it *it;
4319 int dy;
4320{
4321 int nlines, h, line_height;
4322 struct it it2;
4323 int start_pos = IT_CHARPOS (*it);
4324
4325 xassert (dy >= 0);
4326
4327 /* Estimate how many newlines we must move back. */
4328 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4329
4330 /* Set the iterator's position that many lines back. */
4331 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4332 back_to_previous_visible_line_start (it);
4333
4334 /* Reseat the iterator here. When moving backward, we don't want
4335 reseat to skip forward over invisible text, set up the iterator
4336 to deliver from overlay strings at the new position etc. So,
4337 use reseat_1 here. */
4338 reseat_1 (it, it->current.pos, 1);
4339
4340 /* We are now surely at a line start. */
4341 it->current_x = it->hpos = 0;
4342
4343 /* Move forward and see what y-distance we moved. First move to the
4344 start of the next line so that we get its height. We need this
4345 height to be able to tell whether we reached the specified
4346 y-distance. */
4347 it2 = *it;
4348 it2.max_ascent = it2.max_descent = 0;
4349 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4350 MOVE_TO_POS | MOVE_TO_VPOS);
4351 xassert (IT_CHARPOS (*it) >= BEGV);
4352 line_height = it2.max_ascent + it2.max_descent;
4353 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4354 xassert (IT_CHARPOS (*it) >= BEGV);
4355 h = it2.current_y - it->current_y;
4356 nlines = it2.vpos - it->vpos;
4357
4358 /* Correct IT's y and vpos position. */
4359 it->vpos -= nlines;
4360 it->current_y -= h;
4361
4362 if (dy == 0)
4363 {
4364 /* DY == 0 means move to the start of the screen line. The
4365 value of nlines is > 0 if continuation lines were involved. */
4366 if (nlines > 0)
4367 move_it_by_lines (it, nlines, 1);
4368 xassert (IT_CHARPOS (*it) <= start_pos);
4369 }
4370 else if (nlines)
4371 {
4372 /* The y-position we try to reach. Note that h has been
4373 subtracted in front of the if-statement. */
4374 int target_y = it->current_y + h - dy;
4375
4376 /* If we did not reach target_y, try to move further backward if
4377 we can. If we moved too far backward, try to move forward. */
4378 if (target_y < it->current_y
4379 && IT_CHARPOS (*it) > BEGV)
4380 {
4381 move_it_vertically (it, target_y - it->current_y);
4382 xassert (IT_CHARPOS (*it) >= BEGV);
4383 }
4384 else if (target_y >= it->current_y + line_height
4385 && IT_CHARPOS (*it) < ZV)
4386 {
4387 move_it_vertically (it, target_y - (it->current_y + line_height));
4388 xassert (IT_CHARPOS (*it) >= BEGV);
4389 }
4390 }
4391}
4392
4393
4394/* Move IT by a specified amount of pixel lines DY. DY negative means
4395 move backwards. DY = 0 means move to start of screen line. At the
4396 end, IT will be on the start of a screen line. */
4397
4398void
4399move_it_vertically (it, dy)
4400 struct it *it;
4401 int dy;
4402{
4403 if (dy <= 0)
4404 move_it_vertically_backward (it, -dy);
4405 else if (dy > 0)
4406 {
4407 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4408 MOVE_TO_POS | MOVE_TO_Y);
4409
4410 /* If buffer ends in ZV without a newline, move to the start of
4411 the line to satisfy the post-condition. */
4412 if (IT_CHARPOS (*it) == ZV
4413 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4414 move_it_by_lines (it, 0, 0);
4415 }
4416}
4417
4418
4419/* Return non-zero if some text between buffer positions START_CHARPOS
4420 and END_CHARPOS is invisible. IT->window is the window for text
4421 property lookup. */
4422
4423static int
4424invisible_text_between_p (it, start_charpos, end_charpos)
4425 struct it *it;
4426 int start_charpos, end_charpos;
4427{
4428#ifdef USE_TEXT_PROPERTIES
4429 Lisp_Object prop, limit;
4430 int invisible_found_p;
4431
4432 xassert (it != NULL && start_charpos <= end_charpos);
4433
4434 /* Is text at START invisible? */
4435 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4436 it->window);
4437 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4438 invisible_found_p = 1;
4439 else
4440 {
4441 limit = Fnext_single_property_change (make_number (start_charpos),
4442 Qinvisible,
4443 Fcurrent_buffer (),
4444 make_number (end_charpos));
4445 invisible_found_p = XFASTINT (limit) < end_charpos;
4446 }
4447
4448 return invisible_found_p;
4449
4450#else /* not USE_TEXT_PROPERTIES */
4451 return 0;
4452#endif /* not USE_TEXT_PROPERTIES */
4453}
4454
4455
4456/* Move IT by a specified number DVPOS of screen lines down. DVPOS
4457 negative means move up. DVPOS == 0 means move to the start of the
4458 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4459 NEED_Y_P is zero, IT->current_y will be left unchanged.
4460
4461 Further optimization ideas: If we would know that IT->f doesn't use
4462 a face with proportional font, we could be faster for
4463 truncate-lines nil. */
4464
4465void
4466move_it_by_lines (it, dvpos, need_y_p)
4467 struct it *it;
4468 int dvpos, need_y_p;
4469{
4470 struct position pos;
4471
4472 if (!FRAME_WINDOW_P (it->f))
4473 {
4474 struct text_pos textpos;
4475
4476 /* We can use vmotion on frames without proportional fonts. */
4477 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4478 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4479 reseat (it, textpos, 1);
4480 it->vpos += pos.vpos;
4481 it->current_y += pos.vpos;
4482 }
4483 else if (dvpos == 0)
4484 {
4485 /* DVPOS == 0 means move to the start of the screen line. */
4486 move_it_vertically_backward (it, 0);
4487 xassert (it->current_x == 0 && it->hpos == 0);
4488 }
4489 else if (dvpos > 0)
4490 {
4491 /* If there are no continuation lines, and if there is no
4492 selective display, try the simple method of moving forward
4493 DVPOS newlines, then see where we are. */
4494 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4495 {
4496 int shortage = 0, charpos;
4497
4498 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4499 charpos = IT_CHARPOS (*it) + 1;
4500 else
4501 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4502 &shortage, 0);
4503
4504 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4505 {
4506 struct text_pos pos;
4507 CHARPOS (pos) = charpos;
4508 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4509 reseat (it, pos, 1);
4510 it->vpos += dvpos - shortage;
4511 it->hpos = it->current_x = 0;
4512 return;
4513 }
4514 }
4515
4516 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4517 }
4518 else
4519 {
4520 struct it it2;
4521 int start_charpos, i;
4522
4523 /* If there are no continuation lines, and if there is no
4524 selective display, try the simple method of moving backward
4525 -DVPOS newlines. */
4526 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4527 {
4528 int shortage;
4529 int charpos = IT_CHARPOS (*it);
4530 int bytepos = IT_BYTEPOS (*it);
4531
4532 /* If in the middle of a line, go to its start. */
4533 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4534 {
4535 charpos = find_next_newline_no_quit (charpos, -1);
4536 bytepos = CHAR_TO_BYTE (charpos);
4537 }
4538
4539 if (charpos == BEGV)
4540 {
4541 struct text_pos pos;
4542 CHARPOS (pos) = charpos;
4543 BYTEPOS (pos) = bytepos;
4544 reseat (it, pos, 1);
4545 it->hpos = it->current_x = 0;
4546 return;
4547 }
4548 else
4549 {
4550 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4551 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4552 {
4553 struct text_pos pos;
4554 CHARPOS (pos) = charpos;
4555 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4556 reseat (it, pos, 1);
4557 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4558 it->hpos = it->current_x = 0;
4559 return;
4560 }
4561 }
4562 }
4563
4564 /* Go back -DVPOS visible lines and reseat the iterator there. */
4565 start_charpos = IT_CHARPOS (*it);
4566 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4567 back_to_previous_visible_line_start (it);
4568 reseat (it, it->current.pos, 1);
4569 it->current_x = it->hpos = 0;
4570
4571 /* Above call may have moved too far if continuation lines
4572 are involved. Scan forward and see if it did. */
4573 it2 = *it;
4574 it2.vpos = it2.current_y = 0;
4575 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4576 it->vpos -= it2.vpos;
4577 it->current_y -= it2.current_y;
4578 it->current_x = it->hpos = 0;
4579
4580 /* If we moved too far, move IT some lines forward. */
4581 if (it2.vpos > -dvpos)
4582 {
4583 int delta = it2.vpos + dvpos;
4584 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4585 }
4586 }
4587}
4588
4589
4590\f
4591/***********************************************************************
4592 Messages
4593 ***********************************************************************/
4594
4595
4596/* Output a newline in the *Messages* buffer if "needs" one. */
4597
4598void
4599message_log_maybe_newline ()
4600{
4601 if (message_log_need_newline)
4602 message_dolog ("", 0, 1, 0);
4603}
4604
4605
4606/* Add a string M of length LEN to the message log, optionally
4607 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4608 nonzero, means interpret the contents of M as multibyte. This
4609 function calls low-level routines in order to bypass text property
4610 hooks, etc. which might not be safe to run. */
4611
4612void
4613message_dolog (m, len, nlflag, multibyte)
4614 char *m;
4615 int len, nlflag, multibyte;
4616{
4617 if (!NILP (Vmessage_log_max))
4618 {
4619 struct buffer *oldbuf;
4620 Lisp_Object oldpoint, oldbegv, oldzv;
4621 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4622 int point_at_end = 0;
4623 int zv_at_end = 0;
4624 Lisp_Object old_deactivate_mark, tem;
4625 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4626
4627 old_deactivate_mark = Vdeactivate_mark;
4628 oldbuf = current_buffer;
4629 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4630 current_buffer->undo_list = Qt;
4631
4632 oldpoint = Fpoint_marker ();
4633 oldbegv = Fpoint_min_marker ();
4634 oldzv = Fpoint_max_marker ();
4635 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4636
4637 if (PT == Z)
4638 point_at_end = 1;
4639 if (ZV == Z)
4640 zv_at_end = 1;
4641
4642 BEGV = BEG;
4643 BEGV_BYTE = BEG_BYTE;
4644 ZV = Z;
4645 ZV_BYTE = Z_BYTE;
4646 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4647
4648 /* Insert the string--maybe converting multibyte to single byte
4649 or vice versa, so that all the text fits the buffer. */
4650 if (multibyte
4651 && NILP (current_buffer->enable_multibyte_characters))
4652 {
4653 int i, c, nbytes;
4654 unsigned char work[1];
4655
4656 /* Convert a multibyte string to single-byte
4657 for the *Message* buffer. */
4658 for (i = 0; i < len; i += nbytes)
4659 {
4fdb80f2 4660 c = string_char_and_length (m + i, len - i, &nbytes);
5f5c8ee5
GM
4661 work[0] = (SINGLE_BYTE_CHAR_P (c)
4662 ? c
4663 : multibyte_char_to_unibyte (c, Qnil));
4664 insert_1_both (work, 1, 1, 1, 0, 0);
4665 }
4666 }
4667 else if (! multibyte
4668 && ! NILP (current_buffer->enable_multibyte_characters))
4669 {
4670 int i, c, nbytes;
4671 unsigned char *msg = (unsigned char *) m;
4672 unsigned char *str, work[4];
4673 /* Convert a single-byte string to multibyte
4674 for the *Message* buffer. */
4675 for (i = 0; i < len; i++)
4676 {
4677 c = unibyte_char_to_multibyte (msg[i]);
4678 nbytes = CHAR_STRING (c, work, str);
4679 insert_1_both (work, 1, nbytes, 1, 0, 0);
4680 }
4681 }
4682 else if (len)
4683 insert_1 (m, len, 1, 0, 0);
4684
4685 if (nlflag)
4686 {
4687 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4688 insert_1 ("\n", 1, 1, 0, 0);
4689
4690 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4691 this_bol = PT;
4692 this_bol_byte = PT_BYTE;
4693
4694 if (this_bol > BEG)
4695 {
4696 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4697 prev_bol = PT;
4698 prev_bol_byte = PT_BYTE;
4699
4700 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4701 this_bol, this_bol_byte);
4702 if (dup)
4703 {
4704 del_range_both (prev_bol, prev_bol_byte,
4705 this_bol, this_bol_byte, 0);
4706 if (dup > 1)
4707 {
4708 char dupstr[40];
4709 int duplen;
4710
4711 /* If you change this format, don't forget to also
4712 change message_log_check_duplicate. */
4713 sprintf (dupstr, " [%d times]", dup);
4714 duplen = strlen (dupstr);
4715 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4716 insert_1 (dupstr, duplen, 1, 0, 1);
4717 }
4718 }
4719 }
4720
4721 if (NATNUMP (Vmessage_log_max))
4722 {
4723 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4724 -XFASTINT (Vmessage_log_max) - 1, 0);
4725 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4726 }
4727 }
4728 BEGV = XMARKER (oldbegv)->charpos;
4729 BEGV_BYTE = marker_byte_position (oldbegv);
4730
4731 if (zv_at_end)
4732 {
4733 ZV = Z;
4734 ZV_BYTE = Z_BYTE;
4735 }
4736 else
4737 {
4738 ZV = XMARKER (oldzv)->charpos;
4739 ZV_BYTE = marker_byte_position (oldzv);
4740 }
4741
4742 if (point_at_end)
4743 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4744 else
4745 /* We can't do Fgoto_char (oldpoint) because it will run some
4746 Lisp code. */
4747 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4748 XMARKER (oldpoint)->bytepos);
4749
4750 UNGCPRO;
4751 free_marker (oldpoint);
4752 free_marker (oldbegv);
4753 free_marker (oldzv);
4754
4755 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4756 set_buffer_internal (oldbuf);
4757 if (NILP (tem))
4758 windows_or_buffers_changed = old_windows_or_buffers_changed;
4759 message_log_need_newline = !nlflag;
4760 Vdeactivate_mark = old_deactivate_mark;
4761 }
4762}
4763
4764
4765/* We are at the end of the buffer after just having inserted a newline.
4766 (Note: We depend on the fact we won't be crossing the gap.)
4767 Check to see if the most recent message looks a lot like the previous one.
4768 Return 0 if different, 1 if the new one should just replace it, or a
4769 value N > 1 if we should also append " [N times]". */
4770
4771static int
4772message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4773 int prev_bol, this_bol;
4774 int prev_bol_byte, this_bol_byte;
4775{
4776 int i;
4777 int len = Z_BYTE - 1 - this_bol_byte;
4778 int seen_dots = 0;
4779 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4780 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4781
4782 for (i = 0; i < len; i++)
4783 {
4784 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4785 && p1[i] != '\n')
4786 seen_dots = 1;
4787 if (p1[i] != p2[i])
4788 return seen_dots;
4789 }
4790 p1 += len;
4791 if (*p1 == '\n')
4792 return 2;
4793 if (*p1++ == ' ' && *p1++ == '[')
4794 {
4795 int n = 0;
4796 while (*p1 >= '0' && *p1 <= '9')
4797 n = n * 10 + *p1++ - '0';
4798 if (strncmp (p1, " times]\n", 8) == 0)
4799 return n+1;
4800 }
4801 return 0;
4802}
4803
4804
4805/* Display an echo area message M with a specified length of LEN
4806 chars. The string may include null characters. If M is 0, clear
4807 out any existing message, and let the mini-buffer text show through.
4808
4809 The buffer M must continue to exist until after the echo area gets
4810 cleared or some other message gets displayed there. This means do
4811 not pass text that is stored in a Lisp string; do not pass text in
4812 a buffer that was alloca'd. */
4813
4814void
4815message2 (m, len, multibyte)
4816 char *m;
4817 int len;
4818 int multibyte;
4819{
4820 /* First flush out any partial line written with print. */
4821 message_log_maybe_newline ();
4822 if (m)
4823 message_dolog (m, len, 1, multibyte);
4824 message2_nolog (m, len, multibyte);
4825}
4826
4827
4828/* The non-logging counterpart of message2. */
4829
4830void
4831message2_nolog (m, len, multibyte)
4832 char *m;
4833 int len;
4834{
4835 message_enable_multibyte = multibyte;
4836
4837 if (noninteractive)
4838 {
4839 if (noninteractive_need_newline)
4840 putc ('\n', stderr);
4841 noninteractive_need_newline = 0;
4842 if (m)
4843 fwrite (m, len, 1, stderr);
4844 if (cursor_in_echo_area == 0)
4845 fprintf (stderr, "\n");
4846 fflush (stderr);
4847 }
4848 /* A null message buffer means that the frame hasn't really been
4849 initialized yet. Error messages get reported properly by
4850 cmd_error, so this must be just an informative message; toss it. */
4851 else if (INTERACTIVE
4852 && selected_frame->glyphs_initialized_p
4853 && FRAME_MESSAGE_BUF (selected_frame))
4854 {
4855 Lisp_Object mini_window;
4856 struct frame *f;
4857
4858 /* Get the frame containing the mini-buffer
4859 that the selected frame is using. */
4860 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4861 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4862
4863 FRAME_SAMPLE_VISIBILITY (f);
4864 if (FRAME_VISIBLE_P (selected_frame)
4865 && ! FRAME_VISIBLE_P (f))
4866 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4867
4868 if (m)
4869 {
4870 echo_area_glyphs = m;
4871 echo_area_glyphs_length = len;
4872 echo_area_message = Qnil;
4873
4874 if (minibuffer_auto_raise)
4875 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4876 }
4877 else
4878 {
4879 echo_area_glyphs = previous_echo_glyphs = NULL;
4880 echo_area_message = previous_echo_area_message = Qnil;
4881 }
4882
4883 do_pending_window_change ();
4884 echo_area_display (1);
4885 do_pending_window_change ();
4886 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4887 (*frame_up_to_date_hook) (f);
4888 }
4889}
4890
4891
4892/* Display an echo area message M with a specified length of LEN
4893 chars. The string may include null characters. If M is not a
4894 string, clear out any existing message, and let the mini-buffer
4895 text show through. */
4896
4897void
4898message3 (m, len, multibyte)
4899 Lisp_Object m;
4900 int len;
4901 int multibyte;
4902{
4903 struct gcpro gcpro1;
4904
4905 GCPRO1 (m);
4906
4907 /* First flush out any partial line written with print. */
4908 message_log_maybe_newline ();
4909 if (STRINGP (m))
4910 message_dolog (XSTRING (m)->data, len, 1, multibyte);
4911 message3_nolog (m, len, multibyte);
4912
4913 UNGCPRO;
4914}
4915
4916
4917/* The non-logging version of message3. */
4918
4919void
4920message3_nolog (m, len, multibyte)
4921 Lisp_Object m;
4922 int len, multibyte;
4923{
4924 message_enable_multibyte = multibyte;
4925
4926 if (noninteractive)
4927 {
4928 if (noninteractive_need_newline)
4929 putc ('\n', stderr);
4930 noninteractive_need_newline = 0;
4931 if (STRINGP (m))
4932 fwrite (XSTRING (m)->data, len, 1, stderr);
4933 if (cursor_in_echo_area == 0)
4934 fprintf (stderr, "\n");
4935 fflush (stderr);
4936 }
4937 /* A null message buffer means that the frame hasn't really been
4938 initialized yet. Error messages get reported properly by
4939 cmd_error, so this must be just an informative message; toss it. */
4940 else if (INTERACTIVE
4941 && selected_frame->glyphs_initialized_p
4942 && FRAME_MESSAGE_BUF (selected_frame))
4943 {
4944 Lisp_Object mini_window;
4945 struct frame *f;
4946
4947 /* Get the frame containing the mini-buffer
4948 that the selected frame is using. */
4949 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4950 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4951
4952 FRAME_SAMPLE_VISIBILITY (f);
4953 if (FRAME_VISIBLE_P (selected_frame)
4954 && ! FRAME_VISIBLE_P (f))
4955 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4956
4957 if (STRINGP (m))
4958 {
4959 echo_area_glyphs = NULL;
4960 echo_area_message = m;
4961 echo_area_glyphs_length = len;
4962
4963 if (minibuffer_auto_raise)
4964 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4965 }
4966 else
4967 {
4968 echo_area_glyphs = previous_echo_glyphs = NULL;
4969 echo_area_message = previous_echo_area_message = Qnil;
4970 }
4971
4972 do_pending_window_change ();
4973 echo_area_display (1);
4974 do_pending_window_change ();
4975 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4976 (*frame_up_to_date_hook) (f);
4977 }
4978}
4979
4980
4981/* Display a null-terminated echo area message M. If M is 0, clear
4982 out any existing message, and let the mini-buffer text show through.
4983
4984 The buffer M must continue to exist until after the echo area gets
4985 cleared or some other message gets displayed there. Do not pass
4986 text that is stored in a Lisp string. Do not pass text in a buffer
4987 that was alloca'd. */
4988
4989void
4990message1 (m)
4991 char *m;
4992{
4993 message2 (m, (m ? strlen (m) : 0), 0);
4994}
4995
4996
4997/* The non-logging counterpart of message1. */
4998
4999void
5000message1_nolog (m)
5001 char *m;
5002{
5003 message2_nolog (m, (m ? strlen (m) : 0), 0);
5004}
5005
5006/* Display a message M which contains a single %s
5007 which gets replaced with STRING. */
5008
5009void
5010message_with_string (m, string, log)
5011 char *m;
5012 Lisp_Object string;
5013 int log;
5014{
5015 if (noninteractive)
5016 {
5017 if (m)
5018 {
5019 if (noninteractive_need_newline)
5020 putc ('\n', stderr);
5021 noninteractive_need_newline = 0;
5022 fprintf (stderr, m, XSTRING (string)->data);
5023 if (cursor_in_echo_area == 0)
5024 fprintf (stderr, "\n");
5025 fflush (stderr);
5026 }
5027 }
5028 else if (INTERACTIVE)
5029 {
5030 /* The frame whose minibuffer we're going to display the message on.
5031 It may be larger than the selected frame, so we need
5032 to use its buffer, not the selected frame's buffer. */
5033 Lisp_Object mini_window;
5034 FRAME_PTR f;
5035
5036 /* Get the frame containing the minibuffer
5037 that the selected frame is using. */
5038 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5039 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5040
5041 /* A null message buffer means that the frame hasn't really been
5042 initialized yet. Error messages get reported properly by
5043 cmd_error, so this must be just an informative message; toss it. */
5044 if (FRAME_MESSAGE_BUF (f))
5045 {
5046 int len;
5047 char *a[1];
5048 a[0] = (char *) XSTRING (string)->data;
5049
5050 len = doprnt (FRAME_MESSAGE_BUF (f),
5051 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5052
5053 if (log)
5054 message2 (FRAME_MESSAGE_BUF (f), len,
5055 STRING_MULTIBYTE (string));
5056 else
5057 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5058 STRING_MULTIBYTE (string));
5059
5060 /* Print should start at the beginning of the message
5061 buffer next time. */
5062 message_buf_print = 0;
5063 }
5064 }
5065}
5066
5067
5068/* Truncate what will be displayed in the echo area
5069 the next time we display it--but don't redisplay it now. */
5070
5071void
5072truncate_echo_area (len)
5073 int len;
5074{
5075 /* A null message buffer means that the frame hasn't really been
5076 initialized yet. Error messages get reported properly by
5077 cmd_error, so this must be just an informative message; toss it. */
5078 if (!noninteractive && INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame))
5079 echo_area_glyphs_length = len;
5080}
5081
5082
5083/* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by
5084 print; zero if being used by message. */
5085
5086int message_buf_print;
5087
5088
5089/* Dump an informative message to the minibuf. If M is 0, clear out
5090 any existing message, and let the mini-buffer text show through. */
5091
5092/* VARARGS 1 */
5093void
5094message (m, a1, a2, a3)
5095 char *m;
5096 EMACS_INT a1, a2, a3;
5097{
5098 if (noninteractive)
5099 {
5100 if (m)
5101 {
5102 if (noninteractive_need_newline)
5103 putc ('\n', stderr);
5104 noninteractive_need_newline = 0;
5105 fprintf (stderr, m, a1, a2, a3);
5106 if (cursor_in_echo_area == 0)
5107 fprintf (stderr, "\n");
5108 fflush (stderr);
5109 }
5110 }
5111 else if (INTERACTIVE)
5112 {
5113 /* The frame whose mini-buffer we're going to display the message
5114 on. It may be larger than the selected frame, so we need to
5115 use its buffer, not the selected frame's buffer. */
5116 Lisp_Object mini_window;
5117 struct frame *f;
5118
5119 /* Get the frame containing the mini-buffer
5120 that the selected frame is using. */
5121 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5122 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5123
5124 /* A null message buffer means that the frame hasn't really been
5125 initialized yet. Error messages get reported properly by
5126 cmd_error, so this must be just an informative message; toss
5127 it. */
5128 if (FRAME_MESSAGE_BUF (f))
5129 {
5130 if (m)
5131 {
5132 int len;
5133#ifdef NO_ARG_ARRAY
5134 char *a[3];
5135 a[0] = (char *) a1;
5136 a[1] = (char *) a2;
5137 a[2] = (char *) a3;
5138
5139 len = doprnt (FRAME_MESSAGE_BUF (f),
5140 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5141#else
5142 len = doprnt (FRAME_MESSAGE_BUF (f),
5143 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5144 (char **) &a1);
5145#endif /* NO_ARG_ARRAY */
5146
5147 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5148 }
5149 else
5150 message1 (0);
5151
5152 /* Print should start at the beginning of the message
5153 buffer next time. */
5154 message_buf_print = 0;
5155 }
5156 }
5157}
5158
5159
5160/* The non-logging version of message. */
5161
5162void
5163message_nolog (m, a1, a2, a3)
5164 char *m;
5165 EMACS_INT a1, a2, a3;
5166{
5167 Lisp_Object old_log_max;
5168 old_log_max = Vmessage_log_max;
5169 Vmessage_log_max = Qnil;
5170 message (m, a1, a2, a3);
5171 Vmessage_log_max = old_log_max;
5172}
5173
5174
5175/* Display echo_area_message or echo_area_glyphs in the current
5176 mini-buffer. */
5177
5178void
5179update_echo_area ()
5180{
5181 if (STRINGP (echo_area_message))
5182 message3 (echo_area_message, echo_area_glyphs_length,
5183 !NILP (current_buffer->enable_multibyte_characters));
5184 else
5185 message2 (echo_area_glyphs, echo_area_glyphs_length,
5186 !NILP (current_buffer->enable_multibyte_characters));
5187}
5188
5189
5190/* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
5191 non-zero update selected_frame. */
5192
5193static void
5194echo_area_display (update_frame_p)
5195 int update_frame_p;
5196{
5197 Lisp_Object mini_window;
5198 struct window *w;
5199 struct frame *f;
5200
5201 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5202 w = XWINDOW (mini_window);
5203 f = XFRAME (WINDOW_FRAME (w));
5204
5205 /* Don't display if frame is invisible or not yet initialized. */
5206 if (!FRAME_VISIBLE_P (f)
5207 || !f->glyphs_initialized_p)
5208 return;
5209
5210 /* When Emacs starts, selected_frame may be a visible terminal
5211 frame, even if we run under a window system. If we let this
5212 through, a message would be displayed on the terminal. */
5213#ifdef HAVE_WINDOW_SYSTEM
5214 if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
5215 return;
5216#endif /* HAVE_WINDOW_SYSTEM */
5217
5218 /* Redraw garbaged frames. */
5219 if (frame_garbaged)
5220 {
5221 /* Old redisplay called redraw_garbaged_frames here which in
5222 turn called redraw_frame which in turn called clear_frame.
5223 The call to clear_frame is a source of flickering. After
5224 checking the places where SET_FRAME_GARBAGED is called, I
5225 believe a clear_frame is not necessary. It should suffice in
5226 the new redisplay to invalidate all current matrices, and
5227 ensure a complete redisplay of all windows. */
5228 Lisp_Object tail, frame;
5229
5230 FOR_EACH_FRAME (tail, frame)
5231 {
5232 struct frame *f = XFRAME (frame);
5233
5234 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5235 {
5236 clear_current_matrices (f);
5237 f->garbaged = 0;
5238 }
5239 }
5240
5241 frame_garbaged = 0;
5242 ++windows_or_buffers_changed;
5243 }
5244
5245 if (echo_area_glyphs
5246 || STRINGP (echo_area_message)
5247 || minibuf_level == 0)
5248 {
5249 struct it it;
5250
5251 echo_area_window = mini_window;
5252 clear_glyph_matrix (w->desired_matrix);
5253 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, DEFAULT_FACE_ID);
5254
5255 if (STRINGP (echo_area_message)
5256 && echo_area_glyphs_length)
5257 {
5258 prepare_desired_row (it.glyph_row);
5259 display_string (NULL, echo_area_message, Qnil, 0, 0,
5260 &it, -1, echo_area_glyphs_length, 0,
5261 message_enable_multibyte);
5262 it.glyph_row->truncated_on_right_p = 0;
5263 compute_line_metrics (&it);
5264 }
5265 else if (echo_area_glyphs
5266 && echo_area_glyphs_length)
5267 {
5268 prepare_desired_row (it.glyph_row);
5269 display_string (echo_area_glyphs, Qnil, Qnil, 0, 0, &it,
5270 -1, echo_area_glyphs_length, 0,
5271 message_enable_multibyte);
5272 it.glyph_row->truncated_on_right_p = 0;
5273 compute_line_metrics (&it);
5274 }
5275 else
5276 blank_row (w, it.glyph_row, 0);
5277
5278 it.glyph_row->y = it.current_y;
5279 it.current_y += it.glyph_row->height;
5280
5281 /* Clear the rest of the lines. */
5282 while (it.current_y < it.last_visible_y)
5283 {
5284 ++it.glyph_row;
5285 blank_row (w, it.glyph_row, it.current_y);
5286 it.current_y += it.glyph_row->height;
5287 }
5288
5289 w->must_be_updated_p = 1;
5290 if (update_frame_p)
5291 {
5292 /* Calling update_single_window is faster when we can use
5293 window-based redisplay. */
5294 if (FRAME_WINDOW_P (f))
5295 {
5296 update_single_window (w, 1);
5297 rif->flush_display (f);
5298 }
5299 else
5300 update_frame (f, 1, 1);
5301 }
5302 }
5303 else if (!EQ (mini_window, selected_window))
5304 windows_or_buffers_changed++;
5305
5306 /* Prevent redisplay optimization in redisplay_internal by resetting
5307 this_line_start_pos. This is done because the mini-buffer now
5308 displays the message instead of its buffer text. */
5309 if (EQ (mini_window, selected_window))
5310 CHARPOS (this_line_start_pos) = 0;
5311
5312 previous_echo_glyphs = echo_area_glyphs;
5313 previous_echo_area_message = echo_area_message;
5314 previous_echo_glyphs_length = echo_area_glyphs_length;
5315}
5316
5317
5318\f
5319/***********************************************************************
5320 Frame Titles
5321 ***********************************************************************/
5322
5323
5324#ifdef HAVE_WINDOW_SYSTEM
5325
5326/* A buffer for constructing frame titles in it; allocated from the
5327 heap in init_xdisp and resized as needed in store_frame_title_char. */
5328
5329static char *frame_title_buf;
5330
5331/* The buffer's end, and a current output position in it. */
5332
5333static char *frame_title_buf_end;
5334static char *frame_title_ptr;
5335
5336
5337/* Store a single character C for the frame title in frame_title_buf.
5338 Re-allocate frame_title_buf if necessary. */
5339
5340static void
5341store_frame_title_char (c)
5342 char c;
5343{
5344 /* If output position has reached the end of the allocated buffer,
5345 double the buffer's size. */
5346 if (frame_title_ptr == frame_title_buf_end)
5347 {
5348 int len = frame_title_ptr - frame_title_buf;
5349 int new_size = 2 * len * sizeof *frame_title_buf;
5350 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
5351 frame_title_buf_end = frame_title_buf + new_size;
5352 frame_title_ptr = frame_title_buf + len;
5353 }
5354
5355 *frame_title_ptr++ = c;
5356}
5357
5358
5359/* Store part of a frame title in frame_title_buf, beginning at
5360 frame_title_ptr. STR is the string to store. Do not copy more
5361 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
5362 the whole string. Pad with spaces until FIELD_WIDTH number of
5363 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
5364 Called from display_mode_element when it is used to build a frame
5365 title. */
5366
5367static int
5368store_frame_title (str, field_width, precision)
5369 unsigned char *str;
5370 int field_width, precision;
5371{
5372 int n = 0;
5373
5374 /* Copy at most PRECISION chars from STR. */
5375 while ((precision <= 0 || n < precision)
5376 && *str)
5377 {
5378 store_frame_title_char (*str++);
5379 ++n;
5380 }
5381
5382 /* Fill up with spaces until FIELD_WIDTH reached. */
5383 while (field_width > 0
5384 && n < field_width)
5385 {
5386 store_frame_title_char (' ');
5387 ++n;
5388 }
5389
5390 return n;
5391}
5392
5393
5394/* Set the title of FRAME, if it has changed. The title format is
5395 Vicon_title_format if FRAME is iconified, otherwise it is
5396 frame_title_format. */
5397
5398static void
5399x_consider_frame_title (frame)
5400 Lisp_Object frame;
5401{
5402 struct frame *f = XFRAME (frame);
5403
5404 if (FRAME_WINDOW_P (f)
5405 || FRAME_MINIBUF_ONLY_P (f)
5406 || f->explicit_name)
5407 {
5408 /* Do we have more than one visible frame on this X display? */
5409 Lisp_Object tail;
5410 Lisp_Object fmt;
5411 struct buffer *obuf;
5412 int len;
5413 struct it it;
5414
5415 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
5416 {
5417 struct frame *tf = XFRAME (XCONS (tail)->car);
5418
5419 if (tf != f
5420 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
5421 && !FRAME_MINIBUF_ONLY_P (tf)
5422 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
5423 break;
5424 }
5425
5426 /* Set global variable indicating that multiple frames exist. */
5427 multiple_frames = CONSP (tail);
5428
5429 /* Switch to the buffer of selected window of the frame. Set up
5430 frame_title_ptr so that display_mode_element will output into it;
5431 then display the title. */
5432 obuf = current_buffer;
5433 Fset_buffer (XWINDOW (f->selected_window)->buffer);
5434 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
5435 frame_title_ptr = frame_title_buf;
5436 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
5437 NULL, DEFAULT_FACE_ID);
5438 len = display_mode_element (&it, 0, -1, -1, fmt);
5439 frame_title_ptr = NULL;
5440 set_buffer_internal (obuf);
5441
5442 /* Set the title only if it's changed. This avoids consing in
5443 the common case where it hasn't. (If it turns out that we've
5444 already wasted too much time by walking through the list with
5445 display_mode_element, then we might need to optimize at a
5446 higher level than this.) */
5447 if (! STRINGP (f->name)
5448 || STRING_BYTES (XSTRING (f->name)) != len
5449 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
5450 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
5451 }
5452}
5453
5454#else /* not HAVE_WINDOW_SYSTEM */
5455
5456#define frame_title_ptr ((char *)0)
5457#define store_frame_title(str, mincol, maxcol) 0
5458
5459#endif /* not HAVE_WINDOW_SYSTEM */
5460
5461
5462
5463\f
5464/***********************************************************************
5465 Menu Bars
5466 ***********************************************************************/
5467
5468
5469/* Prepare for redisplay by updating menu-bar item lists when
5470 appropriate. This can call eval. */
5471
5472void
5473prepare_menu_bars ()
5474{
5475 int all_windows;
5476 struct gcpro gcpro1, gcpro2;
5477 struct frame *f;
5478 struct frame *tooltip_frame;
5479
5480#ifdef HAVE_X_WINDOWS
5481 tooltip_frame = tip_frame;
5482#else
5483 tooltip_frame = NULL;
5484#endif
5485
5486 /* Update all frame titles based on their buffer names, etc. We do
5487 this before the menu bars so that the buffer-menu will show the
5488 up-to-date frame titles. */
5489#ifdef HAVE_WINDOW_SYSTEM
5490 if (windows_or_buffers_changed || update_mode_lines)
5491 {
5492 Lisp_Object tail, frame;
5493
5494 FOR_EACH_FRAME (tail, frame)
5495 {
5496 f = XFRAME (frame);
5497 if (f != tooltip_frame
5498 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
5499 x_consider_frame_title (frame);
5500 }
5501 }
5502#endif /* HAVE_WINDOW_SYSTEM */
5503
5504 /* Update the menu bar item lists, if appropriate. This has to be
5505 done before any actual redisplay or generation of display lines. */
5506 all_windows = (update_mode_lines
5507 || buffer_shared > 1
5508 || windows_or_buffers_changed);
5509 if (all_windows)
5510 {
5511 Lisp_Object tail, frame;
5512 int count = specpdl_ptr - specpdl;
5513
5514 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5515
5516 FOR_EACH_FRAME (tail, frame)
5517 {
5518 f = XFRAME (frame);
5519
5520 /* Ignore tooltip frame. */
5521 if (f == tooltip_frame)
5522 continue;
5523
5524 /* If a window on this frame changed size, report that to
5525 the user and clear the size-change flag. */
5526 if (FRAME_WINDOW_SIZES_CHANGED (f))
5527 {
5528 Lisp_Object functions;
5529
5530 /* Clear flag first in case we get an error below. */
5531 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
5532 functions = Vwindow_size_change_functions;
5533 GCPRO2 (tail, functions);
5534
5535 while (CONSP (functions))
5536 {
5537 call1 (XCAR (functions), frame);
5538 functions = XCDR (functions);
5539 }
5540 UNGCPRO;
5541 }
5542
5543 GCPRO1 (tail);
5544 update_menu_bar (f, 0);
5545#ifdef HAVE_WINDOW_SYSTEM
5546 update_toolbar (f, 0);
5547#endif
5548 UNGCPRO;
5549 }
5550
5551 unbind_to (count, Qnil);
5552 }
5553 else
5554 {
5555 update_menu_bar (selected_frame, 1);
5556#ifdef HAVE_WINDOW_SYSTEM
5557 update_toolbar (selected_frame, 1);
5558#endif
5559 }
5560
5561 /* Motif needs this. See comment in xmenu.c. Turn it off when
5562 pending_menu_activation is not defined. */
5563#ifdef USE_X_TOOLKIT
5564 pending_menu_activation = 0;
5565#endif
5566}
5567
5568
5569/* Update the menu bar item list for frame F. This has to be done
5570 before we start to fill in any display lines, because it can call
5571 eval.
5572
5573 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
5574
5575static void
5576update_menu_bar (f, save_match_data)
5577 struct frame *f;
5578 int save_match_data;
5579{
5580 Lisp_Object window;
5581 register struct window *w;
5582
5583 window = FRAME_SELECTED_WINDOW (f);
5584 w = XWINDOW (window);
5585
5586 if (update_mode_lines)
5587 w->update_mode_line = Qt;
5588
5589 if (FRAME_WINDOW_P (f)
5590 ?
5591#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5592 FRAME_EXTERNAL_MENU_BAR (f)
5593#else
5594 FRAME_MENU_BAR_LINES (f) > 0
5595#endif
5596 : FRAME_MENU_BAR_LINES (f) > 0)
5597 {
5598 /* If the user has switched buffers or windows, we need to
5599 recompute to reflect the new bindings. But we'll
5600 recompute when update_mode_lines is set too; that means
5601 that people can use force-mode-line-update to request
5602 that the menu bar be recomputed. The adverse effect on
5603 the rest of the redisplay algorithm is about the same as
5604 windows_or_buffers_changed anyway. */
5605 if (windows_or_buffers_changed
5606 || !NILP (w->update_mode_line)
5607 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
5608 < BUF_MODIFF (XBUFFER (w->buffer)))
5609 != !NILP (w->last_had_star))
5610 || ((!NILP (Vtransient_mark_mode)
5611 && !NILP (XBUFFER (w->buffer)->mark_active))
5612 != !NILP (w->region_showing)))
5613 {
5614 struct buffer *prev = current_buffer;
5615 int count = specpdl_ptr - specpdl;
5616
5617 set_buffer_internal_1 (XBUFFER (w->buffer));
5618 if (save_match_data)
5619 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5620 if (NILP (Voverriding_local_map_menu_flag))
5621 {
5622 specbind (Qoverriding_terminal_local_map, Qnil);
5623 specbind (Qoverriding_local_map, Qnil);
5624 }
5625
5626 /* Run the Lucid hook. */
5627 call1 (Vrun_hooks, Qactivate_menubar_hook);
5628
5629 /* If it has changed current-menubar from previous value,
5630 really recompute the menu-bar from the value. */
5631 if (! NILP (Vlucid_menu_bar_dirty_flag))
5632 call0 (Qrecompute_lucid_menubar);
5633
5634 safe_run_hooks (Qmenu_bar_update_hook);
5635 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
5636
5637 /* Redisplay the menu bar in case we changed it. */
5638#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5639 if (FRAME_WINDOW_P (f))
5640 set_frame_menubar (f, 0, 0);
5641 else
5642 /* On a terminal screen, the menu bar is an ordinary screen
5643 line, and this makes it get updated. */
5644 w->update_mode_line = Qt;
5645#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5646 /* In the non-toolkit version, the menu bar is an ordinary screen
5647 line, and this makes it get updated. */
5648 w->update_mode_line = Qt;
5649#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5650
5651 unbind_to (count, Qnil);
5652 set_buffer_internal_1 (prev);
5653 }
5654 }
5655}
5656
5657
5658\f
5659/***********************************************************************
5660 Toolbars
5661 ***********************************************************************/
5662
5663#ifdef HAVE_WINDOW_SYSTEM
5664
5665/* Update the toolbar item list for frame F. This has to be done
5666 before we start to fill in any display lines. Called from
5667 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
5668 and restore it here. */
5669
5670static void
5671update_toolbar (f, save_match_data)
5672 struct frame *f;
5673 int save_match_data;
5674{
5675 if (WINDOWP (f->toolbar_window)
5676 && XFASTINT (XWINDOW (f->toolbar_window)->height) > 0)
5677 {
5678 Lisp_Object window;
5679 struct window *w;
5680
5681 window = FRAME_SELECTED_WINDOW (f);
5682 w = XWINDOW (window);
5683
5684 /* If the user has switched buffers or windows, we need to
5685 recompute to reflect the new bindings. But we'll
5686 recompute when update_mode_lines is set too; that means
5687 that people can use force-mode-line-update to request
5688 that the menu bar be recomputed. The adverse effect on
5689 the rest of the redisplay algorithm is about the same as
5690 windows_or_buffers_changed anyway. */
5691 if (windows_or_buffers_changed
5692 || !NILP (w->update_mode_line)
5693 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
5694 < BUF_MODIFF (XBUFFER (w->buffer)))
5695 != !NILP (w->last_had_star))
5696 || ((!NILP (Vtransient_mark_mode)
5697 && !NILP (XBUFFER (w->buffer)->mark_active))
5698 != !NILP (w->region_showing)))
5699 {
5700 struct buffer *prev = current_buffer;
5701 int count = specpdl_ptr - specpdl;
a2889657 5702
5f5c8ee5
GM
5703 /* Set current_buffer to the buffer of the selected
5704 window of the frame, so that we get the right local
5705 keymaps. */
5706 set_buffer_internal_1 (XBUFFER (w->buffer));
1f40cad2 5707
5f5c8ee5
GM
5708 /* Save match data, if we must. */
5709 if (save_match_data)
5710 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5711
5712 /* Make sure that we don't accidentally use bogus keymaps. */
5713 if (NILP (Voverriding_local_map_menu_flag))
5714 {
5715 specbind (Qoverriding_terminal_local_map, Qnil);
5716 specbind (Qoverriding_local_map, Qnil);
1f40cad2 5717 }
1f40cad2 5718
5f5c8ee5
GM
5719 /* Build desired toolbar items from keymaps. */
5720 f->desired_toolbar_items
5721 = toolbar_items (f->desired_toolbar_items,
5722 &f->n_desired_toolbar_items);
5723
5724 /* Redisplay the toolbar in case we changed it. */
5725 w->update_mode_line = Qt;
5726
5727 unbind_to (count, Qnil);
5728 set_buffer_internal_1 (prev);
81d478f3 5729 }
a2889657
JB
5730 }
5731}
5732
6c4429a5 5733
5f5c8ee5
GM
5734/* Set F->desired_toolbar_string to a Lisp string representing frame
5735 F's desired toolbar contents. F->desired_toolbar_items must have
5736 been set up previously by calling prepare_menu_bars. */
5737
a2889657 5738static void
5f5c8ee5
GM
5739build_desired_toolbar_string (f)
5740 struct frame *f;
a2889657 5741{
5f5c8ee5
GM
5742 int i, size, size_needed, string_idx;
5743 struct gcpro gcpro1, gcpro2, gcpro3;
5744 Lisp_Object image, plist, props;
a2889657 5745
5f5c8ee5
GM
5746 image = plist = props = Qnil;
5747 GCPRO3 (image, plist, props);
a2889657 5748
5f5c8ee5
GM
5749 /* Prepare F->desired_toolbar_string. If we can reuse it, do so.
5750 Otherwise, make a new string. */
5751
5752 /* The size of the string we might be able to reuse. */
5753 size = (STRINGP (f->desired_toolbar_string)
5754 ? XSTRING (f->desired_toolbar_string)->size
5755 : 0);
5756
5757 /* Each image in the string we build is preceded by a space,
5758 and there is a space at the end. */
5759 size_needed = f->n_desired_toolbar_items + 1;
5760
5761 /* Reuse f->desired_toolbar_string, if possible. */
5762 if (size < size_needed)
5763 f->desired_toolbar_string = Fmake_string (make_number (size_needed), ' ');
5764 else
5765 {
5766 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
5767 Fremove_text_properties (make_number (0), make_number (size),
5768 props, f->desired_toolbar_string);
5769 }
a2889657 5770
5f5c8ee5
GM
5771 /* Put a `display' property on the string for the images to display,
5772 put a `menu_item' property on toolbar items with a value that
5773 is the index of the item in F's toolbar item vector. */
5774 for (i = 0, string_idx = 0;
5775 i < f->n_desired_toolbar_items;
5776 ++i, string_idx += 1)
a2889657 5777 {
5f5c8ee5
GM
5778#define PROP(IDX) \
5779 (XVECTOR (f->desired_toolbar_items) \
5780 ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
5781
5782 int enabled_p = !NILP (PROP (TOOLBAR_ITEM_ENABLED_P));
5783 int selected_p = !NILP (PROP (TOOLBAR_ITEM_SELECTED_P));
5784 int margin, relief;
5785 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
5786 extern Lisp_Object Qlaplace;
5787
5788 /* If image is a vector, choose the image according to the
5789 button state. */
5790 image = PROP (TOOLBAR_ITEM_IMAGES);
5791 if (VECTORP (image))
5792 {
5793 enum toolbar_item_image idx;
5794
5795 if (enabled_p)
5796 idx = (selected_p
5797 ? TOOLBAR_IMAGE_ENABLED_SELECTED
5798 : TOOLBAR_IMAGE_ENABLED_DESELECTED);
5799 else
5800 idx = (selected_p
5801 ? TOOLBAR_IMAGE_DISABLED_SELECTED
5802 : TOOLBAR_IMAGE_DISABLED_DESELECTED);
5803
5804 xassert (XVECTOR (image)->size >= idx);
5805 image = XVECTOR (image)->contents[idx];
5806 }
5807
5808 /* Ignore invalid image specifications. */
5809 if (!valid_image_p (image))
5810 continue;
5811
5812 /* Display the toolbar button pressed, or depressed. */
5813 plist = Fcopy_sequence (XCDR (image));
5814
5815 /* Compute margin and relief to draw. */
5816 relief = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
5817 margin = relief + max (0, toolbar_button_margin);
5818
5819 if (auto_raise_toolbar_buttons_p)
5820 {
5821 /* Add a `:relief' property to the image spec if the item is
5822 selected. */
5823 if (selected_p)
5824 {
5825 plist = Fplist_put (plist, QCrelief, make_number (-relief));
5826 margin -= relief;
5827 }
5828 }
5829 else
5830 {
5831 /* If image is selected, display it pressed, i.e. with a
5832 negative relief. If it's not selected, display it with a
5833 raised relief. */
5834 plist = Fplist_put (plist, QCrelief,
5835 (selected_p
5836 ? make_number (-relief)
5837 : make_number (relief)));
5838 margin -= relief;
5839 }
5840
5841 /* Put a margin around the image. */
5842 if (margin)
5843 plist = Fplist_put (plist, QCmargin, make_number (margin));
5844
5845 /* If button is not enabled, make the image appear disabled by
5846 applying an appropriate algorithm to it. */
5847 if (!enabled_p)
5848 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
5849
5850 /* Put a `display' text property on the string for the image to
5851 display. Put a `menu-item' property on the string that gives
5852 the start of this item's properties in the toolbar items
5853 vector. */
5854 image = Fcons (Qimage, plist);
5855 props = list4 (Qdisplay, image,
5856 Qmenu_item, make_number (i * TOOLBAR_ITEM_NSLOTS)),
5857 Fadd_text_properties (make_number (string_idx),
5858 make_number (string_idx + 1),
5859 props, f->desired_toolbar_string);
5860#undef PROP
a2889657
JB
5861 }
5862
5f5c8ee5
GM
5863 UNGCPRO;
5864}
5865
5866
5867/* Display one line of the toolbar of frame IT->f. */
5868
5869static void
5870display_toolbar_line (it)
5871 struct it *it;
5872{
5873 struct glyph_row *row = it->glyph_row;
5874 int max_x = it->last_visible_x;
5875 struct glyph *last;
5876
5877 prepare_desired_row (row);
5878 row->y = it->current_y;
5879
5880 while (it->current_x < max_x)
a2889657 5881 {
5f5c8ee5 5882 int x_before, x, n_glyphs_before, i, nglyphs;
a2f016e3 5883
5f5c8ee5
GM
5884 /* Get the next display element. */
5885 if (!get_next_display_element (it))
5886 break;
73af359d 5887
5f5c8ee5
GM
5888 /* Produce glyphs. */
5889 x_before = it->current_x;
5890 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
5891 PRODUCE_GLYPHS (it);
daa37602 5892
5f5c8ee5
GM
5893 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
5894 i = 0;
5895 x = x_before;
5896 while (i < nglyphs)
5897 {
5898 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
5899
5900 if (x + glyph->pixel_width > max_x)
5901 {
5902 /* Glyph doesn't fit on line. */
5903 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
5904 it->current_x = x;
5905 goto out;
5906 }
daa37602 5907
5f5c8ee5
GM
5908 ++it->hpos;
5909 x += glyph->pixel_width;
5910 ++i;
5911 }
5912
5913 /* Stop at line ends. */
5914 if (ITERATOR_AT_END_OF_LINE_P (it))
5915 break;
5916
5917 set_iterator_to_next (it);
a2889657 5918 }
a2889657 5919
5f5c8ee5 5920 out:;
a2889657 5921
5f5c8ee5
GM
5922 row->displays_text_p = row->used[TEXT_AREA] != 0;
5923 extend_face_to_end_of_line (it);
5924 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
5925 last->right_box_line_p = 1;
5926 compute_line_metrics (it);
5927
5928 /* If line is empty, make it occupy the rest of the toolbar. */
5929 if (!row->displays_text_p)
5930 {
312246d1
GM
5931 row->height = row->phys_height = it->last_visible_y - row->y;
5932 row->ascent = row->phys_ascent = 0;
5f5c8ee5
GM
5933 }
5934
5935 row->full_width_p = 1;
5936 row->continued_p = 0;
5937 row->truncated_on_left_p = 0;
5938 row->truncated_on_right_p = 0;
5939
5940 it->current_x = it->hpos = 0;
5941 it->current_y += row->height;
5942 ++it->vpos;
5943 ++it->glyph_row;
a2889657 5944}
96a410bc 5945
5f5c8ee5
GM
5946
5947/* Value is the number of screen lines needed to make all toolbar
5948 items of frame F visible. */
96a410bc 5949
d39b6696 5950static int
5f5c8ee5
GM
5951toolbar_lines_needed (f)
5952 struct frame *f;
d39b6696 5953{
5f5c8ee5
GM
5954 struct window *w = XWINDOW (f->toolbar_window);
5955 struct it it;
5956
5957 /* Initialize an iterator for iteration over F->desired_toolbar_string
5958 in the toolbar window of frame F. */
5959 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
5960 it.first_visible_x = 0;
5961 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
5962 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
5963
5964 while (!ITERATOR_AT_END_P (&it))
5965 {
5966 it.glyph_row = w->desired_matrix->rows;
5967 clear_glyph_row (it.glyph_row);
5968 display_toolbar_line (&it);
5969 }
5970
5971 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
d39b6696 5972}
96a410bc 5973
5f5c8ee5
GM
5974
5975/* Display the toolbar of frame F. Value is non-zero if toolbar's
5976 height should be changed. */
5977
5978static int
5979redisplay_toolbar (f)
5980 struct frame *f;
96a410bc 5981{
5f5c8ee5
GM
5982 struct window *w;
5983 struct it it;
5984 struct glyph_row *row;
5985 int change_height_p = 0;
5986
5987 /* If frame hasn't a toolbar window or if it is zero-height, don't
5988 do anything. This means you must start with toolbar-lines
5989 non-zero to get the auto-sizing effect. Or in other words, you
5990 can turn off toolbars by specifying toolbar-lines zero. */
5991 if (!WINDOWP (f->toolbar_window)
5992 || (w = XWINDOW (f->toolbar_window),
5993 XFASTINT (w->height) == 0))
5994 return 0;
96a410bc 5995
5f5c8ee5
GM
5996 /* Set up an iterator for the toolbar window. */
5997 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
5998 it.first_visible_x = 0;
5999 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6000 row = it.glyph_row;
3450d04c 6001
5f5c8ee5
GM
6002 /* Build a string that represents the contents of the toolbar. */
6003 build_desired_toolbar_string (f);
6004 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
3450d04c 6005
5f5c8ee5
GM
6006 /* Display as many lines as needed to display all toolbar items. */
6007 while (it.current_y < it.last_visible_y)
6008 display_toolbar_line (&it);
3450d04c 6009
5f5c8ee5
GM
6010 /* It doesn't make much sense to try scrolling in the toolbar
6011 window, so don't do it. */
6012 w->desired_matrix->no_scrolling_p = 1;
6013 w->must_be_updated_p = 1;
3450d04c 6014
5f5c8ee5
GM
6015 if (auto_resize_toolbars_p)
6016 {
6017 int nlines;
6018
6019 /* If there are blank lines at the end, except for a partially
6020 visible blank line at the end that is smaller than
6021 CANON_Y_UNIT, change the toolbar's height. */
6022 row = it.glyph_row - 1;
6023 if (!row->displays_text_p
6024 && row->height >= CANON_Y_UNIT (f))
6025 change_height_p = 1;
6026
6027 /* If row displays toolbar items, but is partially visible,
6028 change the toolbar's height. */
6029 if (row->displays_text_p
6030 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6031 change_height_p = 1;
6032
6033 /* Resize windows as needed by changing the `toolbar-lines'
6034 frame parameter. */
6035 if (change_height_p
6036 && (nlines = toolbar_lines_needed (f),
6037 nlines != XFASTINT (w->height)))
6038 {
6039 extern Lisp_Object Qtoolbar_lines;
6040 Lisp_Object frame;
6041
6042 XSETFRAME (frame, f);
6043 clear_glyph_matrix (w->desired_matrix);
6044 Fmodify_frame_parameters (frame,
6045 Fcons (Fcons (Qtoolbar_lines,
6046 make_number (nlines)),
6047 Qnil));
6048 fonts_changed_p = 1;
6049 }
6050 }
3450d04c 6051
5f5c8ee5 6052 return change_height_p;
96a410bc 6053}
90adcf20 6054
5f5c8ee5
GM
6055
6056/* Get information about the toolbar item which is displayed in GLYPH
6057 on frame F. Return in *PROP_IDX the index where toolbar item
6058 properties start in F->current_toolbar_items. Value is zero if
6059 GLYPH doesn't display a toolbar item. */
6060
6061int
6062toolbar_item_info (f, glyph, prop_idx)
6063 struct frame *f;
6064 struct glyph *glyph;
6065 int *prop_idx;
90adcf20 6066{
5f5c8ee5
GM
6067 Lisp_Object prop;
6068 int success_p;
6069
6070 /* Get the text property `menu-item' at pos. The value of that
6071 property is the start index of this item's properties in
6072 F->current_toolbar_items. */
6073 prop = Fget_text_property (make_number (glyph->charpos),
6074 Qmenu_item, f->current_toolbar_string);
6075 if (INTEGERP (prop))
6076 {
6077 *prop_idx = XINT (prop);
6078 success_p = 1;
6079 }
6080 else
6081 success_p = 0;
90adcf20 6082
5f5c8ee5
GM
6083 return success_p;
6084}
6085
6086#endif /* HAVE_WINDOW_SYSTEM */
90adcf20 6087
feb0c42f 6088
5f5c8ee5
GM
6089\f
6090/************************************************************************
6091 Horizontal scrolling
6092 ************************************************************************/
feb0c42f 6093
5f5c8ee5
GM
6094static int hscroll_window_tree P_ ((Lisp_Object));
6095static int hscroll_windows P_ ((Lisp_Object));
feb0c42f 6096
5f5c8ee5
GM
6097/* For all leaf windows in the window tree rooted at WINDOW, set their
6098 hscroll value so that PT is (i) visible in the window, and (ii) so
6099 that it is not within a certain margin at the window's left and
6100 right border. Value is non-zero if any window's hscroll has been
6101 changed. */
6102
6103static int
6104hscroll_window_tree (window)
6105 Lisp_Object window;
6106{
6107 int hscrolled_p = 0;
6108
6109 while (WINDOWP (window))
90adcf20 6110 {
5f5c8ee5
GM
6111 struct window *w = XWINDOW (window);
6112
6113 if (WINDOWP (w->hchild))
6114 hscrolled_p |= hscroll_window_tree (w->hchild);
6115 else if (WINDOWP (w->vchild))
6116 hscrolled_p |= hscroll_window_tree (w->vchild);
6117 else if (w->cursor.vpos >= 0)
6118 {
6119 int hscroll_margin, text_area_x, text_area_y;
6120 int text_area_width, text_area_height;
6121 struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
6122 w->cursor.vpos);
a2725ab2 6123
5f5c8ee5
GM
6124 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6125 &text_area_width, &text_area_height);
90adcf20 6126
5f5c8ee5
GM
6127 /* Scroll when cursor is inside this scroll margin. */
6128 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6129
6130 if ((XFASTINT (w->hscroll)
6131 && w->cursor.x < hscroll_margin)
6132 || (cursor_row->truncated_on_right_p
6133 && (w->cursor.x > text_area_width - hscroll_margin)))
08b610e4 6134 {
5f5c8ee5
GM
6135 struct it it;
6136 int hscroll;
6137 struct buffer *saved_current_buffer;
6138 int pt;
6139
6140 /* Find point in a display of infinite width. */
6141 saved_current_buffer = current_buffer;
6142 current_buffer = XBUFFER (w->buffer);
6143
6144 if (w == XWINDOW (selected_window))
6145 pt = BUF_PT (current_buffer);
6146 else
08b610e4 6147 {
5f5c8ee5
GM
6148 pt = marker_position (w->pointm);
6149 pt = max (BEGV, pt);
6150 pt = min (ZV, pt);
6151 }
6152
6153 /* Move iterator to pt starting at cursor_row->start in
6154 a line with infinite width. */
6155 init_to_row_start (&it, w, cursor_row);
6156 it.last_visible_x = INFINITY;
6157 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6158 current_buffer = saved_current_buffer;
6159
6160 /* Center cursor in window. */
6161 hscroll = (max (0, it.current_x - text_area_width / 2)
6162 / CANON_X_UNIT (it.f));
6163
6164 /* Don't call Fset_window_hscroll if value hasn't
6165 changed because it will prevent redisplay
6166 optimizations. */
6167 if (XFASTINT (w->hscroll) != hscroll)
6168 {
6169 Fset_window_hscroll (window, make_number (hscroll));
6170 hscrolled_p = 1;
08b610e4 6171 }
08b610e4 6172 }
08b610e4 6173 }
a2725ab2 6174
5f5c8ee5 6175 window = w->next;
90adcf20 6176 }
cd6dfed6 6177
5f5c8ee5
GM
6178 /* Value is non-zero if hscroll of any leaf window has been changed. */
6179 return hscrolled_p;
6180}
6181
6182
6183/* Set hscroll so that cursor is visible and not inside horizontal
6184 scroll margins for all windows in the tree rooted at WINDOW. See
6185 also hscroll_window_tree above. Value is non-zero if any window's
6186 hscroll has been changed. If it has, desired matrices on the frame
6187 of WINDOW are cleared. */
6188
6189static int
6190hscroll_windows (window)
6191 Lisp_Object window;
6192{
6193 int hscrolled_p = hscroll_window_tree (window);
6194 if (hscrolled_p)
6195 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6196 return hscrolled_p;
90adcf20 6197}
5f5c8ee5
GM
6198
6199
90adcf20 6200\f
5f5c8ee5
GM
6201/************************************************************************
6202 Redisplay
6203 ************************************************************************/
6204
6205/* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6206 to a non-zero value. This is sometimes handy to have in a debugger
6207 session. */
6208
6209#if GLYPH_DEBUG
a2889657 6210
5f5c8ee5
GM
6211/* Values of beg_unchanged and end_unchanged as of last call to
6212 try_window_id. */
6213
6214int debug_beg_unchanged, debug_end_unchanged;
6215
6216/* First and last unchanged row for try_window_id. */
6217
6218int debug_first_unchanged_at_end_vpos;
6219int debug_last_unchanged_at_beg_vpos;
6220
6221/* Delta vpos and y. */
6222
6223int debug_dvpos, debug_dy;
6224
6225/* Delta in characters and bytes for try_window_id. */
6226
6227int debug_delta, debug_delta_bytes;
6228
6229/* Values of window_end_pos and window_end_vpos at the end of
6230 try_window_id. */
6231
6232int debug_end_pos, debug_end_vpos;
6233
6234/* Append a string to W->desired_matrix->method. FMT is a printf
6235 format string. A1...A9 are a supplement for a variable-length
6236 argument list. If trace_redisplay_p is non-zero also printf the
6237 resulting string to stderr. */
6238
6239static void
6240debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
6241 struct window *w;
6242 char *fmt;
6243 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
6244{
6245 char buffer[512];
6246 char *method = w->desired_matrix->method;
6247 int len = strlen (method);
6248 int size = sizeof w->desired_matrix->method;
6249 int remaining = size - len - 1;
6250
6251 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
6252 if (len && remaining)
6253 {
6254 method[len] = '|';
6255 --remaining, ++len;
6256 }
6257
6258 strncpy (method + len, buffer, remaining);
6259
6260 if (trace_redisplay_p)
6261 fprintf (stderr, "%p (%s): %s\n",
6262 w,
6263 ((BUFFERP (w->buffer)
6264 && STRINGP (XBUFFER (w->buffer)->name))
6265 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
6266 : "no buffer"),
6267 buffer);
6268}
a2889657 6269
5f5c8ee5 6270#endif /* GLYPH_DEBUG */
90adcf20 6271
a2889657 6272
5f5c8ee5
GM
6273/* This counter is used to clear the face cache every once in a while
6274 in redisplay_internal. It is incremented for each redisplay.
6275 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
6276 cleared. */
0d231165 6277
5f5c8ee5 6278#define CLEAR_FACE_CACHE_COUNT 10000
463f6b91
RS
6279static int clear_face_cache_count;
6280
20de20dc 6281/* Record the previous terminal frame we displayed. */
5f5c8ee5
GM
6282
6283static struct frame *previous_terminal_frame;
6284
6285/* Non-zero while redisplay_internal is in progress. */
6286
6287int redisplaying_p;
6288
6289
6290/* Value is non-zero if all changes in window W, which displays
6291 current_buffer, are in the text between START and END. START is a
6292 buffer position, END is given as a distance from Z. Used in
6293 redisplay_internal for display optimization. */
6294
6295static INLINE int
6296text_outside_line_unchanged_p (w, start, end)
6297 struct window *w;
6298 int start, end;
6299{
6300 int unchanged_p = 1;
6301
6302 /* If text or overlays have changed, see where. */
6303 if (XFASTINT (w->last_modified) < MODIFF
6304 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
6305 {
6306 /* Gap in the line? */
6307 if (GPT < start || Z - GPT < end)
6308 unchanged_p = 0;
6309
6310 /* Changes start in front of the line, or end after it? */
6311 if (unchanged_p
6312 && (beg_unchanged < start - 1
6313 || end_unchanged < end))
6314 unchanged_p = 0;
6315
6316 /* If selective display, can't optimize if changes start at the
6317 beginning of the line. */
6318 if (unchanged_p
6319 && INTEGERP (current_buffer->selective_display)
6320 && XINT (current_buffer->selective_display) > 0
6321 && (beg_unchanged < start || GPT <= start))
6322 unchanged_p = 0;
6323 }
6324
6325 return unchanged_p;
6326}
6327
6328
6329/* Do a frame update, taking possible shortcuts into account. This is
6330 the main external entry point for redisplay.
6331
6332 If the last redisplay displayed an echo area message and that message
6333 is no longer requested, we clear the echo area or bring back the
6334 mini-buffer if that is in use. */
20de20dc 6335
a2889657
JB
6336void
6337redisplay ()
e9874cee
RS
6338{
6339 redisplay_internal (0);
6340}
6341
5f5c8ee5
GM
6342
6343/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
6344 response to any user action; therefore, we should preserve the echo
6345 area. (Actually, our caller does that job.) Perhaps in the future
6346 avoid recentering windows if it is not necessary; currently that
6347 causes some problems. */
e9874cee
RS
6348
6349static void
6350redisplay_internal (preserve_echo_area)
6351 int preserve_echo_area;
a2889657 6352{
5f5c8ee5
GM
6353 struct window *w = XWINDOW (selected_window);
6354 struct frame *f = XFRAME (w->frame);
6355 int pause;
a2889657 6356 int must_finish = 0;
5f5c8ee5 6357 struct text_pos tlbufpos, tlendpos;
89819bdd 6358 int number_of_visible_frames;
28514cd9 6359 int count;
a2889657 6360
5f5c8ee5
GM
6361 /* Non-zero means redisplay has to consider all windows on all
6362 frames. Zero means, only selected_window is considered. */
6363 int consider_all_windows_p;
6364
6365 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
6366
6367 /* No redisplay if running in batch mode or frame is not yet fully
6368 initialized, or redisplay is explicitly turned off by setting
6369 Vinhibit_redisplay. */
6370 if (noninteractive
6371 || !NILP (Vinhibit_redisplay)
6372 || !f->glyphs_initialized_p)
a2889657
JB
6373 return;
6374
5f5c8ee5
GM
6375 /* The flag redisplay_performed_directly_p is set by
6376 direct_output_for_insert when it already did the whole screen
6377 update necessary. */
6378 if (redisplay_performed_directly_p)
6379 {
6380 redisplay_performed_directly_p = 0;
6381 if (!hscroll_windows (selected_window))
6382 return;
6383 }
6384
15f0cf78
RS
6385#ifdef USE_X_TOOLKIT
6386 if (popup_activated ())
6387 return;
6388#endif
6389
28514cd9 6390 /* I don't think this happens but let's be paranoid. */
5f5c8ee5 6391 if (redisplaying_p)
735c094c
KH
6392 return;
6393
28514cd9
GM
6394 /* Record a function that resets redisplaying_p to its old value
6395 when we leave this function. */
6396 count = specpdl_ptr - specpdl;
6397 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
6398 ++redisplaying_p;
6399
8b32d885
RS
6400 retry:
6401
5f5c8ee5
GM
6402 /* If new fonts have been loaded that make a glyph matrix adjustment
6403 necessary, do it. */
6404 if (fonts_changed_p)
6405 {
6406 adjust_glyphs (NULL);
6407 ++windows_or_buffers_changed;
6408 fonts_changed_p = 0;
6409 }
6410
fd8ff63d 6411 if (! FRAME_WINDOW_P (selected_frame)
20de20dc
RS
6412 && previous_terminal_frame != selected_frame)
6413 {
5f5c8ee5
GM
6414 /* Since frames on an ASCII terminal share the same display
6415 area, displaying a different frame means redisplay the whole
6416 thing. */
20de20dc
RS
6417 windows_or_buffers_changed++;
6418 SET_FRAME_GARBAGED (selected_frame);
6419 XSETFRAME (Vterminal_frame, selected_frame);
6420 }
6421 previous_terminal_frame = selected_frame;
20de20dc 6422
5f5c8ee5
GM
6423 /* Set the visible flags for all frames. Do this before checking
6424 for resized or garbaged frames; they want to know if their frames
6425 are visible. See the comment in frame.h for
6426 FRAME_SAMPLE_VISIBILITY. */
d724d989 6427 {
35f56f96 6428 Lisp_Object tail, frame;
d724d989 6429
89819bdd
RS
6430 number_of_visible_frames = 0;
6431
35f56f96 6432 FOR_EACH_FRAME (tail, frame)
f82aff7c 6433 {
5f5c8ee5
GM
6434 struct frame *f = XFRAME (frame);
6435
6436 FRAME_SAMPLE_VISIBILITY (f);
6437 if (FRAME_VISIBLE_P (f))
6438 ++number_of_visible_frames;
6439 clear_desired_matrices (f);
f82aff7c 6440 }
d724d989
JB
6441 }
6442
44fa5b1e 6443 /* Notice any pending interrupt request to change frame size. */
a2889657
JB
6444 do_pending_window_change ();
6445
5f5c8ee5 6446 /* Clear frames marked as garbaged. */
44fa5b1e 6447 if (frame_garbaged)
a2889657 6448 {
5f5c8ee5
GM
6449 /* Old redisplay called redraw_garbaged_frames here which in
6450 turn called redraw_frame which in turn called clear_frame.
6451 The call to clear_frame is a source of flickering. After
6452 checking the places where SET_FRAME_GARBAGED is called, I
6453 believe a clear_frame is not necessary. It should suffice in
6454 the new redisplay to invalidate all current matrices, and
6455 ensure a complete redisplay of all windows. */
6456 Lisp_Object tail, frame;
6457
6458 FOR_EACH_FRAME (tail, frame)
6459 {
6460 struct frame *f = XFRAME (frame);
6461
6462 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
6463 {
6464 clear_current_matrices (f);
6465 f->garbaged = 0;
6466 }
6467 }
6468
44fa5b1e 6469 frame_garbaged = 0;
5f5c8ee5 6470 ++windows_or_buffers_changed;
a2889657
JB
6471 }
6472
5f5c8ee5 6473 /* Build menubar and toolbar items. */
f82aff7c
RS
6474 prepare_menu_bars ();
6475
28995e67 6476 if (windows_or_buffers_changed)
a2889657
JB
6477 update_mode_lines++;
6478
538f13d4
RS
6479 /* Detect case that we need to write or remove a star in the mode line. */
6480 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
a2889657
JB
6481 {
6482 w->update_mode_line = Qt;
6483 if (buffer_shared > 1)
6484 update_mode_lines++;
6485 }
6486
5f5c8ee5 6487 /* If %c is in the mode line, update it if needed. */
28995e67
RS
6488 if (!NILP (w->column_number_displayed)
6489 /* This alternative quickly identifies a common case
6490 where no change is needed. */
6491 && !(PT == XFASTINT (w->last_point)
8850a573
RS
6492 && XFASTINT (w->last_modified) >= MODIFF
6493 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
6494 && XFASTINT (w->column_number_displayed) != current_column ())
6495 w->update_mode_line = Qt;
6496
44fa5b1e 6497 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
a2889657 6498
5f5c8ee5
GM
6499 /* The variable buffer_shared is set in redisplay_window and
6500 indicates that we redisplay a buffer in different windows. See
6501 there. */
6502 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
a2889657
JB
6503
6504 /* If specs for an arrow have changed, do thorough redisplay
6505 to ensure we remove any arrow that should no longer exist. */
d45de95b 6506 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
ded34426 6507 || ! EQ (Voverlay_arrow_string, last_arrow_string))
5f5c8ee5 6508 consider_all_windows_p = windows_or_buffers_changed = 1;
a2889657 6509
90adcf20
RS
6510 /* Normally the message* functions will have already displayed and
6511 updated the echo area, but the frame may have been trashed, or
6512 the update may have been preempted, so display the echo area
6513 again here. */
5f5c8ee5
GM
6514 if (echo_area_glyphs
6515 || STRINGP (echo_area_message)
6516 || previous_echo_glyphs
6517 || STRINGP (previous_echo_area_message))
90adcf20 6518 {
5f5c8ee5 6519 echo_area_display (0);
90adcf20
RS
6520 must_finish = 1;
6521 }
6522
5f5c8ee5
GM
6523 /* If showing the region, and mark has changed, we must redisplay
6524 the whole window. The assignment to this_line_start_pos prevents
6525 the optimization directly below this if-statement. */
bd66d1ba
RS
6526 if (((!NILP (Vtransient_mark_mode)
6527 && !NILP (XBUFFER (w->buffer)->mark_active))
6528 != !NILP (w->region_showing))
82d04750
JB
6529 || (!NILP (w->region_showing)
6530 && !EQ (w->region_showing,
6531 Fmarker_position (XBUFFER (w->buffer)->mark))))
5f5c8ee5
GM
6532 CHARPOS (this_line_start_pos) = 0;
6533
6534 /* Optimize the case that only the line containing the cursor in the
6535 selected window has changed. Variables starting with this_ are
6536 set in display_line and record information about the line
6537 containing the cursor. */
6538 tlbufpos = this_line_start_pos;
6539 tlendpos = this_line_end_pos;
6540 if (!consider_all_windows_p
6541 && CHARPOS (tlbufpos) > 0
6542 && NILP (w->update_mode_line)
73af359d 6543 && !current_buffer->clip_changed
44fa5b1e 6544 && FRAME_VISIBLE_P (XFRAME (w->frame))
f21ef775 6545 && !FRAME_OBSCURED_P (XFRAME (w->frame))
5f5c8ee5 6546 /* Make sure recorded data applies to current buffer, etc. */
a2889657
JB
6547 && this_line_buffer == current_buffer
6548 && current_buffer == XBUFFER (w->buffer)
265a9e55 6549 && NILP (w->force_start)
5f5c8ee5
GM
6550 /* Point must be on the line that we have info recorded about. */
6551 && PT >= CHARPOS (tlbufpos)
6552 && PT <= Z - CHARPOS (tlendpos)
a2889657
JB
6553 /* All text outside that line, including its final newline,
6554 must be unchanged */
5f5c8ee5
GM
6555 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
6556 CHARPOS (tlendpos)))
6557 {
6558 if (CHARPOS (tlbufpos) > BEGV
6559 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
6560 && (CHARPOS (tlbufpos) == ZV
6561 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
a2889657
JB
6562 /* Former continuation line has disappeared by becoming empty */
6563 goto cancel;
6564 else if (XFASTINT (w->last_modified) < MODIFF
8850a573 6565 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
a2889657
JB
6566 || MINI_WINDOW_P (w))
6567 {
1c9241f5
KH
6568 /* We have to handle the case of continuation around a
6569 wide-column character (See the comment in indent.c around
6570 line 885).
6571
6572 For instance, in the following case:
6573
6574 -------- Insert --------
6575 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
6576 J_I_ ==> J_I_ `^^' are cursors.
6577 ^^ ^^
6578 -------- --------
6579
6580 As we have to redraw the line above, we should goto cancel. */
6581
5f5c8ee5
GM
6582 struct it it;
6583 int line_height_before = this_line_pixel_height;
6584
6585 /* Note that start_display will handle the case that the
6586 line starting at tlbufpos is a continuation lines. */
6587 start_display (&it, w, tlbufpos);
6588
6589 /* Implementation note: It this still necessary? */
6590 if (it.current_x != this_line_start_x)
1c9241f5
KH
6591 goto cancel;
6592
5f5c8ee5
GM
6593 TRACE ((stderr, "trying display optimization 1\n"));
6594 w->cursor.vpos = -1;
a2889657 6595 overlay_arrow_seen = 0;
5f5c8ee5
GM
6596 it.vpos = this_line_vpos;
6597 it.current_y = this_line_y;
6598 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
6599 display_line (&it);
6600
a2889657 6601 /* If line contains point, is not continued,
5f5c8ee5
GM
6602 and ends at same distance from eob as before, we win */
6603 if (w->cursor.vpos >= 0
6604 /* Line is not continued, otherwise this_line_start_pos
6605 would have been set to 0 in display_line. */
6606 && CHARPOS (this_line_start_pos)
6607 /* Line ends as before. */
6608 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
6609 /* Line has same height as before. Otherwise other lines
6610 would have to be shifted up or down. */
6611 && this_line_pixel_height == line_height_before)
a2889657 6612 {
5f5c8ee5
GM
6613 /* If this is not the window's last line, we must adjust
6614 the charstarts of the lines below. */
6615 if (it.current_y < it.last_visible_y)
6616 {
6617 struct glyph_row *row
6618 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
6619 int delta, delta_bytes;
6620
6621 if (Z - CHARPOS (tlendpos) == ZV)
6622 {
6623 /* This line ends at end of (accessible part of)
6624 buffer. There is no newline to count. */
6625 delta = (Z
6626 - CHARPOS (tlendpos)
6627 - MATRIX_ROW_START_CHARPOS (row));
6628 delta_bytes = (Z_BYTE
6629 - BYTEPOS (tlendpos)
6630 - MATRIX_ROW_START_BYTEPOS (row));
6631 }
6632 else
6633 {
6634 /* This line ends in a newline. Must take
6635 account of the newline and the rest of the
6636 text that follows. */
6637 delta = (Z
6638 - CHARPOS (tlendpos)
6639 - MATRIX_ROW_START_CHARPOS (row));
6640 delta_bytes = (Z_BYTE
6641 - BYTEPOS (tlendpos)
6642 - MATRIX_ROW_START_BYTEPOS (row));
6643 }
6644
6645 increment_glyph_matrix_buffer_positions (w->current_matrix,
6646 this_line_vpos + 1,
6647 w->current_matrix->nrows,
6648 delta, delta_bytes);
85bcef6c 6649 }
46db8486 6650
5f5c8ee5
GM
6651 /* If this row displays text now but previously didn't,
6652 or vice versa, w->window_end_vpos may have to be
6653 adjusted. */
6654 if ((it.glyph_row - 1)->displays_text_p)
6655 {
6656 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
6657 XSETINT (w->window_end_vpos, this_line_vpos);
6658 }
6659 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
6660 && this_line_vpos > 0)
6661 XSETINT (w->window_end_vpos, this_line_vpos - 1);
6662 w->window_end_valid = Qnil;
6663
6664 /* Update hint: No need to try to scroll in update_window. */
6665 w->desired_matrix->no_scrolling_p = 1;
6666
6667#if GLYPH_DEBUG
6668 *w->desired_matrix->method = 0;
6669 debug_method_add (w, "optimization 1");
6670#endif
a2889657
JB
6671 goto update;
6672 }
6673 else
6674 goto cancel;
6675 }
5f5c8ee5
GM
6676 else if (/* Cursor position hasn't changed. */
6677 PT == XFASTINT (w->last_point)
b6f0fe04
RS
6678 /* Make sure the cursor was last displayed
6679 in this window. Otherwise we have to reposition it. */
5f5c8ee5
GM
6680 && 0 <= w->cursor.vpos
6681 && XINT (w->height) > w->cursor.vpos)
a2889657
JB
6682 {
6683 if (!must_finish)
6684 {
6685 do_pending_window_change ();
5f5c8ee5
GM
6686
6687 /* We used to always goto end_of_redisplay here, but this
6688 isn't enough if we have a blinking cursor. */
6689 if (w->cursor_off_p == w->last_cursor_off_p)
6690 goto end_of_redisplay;
a2889657
JB
6691 }
6692 goto update;
6693 }
8b51f1e3
KH
6694 /* If highlighting the region, or if the cursor is in the echo area,
6695 then we can't just move the cursor. */
bd66d1ba
RS
6696 else if (! (!NILP (Vtransient_mark_mode)
6697 && !NILP (current_buffer->mark_active))
293a54ce
RS
6698 && (w == XWINDOW (current_buffer->last_selected_window)
6699 || highlight_nonselected_windows)
8b51f1e3 6700 && NILP (w->region_showing)
8f897821 6701 && NILP (Vshow_trailing_whitespace)
8b51f1e3 6702 && !cursor_in_echo_area)
a2889657 6703 {
5f5c8ee5
GM
6704 struct it it;
6705 struct glyph_row *row;
6706
6707 /* Skip from tlbufpos to PT and see where it is. Note that
6708 PT may be in invisible text. If so, we will end at the
6709 next visible position. */
6710 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
6711 NULL, DEFAULT_FACE_ID);
6712 it.current_x = this_line_start_x;
6713 it.current_y = this_line_y;
6714 it.vpos = this_line_vpos;
6715
6716 /* The call to move_it_to stops in front of PT, but
6717 moves over before-strings. */
6718 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6719
6720 if (it.vpos == this_line_vpos
6721 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
6722 row->enabled_p))
a2889657 6723 {
5f5c8ee5
GM
6724 xassert (this_line_vpos == it.vpos);
6725 xassert (this_line_y == it.current_y);
6726 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
a2889657
JB
6727 goto update;
6728 }
6729 else
6730 goto cancel;
6731 }
5f5c8ee5 6732
a2889657 6733 cancel:
5f5c8ee5
GM
6734 /* Text changed drastically or point moved off of line. */
6735 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
a2889657
JB
6736 }
6737
5f5c8ee5
GM
6738 CHARPOS (this_line_start_pos) = 0;
6739 consider_all_windows_p |= buffer_shared > 1;
6740 ++clear_face_cache_count;
a2889657 6741
5f5c8ee5
GM
6742
6743 /* Build desired matrices. If consider_all_windows_p is non-zero,
6744 do it for all windows on all frames. Otherwise do it for
6745 selected_window, only. */
463f6b91 6746
5f5c8ee5 6747 if (consider_all_windows_p)
a2889657 6748 {
35f56f96 6749 Lisp_Object tail, frame;
a2889657 6750
5f5c8ee5
GM
6751 /* Clear the face cache eventually. */
6752 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
463f6b91 6753 {
5f5c8ee5 6754 clear_face_cache (0);
463f6b91
RS
6755 clear_face_cache_count = 0;
6756 }
31b24551 6757
5f5c8ee5
GM
6758 /* Recompute # windows showing selected buffer. This will be
6759 incremented each time such a window is displayed. */
a2889657
JB
6760 buffer_shared = 0;
6761
35f56f96 6762 FOR_EACH_FRAME (tail, frame)
30c566e4 6763 {
5f5c8ee5 6764 struct frame *f = XFRAME (frame);
fd8ff63d 6765 if (FRAME_WINDOW_P (f) || f == selected_frame)
9769686d 6766 {
5f5c8ee5
GM
6767 /* Mark all the scroll bars to be removed; we'll redeem
6768 the ones we want when we redisplay their windows. */
9769686d
RS
6769 if (condemn_scroll_bars_hook)
6770 (*condemn_scroll_bars_hook) (f);
30c566e4 6771
f21ef775 6772 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
5f5c8ee5 6773 redisplay_windows (FRAME_ROOT_WINDOW (f));
30c566e4 6774
5f5c8ee5
GM
6775 /* Any scroll bars which redisplay_windows should have
6776 nuked should now go away. */
9769686d
RS
6777 if (judge_scroll_bars_hook)
6778 (*judge_scroll_bars_hook) (f);
6779 }
30c566e4 6780 }
a2889657 6781 }
5f5c8ee5
GM
6782 else if (FRAME_VISIBLE_P (selected_frame)
6783 && !FRAME_OBSCURED_P (selected_frame))
6784 redisplay_window (selected_window, 1);
6785
6786
6787 /* Compare desired and current matrices, perform output. */
6788
6789update:
6790
6791 /* If fonts changed, display again. */
6792 if (fonts_changed_p)
6793 goto retry;
a2889657 6794
a2889657
JB
6795 /* Prevent various kinds of signals during display update.
6796 stdio is not robust about handling signals,
6797 which can cause an apparent I/O error. */
6798 if (interrupt_input)
6799 unrequest_sigio ();
6800 stop_polling ();
6801
5f5c8ee5 6802 if (consider_all_windows_p)
a2889657
JB
6803 {
6804 Lisp_Object tail;
6805
6806 pause = 0;
6807
44fa5b1e 6808 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
a2889657 6809 {
5f5c8ee5 6810 struct frame *f;
a2889657 6811
e24c997d 6812 if (!FRAMEP (XCONS (tail)->car))
a2889657
JB
6813 continue;
6814
44fa5b1e 6815 f = XFRAME (XCONS (tail)->car);
1af9f229 6816
fd8ff63d 6817 if ((FRAME_WINDOW_P (f) || f == selected_frame)
f21ef775 6818 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
a2889657 6819 {
5f5c8ee5
GM
6820 /* Mark all windows as to be updated. */
6821 set_window_update_flags (XWINDOW (f->root_window), 1);
44fa5b1e 6822 pause |= update_frame (f, 0, 0);
a2889657 6823 if (!pause)
efc63ef0 6824 {
5f5c8ee5
GM
6825 if (hscroll_windows (f->root_window))
6826 goto retry;
6827
efc63ef0
RS
6828 mark_window_display_accurate (f->root_window, 1);
6829 if (frame_up_to_date_hook != 0)
6830 (*frame_up_to_date_hook) (f);
6831 }
a2889657
JB
6832 }
6833 }
6834 }
6835 else
6e8290aa 6836 {
5f5c8ee5
GM
6837 if (FRAME_VISIBLE_P (selected_frame)
6838 && !FRAME_OBSCURED_P (selected_frame))
6839 {
6840 XWINDOW (selected_window)->must_be_updated_p = 1;
6841 pause = update_frame (selected_frame, 0, 0);
6842 if (!pause && hscroll_windows (selected_window))
6843 goto retry;
6844 }
4d641a15
KH
6845 else
6846 pause = 0;
d724d989 6847
8de2d90b 6848 /* We may have called echo_area_display at the top of this
44fa5b1e
JB
6849 function. If the echo area is on another frame, that may
6850 have put text on a frame other than the selected one, so the
6851 above call to update_frame would not have caught it. Catch
8de2d90b
JB
6852 it here. */
6853 {
84faf44c 6854 Lisp_Object mini_window;
5f5c8ee5 6855 struct frame *mini_frame;
84faf44c
RS
6856
6857 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
6858 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8de2d90b 6859
fd8ff63d 6860 if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
5f5c8ee5
GM
6861 {
6862 XWINDOW (mini_window)->must_be_updated_p = 1;
6863 pause |= update_frame (mini_frame, 0, 0);
6864 if (!pause && hscroll_windows (mini_window))
6865 goto retry;
6866 }
8de2d90b 6867 }
6e8290aa 6868 }
a2889657 6869
5f5c8ee5
GM
6870 /* If display was paused because of pending input, make sure we do a
6871 thorough update the next time. */
a2889657
JB
6872 if (pause)
6873 {
5f5c8ee5
GM
6874 /* Prevent the optimization at the beginning of
6875 redisplay_internal that tries a single-line update of the
6876 line containing the cursor in the selected window. */
6877 CHARPOS (this_line_start_pos) = 0;
6878
6879 /* Let the overlay arrow be updated the next time. */
265a9e55 6880 if (!NILP (last_arrow_position))
a2889657
JB
6881 {
6882 last_arrow_position = Qt;
6883 last_arrow_string = Qt;
6884 }
5f5c8ee5
GM
6885
6886 /* If we pause after scrolling, some rows in the current
6887 matrices of some windows are not valid. */
6888 if (!WINDOW_FULL_WIDTH_P (w)
6889 && !FRAME_WINDOW_P (XFRAME (w->frame)))
a2889657
JB
6890 update_mode_lines = 1;
6891 }
6892
5f5c8ee5
GM
6893 /* Now text on frame agrees with windows, so put info into the
6894 windows for partial redisplay to follow. */
a2889657
JB
6895 if (!pause)
6896 {
6897 register struct buffer *b = XBUFFER (w->buffer);
6898
a2889657 6899 unchanged_modified = BUF_MODIFF (b);
8850a573 6900 overlay_unchanged_modified = BUF_OVERLAY_MODIFF (b);
a2889657
JB
6901 beg_unchanged = BUF_GPT (b) - BUF_BEG (b);
6902 end_unchanged = BUF_Z (b) - BUF_GPT (b);
6903
5f5c8ee5 6904 if (consider_all_windows_p)
11e82b76 6905 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
a2889657
JB
6906 else
6907 {
5f5c8ee5
GM
6908 XSETFASTINT (w->last_point, BUF_PT (b));
6909 w->last_cursor = w->cursor;
6910 w->last_cursor_off_p = w->cursor_off_p;
6911
28995e67 6912 b->clip_changed = 0;
a2889657 6913 w->update_mode_line = Qnil;
c2213350 6914 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
8850a573 6915 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
538f13d4
RS
6916 w->last_had_star
6917 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6918 ? Qt : Qnil);
3ee4159a
RS
6919
6920 /* Record if we are showing a region, so can make sure to
6921 update it fully at next redisplay. */
6922 w->region_showing = (!NILP (Vtransient_mark_mode)
293a54ce
RS
6923 && (w == XWINDOW (current_buffer->last_selected_window)
6924 || highlight_nonselected_windows)
3ee4159a
RS
6925 && !NILP (XBUFFER (w->buffer)->mark_active)
6926 ? Fmarker_position (XBUFFER (w->buffer)->mark)
6927 : Qnil);
6928
d2f84654 6929 w->window_end_valid = w->buffer;
d45de95b 6930 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657 6931 last_arrow_string = Voverlay_arrow_string;
efc63ef0
RS
6932 if (frame_up_to_date_hook != 0)
6933 (*frame_up_to_date_hook) (selected_frame);
a2889657 6934 }
5f5c8ee5 6935
a2889657
JB
6936 update_mode_lines = 0;
6937 windows_or_buffers_changed = 0;
6938 }
6939
5f5c8ee5
GM
6940 /* Start SIGIO interrupts coming again. Having them off during the
6941 code above makes it less likely one will discard output, but not
6942 impossible, since there might be stuff in the system buffer here.
a2889657 6943 But it is much hairier to try to do anything about that. */
a2889657
JB
6944 if (interrupt_input)
6945 request_sigio ();
6946 start_polling ();
6947
5f5c8ee5
GM
6948 /* If a frame has become visible which was not before, redisplay
6949 again, so that we display it. Expose events for such a frame
6950 (which it gets when becoming visible) don't call the parts of
6951 redisplay constructing glyphs, so simply exposing a frame won't
6952 display anything in this case. So, we have to display these
6953 frames here explicitly. */
11c52c4f
RS
6954 if (!pause)
6955 {
6956 Lisp_Object tail, frame;
6957 int new_count = 0;
6958
6959 FOR_EACH_FRAME (tail, frame)
6960 {
6961 int this_is_visible = 0;
8e83f802
RS
6962
6963 if (XFRAME (frame)->visible)
6964 this_is_visible = 1;
6965 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
6966 if (XFRAME (frame)->visible)
6967 this_is_visible = 1;
11c52c4f
RS
6968
6969 if (this_is_visible)
6970 new_count++;
6971 }
6972
89819bdd 6973 if (new_count != number_of_visible_frames)
11c52c4f
RS
6974 windows_or_buffers_changed++;
6975 }
6976
44fa5b1e 6977 /* Change frame size now if a change is pending. */
a2889657 6978 do_pending_window_change ();
d8e242fd 6979
8b32d885
RS
6980 /* If we just did a pending size change, or have additional
6981 visible frames, redisplay again. */
3c8c72e0 6982 if (windows_or_buffers_changed && !pause)
8b32d885 6983 goto retry;
5f5c8ee5
GM
6984
6985 end_of_redisplay:;
6986
28514cd9 6987 unbind_to (count, Qnil);
a2889657
JB
6988}
6989
5f5c8ee5
GM
6990
6991/* Redisplay, but leave alone any recent echo area message unless
6992 another message has been requested in its place.
a2889657
JB
6993
6994 This is useful in situations where you need to redisplay but no
6995 user action has occurred, making it inappropriate for the message
6996 area to be cleared. See tracking_off and
6997 wait_reading_process_input for examples of these situations. */
6998
8991bb31 6999void
a2889657
JB
7000redisplay_preserve_echo_area ()
7001{
5f5c8ee5
GM
7002 if (!echo_area_glyphs
7003 && !STRINGP (echo_area_message)
7004 && (previous_echo_glyphs
7005 || STRINGP (previous_echo_area_message)))
a2889657
JB
7006 {
7007 echo_area_glyphs = previous_echo_glyphs;
5f5c8ee5
GM
7008 echo_area_message = previous_echo_area_message;
7009 echo_area_glyphs_length = previous_echo_glyphs_length;
e9874cee 7010 redisplay_internal (1);
5f5c8ee5
GM
7011 echo_area_glyphs = NULL;
7012 echo_area_message = Qnil;
a2889657
JB
7013 }
7014 else
e9874cee 7015 redisplay_internal (1);
a2889657
JB
7016}
7017
5f5c8ee5 7018
28514cd9
GM
7019/* Function registered with record_unwind_protect in
7020 redisplay_internal. Clears the flag indicating that a redisplay is
7021 in progress. */
7022
7023static Lisp_Object
7024unwind_redisplay (old_redisplaying_p)
7025 Lisp_Object old_redisplaying_p;
7026{
7027 redisplaying_p = XFASTINT (old_redisplaying_p);
7028}
7029
7030
5f5c8ee5
GM
7031/* Mark the display of windows in the window tree rooted at WINDOW as
7032 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7033 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7034 the next time redisplay_internal is called. */
7035
a2889657 7036void
5f5c8ee5 7037mark_window_display_accurate (window, accurate_p)
a2889657 7038 Lisp_Object window;
5f5c8ee5 7039 int accurate_p;
a2889657 7040{
5f5c8ee5
GM
7041 struct window *w;
7042
7043 for (; !NILP (window); window = w->next)
a2889657
JB
7044 {
7045 w = XWINDOW (window);
7046
5f5c8ee5 7047 if (BUFFERP (w->buffer))
bd66d1ba 7048 {
5f5c8ee5
GM
7049 struct buffer *b = XBUFFER (w->buffer);
7050
c2213350 7051 XSETFASTINT (w->last_modified,
5f5c8ee5 7052 accurate_p ? BUF_MODIFF (b) : 0);
8850a573 7053 XSETFASTINT (w->last_overlay_modified,
5f5c8ee5
GM
7054 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7055 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7056 ? Qt : Qnil);
bd66d1ba 7057
5f5c8ee5
GM
7058#if 0 /* I don't think this is necessary because display_line does it.
7059 Let's check it. */
bd66d1ba
RS
7060 /* Record if we are showing a region, so can make sure to
7061 update it fully at next redisplay. */
5f5c8ee5
GM
7062 w->region_showing
7063 = (!NILP (Vtransient_mark_mode)
7064 && (w == XWINDOW (current_buffer->last_selected_window)
7065 || highlight_nonselected_windows)
7066 && (!NILP (b->mark_active)
7067 ? Fmarker_position (b->mark)
7068 : Qnil));
7069#endif
7070
7071 if (accurate_p)
7072 {
7073 b->clip_changed = 0;
7074 w->last_cursor = w->cursor;
7075 w->last_cursor_off_p = w->cursor_off_p;
7076 if (w == XWINDOW (selected_window))
7077 w->last_point = BUF_PT (b);
7078 else
7079 w->last_point = XMARKER (w->pointm)->charpos;
7080 }
bd66d1ba
RS
7081 }
7082
d2f84654 7083 w->window_end_valid = w->buffer;
a2889657
JB
7084 w->update_mode_line = Qnil;
7085
265a9e55 7086 if (!NILP (w->vchild))
5f5c8ee5 7087 mark_window_display_accurate (w->vchild, accurate_p);
265a9e55 7088 if (!NILP (w->hchild))
5f5c8ee5 7089 mark_window_display_accurate (w->hchild, accurate_p);
a2889657
JB
7090 }
7091
5f5c8ee5 7092 if (accurate_p)
a2889657 7093 {
d45de95b 7094 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657
JB
7095 last_arrow_string = Voverlay_arrow_string;
7096 }
7097 else
7098 {
5f5c8ee5
GM
7099 /* Force a thorough redisplay the next time by setting
7100 last_arrow_position and last_arrow_string to t, which is
7101 unequal to any useful value of Voverlay_arrow_... */
a2889657
JB
7102 last_arrow_position = Qt;
7103 last_arrow_string = Qt;
7104 }
7105}
5f5c8ee5
GM
7106
7107
7108/* Return value in display table DP (Lisp_Char_Table *) for character
7109 C. Since a display table doesn't have any parent, we don't have to
7110 follow parent. Do not call this function directly but use the
7111 macro DISP_CHAR_VECTOR. */
7112
7113Lisp_Object
7114disp_char_vector (dp, c)
7115 struct Lisp_Char_Table *dp;
7116 int c;
7117{
7118 int code[4], i;
7119 Lisp_Object val;
7120
7121 if (SINGLE_BYTE_CHAR_P (c))
7122 return (dp->contents[c]);
7123
7124 SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
7125 if (code[0] != CHARSET_COMPOSITION)
7126 {
7127 if (code[1] < 32)
7128 code[1] = -1;
7129 else if (code[2] < 32)
7130 code[2] = -1;
7131 }
7132
7133 /* Here, the possible range of code[0] (== charset ID) is
7134 128..max_charset. Since the top level char table contains data
7135 for multibyte characters after 256th element, we must increment
7136 code[0] by 128 to get a correct index. */
7137 code[0] += 128;
7138 code[3] = -1; /* anchor */
7139
7140 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
7141 {
7142 val = dp->contents[code[i]];
7143 if (!SUB_CHAR_TABLE_P (val))
7144 return (NILP (val) ? dp->defalt : val);
7145 }
7146
7147 /* Here, val is a sub char table. We return the default value of
7148 it. */
7149 return (dp->defalt);
7150}
7151
7152
a2889657 7153\f
5f5c8ee5
GM
7154/***********************************************************************
7155 Window Redisplay
7156 ***********************************************************************/
a2725ab2 7157
5f5c8ee5 7158/* Redisplay all leaf windows in the window tree rooted at WINDOW. */
90adcf20
RS
7159
7160static void
5f5c8ee5
GM
7161redisplay_windows (window)
7162 Lisp_Object window;
90adcf20 7163{
5f5c8ee5
GM
7164 while (!NILP (window))
7165 {
7166 struct window *w = XWINDOW (window);
7167
7168 if (!NILP (w->hchild))
7169 redisplay_windows (w->hchild);
7170 else if (!NILP (w->vchild))
7171 redisplay_windows (w->vchild);
7172 else
7173 redisplay_window (window, 0);
a2725ab2 7174
5f5c8ee5
GM
7175 window = w->next;
7176 }
7177}
7178
7179
7180/* Set cursor position of W. PT is assumed to be displayed in ROW.
7181 DELTA is the number of bytes by which positions recorded in ROW
7182 differ from current buffer positions. */
7183
7184void
7185set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
7186 struct window *w;
7187 struct glyph_row *row;
7188 struct glyph_matrix *matrix;
7189 int delta, delta_bytes, dy, dvpos;
7190{
7191 struct glyph *glyph = row->glyphs[TEXT_AREA];
7192 struct glyph *end = glyph + row->used[TEXT_AREA];
7193 int x = row->x;
7194 int pt_old = PT - delta;
7195
7196 /* Skip over glyphs not having an object at the start of the row.
7197 These are special glyphs like truncation marks on terminal
7198 frames. */
7199 if (row->displays_text_p)
7200 while (glyph < end
7201 && !glyph->object
7202 && glyph->charpos < 0)
7203 {
7204 x += glyph->pixel_width;
7205 ++glyph;
7206 }
7207
7208 while (glyph < end
7209 && glyph->object
7210 && (!BUFFERP (glyph->object)
7211 || glyph->charpos < pt_old))
7212 {
7213 x += glyph->pixel_width;
7214 ++glyph;
7215 }
7216
7217 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
7218 w->cursor.x = x;
7219 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
7220 w->cursor.y = row->y + dy;
7221
7222 if (w == XWINDOW (selected_window))
7223 {
7224 if (!row->continued_p
7225 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
7226 && row->x == 0)
7227 {
7228 this_line_buffer = XBUFFER (w->buffer);
7229
7230 CHARPOS (this_line_start_pos)
7231 = MATRIX_ROW_START_CHARPOS (row) + delta;
7232 BYTEPOS (this_line_start_pos)
7233 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
7234
7235 CHARPOS (this_line_end_pos)
7236 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
7237 BYTEPOS (this_line_end_pos)
7238 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
7239
7240 this_line_y = w->cursor.y;
7241 this_line_pixel_height = row->height;
7242 this_line_vpos = w->cursor.vpos;
7243 this_line_start_x = row->x;
7244 }
7245 else
7246 CHARPOS (this_line_start_pos) = 0;
7247 }
7248}
7249
7250
7251/* Run window scroll functions, if any, for WINDOW with new window
7252 start STARTP. Sets the window start of WINDOW to that position. */
7253
7254static INLINE struct text_pos
7255run_window_scroll_functions (window, startp)
7256 Lisp_Object window;
7257 struct text_pos startp;
7258{
7259 struct window *w = XWINDOW (window);
7260 SET_MARKER_FROM_TEXT_POS (w->start, startp);
90adcf20 7261
5f5c8ee5
GM
7262 if (!NILP (Vwindow_scroll_functions))
7263 {
7264 run_hook_with_args_2 (Qwindow_scroll_functions, window,
7265 make_number (CHARPOS (startp)));
7266 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7267 }
90adcf20 7268
5f5c8ee5
GM
7269 return startp;
7270}
7271
7272
7273/* Modify the desired matrix of window W and W->vscroll so that the
7274 line containing the cursor is fully visible. */
7275
7276static void
7277make_cursor_line_fully_visible (w)
7278 struct window *w;
7279{
7280 struct glyph_matrix *matrix;
7281 struct glyph_row *row;
7282 int top_line_height;
7283
7284 /* It's not always possible to find the cursor, e.g, when a window
7285 is full of overlay strings. Don't do anything in that case. */
7286 if (w->cursor.vpos < 0)
7287 return;
7288
7289 matrix = w->desired_matrix;
7290 row = MATRIX_ROW (matrix, w->cursor.vpos);
7291
7292 /* If row->y == top y of window display area, the window isn't tall
7293 enough to display a single line. There is nothing we can do
7294 about it. */
7295 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
7296 if (row->y == top_line_height)
7297 return;
7298
7299 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
7300 {
7301 int dy = row->height - row->visible_height;
7302 w->vscroll = 0;
7303 w->cursor.y += dy;
7304 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7305 }
7306 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
7307 {
7308 int dy = - (row->height - row->visible_height);
7309 w->vscroll = dy;
7310 w->cursor.y += dy;
7311 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7312 }
7313
7314 /* When we change the cursor y-position of the selected window,
7315 change this_line_y as well so that the display optimization for
7316 the cursor line of the selected window in redisplay_internal uses
7317 the correct y-position. */
7318 if (w == XWINDOW (selected_window))
7319 this_line_y = w->cursor.y;
7320}
7321
7322
7323/* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
7324 non-zero means only WINDOW is redisplayed in redisplay_internal.
7325 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
7326 in redisplay_window to bring a partially visible line into view in
7327 the case that only the cursor has moved.
7328
7329 Value is
7330
7331 1 if scrolling succeeded
7332
7333 0 if scrolling didn't find point.
7334
7335 -1 if new fonts have been loaded so that we must interrupt
7336 redisplay, adjust glyph matrices, and try again. */
7337
7338static int
7339try_scrolling (window, just_this_one_p, scroll_conservatively,
7340 scroll_step, temp_scroll_step)
7341 Lisp_Object window;
7342 int just_this_one_p;
7343 int scroll_conservatively, scroll_step;
7344 int temp_scroll_step;
7345{
7346 struct window *w = XWINDOW (window);
7347 struct frame *f = XFRAME (w->frame);
7348 struct text_pos scroll_margin_pos;
7349 struct text_pos pos;
7350 struct text_pos startp;
7351 struct it it;
7352 Lisp_Object window_end;
7353 int this_scroll_margin;
7354 int dy = 0;
7355 int scroll_max;
7356 int line_height, rc;
7357 int amount_to_scroll = 0;
7358 Lisp_Object aggressive;
7359 int height;
7360
7361#if GLYPH_DEBUG
7362 debug_method_add (w, "try_scrolling");
78614721 7363#endif
5f5c8ee5
GM
7364
7365 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7366
7367 /* Compute scroll margin height in pixels. We scroll when point is
7368 within this distance from the top or bottom of the window. */
7369 if (scroll_margin > 0)
90adcf20 7370 {
5f5c8ee5
GM
7371 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
7372 this_scroll_margin *= CANON_Y_UNIT (f);
7373 }
7374 else
7375 this_scroll_margin = 0;
7376
7377 /* Compute how much we should try to scroll maximally to bring point
7378 into view. */
7379 if (scroll_step)
7380 scroll_max = scroll_step;
7381 else if (scroll_conservatively)
7382 scroll_max = scroll_conservatively;
7383 else if (temp_scroll_step)
7384 scroll_max = temp_scroll_step;
7385 else if (NUMBERP (current_buffer->scroll_down_aggressively)
7386 || NUMBERP (current_buffer->scroll_up_aggressively))
7387 /* We're trying to scroll because of aggressive scrolling
7388 but no scroll_step is set. Choose an arbitrary one. Maybe
7389 there should be a variable for this. */
7390 scroll_max = 10;
7391 else
7392 scroll_max = 0;
7393 scroll_max *= CANON_Y_UNIT (f);
7394
7395 /* Decide whether we have to scroll down. Start at the window end
7396 and move this_scroll_margin up to find the position of the scroll
7397 margin. */
7398 window_end = Fwindow_end (window, Qt);
7399 CHARPOS (scroll_margin_pos) = XINT (window_end);
7400 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
7401 if (this_scroll_margin)
7402 {
7403 start_display (&it, w, scroll_margin_pos);
7404 move_it_vertically (&it, - this_scroll_margin);
7405 scroll_margin_pos = it.current.pos;
7406 }
7407
7408 if (PT >= CHARPOS (scroll_margin_pos))
7409 {
7410 int y0;
7411
7412 /* Point is in the scroll margin at the bottom of the window, or
7413 below. Compute a new window start that makes point visible. */
7414
7415 /* Compute the distance from the scroll margin to PT.
7416 Give up if the distance is greater than scroll_max. */
7417 start_display (&it, w, scroll_margin_pos);
7418 y0 = it.current_y;
7419 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7420 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7421 line_height = (it.max_ascent + it.max_descent
7422 ? it.max_ascent + it.max_descent
7423 : last_height);
7424 dy = it.current_y + line_height - y0;
7425 if (dy > scroll_max)
7426 return 0;
7427
7428 /* Move the window start down. If scrolling conservatively,
7429 move it just enough down to make point visible. If
7430 scroll_step is set, move it down by scroll_step. */
7431 start_display (&it, w, startp);
7432
7433 if (scroll_conservatively)
7434 amount_to_scroll = dy;
7435 else if (scroll_step || temp_scroll_step)
7436 amount_to_scroll = scroll_max;
7437 else
90adcf20 7438 {
5f5c8ee5
GM
7439 aggressive = current_buffer->scroll_down_aggressively;
7440 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7441 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7442 if (NUMBERP (aggressive))
7443 amount_to_scroll = XFLOATINT (aggressive) * height;
7444 }
a2725ab2 7445
5f5c8ee5
GM
7446 if (amount_to_scroll <= 0)
7447 return 0;
a2725ab2 7448
5f5c8ee5
GM
7449 move_it_vertically (&it, amount_to_scroll);
7450 startp = it.current.pos;
7451 }
7452 else
7453 {
7454 /* See if point is inside the scroll margin at the top of the
7455 window. */
7456 scroll_margin_pos = startp;
7457 if (this_scroll_margin)
7458 {
7459 start_display (&it, w, startp);
7460 move_it_vertically (&it, this_scroll_margin);
7461 scroll_margin_pos = it.current.pos;
7462 }
7463
7464 if (PT < CHARPOS (scroll_margin_pos))
7465 {
7466 /* Point is in the scroll margin at the top of the window or
7467 above what is displayed in the window. */
7468 int y0;
7469
7470 /* Compute the vertical distance from PT to the scroll
7471 margin position. Give up if distance is greater than
7472 scroll_max. */
7473 SET_TEXT_POS (pos, PT, PT_BYTE);
7474 start_display (&it, w, pos);
7475 y0 = it.current_y;
7476 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
7477 it.last_visible_y, -1,
7478 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7479 dy = it.current_y - y0;
7480 if (dy > scroll_max)
7481 return 0;
7482
7483 /* Compute new window start. */
7484 start_display (&it, w, startp);
7485
7486 if (scroll_conservatively)
7487 amount_to_scroll = dy;
7488 else if (scroll_step || temp_scroll_step)
7489 amount_to_scroll = scroll_max;
538f13d4 7490 else
5f5c8ee5
GM
7491 {
7492 aggressive = current_buffer->scroll_up_aggressively;
7493 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7494 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7495 if (NUMBERP (aggressive))
7496 amount_to_scroll = XFLOATINT (aggressive) * height;
7497 }
a2725ab2 7498
5f5c8ee5
GM
7499 if (amount_to_scroll <= 0)
7500 return 0;
7501
7502 move_it_vertically (&it, - amount_to_scroll);
7503 startp = it.current.pos;
90adcf20
RS
7504 }
7505 }
a2889657 7506
5f5c8ee5
GM
7507 /* Run window scroll functions. */
7508 startp = run_window_scroll_functions (window, startp);
90adcf20 7509
5f5c8ee5
GM
7510 /* Display the window. Give up if new fonts are loaded, or if point
7511 doesn't appear. */
7512 if (!try_window (window, startp))
7513 rc = -1;
7514 else if (w->cursor.vpos < 0)
7515 {
7516 clear_glyph_matrix (w->desired_matrix);
7517 rc = 0;
7518 }
7519 else
7520 {
7521 /* Maybe forget recorded base line for line number display. */
7522 if (!just_this_one_p
7523 || current_buffer->clip_changed
7524 || beg_unchanged < CHARPOS (startp))
7525 w->base_line_number = Qnil;
7526
7527 /* If cursor ends up on a partially visible line, shift display
7528 lines up or down. */
7529 make_cursor_line_fully_visible (w);
7530 rc = 1;
7531 }
7532
7533 return rc;
a2889657
JB
7534}
7535
5f5c8ee5
GM
7536
7537/* Compute a suitable window start for window W if display of W starts
7538 on a continuation line. Value is non-zero if a new window start
7539 was computed.
7540
7541 The new window start will be computed, based on W's width, starting
7542 from the start of the continued line. It is the start of the
7543 screen line with the minimum distance from the old start W->start. */
7544
7545static int
7546compute_window_start_on_continuation_line (w)
7547 struct window *w;
1f1ff51d 7548{
5f5c8ee5
GM
7549 struct text_pos pos, start_pos;
7550 int window_start_changed_p = 0;
1f1ff51d 7551
5f5c8ee5 7552 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
1f1ff51d 7553
5f5c8ee5
GM
7554 /* If window start is on a continuation line... Window start may be
7555 < BEGV in case there's invisible text at the start of the
7556 buffer (M-x rmail, for example). */
7557 if (CHARPOS (start_pos) > BEGV
7558 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
1f1ff51d 7559 {
5f5c8ee5
GM
7560 struct it it;
7561 struct glyph_row *row;
7562
7563 /* Find the start of the continued line. This should be fast
7564 because scan_buffer is fast (newline cache). */
7565 row = w->desired_matrix->rows + (WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0);
7566 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
7567 row, DEFAULT_FACE_ID);
7568 reseat_at_previous_visible_line_start (&it);
7569
7570 /* If the line start is "too far" away from the window start,
7571 say it takes too much time to compute a new window start. */
7572 if (CHARPOS (start_pos) - IT_CHARPOS (it)
7573 < XFASTINT (w->height) * XFASTINT (w->width))
7574 {
7575 int min_distance, distance;
7576
7577 /* Move forward by display lines to find the new window
7578 start. If window width was enlarged, the new start can
7579 be expected to be > the old start. If window width was
7580 decreased, the new window start will be < the old start.
7581 So, we're looking for the display line start with the
7582 minimum distance from the old window start. */
7583 pos = it.current.pos;
7584 min_distance = INFINITY;
7585 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
7586 distance < min_distance)
7587 {
7588 min_distance = distance;
7589 pos = it.current.pos;
7590 move_it_by_lines (&it, 1, 0);
7591 }
7592
7593 /* Set the window start there. */
7594 SET_MARKER_FROM_TEXT_POS (w->start, pos);
7595 window_start_changed_p = 1;
7596 }
1f1ff51d 7597 }
5f5c8ee5
GM
7598
7599 return window_start_changed_p;
1f1ff51d
KH
7600}
7601
5f5c8ee5
GM
7602
7603/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
7604 selected_window is redisplayed. */
90adcf20 7605
a2889657 7606static void
5f5c8ee5 7607redisplay_window (window, just_this_one_p)
a2889657 7608 Lisp_Object window;
5f5c8ee5 7609 int just_this_one_p;
a2889657 7610{
5f5c8ee5
GM
7611 struct window *w = XWINDOW (window);
7612 struct frame *f = XFRAME (w->frame);
7613 struct buffer *buffer = XBUFFER (w->buffer);
a2889657 7614 struct buffer *old = current_buffer;
5f5c8ee5 7615 struct text_pos lpoint, opoint, startp;
e481f960 7616 int update_mode_line;
5f5c8ee5
GM
7617 int tem;
7618 struct it it;
7619 /* Record it now because it's overwritten. */
7620 int current_matrix_up_to_date_p = 0;
5ba50c51 7621 int really_switched_buffer = 0;
5f5c8ee5 7622 int temp_scroll_step = 0;
2e54982e 7623 int count = specpdl_ptr - specpdl;
a2889657 7624
5f5c8ee5
GM
7625 SET_TEXT_POS (lpoint, PT, PT_BYTE);
7626 opoint = lpoint;
a2889657 7627
5f5c8ee5
GM
7628 /* W must be a leaf window here. */
7629 xassert (!NILP (w->buffer));
7630#if GLYPH_DEBUG
7631 *w->desired_matrix->method = 0;
7632#endif
2e54982e
RS
7633
7634 specbind (Qinhibit_point_motion_hooks, Qt);
5f5c8ee5
GM
7635
7636 /* Has the mode line to be updated? */
7637 update_mode_line = (!NILP (w->update_mode_line)
7638 || update_mode_lines
7639 || buffer->clip_changed);
8de2d90b
JB
7640
7641 if (MINI_WINDOW_P (w))
7642 {
5f5c8ee5
GM
7643 if (w == XWINDOW (echo_area_window)
7644 && (echo_area_glyphs
7645 || STRINGP (echo_area_message)))
7646 {
7647 if (update_mode_line)
7648 /* We may have to update a tty frame's menu bar or a
7649 toolbar. Example `M-x C-h C-h C-g'. */
7650 goto finish_menu_bars;
7651 else
7652 /* We've already displayed the echo area glyphs in this window. */
7653 goto finish_scroll_bars;
7654 }
73af359d 7655 else if (w != XWINDOW (minibuf_window))
8de2d90b 7656 {
5f5c8ee5
GM
7657 /* W is a mini-buffer window, but it's not the currently
7658 active one, so clear it. */
7659 int yb = window_text_bottom_y (w);
7660 struct glyph_row *row;
7661 int y;
7662
7663 for (y = 0, row = w->desired_matrix->rows;
7664 y < yb;
7665 y += row->height, ++row)
7666 blank_row (w, row, y);
88f22aff 7667 goto finish_scroll_bars;
8de2d90b
JB
7668 }
7669 }
a2889657 7670
5f5c8ee5
GM
7671 /* Otherwise set up data on this window; select its buffer and point
7672 value. */
e481f960 7673 if (update_mode_line)
5ba50c51 7674 {
5f5c8ee5
GM
7675 /* Really select the buffer, for the sake of buffer-local
7676 variables. */
5ba50c51
RS
7677 set_buffer_internal_1 (XBUFFER (w->buffer));
7678 really_switched_buffer = 1;
7679 }
e481f960
RS
7680 else
7681 set_buffer_temp (XBUFFER (w->buffer));
5f5c8ee5
GM
7682 SET_TEXT_POS (opoint, PT, PT_BYTE);
7683
7684 current_matrix_up_to_date_p
7685 = (!NILP (w->window_end_valid)
7686 && !current_buffer->clip_changed
7687 && XFASTINT (w->last_modified) >= MODIFF
7688 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
e481f960 7689
5f5c8ee5
GM
7690 /* When windows_or_buffers_changed is non-zero, we can't rely on
7691 the window end being valid, so set it to nil there. */
7692 if (windows_or_buffers_changed)
7693 {
7694 /* If window starts on a continuation line, maybe adjust the
7695 window start in case the window's width changed. */
7696 if (XMARKER (w->start)->buffer == current_buffer)
7697 compute_window_start_on_continuation_line (w);
7698
7699 w->window_end_valid = Qnil;
7700 }
12adba34 7701
5f5c8ee5
GM
7702 /* Some sanity checks. */
7703 CHECK_WINDOW_END (w);
7704 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12adba34 7705 abort ();
5f5c8ee5 7706 if (BYTEPOS (opoint) < CHARPOS (opoint))
12adba34 7707 abort ();
a2889657 7708
28995e67
RS
7709 /* If %c is in mode line, update it if needed. */
7710 if (!NILP (w->column_number_displayed)
7711 /* This alternative quickly identifies a common case
7712 where no change is needed. */
7713 && !(PT == XFASTINT (w->last_point)
8850a573
RS
7714 && XFASTINT (w->last_modified) >= MODIFF
7715 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
7716 && XFASTINT (w->column_number_displayed) != current_column ())
7717 update_mode_line = 1;
7718
5f5c8ee5
GM
7719 /* Count number of windows showing the selected buffer. An indirect
7720 buffer counts as its base buffer. */
7721 if (!just_this_one_p)
42640f83
RS
7722 {
7723 struct buffer *current_base, *window_base;
7724 current_base = current_buffer;
7725 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
7726 if (current_base->base_buffer)
7727 current_base = current_base->base_buffer;
7728 if (window_base->base_buffer)
7729 window_base = window_base->base_buffer;
7730 if (current_base == window_base)
7731 buffer_shared++;
7732 }
a2889657 7733
5f5c8ee5
GM
7734 /* Point refers normally to the selected window. For any other
7735 window, set up appropriate value. */
a2889657
JB
7736 if (!EQ (window, selected_window))
7737 {
12adba34
RS
7738 int new_pt = XMARKER (w->pointm)->charpos;
7739 int new_pt_byte = marker_byte_position (w->pointm);
f67a0f51 7740 if (new_pt < BEGV)
a2889657 7741 {
f67a0f51 7742 new_pt = BEGV;
12adba34
RS
7743 new_pt_byte = BEGV_BYTE;
7744 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
a2889657 7745 }
f67a0f51 7746 else if (new_pt > (ZV - 1))
a2889657 7747 {
f67a0f51 7748 new_pt = ZV;
12adba34
RS
7749 new_pt_byte = ZV_BYTE;
7750 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
a2889657 7751 }
5f5c8ee5 7752
f67a0f51 7753 /* We don't use SET_PT so that the point-motion hooks don't run. */
12adba34 7754 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
a2889657
JB
7755 }
7756
f4faa47c 7757 /* If any of the character widths specified in the display table
5f5c8ee5
GM
7758 have changed, invalidate the width run cache. It's true that
7759 this may be a bit late to catch such changes, but the rest of
f4faa47c
JB
7760 redisplay goes (non-fatally) haywire when the display table is
7761 changed, so why should we worry about doing any better? */
7762 if (current_buffer->width_run_cache)
7763 {
f908610f 7764 struct Lisp_Char_Table *disptab = buffer_display_table ();
f4faa47c
JB
7765
7766 if (! disptab_matches_widthtab (disptab,
7767 XVECTOR (current_buffer->width_table)))
7768 {
7769 invalidate_region_cache (current_buffer,
7770 current_buffer->width_run_cache,
7771 BEG, Z);
7772 recompute_width_table (current_buffer, disptab);
7773 }
7774 }
7775
a2889657 7776 /* If window-start is screwed up, choose a new one. */
a2889657
JB
7777 if (XMARKER (w->start)->buffer != current_buffer)
7778 goto recenter;
7779
5f5c8ee5 7780 SET_TEXT_POS_FROM_MARKER (startp, w->start);
a2889657 7781
cf0df6ab
RS
7782 /* If someone specified a new starting point but did not insist,
7783 check whether it can be used. */
5f5c8ee5 7784 if (!NILP (w->optional_new_start))
cf0df6ab
RS
7785 {
7786 w->optional_new_start = Qnil;
5f5c8ee5
GM
7787 /* This takes a mini-buffer prompt into account. */
7788 start_display (&it, w, startp);
7789 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7790 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7791 if (IT_CHARPOS (it) == PT)
cf0df6ab
RS
7792 w->force_start = Qt;
7793 }
7794
8de2d90b 7795 /* Handle case where place to start displaying has been specified,
aa6d10fa 7796 unless the specified location is outside the accessible range. */
265a9e55 7797 if (!NILP (w->force_start))
a2889657 7798 {
e63574d7 7799 w->force_start = Qnil;
5f5c8ee5 7800 w->vscroll = 0;
b5174a51 7801 w->window_end_valid = Qnil;
5f5c8ee5
GM
7802
7803 /* Forget any recorded base line for line number display. */
7804 if (!current_matrix_up_to_date_p
7805 || current_buffer->clip_changed)
7806 w->base_line_number = Qnil;
7807
75c43375
RS
7808 /* Redisplay the mode line. Select the buffer properly for that.
7809 Also, run the hook window-scroll-functions
7810 because we have scrolled. */
e63574d7
RS
7811 /* Note, we do this after clearing force_start because
7812 if there's an error, it is better to forget about force_start
7813 than to get into an infinite loop calling the hook functions
7814 and having them get more errors. */
75c43375
RS
7815 if (!update_mode_line
7816 || ! NILP (Vwindow_scroll_functions))
e481f960 7817 {
5ba50c51
RS
7818 if (!really_switched_buffer)
7819 {
7820 set_buffer_temp (old);
7821 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 7822 really_switched_buffer = 1;
5ba50c51 7823 }
5f5c8ee5 7824
e481f960
RS
7825 update_mode_line = 1;
7826 w->update_mode_line = Qt;
5f5c8ee5 7827 startp = run_window_scroll_functions (window, startp);
e481f960 7828 }
5f5c8ee5 7829
c2213350 7830 XSETFASTINT (w->last_modified, 0);
8850a573 7831 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5
GM
7832 if (CHARPOS (startp) < BEGV)
7833 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
7834 else if (CHARPOS (startp) > ZV)
7835 SET_TEXT_POS (startp, ZV, ZV_BYTE);
7836
7837 /* Redisplay, then check if cursor has been set during the
7838 redisplay. Give up if new fonts were loaded. */
7839 if (!try_window (window, startp))
7840 {
7841 w->force_start = Qt;
7842 clear_glyph_matrix (w->desired_matrix);
7843 goto restore_buffers;
7844 }
7845
7846 if (w->cursor.vpos < 0)
7847 {
7848 /* If point does not appear, or on a line that is not fully
7849 visible, move point so it does appear. The desired
7850 matrix has been built above, so we can use it. */
7851 int height = window_box_height (w) / 2;
7852 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
7853
7854 while (row->y < height)
7855 ++row;
7856
7857 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
7858 MATRIX_ROW_START_BYTEPOS (row));
7859
90adcf20 7860 if (w != XWINDOW (selected_window))
12adba34 7861 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5f5c8ee5
GM
7862 else if (current_buffer == old)
7863 SET_TEXT_POS (lpoint, PT, PT_BYTE);
7864
7865 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
7866
7867 /* If we are highlighting the region, then we just changed
7868 the region, so redisplay to show it. */
df0b5ea1
RS
7869 if (!NILP (Vtransient_mark_mode)
7870 && !NILP (current_buffer->mark_active))
6f27fa9b 7871 {
5f5c8ee5
GM
7872 clear_glyph_matrix (w->desired_matrix);
7873 if (!try_window (window, startp))
7874 goto restore_buffers;
6f27fa9b 7875 }
a2889657 7876 }
5f5c8ee5
GM
7877
7878 make_cursor_line_fully_visible (w);
7879#if GLYPH_DEBUG
7880 debug_method_add (w, "forced window start");
7881#endif
a2889657
JB
7882 goto done;
7883 }
7884
5f5c8ee5
GM
7885 /* Handle case where text has not changed, only point, and it has
7886 not moved off the frame. */
7887 if (current_matrix_up_to_date_p
7888 /* Point may be in this window. */
7889 && PT >= CHARPOS (startp)
7890 /* If we don't check this, we are called to move the cursor in a
7891 horizontally split window with a current matrix that doesn't
7892 fit the display. */
7893 && !windows_or_buffers_changed
7894 /* Selective display hasn't changed. */
7895 && !current_buffer->clip_changed
b1aa6cb3
RS
7896 /* If force-mode-line-update was called, really redisplay;
7897 that's how redisplay is forced after e.g. changing
7898 buffer-invisibility-spec. */
632ab665 7899 && NILP (w->update_mode_line)
5f5c8ee5
GM
7900 /* Can't use this case if highlighting a region. When a
7901 region exists, cursor movement has to do more than just
7902 set the cursor. */
7903 && !(!NILP (Vtransient_mark_mode)
7904 && !NILP (current_buffer->mark_active))
bd66d1ba 7905 && NILP (w->region_showing)
8f897821 7906 && NILP (Vshow_trailing_whitespace)
5f5c8ee5
GM
7907 /* Right after splitting windows, last_point may be nil. */
7908 && INTEGERP (w->last_point)
7909 /* This code is not used for mini-buffer for the sake of the case
7910 of redisplaying to replace an echo area message; since in
7911 that case the mini-buffer contents per se are usually
7912 unchanged. This code is of no real use in the mini-buffer
7913 since the handling of this_line_start_pos, etc., in redisplay
7914 handles the same cases. */
d45de95b 7915 && !EQ (window, minibuf_window)
5f5c8ee5
GM
7916 /* When splitting windows or for new windows, it happens that
7917 redisplay is called with a nil window_end_vpos or one being
7918 larger than the window. This should really be fixed in
7919 window.c. I don't have this on my list, now, so we do
7920 approximately the same as the old redisplay code. --gerd. */
7921 && INTEGERP (w->window_end_vpos)
7922 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
7923 && (FRAME_WINDOW_P (f)
7924 || !MARKERP (Voverlay_arrow_position)
377dbd97 7925 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
a2889657 7926 {
5f5c8ee5
GM
7927 int this_scroll_margin;
7928 struct glyph_row *row;
7929 int scroll_p;
a2889657 7930
5f5c8ee5
GM
7931#if GLYPH_DEBUG
7932 debug_method_add (w, "cursor movement");
7933#endif
9afd2168 7934
5f5c8ee5
GM
7935 /* Scroll if point within this distance from the top or bottom
7936 of the window. This is a pixel value. */
7937 this_scroll_margin = max (0, scroll_margin);
7938 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
7939 this_scroll_margin *= CANON_Y_UNIT (f);
7940
7941 /* Start with the row the cursor was displayed during the last
7942 not paused redisplay. Give up if that row is not valid. */
7943 if (w->last_cursor.vpos >= w->current_matrix->nrows)
7944 goto try_to_scroll;
7945 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
7946 if (row->mode_line_p)
7947 ++row;
7948 if (!row->enabled_p)
7949 goto try_to_scroll;
7950
7951 scroll_p = 0;
7952 if (PT > XFASTINT (w->last_point))
7953 {
7954 /* Point has moved forward. */
7955 int last_y = window_text_bottom_y (w) - this_scroll_margin;
7956
7957 while ((MATRIX_ROW_END_CHARPOS (row) < PT
7958 /* The end position of a row equals the start
7959 position of the next row. If PT is there, we
7960 would rather display it in the next line, except
7961 when this line ends in ZV. */
7962 || (MATRIX_ROW_END_CHARPOS (row) == PT
7963 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
7964 || !row->ends_at_zv_p)))
7965 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
7966 {
7967 xassert (row->enabled_p);
7968 ++row;
7969 }
9afd2168 7970
5f5c8ee5
GM
7971 /* If within the scroll margin, scroll. Note that
7972 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
7973 next line would be drawn, and that this_scroll_margin can
7974 be zero. */
7975 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
7976 || PT > MATRIX_ROW_END_CHARPOS (row)
7977 /* Line is completely visible last line in window and PT
7978 is to be set in the next line. */
7979 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
7980 && PT == MATRIX_ROW_END_CHARPOS (row)
7981 && !row->ends_at_zv_p
7982 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
7983 scroll_p = 1;
7984 }
7985 else if (PT < XFASTINT (w->last_point))
a2889657 7986 {
5f5c8ee5
GM
7987 /* Cursor has to be moved backward. Note that PT >=
7988 CHARPOS (startp) because of the outer if-statement. */
7989 while (!row->mode_line_p
7990 && (MATRIX_ROW_START_CHARPOS (row) > PT
7991 || (MATRIX_ROW_START_CHARPOS (row) == PT
7992 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
7993 && (row->y > this_scroll_margin
7994 || CHARPOS (startp) == BEGV))
a2889657 7995 {
5f5c8ee5
GM
7996 xassert (row->enabled_p);
7997 --row;
a2889657 7998 }
abb4c08f 7999
5f5c8ee5
GM
8000 /* Consider the following case: Window starts at BEGV, there
8001 is invisible, intangible text at BEGV, so that display
8002 starts at some point START > BEGV. It can happen that
8003 we are called with PT somewhere between BEGV and START.
8004 Try to handle that case. */
8005 if (row < w->current_matrix->rows
8006 || row->mode_line_p)
8007 {
8008 row = w->current_matrix->rows;
8009 if (row->mode_line_p)
8010 ++row;
8011 }
8012
8013 /* Due to newlines in overlay strings, we may have to skip
8014 forward over overlay strings. */
8015 while (MATRIX_ROW_END_CHARPOS (row) == PT
8016 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8017 && !row->ends_at_zv_p)
8018 ++row;
8019
8020 /* If within the scroll margin, scroll. */
8021 if (row->y < this_scroll_margin
8022 && CHARPOS (startp) != BEGV)
8023 scroll_p = 1;
8024 }
8025
8026 /* if PT is not in the glyph row, give up. */
8027 if (PT < MATRIX_ROW_START_CHARPOS (row)
8028 || PT > MATRIX_ROW_END_CHARPOS (row))
8029 goto try_to_scroll;
8030
8031 /* If we end up in a partially visible line, let's make it fully
8032 visible. This can be done most easily by using the existing
8033 scrolling code. */
8034 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8035 {
8036 temp_scroll_step = 1;
8037 goto try_to_scroll;
a2889657 8038 }
5f5c8ee5
GM
8039 else if (scroll_p)
8040 goto try_to_scroll;
8041
8042 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8043 goto done;
a2889657 8044 }
5f5c8ee5 8045
a2889657
JB
8046 /* If current starting point was originally the beginning of a line
8047 but no longer is, find a new starting point. */
265a9e55 8048 else if (!NILP (w->start_at_line_beg)
5f5c8ee5
GM
8049 && !(CHARPOS (startp) <= BEGV
8050 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
a2889657 8051 {
5f5c8ee5
GM
8052#if GLYPH_DEBUG
8053 debug_method_add (w, "recenter 1");
8054#endif
a2889657
JB
8055 goto recenter;
8056 }
5f5c8ee5
GM
8057
8058 /* Try scrolling with try_window_id. */
8059 else if (!windows_or_buffers_changed
8060 /* Window must be either use window-based redisplay or
8061 be full width. */
8062 && (FRAME_WINDOW_P (f)
8063 || ((line_ins_del_ok && WINDOW_FULL_WIDTH_P (w))
8064 && just_this_one_p))
8065 && !MINI_WINDOW_P (w)
8066 /* Point is not known NOT to appear in window. */
8067 && PT >= CHARPOS (startp)
a2889657 8068 && XFASTINT (w->last_modified)
5f5c8ee5
GM
8069 /* Window is not hscrolled. */
8070 && XFASTINT (w->hscroll) == 0
8071 /* Selective display has not changed. */
8072 && !current_buffer->clip_changed
8073 /* Current matrix is up to date. */
8074 && !NILP (w->window_end_valid)
8075 /* Can't use this case if highlighting a region because
8076 a cursor movement will do more than just set the cursor. */
bd66d1ba
RS
8077 && !(!NILP (Vtransient_mark_mode)
8078 && !NILP (current_buffer->mark_active))
8079 && NILP (w->region_showing)
8f897821 8080 && NILP (Vshow_trailing_whitespace)
5f5c8ee5 8081 /* Overlay arrow position and string not changed. */
d45de95b 8082 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
a2889657 8083 && EQ (last_arrow_string, Voverlay_arrow_string)
5f5c8ee5
GM
8084 /* Value is > 0 if update has been done, it is -1 if we
8085 know that the same window start will not work. It is 0
8086 if unsuccessful for some other reason. */
8087 && (tem = try_window_id (w)) != 0)
a2889657 8088 {
5f5c8ee5
GM
8089#if GLYPH_DEBUG
8090 debug_method_add (w, "try_window_id");
8091#endif
8092
8093 if (fonts_changed_p)
8094 goto restore_buffers;
a2889657
JB
8095 if (tem > 0)
8096 goto done;
5f5c8ee5
GM
8097 /* Otherwise try_window_id has returned -1 which means that we
8098 don't want the alternative below this comment to execute. */
a2889657 8099 }
5f5c8ee5
GM
8100 else if (CHARPOS (startp) >= BEGV
8101 && CHARPOS (startp) <= ZV
8102 && PT >= CHARPOS (startp)
8103 && (CHARPOS (startp) < ZV
e9874cee 8104 /* Avoid starting at end of buffer. */
5f5c8ee5 8105 || CHARPOS (startp) == BEGV
8850a573
RS
8106 || (XFASTINT (w->last_modified) >= MODIFF
8107 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
a2889657 8108 {
5f5c8ee5
GM
8109#if GLYPH_DEBUG
8110 debug_method_add (w, "same window start");
8111#endif
8112
8113 /* Try to redisplay starting at same place as before.
8114 If point has not moved off frame, accept the results. */
8115 if (!current_matrix_up_to_date_p
8116 /* Don't use try_window_reusing_current_matrix in this case
8117 because it can have changed the buffer. */
8118 || !NILP (Vwindow_scroll_functions)
8119 || MINI_WINDOW_P (w)
8120 || !try_window_reusing_current_matrix (w))
8121 {
8122 IF_DEBUG (debug_method_add (w, "1"));
8123 try_window (window, startp);
8124 }
8125
8126 if (fonts_changed_p)
8127 goto restore_buffers;
8128
8129 if (w->cursor.vpos >= 0)
aa6d10fa 8130 {
5f5c8ee5
GM
8131 if (!just_this_one_p
8132 || current_buffer->clip_changed
8133 || beg_unchanged < CHARPOS (startp))
aa6d10fa
RS
8134 /* Forget any recorded base line for line number display. */
8135 w->base_line_number = Qnil;
5f5c8ee5
GM
8136
8137 make_cursor_line_fully_visible (w);
aa6d10fa
RS
8138 goto done;
8139 }
a2889657 8140 else
5f5c8ee5 8141 clear_glyph_matrix (w->desired_matrix);
a2889657
JB
8142 }
8143
5f5c8ee5
GM
8144 try_to_scroll:
8145
c2213350 8146 XSETFASTINT (w->last_modified, 0);
8850a573 8147 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5 8148
e481f960
RS
8149 /* Redisplay the mode line. Select the buffer properly for that. */
8150 if (!update_mode_line)
8151 {
5ba50c51
RS
8152 if (!really_switched_buffer)
8153 {
8154 set_buffer_temp (old);
8155 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 8156 really_switched_buffer = 1;
5ba50c51 8157 }
e481f960
RS
8158 update_mode_line = 1;
8159 w->update_mode_line = Qt;
8160 }
a2889657 8161
5f5c8ee5
GM
8162 /* Try to scroll by specified few lines. */
8163 if ((scroll_conservatively
8164 || scroll_step
8165 || temp_scroll_step
8166 || NUMBERP (current_buffer->scroll_up_aggressively)
8167 || NUMBERP (current_buffer->scroll_down_aggressively))
09cacf9c 8168 && !current_buffer->clip_changed
5f5c8ee5
GM
8169 && CHARPOS (startp) >= BEGV
8170 && CHARPOS (startp) <= ZV)
0789adb2 8171 {
5f5c8ee5
GM
8172 /* The function returns -1 if new fonts were loaded, 1 if
8173 successful, 0 if not successful. */
8174 int rc = try_scrolling (window, just_this_one_p,
8175 scroll_conservatively,
8176 scroll_step,
8177 temp_scroll_step);
8178 if (rc > 0)
8179 goto done;
8180 else if (rc < 0)
8181 goto restore_buffers;
8182 }
f9c8af06 8183
5f5c8ee5 8184 /* Finally, just choose place to start which centers point */
5936754e 8185
5f5c8ee5 8186 recenter:
44173109 8187
5f5c8ee5
GM
8188#if GLYPH_DEBUG
8189 debug_method_add (w, "recenter");
8190#endif
0789adb2 8191
5f5c8ee5 8192 /* w->vscroll = 0; */
0789adb2 8193
5f5c8ee5
GM
8194 /* Forget any previously recorded base line for line number display. */
8195 if (!current_matrix_up_to_date_p
8196 || current_buffer->clip_changed)
8197 w->base_line_number = Qnil;
8198
8199 /* Move backward half the height of the window. */
8200 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8201 it.current_y = it.last_visible_y;
8202 move_it_vertically_backward (&it, it.last_visible_y / 2);
8203 xassert (IT_CHARPOS (it) >= BEGV);
8204
8205 /* The function move_it_vertically_backward may move over more
8206 than the specified y-distance. If it->w is small, e.g. a
8207 mini-buffer window, we may end up in front of the window's
8208 display area. Start displaying at the start of the line
8209 containing PT in this case. */
8210 if (it.current_y <= 0)
8211 {
8212 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8213 move_it_vertically (&it, 0);
8214 xassert (IT_CHARPOS (it) <= PT);
8215 it.current_y = 0;
0789adb2
RS
8216 }
8217
5f5c8ee5
GM
8218 it.current_x = it.hpos = 0;
8219
8220 /* Set startp here explicitly in case that helps avoid an infinite loop
8221 in case the window-scroll-functions functions get errors. */
8222 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
8223
8224 /* Run scroll hooks. */
8225 startp = run_window_scroll_functions (window, it.current.pos);
8226
8227 /* Redisplay the window. */
8228 if (!current_matrix_up_to_date_p
8229 || windows_or_buffers_changed
8230 /* Don't use try_window_reusing_current_matrix in this case
8231 because it can have changed the buffer. */
8232 || !NILP (Vwindow_scroll_functions)
8233 || !just_this_one_p
8234 || MINI_WINDOW_P (w)
8235 || !try_window_reusing_current_matrix (w))
8236 try_window (window, startp);
8237
8238 /* If new fonts have been loaded (due to fontsets), give up. We
8239 have to start a new redisplay since we need to re-adjust glyph
8240 matrices. */
8241 if (fonts_changed_p)
8242 goto restore_buffers;
8243
8244 /* If cursor did not appear assume that the middle of the window is
8245 in the first line of the window. Do it again with the next line.
8246 (Imagine a window of height 100, displaying two lines of height
8247 60. Moving back 50 from it->last_visible_y will end in the first
8248 line.) */
8249 if (w->cursor.vpos < 0)
a2889657 8250 {
5f5c8ee5
GM
8251 if (!NILP (w->window_end_valid)
8252 && PT >= Z - XFASTINT (w->window_end_pos))
a2889657 8253 {
5f5c8ee5
GM
8254 clear_glyph_matrix (w->desired_matrix);
8255 move_it_by_lines (&it, 1, 0);
8256 try_window (window, it.current.pos);
a2889657 8257 }
5f5c8ee5 8258 else if (PT < IT_CHARPOS (it))
a2889657 8259 {
5f5c8ee5
GM
8260 clear_glyph_matrix (w->desired_matrix);
8261 move_it_by_lines (&it, -1, 0);
8262 try_window (window, it.current.pos);
8263 }
8264 else
8265 {
8266 /* Not much we can do about it. */
a2889657 8267 }
a2889657 8268 }
010494d0 8269
5f5c8ee5
GM
8270 /* Consider the following case: Window starts at BEGV, there is
8271 invisible, intangible text at BEGV, so that display starts at
8272 some point START > BEGV. It can happen that we are called with
8273 PT somewhere between BEGV and START. Try to handle that case. */
8274 if (w->cursor.vpos < 0)
835766b6 8275 {
5f5c8ee5
GM
8276 struct glyph_row *row = w->current_matrix->rows;
8277 if (row->mode_line_p)
8278 ++row;
8279 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
835766b6 8280 }
5f5c8ee5
GM
8281
8282 make_cursor_line_fully_visible (w);
b5174a51 8283
5f5c8ee5
GM
8284 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8285 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
8286 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
8287 ? Qt : Qnil);
a2889657 8288
5f5c8ee5 8289 done:
a2889657 8290
5f5c8ee5 8291 /* Display the mode line, if we must. */
e481f960 8292 if ((update_mode_line
aa6d10fa 8293 /* If window not full width, must redo its mode line
5f5c8ee5
GM
8294 if (a) the window to its side is being redone and
8295 (b) we do a frame-based redisplay. This is a consequence
8296 of how inverted lines are drawn in frame-based redisplay. */
8297 || (!just_this_one_p
8298 && !FRAME_WINDOW_P (f)
8299 && !WINDOW_FULL_WIDTH_P (w))
8300 /* Line number to display. */
155ef550 8301 || INTEGERP (w->base_line_pos)
5f5c8ee5 8302 /* Column number is displayed and different from the one displayed. */
155ef550
KH
8303 || (!NILP (w->column_number_displayed)
8304 && XFASTINT (w->column_number_displayed) != current_column ()))
5f5c8ee5
GM
8305 /* This means that the window has a mode line. */
8306 && (WINDOW_WANTS_MODELINE_P (w)
8307 || WINDOW_WANTS_TOP_LINE_P (w)))
5ba50c51 8308 {
5f5c8ee5
GM
8309 display_mode_lines (w);
8310
8311 /* If mode line height has changed, arrange for a thorough
8312 immediate redisplay using the correct mode line height. */
8313 if (WINDOW_WANTS_MODELINE_P (w)
8314 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
5ba50c51 8315 {
5f5c8ee5
GM
8316 fonts_changed_p = 1;
8317 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
8318 = DESIRED_MODE_LINE_HEIGHT (w);
5ba50c51 8319 }
5f5c8ee5
GM
8320
8321 /* If top line height has changed, arrange for a thorough
8322 immediate redisplay using the correct mode line height. */
8323 if (WINDOW_WANTS_TOP_LINE_P (w)
8324 && CURRENT_TOP_LINE_HEIGHT (w) != DESIRED_TOP_LINE_HEIGHT (w))
8325 {
8326 fonts_changed_p = 1;
8327 MATRIX_TOP_LINE_ROW (w->current_matrix)->height
8328 = DESIRED_TOP_LINE_HEIGHT (w);
8329 }
8330
8331 if (fonts_changed_p)
8332 goto restore_buffers;
5ba50c51 8333 }
5f5c8ee5
GM
8334
8335 if (!line_number_displayed
8336 && !BUFFERP (w->base_line_pos))
aa6d10fa
RS
8337 {
8338 w->base_line_pos = Qnil;
8339 w->base_line_number = Qnil;
8340 }
a2889657 8341
5f5c8ee5
GM
8342 finish_menu_bars:
8343
7ce2c095 8344 /* When we reach a frame's selected window, redo the frame's menu bar. */
e481f960 8345 if (update_mode_line
5f5c8ee5
GM
8346 && EQ (FRAME_SELECTED_WINDOW (f), window))
8347 {
8348 int redisplay_menu_p = 0;
8349
8350 if (FRAME_WINDOW_P (f))
8351 {
dc937613 8352#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5f5c8ee5 8353 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
76412d64 8354#else
5f5c8ee5 8355 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
76412d64 8356#endif
5f5c8ee5
GM
8357 }
8358 else
8359 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
8360
8361 if (redisplay_menu_p)
8362 display_menu_bar (w);
8363
8364#ifdef HAVE_WINDOW_SYSTEM
8365 if (WINDOWP (f->toolbar_window)
8366 && (FRAME_TOOLBAR_LINES (f) > 0
8367 || auto_resize_toolbars_p))
8368 redisplay_toolbar (f);
8369#endif
8370 }
7ce2c095 8371
88f22aff 8372 finish_scroll_bars:
5f5c8ee5 8373
88f22aff 8374 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
30c566e4 8375 {
b1d1124b 8376 int start, end, whole;
30c566e4 8377
b1d1124b 8378 /* Calculate the start and end positions for the current window.
3505ea70
JB
8379 At some point, it would be nice to choose between scrollbars
8380 which reflect the whole buffer size, with special markers
8381 indicating narrowing, and scrollbars which reflect only the
8382 visible region.
8383
5f5c8ee5 8384 Note that mini-buffers sometimes aren't displaying any text. */
b1d1124b 8385 if (! MINI_WINDOW_P (w)
5f5c8ee5
GM
8386 || (w == XWINDOW (minibuf_window)
8387 && !echo_area_glyphs
8388 && !STRINGP (echo_area_message)))
b1d1124b 8389 {
8a9311d7 8390 whole = ZV - BEGV;
4d641a15 8391 start = marker_position (w->start) - BEGV;
b1d1124b
JB
8392 /* I don't think this is guaranteed to be right. For the
8393 moment, we'll pretend it is. */
5f5c8ee5 8394 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
3505ea70 8395
5f5c8ee5
GM
8396 if (end < start)
8397 end = start;
8398 if (whole < (end - start))
8399 whole = end - start;
b1d1124b
JB
8400 }
8401 else
8402 start = end = whole = 0;
30c566e4 8403
88f22aff 8404 /* Indicate what this scroll bar ought to be displaying now. */
7eb9ba41 8405 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
30c566e4 8406
5f5c8ee5
GM
8407 /* Note that we actually used the scroll bar attached to this
8408 window, so it shouldn't be deleted at the end of redisplay. */
88f22aff 8409 (*redeem_scroll_bar_hook) (w);
30c566e4 8410 }
b1d1124b 8411
5f5c8ee5
GM
8412 restore_buffers:
8413
8414 /* Restore current_buffer and value of point in it. */
8415 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
5ba50c51 8416 if (really_switched_buffer)
f72df6ac 8417 set_buffer_internal_1 (old);
e481f960
RS
8418 else
8419 set_buffer_temp (old);
5f5c8ee5 8420 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
2e54982e
RS
8421
8422 unbind_to (count, Qnil);
a2889657 8423}
a2889657 8424
5f5c8ee5
GM
8425
8426/* Build the complete desired matrix of WINDOW with a window start
8427 buffer position POS. Value is non-zero if successful. It is zero
8428 if fonts were loaded during redisplay which makes re-adjusting
8429 glyph matrices necessary. */
8430
8431int
a2889657
JB
8432try_window (window, pos)
8433 Lisp_Object window;
5f5c8ee5
GM
8434 struct text_pos pos;
8435{
8436 struct window *w = XWINDOW (window);
8437 struct it it;
8438 struct glyph_row *last_text_row = NULL;
9cbab4ff 8439
5f5c8ee5
GM
8440 /* Make POS the new window start. */
8441 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12adba34 8442
5f5c8ee5
GM
8443 /* Mark cursor position as unknown. No overlay arrow seen. */
8444 w->cursor.vpos = -1;
a2889657 8445 overlay_arrow_seen = 0;
642eefc6 8446
5f5c8ee5
GM
8447 /* Initialize iterator and info to start at POS. */
8448 start_display (&it, w, pos);
a2889657 8449
5f5c8ee5
GM
8450 /* Display all lines of W. */
8451 while (it.current_y < it.last_visible_y)
8452 {
8453 if (display_line (&it))
8454 last_text_row = it.glyph_row - 1;
8455 if (fonts_changed_p)
8456 return 0;
8457 }
a2889657 8458
5f5c8ee5
GM
8459 /* If bottom moved off end of frame, change mode line percentage. */
8460 if (XFASTINT (w->window_end_pos) <= 0
8461 && Z != IT_CHARPOS (it))
a2889657
JB
8462 w->update_mode_line = Qt;
8463
5f5c8ee5
GM
8464 /* Set window_end_pos to the offset of the last character displayed
8465 on the window from the end of current_buffer. Set
8466 window_end_vpos to its row number. */
8467 if (last_text_row)
8468 {
8469 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
8470 w->window_end_bytepos
8471 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8472 XSETFASTINT (w->window_end_pos,
8473 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8474 XSETFASTINT (w->window_end_vpos,
8475 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8476 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
8477 ->displays_text_p);
8478 }
8479 else
8480 {
8481 w->window_end_bytepos = 0;
8482 XSETFASTINT (w->window_end_pos, 0);
8483 XSETFASTINT (w->window_end_vpos, 0);
8484 }
8485
a2889657
JB
8486 /* But that is not valid info until redisplay finishes. */
8487 w->window_end_valid = Qnil;
5f5c8ee5 8488 return 1;
a2889657 8489}
5f5c8ee5
GM
8490
8491
a2889657 8492\f
5f5c8ee5
GM
8493/************************************************************************
8494 Window redisplay reusing current matrix when buffer has not changed
8495 ************************************************************************/
8496
8497/* Try redisplay of window W showing an unchanged buffer with a
8498 different window start than the last time it was displayed by
8499 reusing its current matrix. Value is non-zero if successful.
8500 W->start is the new window start. */
a2889657
JB
8501
8502static int
5f5c8ee5
GM
8503try_window_reusing_current_matrix (w)
8504 struct window *w;
a2889657 8505{
5f5c8ee5
GM
8506 struct frame *f = XFRAME (w->frame);
8507 struct glyph_row *row, *bottom_row;
8508 struct it it;
8509 struct run run;
8510 struct text_pos start, new_start;
8511 int nrows_scrolled, i;
8512 struct glyph_row *last_text_row;
8513 struct glyph_row *last_reused_text_row;
8514 struct glyph_row *start_row;
8515 int start_vpos, min_y, max_y;
8516
8517 /* Right now this function doesn't handle terminal frames. */
8518 if (!FRAME_WINDOW_P (f))
8519 return 0;
a2889657 8520
5f5c8ee5
GM
8521 /* Can't do this if region may have changed. */
8522 if ((!NILP (Vtransient_mark_mode)
8523 && !NILP (current_buffer->mark_active))
8f897821
GM
8524 || !NILP (w->region_showing)
8525 || !NILP (Vshow_trailing_whitespace))
5f5c8ee5 8526 return 0;
a2889657 8527
5f5c8ee5
GM
8528 /* If top-line visibility has changed, give up. */
8529 if (WINDOW_WANTS_TOP_LINE_P (w)
8530 != MATRIX_TOP_LINE_ROW (w->current_matrix)->mode_line_p)
8531 return 0;
8532
8533 /* Give up if old or new display is scrolled vertically. We could
8534 make this function handle this, but right now it doesn't. */
8535 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8536 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
8537 return 0;
8538
8539 /* The variable new_start now holds the new window start. The old
8540 start `start' can be determined from the current matrix. */
8541 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
8542 start = start_row->start.pos;
8543 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
a2889657 8544
5f5c8ee5
GM
8545 /* Clear the desired matrix for the display below. */
8546 clear_glyph_matrix (w->desired_matrix);
8547
8548 if (CHARPOS (new_start) <= CHARPOS (start))
8549 {
8550 int first_row_y;
8551
8552 IF_DEBUG (debug_method_add (w, "twu1"));
8553
8554 /* Display up to a row that can be reused. The variable
8555 last_text_row is set to the last row displayed that displays
8556 text. */
8557 start_display (&it, w, new_start);
8558 first_row_y = it.current_y;
8559 w->cursor.vpos = -1;
8560 last_text_row = last_reused_text_row = NULL;
8561 while (it.current_y < it.last_visible_y
8562 && IT_CHARPOS (it) < CHARPOS (start)
8563 && !fonts_changed_p)
8564 if (display_line (&it))
8565 last_text_row = it.glyph_row - 1;
8566
8567 /* A value of current_y < last_visible_y means that we stopped
8568 at the previous window start, which in turn means that we
8569 have at least one reusable row. */
8570 if (it.current_y < it.last_visible_y)
a2889657 8571 {
5f5c8ee5
GM
8572 nrows_scrolled = it.vpos;
8573
8574 /* Find PT if not already found in the lines displayed. */
8575 if (w->cursor.vpos < 0)
a2889657 8576 {
5f5c8ee5
GM
8577 int dy = it.current_y - first_row_y;
8578
8579 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8580 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8581 {
8582 if (PT >= MATRIX_ROW_START_CHARPOS (row)
8583 && PT < MATRIX_ROW_END_CHARPOS (row))
8584 {
8585 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
8586 dy, nrows_scrolled);
8587 break;
8588 }
8589
8590 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
8591 break;
8592
8593 ++row;
8594 }
8595
8596 /* Give up if point was not found. This shouldn't
8597 happen often; not more often than with try_window
8598 itself. */
8599 if (w->cursor.vpos < 0)
8600 {
8601 clear_glyph_matrix (w->desired_matrix);
8602 return 0;
8603 }
a2889657 8604 }
5f5c8ee5
GM
8605
8606 /* Scroll the display. Do it before the current matrix is
8607 changed. The problem here is that update has not yet
8608 run, i.e. part of the current matrix is not up to date.
8609 scroll_run_hook will clear the cursor, and use the
8610 current matrix to get the height of the row the cursor is
8611 in. */
8612 run.current_y = first_row_y;
8613 run.desired_y = it.current_y;
8614 run.height = it.last_visible_y - it.current_y;
8615 if (run.height > 0)
a2889657 8616 {
5f5c8ee5
GM
8617 update_begin (f);
8618 rif->update_window_begin_hook (w);
8619 rif->scroll_run_hook (w, &run);
8620 rif->update_window_end_hook (w, 0);
8621 update_end (f);
a2889657 8622 }
5f5c8ee5
GM
8623
8624 /* Shift current matrix down by nrows_scrolled lines. */
8625 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
8626 rotate_matrix (w->current_matrix,
8627 start_vpos,
8628 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
8629 nrows_scrolled);
8630
8631 /* Disable lines not reused. */
8632 for (i = 0; i < it.vpos; ++i)
8633 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
8634
8635 /* Re-compute Y positions. */
8636 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
8637 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8638 max_y = it.last_visible_y;
8639 while (row < bottom_row)
d2f84654 8640 {
5f5c8ee5
GM
8641 row->y = it.current_y;
8642
8643 if (row->y < min_y)
8644 row->visible_height = row->height - (min_y - row->y);
8645 else if (row->y + row->height > max_y)
8646 row->visible_height
8647 = row->height - (row->y + row->height - max_y);
8648 else
8649 row->visible_height = row->height;
8650
8651 it.current_y += row->height;
8652 ++it.vpos;
8653
8654 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8655 last_reused_text_row = row;
8656 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
8657 break;
8658 ++row;
d2f84654 8659 }
a2889657 8660 }
5f5c8ee5
GM
8661
8662 /* Update window_end_pos etc.; last_reused_text_row is the last
8663 reused row from the current matrix containing text, if any.
8664 The value of last_text_row is the last displayed line
8665 containing text. */
8666 if (last_reused_text_row)
a2889657 8667 {
5f5c8ee5
GM
8668 w->window_end_bytepos
8669 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
8670 XSETFASTINT (w->window_end_pos,
8671 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
8672 XSETFASTINT (w->window_end_vpos,
8673 MATRIX_ROW_VPOS (last_reused_text_row,
8674 w->current_matrix));
a2889657 8675 }
5f5c8ee5
GM
8676 else if (last_text_row)
8677 {
8678 w->window_end_bytepos
8679 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8680 XSETFASTINT (w->window_end_pos,
8681 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8682 XSETFASTINT (w->window_end_vpos,
8683 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8684 }
8685 else
8686 {
8687 /* This window must be completely empty. */
8688 w->window_end_bytepos = 0;
8689 XSETFASTINT (w->window_end_pos, 0);
8690 XSETFASTINT (w->window_end_vpos, 0);
8691 }
8692 w->window_end_valid = Qnil;
a2889657 8693
5f5c8ee5
GM
8694 /* Update hint: don't try scrolling again in update_window. */
8695 w->desired_matrix->no_scrolling_p = 1;
8696
8697#if GLYPH_DEBUG
8698 debug_method_add (w, "try_window_reusing_current_matrix 1");
8699#endif
8700 return 1;
a2889657 8701 }
5f5c8ee5
GM
8702 else if (CHARPOS (new_start) > CHARPOS (start))
8703 {
8704 struct glyph_row *pt_row, *row;
8705 struct glyph_row *first_reusable_row;
8706 struct glyph_row *first_row_to_display;
8707 int dy;
8708 int yb = window_text_bottom_y (w);
8709
8710 IF_DEBUG (debug_method_add (w, "twu2"));
8711
8712 /* Find the row starting at new_start, if there is one. Don't
8713 reuse a partially visible line at the end. */
8714 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8715 while (first_reusable_row->enabled_p
8716 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
8717 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
8718 < CHARPOS (new_start)))
8719 ++first_reusable_row;
8720
8721 /* Give up if there is no row to reuse. */
8722 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
28514cd9
GM
8723 || !first_reusable_row->enabled_p
8724 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
8725 != CHARPOS (new_start)))
5f5c8ee5
GM
8726 return 0;
8727
5f5c8ee5
GM
8728 /* We can reuse fully visible rows beginning with
8729 first_reusable_row to the end of the window. Set
8730 first_row_to_display to the first row that cannot be reused.
8731 Set pt_row to the row containing point, if there is any. */
8732 first_row_to_display = first_reusable_row;
8733 pt_row = NULL;
8734 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
8735 {
8736 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
8737 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
8738 pt_row = first_row_to_display;
a2889657 8739
5f5c8ee5
GM
8740 ++first_row_to_display;
8741 }
a2889657 8742
5f5c8ee5
GM
8743 /* Start displaying at the start of first_row_to_display. */
8744 xassert (first_row_to_display->y < yb);
8745 init_to_row_start (&it, w, first_row_to_display);
8746 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
8747 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
8748 - nrows_scrolled);
8749 it.current_y = first_row_to_display->y - first_reusable_row->y;
8750
8751 /* Display lines beginning with first_row_to_display in the
8752 desired matrix. Set last_text_row to the last row displayed
8753 that displays text. */
8754 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
8755 if (pt_row == NULL)
8756 w->cursor.vpos = -1;
8757 last_text_row = NULL;
8758 while (it.current_y < it.last_visible_y && !fonts_changed_p)
8759 if (display_line (&it))
8760 last_text_row = it.glyph_row - 1;
8761
8762 /* Give up If point isn't in a row displayed or reused. */
8763 if (w->cursor.vpos < 0)
8764 {
8765 clear_glyph_matrix (w->desired_matrix);
8766 return 0;
8767 }
12adba34 8768
5f5c8ee5
GM
8769 /* If point is in a reused row, adjust y and vpos of the cursor
8770 position. */
8771 if (pt_row)
8772 {
8773 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
8774 w->current_matrix);
8775 w->cursor.y -= first_reusable_row->y;
a2889657
JB
8776 }
8777
5f5c8ee5
GM
8778 /* Scroll the display. */
8779 run.current_y = first_reusable_row->y;
8780 run.desired_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8781 run.height = it.last_visible_y - run.current_y;
8782 if (run.height)
8783 {
8784 struct frame *f = XFRAME (WINDOW_FRAME (w));
8785 update_begin (f);
8786 rif->update_window_begin_hook (w);
8787 rif->scroll_run_hook (w, &run);
8788 rif->update_window_end_hook (w, 0);
8789 update_end (f);
8790 }
a2889657 8791
5f5c8ee5
GM
8792 /* Adjust Y positions of reused rows. */
8793 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
8794 row = first_reusable_row;
8795 dy = first_reusable_row->y;
8796 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8797 max_y = it.last_visible_y;
8798 while (row < first_row_to_display)
8799 {
8800 row->y -= dy;
8801 if (row->y < min_y)
8802 row->visible_height = row->height - (min_y - row->y);
8803 else if (row->y + row->height > max_y)
8804 row->visible_height
8805 = row->height - (row->y + row->height - max_y);
8806 else
8807 row->visible_height = row->height;
8808 ++row;
8809 }
a2889657 8810
5f5c8ee5
GM
8811 /* Disable rows not reused. */
8812 while (row < bottom_row)
8813 {
8814 row->enabled_p = 0;
8815 ++row;
8816 }
8817
8818 /* Scroll the current matrix. */
8819 xassert (nrows_scrolled > 0);
8820 rotate_matrix (w->current_matrix,
8821 start_vpos,
8822 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
8823 -nrows_scrolled);
8824
8825 /* Adjust window end. A null value of last_text_row means that
8826 the window end is in reused rows which in turn means that
8827 only its vpos can have changed. */
8828 if (last_text_row)
8829 {
8830 w->window_end_bytepos
8831 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8832 XSETFASTINT (w->window_end_pos,
8833 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8834 XSETFASTINT (w->window_end_vpos,
8835 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8836 }
8837 else
a2889657 8838 {
e8e536a9 8839 XSETFASTINT (w->window_end_vpos,
5f5c8ee5 8840 XFASTINT (w->window_end_vpos) - nrows_scrolled);
a2889657 8841 }
5f5c8ee5
GM
8842
8843 w->window_end_valid = Qnil;
8844 w->desired_matrix->no_scrolling_p = 1;
8845
8846#if GLYPH_DEBUG
8847 debug_method_add (w, "try_window_reusing_current_matrix 2");
8848#endif
8849 return 1;
a2889657 8850 }
5f5c8ee5
GM
8851
8852 return 0;
8853}
a2889657 8854
a2889657 8855
5f5c8ee5
GM
8856\f
8857/************************************************************************
8858 Window redisplay reusing current matrix when buffer has changed
8859 ************************************************************************/
8860
8861static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
8862static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
8863 int *, int *));
8864static struct glyph_row *
8865find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
8866 struct glyph_row *));
8867
8868
8869/* Return the last row in MATRIX displaying text. If row START is
8870 non-null, start searching with that row. IT gives the dimensions
8871 of the display. Value is null if matrix is empty; otherwise it is
8872 a pointer to the row found. */
8873
8874static struct glyph_row *
8875find_last_row_displaying_text (matrix, it, start)
8876 struct glyph_matrix *matrix;
8877 struct it *it;
8878 struct glyph_row *start;
8879{
8880 struct glyph_row *row, *row_found;
8881
8882 /* Set row_found to the last row in IT->w's current matrix
8883 displaying text. The loop looks funny but think of partially
8884 visible lines. */
8885 row_found = NULL;
8886 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
8887 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8888 {
8889 xassert (row->enabled_p);
8890 row_found = row;
8891 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
8892 break;
8893 ++row;
a2889657 8894 }
5f5c8ee5
GM
8895
8896 return row_found;
8897}
8898
a2889657 8899
5f5c8ee5
GM
8900/* Return the last row in the current matrix of W that is not affected
8901 by changes at the start of current_buffer that occurred since the
8902 last time W was redisplayed. Value is null if no such row exists.
a2889657 8903
5f5c8ee5
GM
8904 The global variable beg_unchanged has to contain the number of
8905 bytes unchanged at the start of current_buffer. BEG +
8906 beg_unchanged is the buffer position of the first changed byte in
8907 current_buffer. Characters at positions < BEG + beg_unchanged are
8908 at the same buffer positions as they were when the current matrix
8909 was built. */
8910
8911static struct glyph_row *
8912get_last_unchanged_at_beg_row (w)
8913 struct window *w;
8914{
8915 int first_changed_pos = BEG + beg_unchanged;
8916 struct glyph_row *row;
8917 struct glyph_row *row_found = NULL;
8918 int yb = window_text_bottom_y (w);
8919
8920 /* Find the last row displaying unchanged text. */
8921 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8922 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
8923 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
a2889657 8924 {
5f5c8ee5
GM
8925 if (/* If row ends before first_changed_pos, it is unchanged,
8926 except in some case. */
8927 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
8928 /* When row ends in ZV and we write at ZV it is not
8929 unchanged. */
8930 && !row->ends_at_zv_p
8931 /* When first_changed_pos is the end of a continued line,
8932 row is not unchanged because it may be no longer
8933 continued. */
8934 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
8935 && row->continued_p))
8936 row_found = row;
8937
8938 /* Stop if last visible row. */
8939 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
8940 break;
8941
8942 ++row;
a2889657
JB
8943 }
8944
5f5c8ee5 8945 return row_found;
a2889657 8946}
5f5c8ee5
GM
8947
8948
8949/* Find the first glyph row in the current matrix of W that is not
8950 affected by changes at the end of current_buffer since the last
8951 time the window was redisplayed. Return in *DELTA the number of
8952 bytes by which buffer positions in unchanged text at the end of
8953 current_buffer must be adjusted. Value is null if no such row
8954 exists, i.e. all rows are affected by changes.
8955
8956 The global variable end_unchanged is assumed to contain the number
8957 of unchanged bytes at the end of current_buffer. The buffer
8958 position of the last changed byte in current_buffer is then Z -
8959 end_unchanged. */
8960
8961static struct glyph_row *
8962get_first_unchanged_at_end_row (w, delta, delta_bytes)
8963 struct window *w;
8964 int *delta, *delta_bytes;
a2889657 8965{
5f5c8ee5
GM
8966 struct glyph_row *row;
8967 struct glyph_row *row_found = NULL;
c581d710 8968
5f5c8ee5 8969 *delta = *delta_bytes = 0;
b2a76982 8970
5f5c8ee5
GM
8971 /* A value of window_end_pos >= end_unchanged means that the window
8972 end is in the range of changed text. If so, there is no
8973 unchanged row at the end of W's current matrix. */
8974 xassert (!NILP (w->window_end_valid));
8975 if (XFASTINT (w->window_end_pos) >= end_unchanged)
8976 return NULL;
8977
8978 /* Set row to the last row in W's current matrix displaying text. */
8979 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
8980
8981 /* End vpos should always be on text, except in an entirely empty
8982 matrix. */
8983 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row)
8984 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0);
8985
8986 /* If matrix is entirely empty, no unchanged row exists. */
8987 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8988 {
8989 /* The value of row is the last glyph row in the matrix having a
8990 meaningful buffer position in it. The end position of row
8991 corresponds to window_end_pos. This allows us to translate
8992 buffer positions in the current matrix to current buffer
8993 positions for characters not in changed text. */
8994 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
8995 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
8996 int last_unchanged_pos, last_unchanged_pos_old;
8997 struct glyph_row *first_text_row
8998 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8999
9000 *delta = Z - Z_old;
9001 *delta_bytes = Z_BYTE - Z_BYTE_old;
9002
9003 /* Set last_unchanged_pos to the buffer position of the last
9004 character in the buffer that has not been changed. Z is the
9005 index + 1 of the last byte in current_buffer, i.e. by
9006 subtracting end_unchanged we get the index of the last
9007 unchanged character, and we have to add BEG to get its buffer
9008 position. */
9009 last_unchanged_pos = Z - end_unchanged + BEG;
9010 last_unchanged_pos_old = last_unchanged_pos - *delta;
9011
9012 /* Search backward from ROW for a row displaying a line that
9013 starts at a minimum position >= last_unchanged_pos_old. */
9014 while (row >= first_text_row)
9015 {
9016 xassert (row->enabled_p);
9017 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9018
9019 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9020 row_found = row;
9021 --row;
9022 }
9023 }
9024
9025 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9026 return row_found;
c581d710
RS
9027}
9028
c581d710 9029
5f5c8ee5
GM
9030/* Make sure that glyph rows in the current matrix of window W
9031 reference the same glyph memory as corresponding rows in the
9032 frame's frame matrix. This function is called after scrolling W's
9033 current matrix on a terminal frame in try_window_id and
9034 try_window_reusing_current_matrix. */
9035
9036static void
9037sync_frame_with_window_matrix_rows (w)
9038 struct window *w;
c581d710 9039{
5f5c8ee5
GM
9040 struct frame *f = XFRAME (w->frame);
9041 struct glyph_row *window_row, *window_row_end, *frame_row;
9042
9043 /* Preconditions: W must be a leaf window and full-width. Its frame
9044 must have a frame matrix. */
9045 xassert (NILP (w->hchild) && NILP (w->vchild));
9046 xassert (WINDOW_FULL_WIDTH_P (w));
9047 xassert (!FRAME_WINDOW_P (f));
9048
9049 /* If W is a full-width window, glyph pointers in W's current matrix
9050 have, by definition, to be the same as glyph pointers in the
9051 corresponding frame matrix. */
9052 window_row = w->current_matrix->rows;
9053 window_row_end = window_row + w->current_matrix->nrows;
9054 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9055 while (window_row < window_row_end)
659a218f 9056 {
5f5c8ee5
GM
9057 int area;
9058 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9059 frame_row->glyphs[area] = window_row->glyphs[area];
9060 ++window_row, ++frame_row;
659a218f 9061 }
a2889657 9062}
5f5c8ee5
GM
9063
9064
9065/* Try to redisplay window W by reusing its existing display. W's
9066 current matrix must be up to date when this function is called,
9067 i.e. window_end_valid must not be nil.
9068
9069 Value is
9070
9071 1 if display has been updated
9072 0 if otherwise unsuccessful
9073 -1 if redisplay with same window start is known not to succeed
9074
9075 The following steps are performed:
9076
9077 1. Find the last row in the current matrix of W that is not
9078 affected by changes at the start of current_buffer. If no such row
9079 is found, give up.
9080
9081 2. Find the first row in W's current matrix that is not affected by
9082 changes at the end of current_buffer. Maybe there is no such row.
9083
9084 3. Display lines beginning with the row + 1 found in step 1 to the
9085 row found in step 2 or, if step 2 didn't find a row, to the end of
9086 the window.
9087
9088 4. If cursor is not known to appear on the window, give up.
9089
9090 5. If display stopped at the row found in step 2, scroll the
9091 display and current matrix as needed.
9092
9093 6. Maybe display some lines at the end of W, if we must. This can
9094 happen under various circumstances, like a partially visible line
9095 becoming fully visible, or because newly displayed lines are displayed
9096 in smaller font sizes.
9097
9098 7. Update W's window end information. */
9099
9100 /* Check that window end is what we expect it to be. */
12adba34
RS
9101
9102static int
5f5c8ee5 9103try_window_id (w)
12adba34 9104 struct window *w;
12adba34 9105{
5f5c8ee5
GM
9106 struct frame *f = XFRAME (w->frame);
9107 struct glyph_matrix *current_matrix = w->current_matrix;
9108 struct glyph_matrix *desired_matrix = w->desired_matrix;
9109 struct glyph_row *last_unchanged_at_beg_row;
9110 struct glyph_row *first_unchanged_at_end_row;
9111 struct glyph_row *row;
9112 struct glyph_row *bottom_row;
9113 int bottom_vpos;
9114 struct it it;
9115 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
9116 struct text_pos start_pos;
9117 struct run run;
9118 int first_unchanged_at_end_vpos = 0;
9119 struct glyph_row *last_text_row, *last_text_row_at_end;
9120 struct text_pos start;
9121
9122 SET_TEXT_POS_FROM_MARKER (start, w->start);
9123
9124 /* Check pre-conditions. Window end must be valid, otherwise
9125 the current matrix would not be up to date. */
9126 xassert (!NILP (w->window_end_valid));
9127 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
9128 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
9129
9130 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
9131 only if buffer has really changed. The reason is that the gap is
9132 initially at Z for freshly visited files. The code below would
9133 set end_unchanged to 0 in that case. */
9134 if (MODIFF > SAVE_MODIFF)
9135 {
9136 if (GPT - BEG < beg_unchanged)
9137 beg_unchanged = GPT - BEG;
9138 if (Z - GPT < end_unchanged)
9139 end_unchanged = Z - GPT;
9140 }
9141
9142 /* If window starts after a line end, and the last change is in
9143 front of that newline, then changes don't affect the display.
9144 This case happens with stealth-fontification. */
9145 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9146 if (CHARPOS (start) > BEGV
9147 && Z - end_unchanged < CHARPOS (start) - 1
9148 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
9149 && PT < MATRIX_ROW_END_CHARPOS (row))
9150 {
9151 /* We have to update window end positions because the buffer's
9152 size has changed. */
9153 w->window_end_pos
9154 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9155 w->window_end_bytepos
9156 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9157 return 1;
9158 }
9159
9160 /* Return quickly if changes are all below what is displayed in the
9161 window, and if PT is in the window. */
9162 if (beg_unchanged > MATRIX_ROW_END_CHARPOS (row)
9163 && PT < MATRIX_ROW_END_CHARPOS (row))
9164 {
9165 /* We have to update window end positions because the buffer's
9166 size has changed. */
9167 w->window_end_pos
9168 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9169 w->window_end_bytepos
9170 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9171 return 1;
9172 }
9173
9174 /* Check that window start agrees with the start of the first glyph
9175 row in its current matrix. Check this after we know the window
9176 start is not in changed text, otherwise positions would not be
9177 comparable. */
9178 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9179 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
9180 return 0;
9181
9182 /* Remember beg_unchanged and end_unchanged for debugging purposes. */
9183 IF_DEBUG (debug_beg_unchanged = beg_unchanged;
9184 debug_end_unchanged = end_unchanged);
9185
9186 /* Compute the position at which we have to start displaying new
9187 lines. Some of the lines at the top of the window might be
9188 reusable because they are not displaying changed text. Find the
9189 last row in W's current matrix not affected by changes at the
9190 start of current_buffer. Value is null if changes start in the
9191 first line of window. */
9192 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
9193 if (last_unchanged_at_beg_row)
9194 {
9195 init_to_row_end (&it, w, last_unchanged_at_beg_row);
9196 start_pos = it.current.pos;
9197
9198 /* Start displaying new lines in the desired matrix at the same
9199 vpos we would use in the current matrix, i.e. below
9200 last_unchanged_at_beg_row. */
9201 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
9202 current_matrix);
9203 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9204 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
9205
9206 xassert (it.hpos == 0 && it.current_x == 0);
9207 }
9208 else
9209 {
9210 /* There are no reusable lines at the start of the window.
9211 Start displaying in the first line. */
9212 start_display (&it, w, start);
9213 start_pos = it.current.pos;
9214 }
9215
9216 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
9217 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
9218
9219 /* Find the first row that is not affected by changes at the end of
9220 the buffer. Value will be null if there is no unchanged row, in
9221 which case we must redisplay to the end of the window. delta
9222 will be set to the value by which buffer positions beginning with
9223 first_unchanged_at_end_row have to be adjusted due to text
9224 changes. */
9225 first_unchanged_at_end_row
9226 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
9227 IF_DEBUG (debug_delta = delta);
9228 IF_DEBUG (debug_delta_bytes = delta_bytes);
9229
9230 /* Set stop_pos to the buffer position up to which we will have to
9231 display new lines. If first_unchanged_at_end_row != NULL, this
9232 is the buffer position of the start of the line displayed in that
9233 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
9234 that we don't stop at a buffer position. */
9235 stop_pos = 0;
9236 if (first_unchanged_at_end_row)
9237 {
9238 xassert (last_unchanged_at_beg_row == NULL
9239 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
9240
9241 /* If this is a continuation line, move forward to the next one
9242 that isn't. Changes in lines above affect this line.
9243 Caution: this may move first_unchanged_at_end_row to a row
9244 not displaying text. */
9245 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
9246 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9247 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9248 < it.last_visible_y))
9249 ++first_unchanged_at_end_row;
9250
9251 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9252 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9253 >= it.last_visible_y))
9254 first_unchanged_at_end_row = NULL;
9255 else
9256 {
9257 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
9258 + delta);
9259 first_unchanged_at_end_vpos
9260 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
9261 xassert (stop_pos >= Z - end_unchanged);
9262 }
9263 }
9264 else if (last_unchanged_at_beg_row == NULL)
9265 return 0;
9266
9267
9268#if GLYPH_DEBUG
9269
9270 /* Either there is no unchanged row at the end, or the one we have
9271 now displays text. This is a necessary condition for the window
9272 end pos calculation at the end of this function. */
9273 xassert (first_unchanged_at_end_row == NULL
9274 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
9275
9276 debug_last_unchanged_at_beg_vpos
9277 = (last_unchanged_at_beg_row
9278 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
9279 : -1);
9280 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
9281
9282#endif /* GLYPH_DEBUG != 0 */
9283
9284
9285 /* Display new lines. Set last_text_row to the last new line
9286 displayed which has text on it, i.e. might end up as being the
9287 line where the window_end_vpos is. */
9288 w->cursor.vpos = -1;
9289 last_text_row = NULL;
9290 overlay_arrow_seen = 0;
9291 while (it.current_y < it.last_visible_y
9292 && !fonts_changed_p
9293 && (first_unchanged_at_end_row == NULL
9294 || IT_CHARPOS (it) < stop_pos))
9295 {
9296 if (display_line (&it))
9297 last_text_row = it.glyph_row - 1;
9298 }
9299
9300 if (fonts_changed_p)
9301 return -1;
9302
9303
9304 /* Compute differences in buffer positions, y-positions etc. for
9305 lines reused at the bottom of the window. Compute what we can
9306 scroll. */
9307 if (first_unchanged_at_end_row)
9308 {
9309 dvpos = (it.vpos
9310 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
9311 current_matrix));
9312 dy = it.current_y - first_unchanged_at_end_row->y;
9313 run.current_y = first_unchanged_at_end_row->y;
9314 run.desired_y = run.current_y + dy;
9315 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
9316 }
9317 else
9318 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
9319 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
9320
9321
9322 /* Find the cursor if not already found. We have to decide whether
9323 PT will appear on this window (it sometimes doesn't, but this is
9324 not a very frequent case.) This decision has to be made before
9325 the current matrix is altered. A value of cursor.vpos < 0 means
9326 that PT is either in one of the lines beginning at
9327 first_unchanged_at_end_row or below the window. Don't care for
9328 lines that might be displayed later at the window end; as
9329 mentioned, this is not a frequent case. */
9330 if (w->cursor.vpos < 0)
9331 {
9332 int last_y = min (it.last_visible_y, it.last_visible_y + dy);
9333
9334 /* Cursor in unchanged rows at the top? */
9335 if (PT < CHARPOS (start_pos)
9336 && last_unchanged_at_beg_row)
9337 {
9338 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9339 while (row <= last_unchanged_at_beg_row
9340 && MATRIX_ROW_END_CHARPOS (row) <= PT)
9341 ++row;
9342 xassert (row <= last_unchanged_at_beg_row);
9343 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9344 }
9345
9346 /* Start from first_unchanged_at_end_row looking for PT. */
9347 else if (first_unchanged_at_end_row)
9348 {
9349 row = first_unchanged_at_end_row;
9350 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9351 {
9352 if (PT - delta >= MATRIX_ROW_START_CHARPOS (row)
9353 && PT - delta < MATRIX_ROW_END_CHARPOS (row))
9354 {
9355 set_cursor_from_row (w, row, w->current_matrix, delta,
9356 delta_bytes, dy, dvpos);
9357 break;
9358 }
9359 else if (MATRIX_ROW_BOTTOM_Y (row) >= last_y)
9360 break;
9361 ++row;
9362 }
9363 }
9364
9365 /* Give up if cursor was not found. */
9366 if (w->cursor.vpos < 0)
9367 {
9368 clear_glyph_matrix (w->desired_matrix);
9369 return -1;
9370 }
9371 }
9372
9373 /* Don't let the cursor end in the scroll margins. */
9374 {
9375 int this_scroll_margin, cursor_height;
9376
9377 this_scroll_margin = max (0, scroll_margin);
9378 this_scroll_margin = min (this_scroll_margin,
9379 XFASTINT (w->height) / 4);
9380 this_scroll_margin *= CANON_Y_UNIT (it.f);
9381 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
9382
9383 if ((w->cursor.y < this_scroll_margin
9384 && CHARPOS (start) > BEGV)
9385 /* Don't take scroll margin into account at the bottom because
9386 old redisplay didn't do it either. */
9387 || w->cursor.y + cursor_height > it.last_visible_y)
9388 {
9389 w->cursor.vpos = -1;
9390 clear_glyph_matrix (w->desired_matrix);
9391 return -1;
9392 }
9393 }
9394
9395 /* Scroll the display. Do it before changing the current matrix so
9396 that xterm.c doesn't get confused about where the cursor glyph is
9397 found. */
9398 if (dy)
9399 {
9400 update_begin (f);
9401
9402 if (FRAME_WINDOW_P (f))
9403 {
9404 rif->update_window_begin_hook (w);
9405 rif->scroll_run_hook (w, &run);
9406 rif->update_window_end_hook (w, 0);
9407 }
9408 else
9409 {
9410 /* Terminal frame. In this case, dvpos gives the number of
9411 lines to scroll by; dvpos < 0 means scroll up. */
9412 int first_unchanged_at_end_vpos
9413 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
9414 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
9415 int end = XFASTINT (w->top) + window_internal_height (w);
9416
9417 /* Perform the operation on the screen. */
9418 if (dvpos > 0)
9419 {
9420 /* Scroll last_unchanged_at_beg_row to the end of the
9421 window down dvpos lines. */
9422 set_terminal_window (end);
9423
9424 /* On dumb terminals delete dvpos lines at the end
9425 before inserting dvpos empty lines. */
9426 if (!scroll_region_ok)
9427 ins_del_lines (end - dvpos, -dvpos);
9428
9429 /* Insert dvpos empty lines in front of
9430 last_unchanged_at_beg_row. */
9431 ins_del_lines (from, dvpos);
9432 }
9433 else if (dvpos < 0)
9434 {
9435 /* Scroll up last_unchanged_at_beg_vpos to the end of
9436 the window to last_unchanged_at_beg_vpos - |dvpos|. */
9437 set_terminal_window (end);
9438
9439 /* Delete dvpos lines in front of
9440 last_unchanged_at_beg_vpos. ins_del_lines will set
9441 the cursor to the given vpos and emit |dvpos| delete
9442 line sequences. */
9443 ins_del_lines (from + dvpos, dvpos);
9444
9445 /* On a dumb terminal insert dvpos empty lines at the
9446 end. */
9447 if (!scroll_region_ok)
9448 ins_del_lines (end + dvpos, -dvpos);
9449 }
9450
9451 set_terminal_window (0);
9452 }
9453
9454 update_end (f);
9455 }
9456
9457 /* Shift reused rows of the current matrix to the right position. */
9458 if (dvpos < 0)
9459 {
9460 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
9461 bottom_vpos, dvpos);
9462 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
9463 bottom_vpos, 0);
9464 }
9465 else if (dvpos > 0)
9466 {
9467 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
9468 bottom_vpos, dvpos);
9469 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
9470 first_unchanged_at_end_vpos + dvpos, 0);
9471 }
9472
9473 /* For frame-based redisplay, make sure that current frame and window
9474 matrix are in sync with respect to glyph memory. */
9475 if (!FRAME_WINDOW_P (f))
9476 sync_frame_with_window_matrix_rows (w);
9477
9478 /* Adjust buffer positions in reused rows. */
9479 if (delta)
9480 increment_glyph_matrix_buffer_positions (current_matrix,
9481 first_unchanged_at_end_vpos + dvpos,
9482 bottom_vpos, delta, delta_bytes);
9483
9484 /* Adjust Y positions. */
9485 if (dy)
9486 shift_glyph_matrix (w, current_matrix,
9487 first_unchanged_at_end_vpos + dvpos,
9488 bottom_vpos, dy);
9489
9490 if (first_unchanged_at_end_row)
9491 first_unchanged_at_end_row += dvpos;
9492
9493 /* If scrolling up, there may be some lines to display at the end of
9494 the window. */
9495 last_text_row_at_end = NULL;
9496 if (dy < 0)
9497 {
9498 /* Set last_row to the glyph row in the current matrix where the
9499 window end line is found. It has been moved up or down in
9500 the matrix by dvpos. */
9501 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
9502 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
9503
9504 /* If last_row is the window end line, it should display text. */
9505 xassert (last_row->displays_text_p);
9506
9507 /* If window end line was partially visible before, begin
9508 displaying at that line. Otherwise begin displaying with the
9509 line following it. */
9510 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
9511 {
9512 init_to_row_start (&it, w, last_row);
9513 it.vpos = last_vpos;
9514 it.current_y = last_row->y;
9515 }
9516 else
9517 {
9518 init_to_row_end (&it, w, last_row);
9519 it.vpos = 1 + last_vpos;
9520 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
9521 ++last_row;
9522 }
12adba34 9523
5f5c8ee5
GM
9524 /* We may start in a continuation line. If so, we have to get
9525 the right continuation_lines_width and current_x. */
9526 it.continuation_lines_width = last_row->continuation_lines_width;
9527 it.hpos = it.current_x = 0;
9528
9529 /* Display the rest of the lines at the window end. */
9530 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9531 while (it.current_y < it.last_visible_y
9532 && !fonts_changed_p)
9533 {
9534 /* Is it always sure that the display agrees with lines in
9535 the current matrix? I don't think so, so we mark rows
9536 displayed invalid in the current matrix by setting their
9537 enabled_p flag to zero. */
9538 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
9539 if (display_line (&it))
9540 last_text_row_at_end = it.glyph_row - 1;
9541 }
9542 }
12adba34 9543
5f5c8ee5
GM
9544 /* Update window_end_pos and window_end_vpos. */
9545 if (first_unchanged_at_end_row
9546 && first_unchanged_at_end_row->y < it.last_visible_y
9547 && !last_text_row_at_end)
9548 {
9549 /* Window end line if one of the preserved rows from the current
9550 matrix. Set row to the last row displaying text in current
9551 matrix starting at first_unchanged_at_end_row, after
9552 scrolling. */
9553 xassert (first_unchanged_at_end_row->displays_text_p);
9554 row = find_last_row_displaying_text (w->current_matrix, &it,
9555 first_unchanged_at_end_row);
9556 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
9557
9558 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
9559 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
9560 XSETFASTINT (w->window_end_vpos,
9561 MATRIX_ROW_VPOS (row, w->current_matrix));
9562 }
9563 else if (last_text_row_at_end)
9564 {
9565 XSETFASTINT (w->window_end_pos,
9566 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
9567 w->window_end_bytepos
9568 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
9569 XSETFASTINT (w->window_end_vpos,
9570 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
9571 }
9572 else if (last_text_row)
9573 {
9574 /* We have displayed either to the end of the window or at the
9575 end of the window, i.e. the last row with text is to be found
9576 in the desired matrix. */
9577 XSETFASTINT (w->window_end_pos,
9578 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9579 w->window_end_bytepos
9580 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9581 XSETFASTINT (w->window_end_vpos,
9582 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
9583 }
9584 else if (first_unchanged_at_end_row == NULL
9585 && last_text_row == NULL
9586 && last_text_row_at_end == NULL)
9587 {
9588 /* Displayed to end of window, but no line containing text was
9589 displayed. Lines were deleted at the end of the window. */
9590 int vpos;
9591 int top_line_p = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
9592
9593 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
9594 if ((w->desired_matrix->rows[vpos + top_line_p].enabled_p
9595 && w->desired_matrix->rows[vpos + top_line_p].displays_text_p)
9596 || (!w->desired_matrix->rows[vpos + top_line_p].enabled_p
9597 && w->current_matrix->rows[vpos + top_line_p].displays_text_p))
9598 break;
12adba34 9599
5f5c8ee5
GM
9600 w->window_end_vpos = make_number (vpos);
9601 }
9602 else
9603 abort ();
9604
9605 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
9606 debug_end_vpos = XFASTINT (w->window_end_vpos));
12adba34 9607
5f5c8ee5
GM
9608 /* Record that display has not been completed. */
9609 w->window_end_valid = Qnil;
9610 w->desired_matrix->no_scrolling_p = 1;
9611 return 1;
12adba34 9612}
0f9c0ff0 9613
a2889657 9614
5f5c8ee5
GM
9615\f
9616/***********************************************************************
9617 More debugging support
9618 ***********************************************************************/
a2889657 9619
5f5c8ee5 9620#if GLYPH_DEBUG
a2889657 9621
5f5c8ee5
GM
9622 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
9623static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
1c9241f5 9624
31b24551 9625
5f5c8ee5
GM
9626/* Dump the contents of glyph matrix MATRIX on stderr. If
9627 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
ca26e1c8 9628
5f5c8ee5
GM
9629void
9630dump_glyph_matrix (matrix, with_glyphs_p)
9631 struct glyph_matrix *matrix;
9632 int with_glyphs_p;
9633{
efc63ef0 9634 int i;
5f5c8ee5
GM
9635 for (i = 0; i < matrix->nrows; ++i)
9636 dump_glyph_row (matrix, i, with_glyphs_p);
9637}
31b24551 9638
68a37fa8 9639
5f5c8ee5
GM
9640/* Dump the contents of glyph row at VPOS in MATRIX to stderr.
9641 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
a2889657 9642
5f5c8ee5
GM
9643void
9644dump_glyph_row (matrix, vpos, with_glyphs_p)
9645 struct glyph_matrix *matrix;
9646 int vpos, with_glyphs_p;
9647{
9648 struct glyph_row *row;
9649
9650 if (vpos < 0 || vpos >= matrix->nrows)
9651 return;
9652
9653 row = MATRIX_ROW (matrix, vpos);
9654
9655 fprintf (stderr, "Row Start End Used oEI><O\\CTZF X Y W\n");
9656 fprintf (stderr, "=============================================\n");
9657
9658 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",
9659 row - matrix->rows,
9660 MATRIX_ROW_START_CHARPOS (row),
9661 MATRIX_ROW_END_CHARPOS (row),
9662 row->used[TEXT_AREA],
9663 row->contains_overlapping_glyphs_p,
9664 row->enabled_p,
9665 row->inverse_p,
9666 row->truncated_on_left_p,
9667 row->truncated_on_right_p,
9668 row->overlay_arrow_p,
9669 row->continued_p,
9670 MATRIX_ROW_CONTINUATION_LINE_P (row),
9671 row->displays_text_p,
9672 row->ends_at_zv_p,
9673 row->fill_line_p,
9674 row->x,
9675 row->y,
9676 row->pixel_width);
9677 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
9678 row->end.overlay_string_index);
9679 fprintf (stderr, "%9d %5d\n",
9680 CHARPOS (row->start.string_pos),
9681 CHARPOS (row->end.string_pos));
9682 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
9683 row->end.dpvec_index);
9684
9685 if (with_glyphs_p)
bd66d1ba 9686 {
5f5c8ee5
GM
9687 struct glyph *glyph, *glyph_end;
9688 int prev_had_glyphs_p;
9689
9690 glyph = row->glyphs[TEXT_AREA];
9691 glyph_end = glyph + row->used[TEXT_AREA];
9692
9693 /* Glyph for a line end in text. */
9694 if (glyph == glyph_end && glyph->charpos > 0)
9695 ++glyph_end;
9696
9697 if (glyph < glyph_end)
bd66d1ba 9698 {
5f5c8ee5
GM
9699 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
9700 prev_had_glyphs_p = 1;
bd66d1ba
RS
9701 }
9702 else
5f5c8ee5
GM
9703 prev_had_glyphs_p = 0;
9704
9705 while (glyph < glyph_end)
f7b4b63a 9706 {
5f5c8ee5
GM
9707 if (glyph->type == CHAR_GLYPH)
9708 {
9709 fprintf (stderr,
9710 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9711 glyph - row->glyphs[TEXT_AREA],
9712 'C',
9713 glyph->charpos,
9714 glyph->pixel_width,
9715 glyph->u.ch.code,
9716 (glyph->u.ch.code < 0x80 && glyph->u.ch.code >= ' '
9717 ? glyph->u.ch.code
9718 : '.'),
9719 glyph->u.ch.face_id,
9720 glyph->left_box_line_p,
9721 glyph->right_box_line_p);
9722 }
9723 else if (glyph->type == STRETCH_GLYPH)
9724 {
9725 fprintf (stderr,
9726 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9727 glyph - row->glyphs[TEXT_AREA],
9728 'S',
9729 glyph->charpos,
9730 glyph->pixel_width,
9731 0,
9732 '.',
9733 glyph->u.stretch.face_id,
9734 glyph->left_box_line_p,
9735 glyph->right_box_line_p);
9736 }
9737 else if (glyph->type == IMAGE_GLYPH)
9738 {
9739 fprintf (stderr,
9740 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9741 glyph - row->glyphs[TEXT_AREA],
9742 'I',
9743 glyph->charpos,
9744 glyph->pixel_width,
9745 glyph->u.img.id,
9746 '.',
9747 glyph->u.img.face_id,
9748 glyph->left_box_line_p,
9749 glyph->right_box_line_p);
9750 }
9751 ++glyph;
f7b4b63a 9752 }
f4faa47c 9753 }
5f5c8ee5 9754}
f4faa47c 9755
a2889657 9756
5f5c8ee5
GM
9757DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
9758 Sdump_glyph_matrix, 0, 1, "p",
9759 "Dump the current matrix of the selected window to stderr.\n\
9760Shows contents of glyph row structures. With non-nil optional\n\
9761parameter WITH-GLYPHS-P, dump glyphs as well.")
9762 (with_glyphs_p)
9763{
9764 struct window *w = XWINDOW (selected_window);
9765 struct buffer *buffer = XBUFFER (w->buffer);
9766
9767 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
9768 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
9769 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
9770 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
9771 fprintf (stderr, "=============================================\n");
9772 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
9773 return Qnil;
9774}
1c2250c2 9775
1fca3fae 9776
5f5c8ee5
GM
9777DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
9778 "Dump glyph row ROW to stderr.")
9779 (row)
9780 Lisp_Object row;
9781{
9782 CHECK_NUMBER (row, 0);
9783 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
9784 return Qnil;
9785}
1fca3fae 9786
67481ae5 9787
5f5c8ee5
GM
9788DEFUN ("dump-toolbar-row", Fdump_toolbar_row, Sdump_toolbar_row,
9789 0, 0, "", "")
9790 ()
9791{
9792 struct glyph_matrix *m = (XWINDOW (selected_frame->toolbar_window)
9793 ->current_matrix);
9794 dump_glyph_row (m, 0, 1);
9795 return Qnil;
9796}
ca26e1c8 9797
0f9c0ff0 9798
5f5c8ee5
GM
9799DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
9800 Strace_redisplay_toggle, 0, 0, "",
9801 "Toggle tracing of redisplay.")
9802 ()
9803{
9804 trace_redisplay_p = !trace_redisplay_p;
9805 return Qnil;
9806}
9807
9808
9809#endif /* GLYPH_DEBUG */
ca26e1c8 9810
ca26e1c8 9811
5f5c8ee5
GM
9812\f
9813/***********************************************************************
9814 Building Desired Matrix Rows
9815 ***********************************************************************/
a2889657 9816
5f5c8ee5
GM
9817/* Return a temporary glyph row holding the glyphs of an overlay
9818 arrow. Only used for non-window-redisplay windows. */
ca26e1c8 9819
5f5c8ee5
GM
9820static struct glyph_row *
9821get_overlay_arrow_glyph_row (w)
9822 struct window *w;
9823{
9824 struct frame *f = XFRAME (WINDOW_FRAME (w));
9825 struct buffer *buffer = XBUFFER (w->buffer);
9826 struct buffer *old = current_buffer;
9827 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
9828 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
9829 unsigned char *arrow_end = arrow_string + arrow_len;
9830 unsigned char *p;
9831 struct it it;
9832 int multibyte_p;
9833 int n_glyphs_before;
9834
9835 set_buffer_temp (buffer);
9836 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
9837 it.glyph_row->used[TEXT_AREA] = 0;
9838 SET_TEXT_POS (it.position, 0, 0);
9839
9840 multibyte_p = !NILP (buffer->enable_multibyte_characters);
9841 p = arrow_string;
9842 while (p < arrow_end)
9843 {
9844 Lisp_Object face, ilisp;
9845
9846 /* Get the next character. */
9847 if (multibyte_p)
4fdb80f2 9848 it.c = string_char_and_length (p, arrow_len, &it.len);
5f5c8ee5
GM
9849 else
9850 it.c = *p, it.len = 1;
9851 p += it.len;
9852
9853 /* Get its face. */
9854 XSETFASTINT (ilisp, p - arrow_string);
9855 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
9856 it.face_id = compute_char_face (f, it.c, face);
9857
9858 /* Compute its width, get its glyphs. */
9859 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
337042a9 9860 SET_TEXT_POS (it.position, -1, -1);
5f5c8ee5
GM
9861 PRODUCE_GLYPHS (&it);
9862
9863 /* If this character doesn't fit any more in the line, we have
9864 to remove some glyphs. */
9865 if (it.current_x > it.last_visible_x)
9866 {
9867 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
9868 break;
9869 }
9870 }
9871
9872 set_buffer_temp (old);
9873 return it.glyph_row;
9874}
ca26e1c8 9875
b0a0fbda 9876
5f5c8ee5
GM
9877/* Insert truncation glyphs at the start of IT->glyph_row. Truncation
9878 glyphs are only inserted for terminal frames since we can't really
9879 win with truncation glyphs when partially visible glyphs are
9880 involved. Which glyphs to insert is determined by
9881 produce_special_glyphs. */
67481ae5 9882
5f5c8ee5
GM
9883static void
9884insert_left_trunc_glyphs (it)
9885 struct it *it;
9886{
9887 struct it truncate_it;
9888 struct glyph *from, *end, *to, *toend;
9889
9890 xassert (!FRAME_WINDOW_P (it->f));
9891
9892 /* Get the truncation glyphs. */
9893 truncate_it = *it;
9894 truncate_it.charset = -1;
9895 truncate_it.current_x = 0;
9896 truncate_it.face_id = DEFAULT_FACE_ID;
9897 truncate_it.glyph_row = &scratch_glyph_row;
9898 truncate_it.glyph_row->used[TEXT_AREA] = 0;
9899 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
9900 truncate_it.object = 0;
9901 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
9902
9903 /* Overwrite glyphs from IT with truncation glyphs. */
9904 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
9905 end = from + truncate_it.glyph_row->used[TEXT_AREA];
9906 to = it->glyph_row->glyphs[TEXT_AREA];
9907 toend = to + it->glyph_row->used[TEXT_AREA];
9908
9909 while (from < end)
9910 *to++ = *from++;
9911
9912 /* There may be padding glyphs left over. Remove them. */
9913 from = to;
9914 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
9915 ++from;
9916 while (from < toend)
9917 *to++ = *from++;
9918
9919 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
9920}
e0bfbde6 9921
e0bfbde6 9922
5f5c8ee5 9923/* Compute the pixel height and width of IT->glyph_row.
9c49d3d7 9924
5f5c8ee5
GM
9925 Most of the time, ascent and height of a display line will be equal
9926 to the max_ascent and max_height values of the display iterator
9927 structure. This is not the case if
67481ae5 9928
5f5c8ee5
GM
9929 1. We hit ZV without displaying anything. In this case, max_ascent
9930 and max_height will be zero.
1c9241f5 9931
5f5c8ee5
GM
9932 2. We have some glyphs that don't contribute to the line height.
9933 (The glyph row flag contributes_to_line_height_p is for future
9934 pixmap extensions).
f6fd109b 9935
5f5c8ee5
GM
9936 The first case is easily covered by using default values because in
9937 these cases, the line height does not really matter, except that it
9938 must not be zero. */
67481ae5 9939
5f5c8ee5
GM
9940static void
9941compute_line_metrics (it)
9942 struct it *it;
9943{
9944 struct glyph_row *row = it->glyph_row;
9945 int area, i;
1c2250c2 9946
5f5c8ee5
GM
9947 if (FRAME_WINDOW_P (it->f))
9948 {
9949 int i, top_line_height;
1c2250c2 9950
5f5c8ee5
GM
9951 /* The line may consist of one space only, that was added to
9952 place the cursor on it. If so, the row's height hasn't been
9953 computed yet. */
9954 if (row->height == 0)
9955 {
9956 if (it->max_ascent + it->max_descent == 0)
312246d1 9957 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
5f5c8ee5
GM
9958 row->ascent = it->max_ascent;
9959 row->height = it->max_ascent + it->max_descent;
312246d1
GM
9960 row->phys_ascent = it->max_phys_ascent;
9961 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
9962 }
9963
9964 /* Compute the width of this line. */
9965 row->pixel_width = row->x;
9966 for (i = 0; i < row->used[TEXT_AREA]; ++i)
9967 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
9968
9969 xassert (row->pixel_width >= 0);
9970 xassert (row->ascent >= 0 && row->height > 0);
9971
312246d1
GM
9972 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
9973 || MATRIX_ROW_OVERLAPS_PRED_P (row));
9974
9975 /* If first line's physical ascent is larger than its logical
9976 ascent, use the physical ascent, and make the row taller.
9977 This makes accented characters fully visible. */
9978 if (row == it->w->desired_matrix->rows
9979 && row->phys_ascent > row->ascent)
9980 {
9981 row->height += row->phys_ascent - row->ascent;
9982 row->ascent = row->phys_ascent;
9983 }
9984
5f5c8ee5
GM
9985 /* Compute how much of the line is visible. */
9986 row->visible_height = row->height;
9987
9988 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w);
9989 if (row->y < top_line_height)
9990 row->visible_height -= top_line_height - row->y;
9991 else
9992 {
9993 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
9994 if (row->y + row->height > max_y)
9995 row->visible_height -= row->y + row->height - max_y;
9996 }
9997 }
9998 else
9999 {
10000 row->pixel_width = row->used[TEXT_AREA];
312246d1
GM
10001 row->ascent = row->phys_ascent = 0;
10002 row->height = row->phys_height = row->visible_height = 1;
5f5c8ee5 10003 }
67481ae5 10004
5f5c8ee5
GM
10005 /* Compute a hash code for this row. */
10006 row->hash = 0;
10007 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
10008 for (i = 0; i < row->used[area]; ++i)
10009 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
10010 + row->glyphs[area][i].u.val
10011 + (row->glyphs[area][i].type << 2));
a2889657 10012
5f5c8ee5 10013 it->max_ascent = it->max_descent = 0;
312246d1 10014 it->max_phys_ascent = it->max_phys_descent = 0;
5f5c8ee5 10015}
12adba34 10016
ca26e1c8 10017
5f5c8ee5
GM
10018/* Append one space to the glyph row of iterator IT if doing a
10019 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10020 space have the default face, otherwise let it have the same face as
10021 IT->face_id. This function is called to make sure that there is
10022 always one glyph at the end of a glyph row that the cursor can be
10023 set on under window-systems. (If there weren't such a glyph we
10024 would not know how wide and tall the cursor should be displayed). */
ca26e1c8 10025
5f5c8ee5
GM
10026static void
10027append_space (it, default_face_p)
10028 struct it *it;
10029 int default_face_p;
10030{
10031 if (FRAME_WINDOW_P (it->f))
10032 {
10033 int n = it->glyph_row->used[TEXT_AREA];
ca26e1c8 10034
5f5c8ee5
GM
10035 if (it->glyph_row->glyphs[TEXT_AREA] + n
10036 < it->glyph_row->glyphs[1 + TEXT_AREA])
a2889657 10037 {
5f5c8ee5
GM
10038 /* Save some values that must not be changed. */
10039 int saved_x = it->current_x;
10040 struct text_pos saved_pos;
10041 int saved_what = it->what;
10042 int saved_face_id = it->face_id;
10043 int saved_charset = it->charset;
10044 Lisp_Object saved_object;
10045
10046 saved_object = it->object;
10047 saved_pos = it->position;
10048
10049 it->what = IT_CHARACTER;
10050 bzero (&it->position, sizeof it->position);
10051 it->object = 0;
10052 it->c = ' ';
10053 it->len = 1;
10054 it->charset = CHARSET_ASCII;
10055
10056 if (default_face_p)
10057 it->face_id = DEFAULT_FACE_ID;
10058 if (it->multibyte_p)
10059 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, CHARSET_ASCII);
10060 else
10061 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, -1);
1842fc1a 10062
5f5c8ee5
GM
10063 PRODUCE_GLYPHS (it);
10064
10065 it->current_x = saved_x;
10066 it->object = saved_object;
10067 it->position = saved_pos;
10068 it->what = saved_what;
10069 it->face_id = saved_face_id;
10070 it->charset = saved_charset;
10071 }
10072 }
10073}
12adba34 10074
1842fc1a 10075
5f5c8ee5
GM
10076/* Extend the face of the last glyph in the text area of IT->glyph_row
10077 to the end of the display line. Called from display_line.
10078 If the glyph row is empty, add a space glyph to it so that we
10079 know the face to draw. Set the glyph row flag fill_line_p. */
10080
10081static void
10082extend_face_to_end_of_line (it)
10083 struct it *it;
10084{
10085 struct face *face;
10086 struct frame *f = it->f;
1842fc1a 10087
5f5c8ee5
GM
10088 /* If line is already filled, do nothing. */
10089 if (it->current_x >= it->last_visible_x)
10090 return;
10091
10092 /* Face extension extends the background and box of IT->face_id
10093 to the end of the line. If the background equals the background
10094 of the frame, we haven't to do anything. */
10095 face = FACE_FROM_ID (f, it->face_id);
10096 if (FRAME_WINDOW_P (f)
10097 && face->box == FACE_NO_BOX
10098 && face->background == FRAME_BACKGROUND_PIXEL (f)
10099 && !face->stipple)
10100 return;
1842fc1a 10101
5f5c8ee5
GM
10102 /* Set the glyph row flag indicating that the face of the last glyph
10103 in the text area has to be drawn to the end of the text area. */
10104 it->glyph_row->fill_line_p = 1;
545e04f6 10105
5f5c8ee5
GM
10106 /* If current charset of IT is not ASCII, make sure we have the
10107 ASCII face. This will be automatically undone the next time
10108 get_next_display_element returns a character from a different
10109 charset. Note that the charset will always be ASCII in unibyte
10110 text. */
10111 if (it->charset != CHARSET_ASCII)
10112 {
10113 it->charset = CHARSET_ASCII;
10114 it->face_id = FACE_FOR_CHARSET (f, it->face_id, CHARSET_ASCII);
10115 }
545e04f6 10116
5f5c8ee5
GM
10117 if (FRAME_WINDOW_P (f))
10118 {
10119 /* If the row is empty, add a space with the current face of IT,
10120 so that we know which face to draw. */
10121 if (it->glyph_row->used[TEXT_AREA] == 0)
a2889657 10122 {
5f5c8ee5
GM
10123 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
10124 it->glyph_row->glyphs[TEXT_AREA][0].u.ch.face_id = it->face_id;
10125 it->glyph_row->used[TEXT_AREA] = 1;
a2889657 10126 }
5f5c8ee5
GM
10127 }
10128 else
10129 {
10130 /* Save some values that must not be changed. */
10131 int saved_x = it->current_x;
10132 struct text_pos saved_pos;
10133 Lisp_Object saved_object;
10134 int saved_what = it->what;
10135
10136 saved_object = it->object;
10137 saved_pos = it->position;
10138
10139 it->what = IT_CHARACTER;
10140 bzero (&it->position, sizeof it->position);
10141 it->object = 0;
10142 it->c = ' ';
10143 it->len = 1;
10144
10145 PRODUCE_GLYPHS (it);
10146
10147 while (it->current_x <= it->last_visible_x)
10148 PRODUCE_GLYPHS (it);
10149
10150 /* Don't count these blanks really. It would let us insert a left
10151 truncation glyph below and make us set the cursor on them, maybe. */
10152 it->current_x = saved_x;
10153 it->object = saved_object;
10154 it->position = saved_pos;
10155 it->what = saved_what;
10156 }
10157}
12adba34 10158
545e04f6 10159
5f5c8ee5
GM
10160/* Value is non-zero if text starting at CHARPOS in current_buffer is
10161 trailing whitespace. */
1c9241f5 10162
5f5c8ee5
GM
10163static int
10164trailing_whitespace_p (charpos)
10165 int charpos;
10166{
10167 int bytepos = CHAR_TO_BYTE (charpos);
10168 int c = 0;
7bbe686f 10169
5f5c8ee5
GM
10170 while (bytepos < ZV_BYTE
10171 && (c = FETCH_CHAR (bytepos),
10172 c == ' ' || c == '\t'))
10173 ++bytepos;
0d09d1e6 10174
8f897821
GM
10175 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
10176 {
10177 if (bytepos != PT_BYTE)
10178 return 1;
10179 }
10180 return 0;
5f5c8ee5 10181}
31b24551 10182
545e04f6 10183
5f5c8ee5 10184/* Highlight trailing whitespace, if any, in ROW. */
545e04f6 10185
5f5c8ee5
GM
10186void
10187highlight_trailing_whitespace (f, row)
10188 struct frame *f;
10189 struct glyph_row *row;
10190{
10191 int used = row->used[TEXT_AREA];
10192
10193 if (used)
10194 {
10195 struct glyph *start = row->glyphs[TEXT_AREA];
10196 struct glyph *glyph = start + used - 1;
10197
10198 /* Skip over the space glyph inserted to display the
10199 cursor at the end of a line. */
10200 if (glyph->type == CHAR_GLYPH
10201 && glyph->u.ch.code == ' '
10202 && glyph->object == 0)
10203 --glyph;
10204
10205 /* If last glyph is a space or stretch, and it's trailing
10206 whitespace, set the face of all trailing whitespace glyphs in
10207 IT->glyph_row to `trailing-whitespace'. */
10208 if (glyph >= start
10209 && BUFFERP (glyph->object)
10210 && (glyph->type == STRETCH_GLYPH
10211 || (glyph->type == CHAR_GLYPH
10212 && glyph->u.ch.code == ' '))
10213 && trailing_whitespace_p (glyph->charpos))
545e04f6 10214 {
5f5c8ee5
GM
10215 int face_id = lookup_named_face (f, Qtrailing_whitespace,
10216 CHARSET_ASCII);
10217
10218 while (glyph >= start
10219 && BUFFERP (glyph->object)
10220 && (glyph->type == STRETCH_GLYPH
10221 || (glyph->type == CHAR_GLYPH
10222 && glyph->u.ch.code == ' ')))
545e04f6 10223 {
5f5c8ee5
GM
10224 if (glyph->type == STRETCH_GLYPH)
10225 glyph->u.stretch.face_id = face_id;
10226 else
10227 glyph->u.ch.face_id = face_id;
10228 --glyph;
545e04f6
KH
10229 }
10230 }
a2889657 10231 }
5f5c8ee5 10232}
a2889657 10233
5fcbb24d 10234
5f5c8ee5
GM
10235/* Construct the glyph row IT->glyph_row in the desired matrix of
10236 IT->w from text at the current position of IT. See dispextern.h
10237 for an overview of struct it. Value is non-zero if
10238 IT->glyph_row displays text, as opposed to a line displaying ZV
10239 only. */
10240
10241static int
10242display_line (it)
10243 struct it *it;
10244{
10245 struct glyph_row *row = it->glyph_row;
10246
10247 /* We always start displaying at hpos zero even if hscrolled. */
10248 xassert (it->hpos == 0 && it->current_x == 0);
a2889657 10249
5f5c8ee5
GM
10250 /* We must not display in a row that's not a text row. */
10251 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
10252 < it->w->desired_matrix->nrows);
12adba34 10253
5f5c8ee5
GM
10254 /* Is IT->w showing the region? */
10255 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
12adba34 10256
5f5c8ee5
GM
10257 /* Clear the result glyph row and enable it. */
10258 prepare_desired_row (row);
12adba34 10259
5f5c8ee5
GM
10260 row->y = it->current_y;
10261 row->start = it->current;
10262 row->continuation_lines_width = it->continuation_lines_width;
10263 row->displays_text_p = 1;
10264
10265 /* Arrange the overlays nicely for our purposes. Usually, we call
10266 display_line on only one line at a time, in which case this
10267 can't really hurt too much, or we call it on lines which appear
10268 one after another in the buffer, in which case all calls to
10269 recenter_overlay_lists but the first will be pretty cheap. */
10270 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
10271
10272#if NO_PROMPT_IN_BUFFER
10273 /* Show mini-buffer prompt, if at the beginning of a mini-buffer
10274 window. */
10275 if (MINI_WINDOW_P (it->w)
10276 && MATRIX_ROW_START_CHARPOS (row) == BEG
10277 && it->vpos == 0)
10278 {
10279 if (NILP (minibuf_prompt))
10280 minibuf_prompt_width = minibuf_prompt_pixel_width = 0;
a2889657 10281 else
a2889657 10282 {
5f5c8ee5
GM
10283 /* We would like to truncate the prompt a little bit before
10284 the right margin of the window, so that user input can
10285 start on the first line. Set max_x to this position. */
10286 int max_x = (it->last_visible_x - 4 * CANON_X_UNIT (it->f));
10287
10288 /* We use a temporary iterator different from IT so that
10289 IT's settings are not overwritten when displaying
10290 the prompt. */
10291 struct it ti;
10292
10293 ti = *it;
10294
10295 /* Display the prompt. Set minibuf_prompt_width to the
10296 number of glyphs generated for the prompt, set
10297 minibuf_prompt_pixel_width to its width in pixels. */
10298 xassert (it->current_x == 0);
10299 display_string (NULL, minibuf_prompt, Qnil, 0, 0, &ti,
10300 0, 0, max_x, -1);
10301 minibuf_prompt_width = ti.hpos;
10302 minibuf_prompt_pixel_width = ti.current_x;
10303
10304 /* Transfer pixel and hpos information to IT. */
10305 it->hpos = ti.hpos;
10306 it->current_x = ti.current_x;
10307 }
10308 }
10309#endif /* NO_PROMPT_IN_BUFFER */
10310
10311 /* Move over display elements that are not visible because we are
10312 hscrolled. This may stop at an x-position < IT->first_visible_x
10313 if the first glyph is partially visible or if we hit a line end. */
10314 if (it->current_x < it->first_visible_x)
10315 move_it_in_display_line_to (it, ZV, it->first_visible_x,
10316 MOVE_TO_POS | MOVE_TO_X);
10317
10318 /* Get the initial row height. This is either the height of the
10319 text hscrolled, if there is any, or zero. */
10320 row->ascent = it->max_ascent;
10321 row->height = it->max_ascent + it->max_descent;
312246d1
GM
10322 row->phys_ascent = it->max_phys_ascent;
10323 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
10324
10325 /* Loop generating characters. The loop is left with IT on the next
10326 character to display. */
10327 while (1)
10328 {
10329 int n_glyphs_before, hpos_before, x_before;
10330 int x, i, nglyphs;
10331
10332 /* Retrieve the next thing to display. Value is zero if end of
10333 buffer reached. */
10334 if (!get_next_display_element (it))
10335 {
10336 /* Maybe add a space at the end of this line that is used to
10337 display the cursor there under X. */
10338 append_space (it, 1);
10339
10340 /* The position -1 below indicates a blank line not
10341 corresponding to any text, as opposed to an empty line
10342 corresponding to a line end. */
10343 if (row->used[TEXT_AREA] <= 1)
a2889657 10344 {
5f5c8ee5
GM
10345 row->glyphs[TEXT_AREA]->charpos = -1;
10346 row->displays_text_p = 0;
10347
10348 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
10349 row->indicate_empty_line_p = 1;
a2889657 10350 }
5f5c8ee5
GM
10351
10352 it->continuation_lines_width = 0;
10353 row->ends_at_zv_p = 1;
10354 break;
a2889657 10355 }
a2889657 10356
5f5c8ee5
GM
10357 /* Now, get the metrics of what we want to display. This also
10358 generates glyphs in `row' (which is IT->glyph_row). */
10359 n_glyphs_before = row->used[TEXT_AREA];
10360 x = it->current_x;
10361 PRODUCE_GLYPHS (it);
a2889657 10362
5f5c8ee5
GM
10363 /* If this display element was in marginal areas, continue with
10364 the next one. */
10365 if (it->area != TEXT_AREA)
a2889657 10366 {
5f5c8ee5
GM
10367 row->ascent = max (row->ascent, it->max_ascent);
10368 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
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);
5f5c8ee5
GM
10372 set_iterator_to_next (it);
10373 continue;
10374 }
5936754e 10375
5f5c8ee5
GM
10376 /* Does the display element fit on the line? If we truncate
10377 lines, we should draw past the right edge of the window. If
10378 we don't truncate, we want to stop so that we can display the
10379 continuation glyph before the right margin. If lines are
10380 continued, there are two possible strategies for characters
10381 resulting in more than 1 glyph (e.g. tabs): Display as many
10382 glyphs as possible in this line and leave the rest for the
10383 continuation line, or display the whole element in the next
10384 line. Original redisplay did the former, so we do it also. */
10385 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10386 hpos_before = it->hpos;
10387 x_before = x;
10388
10389 if (nglyphs == 1
10390 && it->current_x < it->last_visible_x)
10391 {
10392 ++it->hpos;
10393 row->ascent = max (row->ascent, it->max_ascent);
10394 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10395 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10396 row->phys_height = max (row->phys_height,
10397 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10398 if (it->current_x - it->pixel_width < it->first_visible_x)
10399 row->x = x - it->first_visible_x;
10400 }
10401 else
10402 {
10403 int new_x;
10404 struct glyph *glyph;
10405
10406 for (i = 0; i < nglyphs; ++i, x = new_x)
b5bbc9a5 10407 {
5f5c8ee5
GM
10408 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10409 new_x = x + glyph->pixel_width;
10410
10411 if (/* Lines are continued. */
10412 !it->truncate_lines_p
10413 && (/* Glyph doesn't fit on the line. */
10414 new_x > it->last_visible_x
10415 /* Or it fits exactly on a window system frame. */
10416 || (new_x == it->last_visible_x
10417 && FRAME_WINDOW_P (it->f))))
a2889657 10418 {
5f5c8ee5
GM
10419 /* End of a continued line. */
10420
10421 if (it->hpos == 0
10422 || (new_x == it->last_visible_x
10423 && FRAME_WINDOW_P (it->f)))
10424 {
10425 /* Current glyph fits exactly on the line. We
10426 must continue the line because we can't draw
10427 the cursor after the glyph. */
10428 row->continued_p = 1;
10429 it->current_x = new_x;
10430 it->continuation_lines_width += new_x;
10431 ++it->hpos;
10432 if (i == nglyphs - 1)
10433 set_iterator_to_next (it);
10434 }
10435 else
5936754e 10436 {
5f5c8ee5
GM
10437 /* Display element draws past the right edge of
10438 the window. Restore positions to values
10439 before the element. The next line starts
10440 with current_x before the glyph that could
10441 not be displayed, so that TAB works right. */
10442 row->used[TEXT_AREA] = n_glyphs_before + i;
10443
10444 /* Display continuation glyphs. */
10445 if (!FRAME_WINDOW_P (it->f))
10446 produce_special_glyphs (it, IT_CONTINUATION);
10447 row->continued_p = 1;
10448
10449 it->current_x = x;
10450 it->continuation_lines_width += x;
5936754e 10451 }
5f5c8ee5
GM
10452 break;
10453 }
10454 else if (new_x > it->first_visible_x)
10455 {
10456 /* Increment number of glyphs actually displayed. */
10457 ++it->hpos;
10458
10459 if (x < it->first_visible_x)
10460 /* Glyph is partially visible, i.e. row starts at
10461 negative X position. */
10462 row->x = x - it->first_visible_x;
10463 }
10464 else
10465 {
10466 /* Glyph is completely off the left margin of the
10467 window. This should not happen because of the
10468 move_it_in_display_line at the start of
10469 this function. */
10470 abort ();
a2889657 10471 }
a2889657 10472 }
5f5c8ee5
GM
10473
10474 row->ascent = max (row->ascent, it->max_ascent);
10475 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10476 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10477 row->phys_height = max (row->phys_height,
10478 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10479
10480 /* End of this display line if row is continued. */
10481 if (row->continued_p)
10482 break;
a2889657 10483 }
a2889657 10484
5f5c8ee5
GM
10485 /* Is this a line end? If yes, we're also done, after making
10486 sure that a non-default face is extended up to the right
10487 margin of the window. */
10488 if (ITERATOR_AT_END_OF_LINE_P (it))
1c9241f5 10489 {
5f5c8ee5
GM
10490 int used_before = row->used[TEXT_AREA];
10491
10492 /* Add a space at the end of the line that is used to
10493 display the cursor there. */
10494 append_space (it, 0);
10495
10496 /* Extend the face to the end of the line. */
10497 extend_face_to_end_of_line (it);
10498
10499 /* Make sure we have the position. */
10500 if (used_before == 0)
10501 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
10502
10503 /* Consume the line end. This skips over invisible lines. */
10504 set_iterator_to_next (it);
10505 it->continuation_lines_width = 0;
10506 break;
1c9241f5 10507 }
a2889657 10508
5f5c8ee5
GM
10509 /* Proceed with next display element. Note that this skips
10510 over lines invisible because of selective display. */
10511 set_iterator_to_next (it);
b1d1124b 10512
5f5c8ee5
GM
10513 /* If we truncate lines, we are done when the last displayed
10514 glyphs reach past the right margin of the window. */
10515 if (it->truncate_lines_p
10516 && (FRAME_WINDOW_P (it->f)
10517 ? (it->current_x >= it->last_visible_x)
10518 : (it->current_x > it->last_visible_x)))
75d13c64 10519 {
5f5c8ee5
GM
10520 /* Maybe add truncation glyphs. */
10521 if (!FRAME_WINDOW_P (it->f))
10522 {
10523 --it->glyph_row->used[TEXT_AREA];
10524 produce_special_glyphs (it, IT_TRUNCATION);
10525 }
10526
10527 row->truncated_on_right_p = 1;
10528 it->continuation_lines_width = 0;
312246d1 10529 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
10530 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
10531 it->hpos = hpos_before;
10532 it->current_x = x_before;
10533 break;
75d13c64 10534 }
a2889657 10535 }
a2889657 10536
5f5c8ee5
GM
10537 /* If line is not empty and hscrolled, maybe insert truncation glyphs
10538 at the left window margin. */
10539 if (it->first_visible_x
10540 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
10541 {
10542 if (!FRAME_WINDOW_P (it->f))
10543 insert_left_trunc_glyphs (it);
10544 row->truncated_on_left_p = 1;
10545 }
a2889657 10546
5f5c8ee5
GM
10547 /* If the start of this line is the overlay arrow-position, then
10548 mark this glyph row as the one containing the overlay arrow.
10549 This is clearly a mess with variable size fonts. It would be
10550 better to let it be displayed like cursors under X. */
e24c997d 10551 if (MARKERP (Voverlay_arrow_position)
a2889657 10552 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
5f5c8ee5
GM
10553 && (MATRIX_ROW_START_CHARPOS (row)
10554 == marker_position (Voverlay_arrow_position))
e24c997d 10555 && STRINGP (Voverlay_arrow_string)
a2889657
JB
10556 && ! overlay_arrow_seen)
10557 {
5f5c8ee5
GM
10558 /* Overlay arrow in window redisplay is a bitmap. */
10559 if (!FRAME_WINDOW_P (it->f))
c4628384 10560 {
5f5c8ee5
GM
10561 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
10562 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
10563 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
10564 struct glyph *p = row->glyphs[TEXT_AREA];
10565 struct glyph *p2, *end;
10566
10567 /* Copy the arrow glyphs. */
10568 while (glyph < arrow_end)
10569 *p++ = *glyph++;
10570
10571 /* Throw away padding glyphs. */
10572 p2 = p;
10573 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
10574 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
10575 ++p2;
10576 if (p2 > p)
212e4f87 10577 {
5f5c8ee5
GM
10578 while (p2 < end)
10579 *p++ = *p2++;
10580 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
c4628384 10581 }
c4628384 10582 }
5f5c8ee5 10583
a2889657 10584 overlay_arrow_seen = 1;
5f5c8ee5 10585 row->overlay_arrow_p = 1;
a2889657
JB
10586 }
10587
5f5c8ee5
GM
10588 /* Compute pixel dimensions of this line. */
10589 compute_line_metrics (it);
10590
10591 /* Remember the position at which this line ends. */
10592 row->end = it->current;
10593
10594 /* Maybe set the cursor. If you change this, it's probably a good
10595 idea to also change the code in redisplay_window for cursor
10596 movement in an unchanged window. */
10597 if (it->w->cursor.vpos < 0
10598 && PT >= MATRIX_ROW_START_CHARPOS (row)
10599 && MATRIX_ROW_END_CHARPOS (row) >= PT
10600 && !(MATRIX_ROW_END_CHARPOS (row) == PT
10601 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
10602 || !row->ends_at_zv_p)))
10603 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
10604
10605 /* Highlight trailing whitespace. */
8f897821 10606 if (!NILP (Vshow_trailing_whitespace))
5f5c8ee5
GM
10607 highlight_trailing_whitespace (it->f, it->glyph_row);
10608
10609 /* Prepare for the next line. This line starts horizontally at (X
10610 HPOS) = (0 0). Vertical positions are incremented. As a
10611 convenience for the caller, IT->glyph_row is set to the next
10612 row to be used. */
10613 it->current_x = it->hpos = 0;
10614 it->current_y += row->height;
10615 ++it->vpos;
10616 ++it->glyph_row;
10617 return row->displays_text_p;
a2889657 10618}
5f5c8ee5
GM
10619
10620
a2889657 10621\f
5f5c8ee5
GM
10622/***********************************************************************
10623 Menu Bar
10624 ***********************************************************************/
10625
10626/* Redisplay the menu bar in the frame for window W.
10627
10628 The menu bar of X frames that don't have X toolkit support is
10629 displayed in a special window W->frame->menu_bar_window.
10630
10631 The menu bar of terminal frames is treated specially as far as
10632 glyph matrices are concerned. Menu bar lines are not part of
10633 windows, so the update is done directly on the frame matrix rows
10634 for the menu bar. */
7ce2c095
RS
10635
10636static void
10637display_menu_bar (w)
10638 struct window *w;
10639{
5f5c8ee5
GM
10640 struct frame *f = XFRAME (WINDOW_FRAME (w));
10641 struct it it;
10642 Lisp_Object items;
8351baf2 10643 int i;
7ce2c095 10644
5f5c8ee5 10645 /* Don't do all this for graphical frames. */
dc937613 10646#ifdef HAVE_NTGUI
d129c4c2
KH
10647 if (!NILP (Vwindow_system))
10648 return;
dc937613 10649#endif
dc937613 10650#ifdef USE_X_TOOLKIT
d3413a53 10651 if (FRAME_X_P (f))
7ce2c095 10652 return;
5f5c8ee5
GM
10653#endif
10654
10655#ifdef USE_X_TOOLKIT
10656 xassert (!FRAME_WINDOW_P (f));
10657 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
10658 it.first_visible_x = 0;
10659 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
10660#else /* not USE_X_TOOLKIT */
10661 if (FRAME_WINDOW_P (f))
10662 {
10663 /* Menu bar lines are displayed in the desired matrix of the
10664 dummy window menu_bar_window. */
10665 struct window *menu_w;
10666 xassert (WINDOWP (f->menu_bar_window));
10667 menu_w = XWINDOW (f->menu_bar_window);
10668 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
10669 MODE_LINE_FACE_ID);
10670 it.first_visible_x = 0;
10671 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
10672 }
10673 else
10674 {
10675 /* This is a TTY frame, i.e. character hpos/vpos are used as
10676 pixel x/y. */
10677 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
10678 MODE_LINE_FACE_ID);
10679 it.first_visible_x = 0;
10680 it.last_visible_x = FRAME_WIDTH (f);
10681 }
10682#endif /* not USE_X_TOOLKIT */
10683
10684 /* Clear all rows of the menu bar. */
10685 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
10686 {
10687 struct glyph_row *row = it.glyph_row + i;
10688 clear_glyph_row (row);
10689 row->enabled_p = 1;
10690 row->full_width_p = 1;
10691 }
7ce2c095 10692
5f5c8ee5
GM
10693 /* Make the first line of the menu bar appear in reverse video. */
10694 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
7ce2c095 10695
5f5c8ee5
GM
10696 /* Display all items of the menu bar. */
10697 items = FRAME_MENU_BAR_ITEMS (it.f);
469937ac 10698 for (i = 0; i < XVECTOR (items)->size; i += 4)
7ce2c095 10699 {
5f5c8ee5
GM
10700 Lisp_Object string;
10701
10702 /* Stop at nil string. */
8351baf2
RS
10703 string = XVECTOR (items)->contents[i + 1];
10704 if (NILP (string))
10705 break;
2d66ad19 10706
5f5c8ee5
GM
10707 /* Remember where item was displayed. */
10708 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
7ce2c095 10709
5f5c8ee5
GM
10710 /* Display the item, pad with one space. */
10711 if (it.current_x < it.last_visible_x)
10712 display_string (NULL, string, Qnil, 0, 0, &it,
10713 XSTRING (string)->size + 1, 0, 0, -1);
7ce2c095
RS
10714 }
10715
2d66ad19 10716 /* Fill out the line with spaces. */
5f5c8ee5
GM
10717 if (it.current_x < it.last_visible_x)
10718 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
db6f348c 10719
5f5c8ee5
GM
10720 /* Compute the total height of the lines. */
10721 compute_line_metrics (&it);
7ce2c095 10722}
5f5c8ee5
GM
10723
10724
7ce2c095 10725\f
5f5c8ee5
GM
10726/***********************************************************************
10727 Mode Line
10728 ***********************************************************************/
10729
10730/* Display the mode and/or top line of window W. */
a2889657
JB
10731
10732static void
5f5c8ee5 10733display_mode_lines (w)
a2889657
JB
10734 struct window *w;
10735{
5f5c8ee5 10736 /* These will be set while the mode line specs are processed. */
aa6d10fa 10737 line_number_displayed = 0;
155ef550 10738 w->column_number_displayed = Qnil;
aa6d10fa 10739
5f5c8ee5
GM
10740 if (WINDOW_WANTS_MODELINE_P (w))
10741 display_mode_line (w, MODE_LINE_FACE_ID, current_buffer->mode_line_format);
10742
10743 if (WINDOW_WANTS_TOP_LINE_P (w))
10744 display_mode_line (w, TOP_LINE_FACE_ID, current_buffer->top_line_format);
10745}
03b294dc 10746
03b294dc 10747
5f5c8ee5
GM
10748/* Display mode or top line of window W. FACE_ID specifies which line
10749 to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
10750 FORMAT is the mode line format to display. */
03b294dc 10751
5f5c8ee5
GM
10752static void
10753display_mode_line (w, face_id, format)
10754 struct window *w;
10755 enum face_id face_id;
10756 Lisp_Object format;
10757{
10758 struct it it;
10759 struct face *face;
03b294dc 10760
5f5c8ee5
GM
10761 init_iterator (&it, w, -1, -1, NULL, face_id);
10762 prepare_desired_row (it.glyph_row);
10763
10764 /* Temporarily make frame's keyboard the current kboard so that
10765 kboard-local variables in the mode_line_format will get the right
10766 values. */
10767 push_frame_kboard (it.f);
10768 display_mode_element (&it, 0, 0, 0, format);
10769 pop_frame_kboard ();
a2889657 10770
5f5c8ee5
GM
10771 /* Fill up with spaces. */
10772 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
10773
10774 compute_line_metrics (&it);
10775 it.glyph_row->full_width_p = 1;
10776 it.glyph_row->mode_line_p = 1;
10777 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
10778 it.glyph_row->continued_p = 0;
10779 it.glyph_row->truncated_on_left_p = 0;
10780 it.glyph_row->truncated_on_right_p = 0;
10781
10782 /* Make a 3D mode-line have a shadow at its right end. */
10783 face = FACE_FROM_ID (it.f, face_id);
10784 extend_face_to_end_of_line (&it);
10785 if (face->box != FACE_NO_BOX)
d7eb09a0 10786 {
5f5c8ee5
GM
10787 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
10788 + it.glyph_row->used[TEXT_AREA] - 1);
10789 last->right_box_line_p = 1;
d7eb09a0 10790 }
a2889657
JB
10791}
10792
a2889657 10793
5f5c8ee5
GM
10794/* Contribute ELT to the mode line for window IT->w. How it
10795 translates into text depends on its data type.
a2889657 10796
5f5c8ee5 10797 IT describes the display environment in which we display, as usual.
a2889657
JB
10798
10799 DEPTH is the depth in recursion. It is used to prevent
10800 infinite recursion here.
10801
5f5c8ee5
GM
10802 FIELD_WIDTH is the number of characters the display of ELT should
10803 occupy in the mode line, and PRECISION is the maximum number of
10804 characters to display from ELT's representation. See
10805 display_string for details. *
a2889657 10806
5f5c8ee5 10807 Returns the hpos of the end of the text generated by ELT. */
a2889657
JB
10808
10809static int
5f5c8ee5
GM
10810display_mode_element (it, depth, field_width, precision, elt)
10811 struct it *it;
a2889657 10812 int depth;
5f5c8ee5
GM
10813 int field_width, precision;
10814 Lisp_Object elt;
a2889657 10815{
5f5c8ee5
GM
10816 int n = 0, field, prec;
10817
a2889657
JB
10818 tail_recurse:
10819 if (depth > 10)
10820 goto invalid;
10821
10822 depth++;
10823
0220c518 10824 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
a2889657
JB
10825 {
10826 case Lisp_String:
10827 {
10828 /* A string: output it and check for %-constructs within it. */
5f5c8ee5
GM
10829 unsigned char c;
10830 unsigned char *this = XSTRING (elt)->data;
10831 unsigned char *lisp_string = this;
10832
10833 while ((precision <= 0 || n < precision)
10834 && *this
10835 && (frame_title_ptr
10836 || it->current_x < it->last_visible_x))
a2889657
JB
10837 {
10838 unsigned char *last = this;
5f5c8ee5
GM
10839
10840 /* Advance to end of string or next format specifier. */
a2889657
JB
10841 while ((c = *this++) != '\0' && c != '%')
10842 ;
5f5c8ee5 10843
a2889657
JB
10844 if (this - 1 != last)
10845 {
5f5c8ee5
GM
10846 /* Output to end of string or up to '%'. Field width
10847 is length of string. Don't output more than
10848 PRECISION allows us. */
10849 prec = --this - last;
10850 if (precision > 0 && prec > precision - n)
10851 prec = precision - n;
10852
d39b6696 10853 if (frame_title_ptr)
5f5c8ee5 10854 n += store_frame_title (last, prec, prec);
d39b6696 10855 else
5f5c8ee5
GM
10856 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
10857 it, 0, prec, 0, -1);
a2889657
JB
10858 }
10859 else /* c == '%' */
10860 {
5f5c8ee5
GM
10861 unsigned char *percent_position = this;
10862
10863 /* Get the specified minimum width. Zero means
10864 don't pad. */
10865 field = 0;
a2889657 10866 while ((c = *this++) >= '0' && c <= '9')
5f5c8ee5 10867 field = field * 10 + c - '0';
a2889657 10868
5f5c8ee5
GM
10869 /* Don't pad beyond the total padding allowed. */
10870 if (field_width - n > 0 && field > field_width - n)
10871 field = field_width - n;
a2889657 10872
5f5c8ee5
GM
10873 /* Note that either PRECISION <= 0 or N < PRECISION. */
10874 prec = precision - n;
10875
a2889657 10876 if (c == 'M')
5f5c8ee5
GM
10877 n += display_mode_element (it, depth, field, prec,
10878 Vglobal_mode_string);
a2889657 10879 else if (c != 0)
d39b6696 10880 {
5f5c8ee5
GM
10881 unsigned char *spec
10882 = decode_mode_spec (it->w, c, field, prec);
10883
d39b6696 10884 if (frame_title_ptr)
5f5c8ee5 10885 n += store_frame_title (spec, field, prec);
d39b6696 10886 else
5f5c8ee5
GM
10887 {
10888 int nglyphs_before
10889 = it->glyph_row->used[TEXT_AREA];
10890 int charpos
10891 = percent_position - XSTRING (elt)->data;
10892 int nwritten
10893 = display_string (spec, Qnil, elt, charpos, 0, it,
10894 field, prec, 0, -1);
10895
10896 /* Assign to the glyphs written above the
10897 string where the `%x' came from, position
10898 of the `%'. */
10899 if (nwritten > 0)
10900 {
10901 struct glyph *glyph
10902 = (it->glyph_row->glyphs[TEXT_AREA]
10903 + nglyphs_before);
10904 int i;
10905
10906 for (i = 0; i < nwritten; ++i)
10907 {
10908 glyph[i].object = elt;
10909 glyph[i].charpos = charpos;
10910 }
10911
10912 n += nwritten;
10913 }
10914 }
d39b6696 10915 }
a2889657
JB
10916 }
10917 }
10918 }
10919 break;
10920
10921 case Lisp_Symbol:
10922 /* A symbol: process the value of the symbol recursively
10923 as if it appeared here directly. Avoid error if symbol void.
10924 Special case: if value of symbol is a string, output the string
10925 literally. */
10926 {
10927 register Lisp_Object tem;
10928 tem = Fboundp (elt);
265a9e55 10929 if (!NILP (tem))
a2889657
JB
10930 {
10931 tem = Fsymbol_value (elt);
10932 /* If value is a string, output that string literally:
10933 don't check for % within it. */
e24c997d 10934 if (STRINGP (tem))
d39b6696 10935 {
5f5c8ee5
GM
10936 prec = XSTRING (tem)->size;
10937 if (precision > 0 && prec > precision - n)
10938 prec = precision - n;
d39b6696 10939 if (frame_title_ptr)
5f5c8ee5 10940 n += store_frame_title (XSTRING (tem)->data, -1, prec);
d39b6696 10941 else
5f5c8ee5
GM
10942 n += display_string (NULL, tem, Qnil, 0, 0, it,
10943 0, prec, 0, -1);
d39b6696 10944 }
a2889657 10945 else if (!EQ (tem, elt))
5f5c8ee5
GM
10946 {
10947 /* Give up right away for nil or t. */
10948 elt = tem;
10949 goto tail_recurse;
10950 }
a2889657
JB
10951 }
10952 }
10953 break;
10954
10955 case Lisp_Cons:
10956 {
10957 register Lisp_Object car, tem;
10958
10959 /* A cons cell: three distinct cases.
10960 If first element is a string or a cons, process all the elements
10961 and effectively concatenate them.
10962 If first element is a negative number, truncate displaying cdr to
10963 at most that many characters. If positive, pad (with spaces)
10964 to at least that many characters.
10965 If first element is a symbol, process the cadr or caddr recursively
10966 according to whether the symbol's value is non-nil or nil. */
10967 car = XCONS (elt)->car;
5f5c8ee5
GM
10968 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
10969 {
10970 /* An element of the form (:eval FORM) means evaluate FORM
10971 and use the result as mode line elements. */
10972 struct gcpro gcpro1;
10973 Lisp_Object spec;
10974
10975 spec = eval_form (XCAR (XCDR (elt)));
10976 GCPRO1 (spec);
10977 n += display_mode_element (it, depth, field_width - n,
10978 precision - n, spec);
10979 UNGCPRO;
10980 }
10981 else if (SYMBOLP (car))
a2889657
JB
10982 {
10983 tem = Fboundp (car);
10984 elt = XCONS (elt)->cdr;
e24c997d 10985 if (!CONSP (elt))
a2889657
JB
10986 goto invalid;
10987 /* elt is now the cdr, and we know it is a cons cell.
10988 Use its car if CAR has a non-nil value. */
265a9e55 10989 if (!NILP (tem))
a2889657
JB
10990 {
10991 tem = Fsymbol_value (car);
265a9e55 10992 if (!NILP (tem))
a2889657
JB
10993 { elt = XCONS (elt)->car; goto tail_recurse; }
10994 }
10995 /* Symbol's value is nil (or symbol is unbound)
10996 Get the cddr of the original list
10997 and if possible find the caddr and use that. */
10998 elt = XCONS (elt)->cdr;
265a9e55 10999 if (NILP (elt))
a2889657 11000 break;
e24c997d 11001 else if (!CONSP (elt))
a2889657
JB
11002 goto invalid;
11003 elt = XCONS (elt)->car;
11004 goto tail_recurse;
11005 }
e24c997d 11006 else if (INTEGERP (car))
a2889657
JB
11007 {
11008 register int lim = XINT (car);
11009 elt = XCONS (elt)->cdr;
11010 if (lim < 0)
5f5c8ee5
GM
11011 {
11012 /* Negative int means reduce maximum width. */
11013 if (precision <= 0)
11014 precision = -lim;
11015 else
11016 precision = min (precision, -lim);
11017 }
a2889657
JB
11018 else if (lim > 0)
11019 {
11020 /* Padding specified. Don't let it be more than
11021 current maximum. */
5f5c8ee5
GM
11022 if (precision > 0)
11023 lim = min (precision, lim);
11024
a2889657
JB
11025 /* If that's more padding than already wanted, queue it.
11026 But don't reduce padding already specified even if
11027 that is beyond the current truncation point. */
5f5c8ee5 11028 field_width = max (lim, field_width);
a2889657
JB
11029 }
11030 goto tail_recurse;
11031 }
e24c997d 11032 else if (STRINGP (car) || CONSP (car))
a2889657
JB
11033 {
11034 register int limit = 50;
5f5c8ee5
GM
11035 /* Limit is to protect against circular lists. */
11036 while (CONSP (elt)
11037 && --limit > 0
11038 && (precision <= 0 || n < precision))
a2889657 11039 {
5f5c8ee5
GM
11040 n += display_mode_element (it, depth, field_width - n,
11041 precision - n, XCONS (elt)->car);
a2889657
JB
11042 elt = XCONS (elt)->cdr;
11043 }
11044 }
11045 }
11046 break;
11047
11048 default:
11049 invalid:
d39b6696 11050 if (frame_title_ptr)
5f5c8ee5 11051 n += store_frame_title ("*invalid*", 0, precision - n);
d39b6696 11052 else
5f5c8ee5
GM
11053 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
11054 precision - n, 0, 0);
11055 return n;
a2889657
JB
11056 }
11057
5f5c8ee5
GM
11058 /* Pad to FIELD_WIDTH. */
11059 if (field_width > 0 && n < field_width)
11060 {
11061 if (frame_title_ptr)
11062 n += store_frame_title ("", field_width - n, 0);
11063 else
11064 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
11065 0, 0, 0);
11066 }
11067
11068 return n;
a2889657 11069}
5f5c8ee5
GM
11070
11071
766525bc
RS
11072/* Write a null-terminated, right justified decimal representation of
11073 the positive integer D to BUF using a minimal field width WIDTH. */
11074
11075static void
11076pint2str (buf, width, d)
11077 register char *buf;
11078 register int width;
11079 register int d;
11080{
11081 register char *p = buf;
11082
11083 if (d <= 0)
5f5c8ee5 11084 *p++ = '0';
766525bc 11085 else
5f5c8ee5 11086 {
766525bc 11087 while (d > 0)
5f5c8ee5 11088 {
766525bc
RS
11089 *p++ = d % 10 + '0';
11090 d /= 10;
5f5c8ee5
GM
11091 }
11092 }
11093
11094 for (width -= (int) (p - buf); width > 0; --width)
11095 *p++ = ' ';
766525bc
RS
11096 *p-- = '\0';
11097 while (p > buf)
5f5c8ee5 11098 {
766525bc
RS
11099 d = *buf;
11100 *buf++ = *p;
11101 *p-- = d;
5f5c8ee5 11102 }
766525bc
RS
11103}
11104
5f5c8ee5 11105/* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
1c9241f5
KH
11106 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
11107 type of CODING_SYSTEM. Return updated pointer into BUF. */
11108
6693a99a 11109static unsigned char invalid_eol_type[] = "(*invalid*)";
d24715e8 11110
1c9241f5
KH
11111static char *
11112decode_mode_spec_coding (coding_system, buf, eol_flag)
11113 Lisp_Object coding_system;
11114 register char *buf;
11115 int eol_flag;
11116{
1e1078d6 11117 Lisp_Object val;
916848d8 11118 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
302f2b38
EZ
11119 unsigned char *eol_str;
11120 int eol_str_len;
11121 /* The EOL conversion we are using. */
11122 Lisp_Object eoltype;
1e1078d6
RS
11123
11124 val = coding_system;
1c9241f5
KH
11125
11126 if (NILP (val)) /* Not yet decided. */
11127 {
916848d8
RS
11128 if (multibyte)
11129 *buf++ = '-';
21e989e3 11130 if (eol_flag)
302f2b38 11131 eoltype = eol_mnemonic_undecided;
1e1078d6 11132 /* Don't mention EOL conversion if it isn't decided. */
1c9241f5
KH
11133 }
11134 else
11135 {
1e1078d6
RS
11136 Lisp_Object eolvalue;
11137
11138 eolvalue = Fget (coding_system, Qeol_type);
11139
1c9241f5 11140 while (!NILP (val) && SYMBOLP (val))
1e1078d6
RS
11141 {
11142 val = Fget (val, Qcoding_system);
11143 if (NILP (eolvalue))
b070c1d7 11144 eolvalue = Fget (val, Qeol_type);
1e1078d6
RS
11145 }
11146
916848d8
RS
11147 if (multibyte)
11148 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
11149
1c9241f5
KH
11150 if (eol_flag)
11151 {
1e1078d6
RS
11152 /* The EOL conversion that is normal on this system. */
11153
11154 if (NILP (eolvalue)) /* Not yet decided. */
11155 eoltype = eol_mnemonic_undecided;
11156 else if (VECTORP (eolvalue)) /* Not yet decided. */
11157 eoltype = eol_mnemonic_undecided;
11158 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
11159 eoltype = (XFASTINT (eolvalue) == 0
11160 ? eol_mnemonic_unix
11161 : (XFASTINT (eolvalue) == 1
11162 ? eol_mnemonic_dos : eol_mnemonic_mac));
302f2b38
EZ
11163 }
11164 }
5f5c8ee5 11165
302f2b38
EZ
11166 if (eol_flag)
11167 {
11168 /* Mention the EOL conversion if it is not the usual one. */
11169 if (STRINGP (eoltype))
11170 {
11171 eol_str = XSTRING (eoltype)->data;
11172 eol_str_len = XSTRING (eoltype)->size;
11173 }
f30b3499
KH
11174 else if (INTEGERP (eoltype)
11175 && CHAR_VALID_P (XINT (eoltype), 0))
11176 {
11177 int c = XINT (eoltype);
11178 unsigned char work[4];
11179
11180 eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
11181 }
302f2b38
EZ
11182 else
11183 {
11184 eol_str = invalid_eol_type;
11185 eol_str_len = sizeof (invalid_eol_type) - 1;
1c9241f5 11186 }
f30b3499 11187 bcopy (eol_str, buf, eol_str_len);
302f2b38 11188 buf += eol_str_len;
1c9241f5 11189 }
302f2b38 11190
1c9241f5
KH
11191 return buf;
11192}
11193
a2889657 11194/* Return a string for the output of a mode line %-spec for window W,
5f5c8ee5
GM
11195 generated by character C. PRECISION >= 0 means don't return a
11196 string longer than that value. FIELD_WIDTH > 0 means pad the
11197 string returned with spaces to that value. */
a2889657 11198
11e82b76
JB
11199static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
11200
a2889657 11201static char *
5f5c8ee5 11202decode_mode_spec (w, c, field_width, precision)
a2889657
JB
11203 struct window *w;
11204 register char c;
5f5c8ee5 11205 int field_width, precision;
a2889657 11206{
0b67772d 11207 Lisp_Object obj;
5f5c8ee5
GM
11208 struct frame *f = XFRAME (WINDOW_FRAME (w));
11209 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
d39b6696 11210 struct buffer *b = XBUFFER (w->buffer);
a2889657 11211
0b67772d 11212 obj = Qnil;
a2889657
JB
11213
11214 switch (c)
11215 {
1af9f229
RS
11216 case '*':
11217 if (!NILP (b->read_only))
11218 return "%";
11219 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11220 return "*";
11221 return "-";
11222
11223 case '+':
11224 /* This differs from %* only for a modified read-only buffer. */
11225 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11226 return "*";
11227 if (!NILP (b->read_only))
11228 return "%";
11229 return "-";
11230
11231 case '&':
11232 /* This differs from %* in ignoring read-only-ness. */
11233 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11234 return "*";
11235 return "-";
11236
11237 case '%':
11238 return "%";
11239
11240 case '[':
11241 {
11242 int i;
11243 char *p;
11244
11245 if (command_loop_level > 5)
11246 return "[[[... ";
11247 p = decode_mode_spec_buf;
11248 for (i = 0; i < command_loop_level; i++)
11249 *p++ = '[';
11250 *p = 0;
11251 return decode_mode_spec_buf;
11252 }
11253
11254 case ']':
11255 {
11256 int i;
11257 char *p;
11258
11259 if (command_loop_level > 5)
11260 return " ...]]]";
11261 p = decode_mode_spec_buf;
11262 for (i = 0; i < command_loop_level; i++)
11263 *p++ = ']';
11264 *p = 0;
11265 return decode_mode_spec_buf;
11266 }
11267
11268 case '-':
11269 {
1af9f229 11270 register int i;
5f5c8ee5
GM
11271
11272 /* Let lots_of_dashes be a string of infinite length. */
11273 if (field_width <= 0
11274 || field_width > sizeof (lots_of_dashes))
1af9f229 11275 {
5f5c8ee5
GM
11276 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
11277 decode_mode_spec_buf[i] = '-';
11278 decode_mode_spec_buf[i] = '\0';
11279 return decode_mode_spec_buf;
1af9f229 11280 }
5f5c8ee5
GM
11281 else
11282 return lots_of_dashes;
1af9f229
RS
11283 }
11284
a2889657 11285 case 'b':
d39b6696 11286 obj = b->name;
a2889657
JB
11287 break;
11288
1af9f229
RS
11289 case 'c':
11290 {
11291 int col = current_column ();
11292 XSETFASTINT (w->column_number_displayed, col);
5f5c8ee5 11293 pint2str (decode_mode_spec_buf, field_width, col);
1af9f229
RS
11294 return decode_mode_spec_buf;
11295 }
11296
11297 case 'F':
11298 /* %F displays the frame name. */
5f5c8ee5 11299 if (!NILP (f->title))
95184b48 11300 return (char *) XSTRING (f->title)->data;
fd8ff63d 11301 if (f->explicit_name || ! FRAME_WINDOW_P (f))
95184b48 11302 return (char *) XSTRING (f->name)->data;
9c6da96f 11303 return "Emacs";
1af9f229 11304
a2889657 11305 case 'f':
d39b6696 11306 obj = b->filename;
a2889657
JB
11307 break;
11308
aa6d10fa
RS
11309 case 'l':
11310 {
12adba34
RS
11311 int startpos = XMARKER (w->start)->charpos;
11312 int startpos_byte = marker_byte_position (w->start);
11313 int line, linepos, linepos_byte, topline;
aa6d10fa 11314 int nlines, junk;
aa6d10fa
RS
11315 int height = XFASTINT (w->height);
11316
11317 /* If we decided that this buffer isn't suitable for line numbers,
11318 don't forget that too fast. */
11319 if (EQ (w->base_line_pos, w->buffer))
766525bc 11320 goto no_value;
5300fd39
RS
11321 /* But do forget it, if the window shows a different buffer now. */
11322 else if (BUFFERP (w->base_line_pos))
11323 w->base_line_pos = Qnil;
aa6d10fa
RS
11324
11325 /* If the buffer is very big, don't waste time. */
d39b6696 11326 if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit)
aa6d10fa
RS
11327 {
11328 w->base_line_pos = Qnil;
11329 w->base_line_number = Qnil;
766525bc 11330 goto no_value;
aa6d10fa
RS
11331 }
11332
11333 if (!NILP (w->base_line_number)
11334 && !NILP (w->base_line_pos)
12adba34 11335 && XFASTINT (w->base_line_pos) <= startpos)
aa6d10fa
RS
11336 {
11337 line = XFASTINT (w->base_line_number);
11338 linepos = XFASTINT (w->base_line_pos);
12adba34 11339 linepos_byte = buf_charpos_to_bytepos (b, linepos);
aa6d10fa
RS
11340 }
11341 else
11342 {
11343 line = 1;
d39b6696 11344 linepos = BUF_BEGV (b);
12adba34 11345 linepos_byte = BUF_BEGV_BYTE (b);
aa6d10fa
RS
11346 }
11347
11348 /* Count lines from base line to window start position. */
12adba34
RS
11349 nlines = display_count_lines (linepos, linepos_byte,
11350 startpos_byte,
11351 startpos, &junk);
aa6d10fa
RS
11352
11353 topline = nlines + line;
11354
11355 /* Determine a new base line, if the old one is too close
11356 or too far away, or if we did not have one.
11357 "Too close" means it's plausible a scroll-down would
11358 go back past it. */
d39b6696 11359 if (startpos == BUF_BEGV (b))
aa6d10fa 11360 {
c2213350
KH
11361 XSETFASTINT (w->base_line_number, topline);
11362 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
aa6d10fa
RS
11363 }
11364 else if (nlines < height + 25 || nlines > height * 3 + 50
d39b6696 11365 || linepos == BUF_BEGV (b))
aa6d10fa 11366 {
d39b6696 11367 int limit = BUF_BEGV (b);
12adba34 11368 int limit_byte = BUF_BEGV_BYTE (b);
aa6d10fa 11369 int position;
5d121aec 11370 int distance = (height * 2 + 30) * line_number_display_limit_width;
aa6d10fa
RS
11371
11372 if (startpos - distance > limit)
12adba34
RS
11373 {
11374 limit = startpos - distance;
11375 limit_byte = CHAR_TO_BYTE (limit);
11376 }
aa6d10fa 11377
12adba34
RS
11378 nlines = display_count_lines (startpos, startpos_byte,
11379 limit_byte,
11380 - (height * 2 + 30),
aa6d10fa
RS
11381 &position);
11382 /* If we couldn't find the lines we wanted within
5d121aec 11383 line_number_display_limit_width chars per line,
aa6d10fa 11384 give up on line numbers for this window. */
12adba34 11385 if (position == limit_byte && limit == startpos - distance)
aa6d10fa
RS
11386 {
11387 w->base_line_pos = w->buffer;
11388 w->base_line_number = Qnil;
766525bc 11389 goto no_value;
aa6d10fa
RS
11390 }
11391
c2213350 11392 XSETFASTINT (w->base_line_number, topline - nlines);
12adba34 11393 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
aa6d10fa
RS
11394 }
11395
11396 /* Now count lines from the start pos to point. */
12adba34
RS
11397 nlines = display_count_lines (startpos, startpos_byte,
11398 PT_BYTE, PT, &junk);
aa6d10fa
RS
11399
11400 /* Record that we did display the line number. */
11401 line_number_displayed = 1;
11402
11403 /* Make the string to show. */
5f5c8ee5 11404 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
aa6d10fa 11405 return decode_mode_spec_buf;
766525bc
RS
11406 no_value:
11407 {
11408 char* p = decode_mode_spec_buf;
5f5c8ee5
GM
11409 int pad = field_width - 2;
11410 while (pad-- > 0)
11411 *p++ = ' ';
11412 *p++ = '?';
11413 *p = '?';
766525bc
RS
11414 return decode_mode_spec_buf;
11415 }
aa6d10fa
RS
11416 }
11417 break;
11418
a2889657 11419 case 'm':
d39b6696 11420 obj = b->mode_name;
a2889657
JB
11421 break;
11422
11423 case 'n':
d39b6696 11424 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
a2889657
JB
11425 return " Narrow";
11426 break;
11427
a2889657
JB
11428 case 'p':
11429 {
11430 int pos = marker_position (w->start);
d39b6696 11431 int total = BUF_ZV (b) - BUF_BEGV (b);
a2889657 11432
d39b6696 11433 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
a2889657 11434 {
d39b6696 11435 if (pos <= BUF_BEGV (b))
a2889657
JB
11436 return "All";
11437 else
11438 return "Bottom";
11439 }
d39b6696 11440 else if (pos <= BUF_BEGV (b))
a2889657
JB
11441 return "Top";
11442 else
11443 {
3c7d31b9
RS
11444 if (total > 1000000)
11445 /* Do it differently for a large value, to avoid overflow. */
11446 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11447 else
11448 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
a2889657
JB
11449 /* We can't normally display a 3-digit number,
11450 so get us a 2-digit number that is close. */
11451 if (total == 100)
11452 total = 99;
11453 sprintf (decode_mode_spec_buf, "%2d%%", total);
11454 return decode_mode_spec_buf;
11455 }
11456 }
11457
8ffcb79f
RS
11458 /* Display percentage of size above the bottom of the screen. */
11459 case 'P':
11460 {
11461 int toppos = marker_position (w->start);
d39b6696
KH
11462 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
11463 int total = BUF_ZV (b) - BUF_BEGV (b);
8ffcb79f 11464
d39b6696 11465 if (botpos >= BUF_ZV (b))
8ffcb79f 11466 {
d39b6696 11467 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11468 return "All";
11469 else
11470 return "Bottom";
11471 }
11472 else
11473 {
3c7d31b9
RS
11474 if (total > 1000000)
11475 /* Do it differently for a large value, to avoid overflow. */
11476 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11477 else
11478 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
8ffcb79f
RS
11479 /* We can't normally display a 3-digit number,
11480 so get us a 2-digit number that is close. */
11481 if (total == 100)
11482 total = 99;
d39b6696 11483 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11484 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
11485 else
11486 sprintf (decode_mode_spec_buf, "%2d%%", total);
11487 return decode_mode_spec_buf;
11488 }
11489 }
11490
1af9f229
RS
11491 case 's':
11492 /* status of process */
11493 obj = Fget_buffer_process (w->buffer);
11494 if (NILP (obj))
11495 return "no process";
11496#ifdef subprocesses
11497 obj = Fsymbol_name (Fprocess_status (obj));
11498#endif
11499 break;
d39b6696 11500
1af9f229
RS
11501 case 't': /* indicate TEXT or BINARY */
11502#ifdef MODE_LINE_BINARY_TEXT
11503 return MODE_LINE_BINARY_TEXT (b);
11504#else
11505 return "T";
11506#endif
1c9241f5
KH
11507
11508 case 'z':
11509 /* coding-system (not including end-of-line format) */
11510 case 'Z':
11511 /* coding-system (including end-of-line type) */
11512 {
11513 int eol_flag = (c == 'Z');
539b4d41 11514 char *p = decode_mode_spec_buf;
1c9241f5 11515
d30e754b 11516 if (! FRAME_WINDOW_P (f))
1c9241f5 11517 {
11c52c4f
RS
11518 /* No need to mention EOL here--the terminal never needs
11519 to do EOL conversion. */
11520 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
11521 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
1c9241f5 11522 }
f13c925f 11523 p = decode_mode_spec_coding (b->buffer_file_coding_system,
539b4d41 11524 p, eol_flag);
f13c925f 11525
11c52c4f 11526#if 0 /* This proves to be annoying; I think we can do without. -- rms. */
1c9241f5
KH
11527#ifdef subprocesses
11528 obj = Fget_buffer_process (Fcurrent_buffer ());
11529 if (PROCESSP (obj))
11530 {
11531 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
11532 p, eol_flag);
11533 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
11534 p, eol_flag);
11535 }
11536#endif /* subprocesses */
11c52c4f 11537#endif /* 0 */
1c9241f5
KH
11538 *p = 0;
11539 return decode_mode_spec_buf;
11540 }
a2889657 11541 }
d39b6696 11542
e24c997d 11543 if (STRINGP (obj))
a2889657
JB
11544 return (char *) XSTRING (obj)->data;
11545 else
11546 return "";
11547}
5f5c8ee5
GM
11548
11549
12adba34
RS
11550/* Count up to COUNT lines starting from START / START_BYTE.
11551 But don't go beyond LIMIT_BYTE.
11552 Return the number of lines thus found (always nonnegative).
59b49f63 11553
12adba34 11554 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
59b49f63
RS
11555
11556static int
12adba34
RS
11557display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
11558 int start, start_byte, limit_byte, count;
11559 int *byte_pos_ptr;
59b49f63 11560{
59b49f63
RS
11561 register unsigned char *cursor;
11562 unsigned char *base;
11563
11564 register int ceiling;
11565 register unsigned char *ceiling_addr;
12adba34 11566 int orig_count = count;
59b49f63
RS
11567
11568 /* If we are not in selective display mode,
11569 check only for newlines. */
12adba34
RS
11570 int selective_display = (!NILP (current_buffer->selective_display)
11571 && !INTEGERP (current_buffer->selective_display));
59b49f63
RS
11572
11573 if (count > 0)
12adba34
RS
11574 {
11575 while (start_byte < limit_byte)
11576 {
11577 ceiling = BUFFER_CEILING_OF (start_byte);
11578 ceiling = min (limit_byte - 1, ceiling);
11579 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
11580 base = (cursor = BYTE_POS_ADDR (start_byte));
11581 while (1)
11582 {
11583 if (selective_display)
11584 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
11585 ;
11586 else
11587 while (*cursor != '\n' && ++cursor != ceiling_addr)
11588 ;
11589
11590 if (cursor != ceiling_addr)
11591 {
11592 if (--count == 0)
11593 {
11594 start_byte += cursor - base + 1;
11595 *byte_pos_ptr = start_byte;
11596 return orig_count;
11597 }
11598 else
11599 if (++cursor == ceiling_addr)
11600 break;
11601 }
11602 else
11603 break;
11604 }
11605 start_byte += cursor - base;
11606 }
11607 }
59b49f63
RS
11608 else
11609 {
12adba34
RS
11610 while (start_byte > limit_byte)
11611 {
11612 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
11613 ceiling = max (limit_byte, ceiling);
11614 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
11615 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
59b49f63
RS
11616 while (1)
11617 {
12adba34
RS
11618 if (selective_display)
11619 while (--cursor != ceiling_addr
11620 && *cursor != '\n' && *cursor != 015)
11621 ;
11622 else
11623 while (--cursor != ceiling_addr && *cursor != '\n')
11624 ;
11625
59b49f63
RS
11626 if (cursor != ceiling_addr)
11627 {
11628 if (++count == 0)
11629 {
12adba34
RS
11630 start_byte += cursor - base + 1;
11631 *byte_pos_ptr = start_byte;
11632 /* When scanning backwards, we should
11633 not count the newline posterior to which we stop. */
11634 return - orig_count - 1;
59b49f63
RS
11635 }
11636 }
11637 else
11638 break;
11639 }
12adba34
RS
11640 /* Here we add 1 to compensate for the last decrement
11641 of CURSOR, which took it past the valid range. */
11642 start_byte += cursor - base + 1;
59b49f63
RS
11643 }
11644 }
11645
12adba34 11646 *byte_pos_ptr = limit_byte;
aa6d10fa 11647
12adba34
RS
11648 if (count < 0)
11649 return - orig_count + count;
11650 return orig_count - count;
aa6d10fa 11651
12adba34 11652}
a2889657 11653
a2889657 11654
5f5c8ee5
GM
11655\f
11656/***********************************************************************
11657 Displaying strings
11658 ***********************************************************************/
278feba9 11659
5f5c8ee5 11660/* Display a NUL-terminated string, starting with index START.
a3788d53 11661
5f5c8ee5
GM
11662 If STRING is non-null, display that C string. Otherwise, the Lisp
11663 string LISP_STRING is displayed.
a2889657 11664
5f5c8ee5
GM
11665 If FACE_STRING is not nil, FACE_STRING_POS is a position in
11666 FACE_STRING. Display STRING or LISP_STRING with the face at
11667 FACE_STRING_POS in FACE_STRING:
a2889657 11668
5f5c8ee5
GM
11669 Display the string in the environment given by IT, but use the
11670 standard display table, temporarily.
a3788d53 11671
5f5c8ee5
GM
11672 FIELD_WIDTH is the minimum number of output glyphs to produce.
11673 If STRING has fewer characters than FIELD_WIDTH, pad to the right
11674 with spaces. If STRING has more characters, more than FIELD_WIDTH
11675 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
11676
11677 PRECISION is the maximum number of characters to output from
11678 STRING. PRECISION < 0 means don't truncate the string.
a2889657 11679
5f5c8ee5 11680 This is roughly equivalent to printf format specifiers:
a2889657 11681
5f5c8ee5
GM
11682 FIELD_WIDTH PRECISION PRINTF
11683 ----------------------------------------
11684 -1 -1 %s
11685 -1 10 %.10s
11686 10 -1 %10s
11687 20 10 %20.10s
a2889657 11688
5f5c8ee5
GM
11689 MULTIBYTE zero means do not display multibyte chars, > 0 means do
11690 display them, and < 0 means obey the current buffer's value of
11691 enable_multibyte_characters.
278feba9 11692
5f5c8ee5 11693 Value is the number of glyphs produced. */
b1d1124b 11694
5f5c8ee5
GM
11695static int
11696display_string (string, lisp_string, face_string, face_string_pos,
11697 start, it, field_width, precision, max_x, multibyte)
11698 unsigned char *string;
11699 Lisp_Object lisp_string;
11700 int start;
11701 struct it *it;
11702 int field_width, precision, max_x;
11703 int multibyte;
11704{
11705 int hpos_at_start = it->hpos;
11706 int saved_face_id = it->face_id;
11707 struct glyph_row *row = it->glyph_row;
11708
11709 /* Initialize the iterator IT for iteration over STRING beginning
11710 with index START. We assume that IT may be modified here (which
11711 means that display_line has to do something when displaying a
11712 mini-buffer prompt, which it does). */
11713 reseat_to_string (it, string, lisp_string, start,
11714 precision, field_width, multibyte);
11715
11716 /* If displaying STRING, set up the face of the iterator
11717 from LISP_STRING, if that's given. */
11718 if (STRINGP (face_string))
11719 {
11720 int endptr;
11721 struct face *face;
11722
11723 it->face_id
11724 = face_at_string_position (it->w, face_string, face_string_pos,
11725 0, it->region_beg_charpos,
11726 it->region_end_charpos,
11727 &endptr, it->base_face_id);
11728 face = FACE_FROM_ID (it->f, it->face_id);
11729 it->face_box_p = face->box != FACE_NO_BOX;
b1d1124b 11730 }
a2889657 11731
5f5c8ee5
GM
11732 /* Set max_x to the maximum allowed X position. Don't let it go
11733 beyond the right edge of the window. */
11734 if (max_x <= 0)
11735 max_x = it->last_visible_x;
11736 else
11737 max_x = min (max_x, it->last_visible_x);
efc63ef0 11738
5f5c8ee5
GM
11739 /* Skip over display elements that are not visible. because IT->w is
11740 hscrolled. */
11741 if (it->current_x < it->first_visible_x)
11742 move_it_in_display_line_to (it, 100000, it->first_visible_x,
11743 MOVE_TO_POS | MOVE_TO_X);
a2889657 11744
5f5c8ee5
GM
11745 row->ascent = it->max_ascent;
11746 row->height = it->max_ascent + it->max_descent;
312246d1
GM
11747 row->phys_ascent = it->max_phys_ascent;
11748 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
1c9241f5 11749
5f5c8ee5
GM
11750 /* This condition is for the case that we are called with current_x
11751 past last_visible_x. */
11752 while (it->current_x < max_x)
a2889657 11753 {
5f5c8ee5 11754 int x_before, x, n_glyphs_before, i, nglyphs;
1c9241f5 11755
5f5c8ee5
GM
11756 /* Get the next display element. */
11757 if (!get_next_display_element (it))
90adcf20 11758 break;
1c9241f5 11759
5f5c8ee5
GM
11760 /* Produce glyphs. */
11761 x_before = it->current_x;
11762 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
11763 PRODUCE_GLYPHS (it);
90adcf20 11764
5f5c8ee5
GM
11765 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
11766 i = 0;
11767 x = x_before;
11768 while (i < nglyphs)
a2889657 11769 {
5f5c8ee5
GM
11770 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11771
11772 if (!it->truncate_lines_p
11773 && x + glyph->pixel_width > max_x)
11774 {
11775 /* End of continued line or max_x reached. */
11776 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
11777 it->current_x = x;
11778 break;
11779 }
11780 else if (x + glyph->pixel_width > it->first_visible_x)
11781 {
11782 /* Glyph is at least partially visible. */
11783 ++it->hpos;
11784 if (x < it->first_visible_x)
11785 it->glyph_row->x = x - it->first_visible_x;
11786 }
11787 else
a2889657 11788 {
5f5c8ee5
GM
11789 /* Glyph is off the left margin of the display area.
11790 Should not happen. */
11791 abort ();
a2889657 11792 }
5f5c8ee5
GM
11793
11794 row->ascent = max (row->ascent, it->max_ascent);
11795 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
11796 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11797 row->phys_height = max (row->phys_height,
11798 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
11799 x += glyph->pixel_width;
11800 ++i;
a2889657 11801 }
5f5c8ee5
GM
11802
11803 /* Stop if max_x reached. */
11804 if (i < nglyphs)
11805 break;
11806
11807 /* Stop at line ends. */
11808 if (ITERATOR_AT_END_OF_LINE_P (it))
a2889657 11809 {
5f5c8ee5
GM
11810 it->continuation_lines_width = 0;
11811 break;
a2889657 11812 }
1c9241f5 11813
5f5c8ee5 11814 set_iterator_to_next (it);
a688bb24 11815
5f5c8ee5
GM
11816 /* Stop if truncating at the right edge. */
11817 if (it->truncate_lines_p
11818 && it->current_x >= it->last_visible_x)
11819 {
11820 /* Add truncation mark, but don't do it if the line is
11821 truncated at a padding space. */
11822 if (IT_CHARPOS (*it) < it->string_nchars)
1c9241f5 11823 {
5f5c8ee5
GM
11824 if (!FRAME_WINDOW_P (it->f))
11825 produce_special_glyphs (it, IT_TRUNCATION);
11826 it->glyph_row->truncated_on_right_p = 1;
1c9241f5 11827 }
5f5c8ee5 11828 break;
1c9241f5 11829 }
a2889657
JB
11830 }
11831
5f5c8ee5
GM
11832 /* Maybe insert a truncation at the left. */
11833 if (it->first_visible_x
11834 && IT_CHARPOS (*it) > 0)
a2889657 11835 {
5f5c8ee5
GM
11836 if (!FRAME_WINDOW_P (it->f))
11837 insert_left_trunc_glyphs (it);
11838 it->glyph_row->truncated_on_left_p = 1;
a2889657
JB
11839 }
11840
5f5c8ee5
GM
11841 it->face_id = saved_face_id;
11842
11843 /* Value is number of columns displayed. */
11844 return it->hpos - hpos_at_start;
11845}
a2889657 11846
a2889657 11847
a2889657 11848\f
5f5c8ee5
GM
11849/* This is like a combination of memq and assq. Return 1 if PROPVAL
11850 appears as an element of LIST or as the car of an element of LIST.
11851 If PROPVAL is a list, compare each element against LIST in that
11852 way, and return 1 if any element of PROPVAL is found in LIST.
11853 Otherwise return 0. This function cannot quit. */
642eefc6
RS
11854
11855int
11856invisible_p (propval, list)
11857 register Lisp_Object propval;
11858 Lisp_Object list;
11859{
af460d46
RS
11860 register Lisp_Object tail, proptail;
11861 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
11862 {
11863 register Lisp_Object tem;
af460d46 11864 tem = XCONS (tail)->car;
642eefc6
RS
11865 if (EQ (propval, tem))
11866 return 1;
11867 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
11868 return 1;
11869 }
af460d46
RS
11870 if (CONSP (propval))
11871 for (proptail = propval; CONSP (proptail);
11872 proptail = XCONS (proptail)->cdr)
11873 {
11874 Lisp_Object propelt;
11875 propelt = XCONS (proptail)->car;
11876 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11877 {
11878 register Lisp_Object tem;
11879 tem = XCONS (tail)->car;
11880 if (EQ (propelt, tem))
11881 return 1;
11882 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
11883 return 1;
11884 }
11885 }
642eefc6
RS
11886 return 0;
11887}
11888
5f5c8ee5
GM
11889
11890/* Return 1 if PROPVAL appears as the car of an element of LIST and
11891 the cdr of that element is non-nil. If PROPVAL is a list, check
11892 each element of PROPVAL in that way, and the first time some
11893 element is found, return 1 if the cdr of that element is non-nil.
11894 Otherwise return 0. This function cannot quit. */
642eefc6
RS
11895
11896int
11897invisible_ellipsis_p (propval, list)
11898 register Lisp_Object propval;
11899 Lisp_Object list;
11900{
af460d46
RS
11901 register Lisp_Object tail, proptail;
11902 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
11903 {
11904 register Lisp_Object tem;
af460d46 11905 tem = XCONS (tail)->car;
642eefc6
RS
11906 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
11907 return ! NILP (XCONS (tem)->cdr);
11908 }
af460d46
RS
11909 if (CONSP (propval))
11910 for (proptail = propval; CONSP (proptail);
11911 proptail = XCONS (proptail)->cdr)
11912 {
11913 Lisp_Object propelt;
11914 propelt = XCONS (proptail)->car;
11915 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11916 {
11917 register Lisp_Object tem;
11918 tem = XCONS (tail)->car;
11919 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
11920 return ! NILP (XCONS (tem)->cdr);
11921 }
11922 }
642eefc6
RS
11923 return 0;
11924}
5f5c8ee5
GM
11925
11926
642eefc6 11927\f
5f5c8ee5
GM
11928/***********************************************************************
11929 Initialization
11930 ***********************************************************************/
11931
a2889657
JB
11932void
11933syms_of_xdisp ()
11934{
5f5c8ee5
GM
11935 echo_area_message = previous_echo_area_message = Qnil;
11936 staticpro (&echo_area_message);
11937 staticpro (&previous_echo_area_message);
11938
735c094c
KH
11939 staticpro (&Qinhibit_redisplay);
11940 Qinhibit_redisplay = intern ("inhibit-redisplay");
11941
5f5c8ee5
GM
11942#if GLYPH_DEBUG
11943 defsubr (&Sdump_glyph_matrix);
11944 defsubr (&Sdump_glyph_row);
11945 defsubr (&Sdump_toolbar_row);
11946 defsubr (&Strace_redisplay_toggle);
11947#endif
11948
cf074754
RS
11949 staticpro (&Qmenu_bar_update_hook);
11950 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
11951
d46fb96a 11952 staticpro (&Qoverriding_terminal_local_map);
7079aefa 11953 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
d46fb96a 11954
399164b4
KH
11955 staticpro (&Qoverriding_local_map);
11956 Qoverriding_local_map = intern ("overriding-local-map");
11957
75c43375
RS
11958 staticpro (&Qwindow_scroll_functions);
11959 Qwindow_scroll_functions = intern ("window-scroll-functions");
11960
e0bfbde6
RS
11961 staticpro (&Qredisplay_end_trigger_functions);
11962 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
5f5c8ee5 11963
2e54982e
RS
11964 staticpro (&Qinhibit_point_motion_hooks);
11965 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
11966
5f5c8ee5
GM
11967 staticpro (&Qdisplay);
11968 Qdisplay = intern ("display");
11969 staticpro (&Qleft_margin);
11970 Qspace_width = intern ("space-width");
11971 staticpro (&Qspace_width);
11972 Qheight = intern ("height");
11973 staticpro (&Qheight);
11974 Qraise = intern ("raise");
11975 staticpro (&Qraise);
11976 Qspace = intern ("space");
11977 staticpro (&Qspace);
11978 Qleft_margin = intern ("left-margin");
11979 staticpro (&Qright_margin);
11980 Qright_margin = intern ("right-margin");
11981 Qalign_to = intern ("align-to");
11982 staticpro (&Qalign_to);
11983 QCalign_to = intern (":align-to");
11984 staticpro (&QCalign_to);
11985 Qwidth = intern ("width");
11986 staticpro (&Qwidth);
11987 Qrelative_width = intern ("relative-width");
11988 staticpro (&Qrelative_width);
11989 QCrelative_width = intern (":relative-width");
11990 staticpro (&QCrelative_width);
11991 QCrelative_height = intern (":relative-height");
11992 staticpro (&QCrelative_height);
11993 QCeval = intern (":eval");
11994 staticpro (&QCeval);
11995 QCwhen = intern (":when");
11996 staticpro (&QCwhen);
11997 Qfontified = intern ("fontified");
11998 staticpro (&Qfontified);
11999 Qfontification_functions = intern ("fontification-functions");
12000 staticpro (&Qfontification_functions);
5f5c8ee5
GM
12001 Qtrailing_whitespace = intern ("trailing-whitespace");
12002 staticpro (&Qtrailing_whitespace);
12003 Qimage = intern ("image");
12004 staticpro (&Qimage);
12005
a2889657
JB
12006 staticpro (&last_arrow_position);
12007 staticpro (&last_arrow_string);
12008 last_arrow_position = Qnil;
12009 last_arrow_string = Qnil;
12010
8f897821
GM
12011 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
12012 "Non-nil means highlight trailing whitespace.\n\
12013The face used for trailing whitespace is `trailing-whitespace'.");
12014 Vshow_trailing_whitespace = Qnil;
12015
735c094c
KH
12016 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
12017 "Non-nil means don't actually do any redisplay.\n\
12018This is used for internal purposes.");
12019 Vinhibit_redisplay = Qnil;
12020
a2889657 12021 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
8c45d522 12022 "String (or mode line construct) included (normally) in `mode-line-format'.");
a2889657
JB
12023 Vglobal_mode_string = Qnil;
12024
12025 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
12026 "Marker for where to display an arrow on top of the buffer text.\n\
12027This must be the beginning of a line in order to work.\n\
12028See also `overlay-arrow-string'.");
12029 Voverlay_arrow_position = Qnil;
12030
12031 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
12032 "String to display as an arrow. See also `overlay-arrow-position'.");
12033 Voverlay_arrow_string = Qnil;
12034
12035 DEFVAR_INT ("scroll-step", &scroll_step,
12036 "*The number of lines to try scrolling a window by when point moves out.\n\
44fa5b1e
JB
12037If that fails to bring point back on frame, point is centered instead.\n\
12038If this is zero, point is always centered after it moves off frame.");
a2889657 12039
0789adb2
RS
12040 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
12041 "*Scroll up to this many lines, to bring point back on screen.");
12042 scroll_conservatively = 0;
12043
9afd2168
RS
12044 DEFVAR_INT ("scroll-margin", &scroll_margin,
12045 "*Number of lines of margin at the top and bottom of a window.\n\
12046Recenter the window whenever point gets within this many lines\n\
12047of the top or bottom of the window.");
12048 scroll_margin = 0;
12049
5f5c8ee5 12050#if GLYPH_DEBUG
a2889657 12051 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
5f5c8ee5 12052#endif
a2889657
JB
12053
12054 DEFVAR_BOOL ("truncate-partial-width-windows",
12055 &truncate_partial_width_windows,
44fa5b1e 12056 "*Non-nil means truncate lines in all windows less than full frame wide.");
a2889657
JB
12057 truncate_partial_width_windows = 1;
12058
12059 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
12060 "*Non-nil means use inverse video for the mode line.");
12061 mode_line_inverse_video = 1;
aa6d10fa
RS
12062
12063 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
5f5c8ee5 12064 "*Maximum buffer size for which line number should be displayed.\n\
db4f2bfa 12065If the buffer is bigger than this, the line number does not appear\n\
9f027393 12066in the mode line.");
aa6d10fa 12067 line_number_display_limit = 1000000;
fba9ce76 12068
5d121aec
KH
12069 DEFVAR_INT ("line-number-display-limit-width", &line_number_display_limit_width,
12070 "*Maximum line width (in characters) for line number display.\n\
12071If the average length of the lines near point is bigger than this, then the\n\
12072line number may be omitted from the mode line.");
12073 line_number_display_limit_width = 200;
12074
fba9ce76
RS
12075 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
12076 "*Non-nil means highlight region even in nonselected windows.");
293a54ce 12077 highlight_nonselected_windows = 0;
d39b6696
KH
12078
12079 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
3450d04c
KH
12080 "Non-nil if more than one frame is visible on this display.\n\
12081Minibuffer-only frames don't count, but iconified frames do.\n\
4c2eb242
RS
12082This variable is not guaranteed to be accurate except while processing\n\
12083`frame-title-format' and `icon-title-format'.");
d39b6696
KH
12084
12085 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
5f5c8ee5 12086 "Template for displaying the title bar of visible frames.\n\
d39b6696
KH
12087\(Assuming the window manager supports this feature.)\n\
12088This variable has the same structure as `mode-line-format' (which see),\n\
12089and is used only on frames for which no explicit name has been set\n\
12090\(see `modify-frame-parameters').");
12091 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
5f5c8ee5 12092 "Template for displaying the title bar of an iconified frame.\n\
d39b6696
KH
12093\(Assuming the window manager supports this feature.)\n\
12094This variable has the same structure as `mode-line-format' (which see),\n\
12095and is used only on frames for which no explicit name has been set\n\
12096\(see `modify-frame-parameters').");
12097 Vicon_title_format
12098 = Vframe_title_format
12099 = Fcons (intern ("multiple-frames"),
12100 Fcons (build_string ("%b"),
12101 Fcons (Fcons (build_string (""),
12102 Fcons (intern ("invocation-name"),
12103 Fcons (build_string ("@"),
12104 Fcons (intern ("system-name"),
12105 Qnil)))),
12106 Qnil)));
5992c4f7
KH
12107
12108 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
12109 "Maximum number of lines to keep in the message log buffer.\n\
12110If nil, disable message logging. If t, log messages but don't truncate\n\
12111the buffer when it becomes large.");
12112 XSETFASTINT (Vmessage_log_max, 50);
08b610e4
RS
12113
12114 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
12115 "Functions called before redisplay, if window sizes have changed.\n\
12116The value should be a list of functions that take one argument.\n\
12117Just before redisplay, for each frame, if any of its windows have changed\n\
12118size since the last redisplay, or have been split or deleted,\n\
12119all the functions in the list are called, with the frame as argument.");
12120 Vwindow_size_change_functions = Qnil;
75c43375
RS
12121
12122 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
5f5c8ee5 12123 "List of Functions to call before redisplaying a window with scrolling.\n\
75c43375 12124Each function is called with two arguments, the window\n\
8d9583b0
RS
12125and its new display-start position. Note that the value of `window-end'\n\
12126is not valid when these functions are called.");
75c43375 12127 Vwindow_scroll_functions = Qnil;
5f5c8ee5
GM
12128
12129 DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p,
12130 "*Non-nil means automatically resize toolbars.\n\
12131This increases a toolbar's height if not all toolbar items are visible.\n\
12132It decreases a toolbar's height when it would display blank lines\n\
12133otherwise.");
12134 auto_resize_toolbars_p = 1;
12135
12136 DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p,
12137 "*Non-nil means raise toolbar buttons when the mouse moves over them.");
12138 auto_raise_toolbar_buttons_p = 1;
12139
12140 DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin,
12141 "*Margin around toolbar buttons in pixels.");
12142 toolbar_button_margin = 1;
12143
12144 DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief,
12145 "Relief thickness of toolbar buttons.");
12146 toolbar_button_relief = 3;
12147
12148 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
12149 "List of functions to call to fontify regions of text.\n\
12150Each function is called with one argument POS. Functions must\n\
12151fontify a region starting at POS in the current buffer, and give\n\
12152fontified regions the property `fontified'.\n\
12153This variable automatically becomes buffer-local when set.");
12154 Vfontification_functions = Qnil;
12155 Fmake_local_variable (Qfontification_functions);
7bbe686f
AI
12156
12157 DEFVAR_BOOL ("unibyte-display-via-language-environment",
5f5c8ee5
GM
12158 &unibyte_display_via_language_environment,
12159 "*Non-nil means display unibyte text according to language environment.\n\
7bbe686f
AI
12160Specifically this means that unibyte non-ASCII characters\n\
12161are displayed by converting them to the equivalent multibyte characters\n\
12162according to the current language environment. As a result, they are\n\
12163displayed according to the current fontset.");
12164 unibyte_display_via_language_environment = 0;
a2889657
JB
12165}
12166
5f5c8ee5
GM
12167
12168/* Initialize this module when Emacs starts. */
12169
dfcf069d 12170void
a2889657
JB
12171init_xdisp ()
12172{
12173 Lisp_Object root_window;
5f5c8ee5 12174 struct window *mini_w;
a2889657 12175
5f5c8ee5 12176 CHARPOS (this_line_start_pos) = 0;
a2889657
JB
12177
12178 mini_w = XWINDOW (minibuf_window);
11e82b76 12179 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
a2889657
JB
12180
12181 echo_area_glyphs = 0;
12182 previous_echo_glyphs = 0;
5f5c8ee5 12183 echo_area_message = previous_echo_area_message = Qnil;
a2889657
JB
12184
12185 if (!noninteractive)
12186 {
5f5c8ee5
GM
12187 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
12188 int i;
12189
12190 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
12c226c5 12191 set_window_height (root_window,
5f5c8ee5 12192 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
12c226c5 12193 0);
c2213350 12194 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
a2889657
JB
12195 set_window_height (minibuf_window, 1, 0);
12196
c2213350
KH
12197 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
12198 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
5f5c8ee5
GM
12199
12200 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
12201 scratch_glyph_row.glyphs[TEXT_AREA + 1]
12202 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
12203
12204 /* The default ellipsis glyphs `...'. */
12205 for (i = 0; i < 3; ++i)
12206 XSETFASTINT (default_invis_vector[i], '.');
a2889657 12207 }
5f5c8ee5
GM
12208
12209#ifdef HAVE_WINDOW_SYSTEM
12210 {
12211 /* Allocate the buffer for frame titles. */
12212 int size = 100;
12213 frame_title_buf = (char *) xmalloc (size);
12214 frame_title_buf_end = frame_title_buf + size;
12215 frame_title_ptr = NULL;
12216 }
12217#endif /* HAVE_WINDOW_SYSTEM */
a2889657 12218}
5f5c8ee5
GM
12219
12220