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