(backward-kill-paragraph): Don't move
[bpt/emacs.git] / src / xdisp.c
CommitLineData
a2889657 1/* Display generation from window structure and buffer text.
5f5c8ee5
GM
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99
3 Free Software Foundation, Inc.
a2889657
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
b1d1124b 9the Free Software Foundation; either version 2, or (at your option)
a2889657
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a2889657 21
5f5c8ee5
GM
22/* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the the description of direct update
37 operations, below.).
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay() +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking a iterator structure (struct it)
124 argument.
125
126 Iteration over things to be be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator
128 (or init_string_iterator for that matter). Calls to
129 get_next_display_element fill the iterator structure with relevant
130 information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
132
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
138 see in dispextern.h.
139
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
147
148
149 Frame matrices.
150
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
157
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
a2889657 169
18160b98 170#include <config.h>
a2889657 171#include <stdio.h>
5f5c8ee5
GM
172#ifdef STDC_HEADERS
173#include <stdlib.h>
174#endif
a2889657 175#include "lisp.h"
44fa5b1e 176#include "frame.h"
a2889657
JB
177#include "window.h"
178#include "termchar.h"
179#include "dispextern.h"
180#include "buffer.h"
1c9241f5 181#include "charset.h"
a2889657
JB
182#include "indent.h"
183#include "commands.h"
184#include "macros.h"
185#include "disptab.h"
30c566e4 186#include "termhooks.h"
b0a0fbda 187#include "intervals.h"
fe8b0cf8 188#include "keyboard.h"
1c9241f5
KH
189#include "coding.h"
190#include "process.h"
dfcf069d
AS
191#include "region-cache.h"
192
6d55d620 193#ifdef HAVE_X_WINDOWS
dfcf069d
AS
194#include "xterm.h"
195#endif
a2889657 196
5f5c8ee5
GM
197#define min(a, b) ((a) < (b) ? (a) : (b))
198#define max(a, b) ((a) > (b) ? (a) : (b))
199
200#define INFINITY 10000000
201
8f3343d0 202#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
76412d64 203extern void set_frame_menubar ();
cd6dfed6 204extern int pending_menu_activation;
76412d64
RS
205#endif
206
a2889657
JB
207extern int interrupt_input;
208extern int command_loop_level;
209
b6436d4e
RS
210extern int minibuffer_auto_raise;
211
c4628384
RS
212extern Lisp_Object Qface;
213
399164b4
KH
214extern Lisp_Object Voverriding_local_map;
215extern Lisp_Object Voverriding_local_map_menu_flag;
5f5c8ee5 216extern Lisp_Object Qmenu_item;
399164b4 217
d46fb96a 218Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
75c43375 219Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
e0bfbde6 220Lisp_Object Qredisplay_end_trigger_functions;
2e54982e 221Lisp_Object Qinhibit_point_motion_hooks;
5f5c8ee5
GM
222Lisp_Object QCeval, QCwhen;
223Lisp_Object Qfontified;
224
225/* Functions called to fontify regions of text. */
226
227Lisp_Object Vfontification_functions;
228Lisp_Object Qfontification_functions;
229
230/* Non-zero means draw toolbar buttons raised when the mouse moves
231 over them. */
232
233int auto_raise_toolbar_buttons_p;
234
235/* Margin around toolbar buttons in pixels. */
236
237int toolbar_button_margin;
238
239/* Thickness of shadow to draw around toolbar buttons. */
240
241int toolbar_button_relief;
242
243/* Non-zero means automatically resize toolbars so that all toolbar
244 items are visible, and no blank lines remain. */
245
246int auto_resize_toolbars_p;
399164b4 247
735c094c
KH
248/* Non-nil means don't actually do any redisplay. */
249
250Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
251
5f5c8ee5
GM
252/* Names of text properties relevant for redisplay. */
253
254Lisp_Object Qdisplay, Qrelative_width, Qwidth, Qalign_to;
255extern Lisp_Object Qface, Qinvisible, Qimage;
256
257/* Symbols used in text property values. */
258
259Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
260Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qheight, Qraise;
261
8f897821 262/* Non-nil means highlight trailing whitespace. */
5f5c8ee5 263
8f897821 264Lisp_Object Vshow_trailing_whitespace;
5f5c8ee5
GM
265
266/* Name of the face used to highlight trailing whitespace. */
267
268Lisp_Object Qtrailing_whitespace;
269
270/* The symbol `image' which is the car of the lists used to represent
271 images in Lisp. */
272
273Lisp_Object Qimage;
274
275/* Non-zero means print newline to stdout before next mini-buffer
276 message. */
a2889657
JB
277
278int noninteractive_need_newline;
279
5f5c8ee5 280/* Non-zero means print newline to message log before next message. */
f88eb0b6 281
3c6595e0 282static int message_log_need_newline;
f88eb0b6 283
5f5c8ee5
GM
284\f
285/* The buffer position of the first character appearing entirely or
286 partially on the line of the selected window which contains the
287 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
288 redisplay optimization in redisplay_internal. */
a2889657 289
5f5c8ee5 290static struct text_pos this_line_start_pos;
a2889657 291
5f5c8ee5
GM
292/* Number of characters past the end of the line above, including the
293 terminating newline. */
294
295static struct text_pos this_line_end_pos;
296
297/* The vertical positions and the height of this line. */
a2889657 298
a2889657 299static int this_line_vpos;
5f5c8ee5
GM
300static int this_line_y;
301static int this_line_pixel_height;
302
303/* X position at which this display line starts. Usually zero;
304 negative if first character is partially visible. */
305
306static int this_line_start_x;
a2889657 307
5f5c8ee5 308/* Buffer that this_line_.* variables are referring to. */
a2889657 309
a2889657
JB
310static struct buffer *this_line_buffer;
311
5f5c8ee5
GM
312/* Nonzero means truncate lines in all windows less wide than the
313 frame. */
a2889657 314
a2889657
JB
315int truncate_partial_width_windows;
316
7bbe686f 317/* A flag to control how to display unibyte 8-bit character. */
5f5c8ee5 318
7bbe686f 319int unibyte_display_via_language_environment;
5f5c8ee5
GM
320
321/* Nonzero means we have more than one non-mini-buffer-only frame.
322 Not guaranteed to be accurate except while parsing
323 frame-title-format. */
7bbe686f 324
d39b6696
KH
325int multiple_frames;
326
a2889657
JB
327Lisp_Object Vglobal_mode_string;
328
329/* Marker for where to display an arrow on top of the buffer text. */
5f5c8ee5 330
a2889657
JB
331Lisp_Object Voverlay_arrow_position;
332
5f5c8ee5
GM
333/* String to display for the arrow. Only used on terminal frames. */
334
a2889657
JB
335Lisp_Object Voverlay_arrow_string;
336
5f5c8ee5
GM
337/* Values of those variables at last redisplay. However, if
338 Voverlay_arrow_position is a marker, last_arrow_position is its
339 numerical position. */
340
d45de95b
RS
341static Lisp_Object last_arrow_position, last_arrow_string;
342
5f5c8ee5
GM
343/* Like mode-line-format, but for the title bar on a visible frame. */
344
d39b6696
KH
345Lisp_Object Vframe_title_format;
346
5f5c8ee5
GM
347/* Like mode-line-format, but for the title bar on an iconified frame. */
348
d39b6696
KH
349Lisp_Object Vicon_title_format;
350
08b610e4
RS
351/* List of functions to call when a window's size changes. These
352 functions get one arg, a frame on which one or more windows' sizes
353 have changed. */
5f5c8ee5 354
08b610e4
RS
355static Lisp_Object Vwindow_size_change_functions;
356
cf074754
RS
357Lisp_Object Qmenu_bar_update_hook;
358
a2889657 359/* Nonzero if overlay arrow has been displayed once in this window. */
a2889657 360
5f5c8ee5 361static int overlay_arrow_seen;
ca26e1c8 362
fba9ce76 363/* Nonzero means highlight the region even in nonselected windows. */
fba9ce76 364
5f5c8ee5
GM
365int highlight_nonselected_windows;
366
367/* If cursor motion alone moves point off frame, try scrolling this
368 many lines up or down if that will bring it back. */
369
14510fee 370static int scroll_step;
a2889657 371
5f5c8ee5
GM
372/* Non-0 means scroll just far enough to bring point back on the
373 screen, when appropriate. */
374
0789adb2
RS
375static int scroll_conservatively;
376
5f5c8ee5
GM
377/* Recenter the window whenever point gets within this many lines of
378 the top or bottom of the window. This value is translated into a
379 pixel value by multiplying it with CANON_Y_UNIT, which means that
380 there is really a fixed pixel height scroll margin. */
381
9afd2168
RS
382int scroll_margin;
383
5f5c8ee5
GM
384/* Number of windows showing the buffer of the selected window (or
385 another buffer with the same base buffer). keyboard.c refers to
386 this. */
a2889657 387
a2889657
JB
388int buffer_shared;
389
5f5c8ee5 390/* Vector containing glyphs for an ellipsis `...'. */
a2889657 391
5f5c8ee5 392static Lisp_Object default_invis_vector[3];
a2889657 393
5f5c8ee5 394/* Nonzero means display mode line highlighted. */
a2889657 395
a2889657
JB
396int mode_line_inverse_video;
397
5f5c8ee5
GM
398/* Prompt to display in front of the mini-buffer contents. */
399
8c5b6a0a 400Lisp_Object minibuf_prompt;
a2889657 401
5f5c8ee5
GM
402/* Width of current mini-buffer prompt. Only set after display_line
403 of the line that contains the prompt. */
404
a2889657 405int minibuf_prompt_width;
5f5c8ee5
GM
406int minibuf_prompt_pixel_width;
407
5f5c8ee5
GM
408/* This is the window where the echo area message was displayed. It
409 is always a mini-buffer window, but it may not be the same window
410 currently active as a mini-buffer. */
411
73af359d
RS
412Lisp_Object echo_area_window;
413
c6e89d6c
GM
414/* List of pairs (MESSAGE . MULTIBYTE). The function save_message
415 pushes the current message and the value of
416 message_enable_multibyte on the stack, the function restore_message
417 pops the stack and displays MESSAGE again. */
418
419Lisp_Object Vmessage_stack;
420
a3788d53
RS
421/* Nonzero means multibyte characters were enabled when the echo area
422 message was specified. */
5f5c8ee5 423
a3788d53
RS
424int message_enable_multibyte;
425
5f5c8ee5
GM
426/* True if we should redraw the mode lines on the next redisplay. */
427
a2889657
JB
428int update_mode_lines;
429
5f5c8ee5
GM
430/* Smallest number of characters before the gap at any time since last
431 redisplay that finished. Valid for current buffer when
432 try_window_id can be called. */
433
a2889657
JB
434int beg_unchanged;
435
5f5c8ee5
GM
436/* Smallest number of characters after the gap at any time since last
437 redisplay that finished. Valid for current buffer when
438 try_window_id can be called. */
439
a2889657
JB
440int end_unchanged;
441
5f5c8ee5
GM
442/* MODIFF as of last redisplay that finished; if it matches MODIFF,
443 and overlay_unchanged_modified matches OVERLAY_MODIFF, that means
444 beg_unchanged and end_unchanged contain no useful information. */
445
a2889657
JB
446int unchanged_modified;
447
8850a573 448/* OVERLAY_MODIFF as of last redisplay that finished. */
5f5c8ee5 449
8850a573
RS
450int overlay_unchanged_modified;
451
5f5c8ee5
GM
452/* Nonzero if window sizes or contents have changed since last
453 redisplay that finished */
454
a2889657
JB
455int windows_or_buffers_changed;
456
5f5c8ee5
GM
457/* Nonzero after display_mode_line if %l was used and it displayed a
458 line number. */
459
aa6d10fa
RS
460int line_number_displayed;
461
462/* Maximum buffer size for which to display line numbers. */
5f5c8ee5 463
14510fee 464static int line_number_display_limit;
5992c4f7 465
5d121aec
KH
466/* line width to consider when repostioning for line number display */
467
468static int line_number_display_limit_width;
469
5f5c8ee5
GM
470/* Number of lines to keep in the message log buffer. t means
471 infinite. nil means don't log at all. */
472
5992c4f7 473Lisp_Object Vmessage_log_max;
d45de95b 474
c6e89d6c
GM
475/* Current, index 0, and last displayed echo area message. Either
476 buffers from echo_buffers, or nil to indicate no message. */
477
478Lisp_Object echo_area_buffer[2];
479
480/* The buffers referenced from echo_area_buffer. */
481
482static Lisp_Object echo_buffer[2];
483
484/* A vector saved used in with_area_buffer to reduce consing. */
485
486static Lisp_Object Vwith_echo_area_save_vector;
487
488/* Non-zero means display_echo_area should display the last echo area
489 message again. Set by redisplay_preserve_echo_area. */
490
491static int display_last_displayed_message_p;
492
493/* Nonzero if echo area is being used by print; zero if being used by
494 message. */
495
496int message_buf_print;
497
498/* Maximum height for resizing mini-windows. */
499
500static Lisp_Object Vmax_mini_window_height;
501
5f5c8ee5
GM
502/* A scratch glyph row with contents used for generating truncation
503 glyphs. Also used in direct_output_for_insert. */
12adba34 504
5f5c8ee5
GM
505#define MAX_SCRATCH_GLYPHS 100
506struct glyph_row scratch_glyph_row;
507static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
1adc55de 508
5f5c8ee5
GM
509/* Ascent and height of the last line processed by move_it_to. */
510
511static int last_max_ascent, last_height;
512
513/* The maximum distance to look ahead for text properties. Values
514 that are too small let us call compute_char_face and similar
515 functions too often which is expensive. Values that are too large
516 let us call compute_char_face and alike too often because we
517 might not be interested in text properties that far away. */
518
519#define TEXT_PROP_DISTANCE_LIMIT 100
520
521/* Non-zero means print traces of redisplay if compiled with
522 GLYPH_DEBUG != 0. */
523
524#if GLYPH_DEBUG
525int trace_redisplay_p;
526#endif
527
528/* Value returned from text property handlers (see below). */
529
530enum prop_handled
3c6595e0 531{
5f5c8ee5
GM
532 HANDLED_NORMALLY,
533 HANDLED_RECOMPUTE_PROPS,
534 HANDLED_OVERLAY_STRING_CONSUMED,
535 HANDLED_RETURN
536};
3c6595e0 537
5f5c8ee5
GM
538/* A description of text properties that redisplay is interested
539 in. */
3c6595e0 540
5f5c8ee5
GM
541struct props
542{
543 /* The name of the property. */
544 Lisp_Object *name;
90adcf20 545
5f5c8ee5
GM
546 /* A unique index for the property. */
547 enum prop_idx idx;
548
549 /* A handler function called to set up iterator IT from the property
550 at IT's current position. Value is used to steer handle_stop. */
551 enum prop_handled (*handler) P_ ((struct it *it));
552};
553
554static enum prop_handled handle_face_prop P_ ((struct it *));
555static enum prop_handled handle_invisible_prop P_ ((struct it *));
556static enum prop_handled handle_display_prop P_ ((struct it *));
557static enum prop_handled handle_overlay_change P_ ((struct it *));
558static enum prop_handled handle_fontified_prop P_ ((struct it *));
559
560/* Properties handled by iterators. */
561
562static struct props it_props[] =
5992c4f7 563{
5f5c8ee5
GM
564 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
565 /* Handle `face' before `display' because some sub-properties of
566 `display' need to know the face. */
567 {&Qface, FACE_PROP_IDX, handle_face_prop},
568 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
569 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
570 {NULL, 0, NULL}
571};
5992c4f7 572
5f5c8ee5
GM
573/* Value is the position described by X. If X is a marker, value is
574 the marker_position of X. Otherwise, value is X. */
12adba34 575
5f5c8ee5 576#define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
12adba34 577
5f5c8ee5 578/* Enumeration returned by some move_it_.* functions internally. */
12adba34 579
5f5c8ee5
GM
580enum move_it_result
581{
582 /* Not used. Undefined value. */
583 MOVE_UNDEFINED,
bab29e15 584
5f5c8ee5
GM
585 /* Move ended at the requested buffer position or ZV. */
586 MOVE_POS_MATCH_OR_ZV,
bab29e15 587
5f5c8ee5
GM
588 /* Move ended at the requested X pixel position. */
589 MOVE_X_REACHED,
12adba34 590
5f5c8ee5
GM
591 /* Move within a line ended at the end of a line that must be
592 continued. */
593 MOVE_LINE_CONTINUED,
594
595 /* Move within a line ended at the end of a line that would
596 be displayed truncated. */
597 MOVE_LINE_TRUNCATED,
ff6c30e5 598
5f5c8ee5
GM
599 /* Move within a line ended at a line end. */
600 MOVE_NEWLINE_OR_CR
601};
12adba34 602
ff6c30e5 603
5f5c8ee5
GM
604\f
605/* Function prototypes. */
606
c6e89d6c
GM
607static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
608static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
609static int resize_mini_window P_ ((struct window *));
610static void clear_garbaged_frames P_ ((void));
611static int current_message_1 P_ ((Lisp_Object *));
612static int truncate_message_1 P_ ((int));
613static int set_message_1 P_ ((char *s, Lisp_Object, int, int));
614static int display_echo_area P_ ((struct window *));
615static int display_echo_area_1 P_ ((struct window *));
28514cd9 616static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
4fdb80f2 617static int string_char_and_length P_ ((unsigned char *, int, int *));
5f5c8ee5
GM
618static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
619 struct text_pos));
620static int compute_window_start_on_continuation_line P_ ((struct window *));
621static Lisp_Object eval_handler P_ ((Lisp_Object));
622static Lisp_Object eval_form P_ ((Lisp_Object));
623static void insert_left_trunc_glyphs P_ ((struct it *));
624static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
625static void extend_face_to_end_of_line P_ ((struct it *));
626static void append_space P_ ((struct it *, int));
627static void make_cursor_line_fully_visible P_ ((struct window *));
628static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
629static int trailing_whitespace_p P_ ((int));
630static int message_log_check_duplicate P_ ((int, int, int, int));
631int invisible_p P_ ((Lisp_Object, Lisp_Object));
632int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
633static void push_it P_ ((struct it *));
634static void pop_it P_ ((struct it *));
635static void sync_frame_with_window_matrix_rows P_ ((struct window *));
636static void redisplay_internal P_ ((int));
c6e89d6c 637static int echo_area_display P_ ((int));
5f5c8ee5
GM
638static void redisplay_windows P_ ((Lisp_Object));
639static void redisplay_window P_ ((Lisp_Object, int));
640static void update_menu_bar P_ ((struct frame *, int));
641static int try_window_reusing_current_matrix P_ ((struct window *));
642static int try_window_id P_ ((struct window *));
643static int display_line P_ ((struct it *));
644static void display_mode_lines P_ ((struct window *));
645static void display_mode_line P_ ((struct window *, enum face_id,
646 Lisp_Object));
647static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
648static char *decode_mode_spec P_ ((struct window *, char, int, int));
649static void display_menu_bar P_ ((struct window *));
650static int display_count_lines P_ ((int, int, int, int, int *));
651static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
652 int, int, struct it *, int, int, int, int));
653static void compute_line_metrics P_ ((struct it *));
654static void run_redisplay_end_trigger_hook P_ ((struct it *));
655static int get_overlay_strings P_ ((struct it *));
656static void next_overlay_string P_ ((struct it *));
657void set_iterator_to_next P_ ((struct it *));
658static void reseat P_ ((struct it *, struct text_pos, int));
659static void reseat_1 P_ ((struct it *, struct text_pos, int));
660static void back_to_previous_visible_line_start P_ ((struct it *));
661static void reseat_at_previous_visible_line_start P_ ((struct it *));
312246d1 662static void reseat_at_next_visible_line_start P_ ((struct it *, int));
5f5c8ee5
GM
663static int next_element_from_display_vector P_ ((struct it *));
664static int next_element_from_string P_ ((struct it *));
665static int next_element_from_c_string P_ ((struct it *));
666static int next_element_from_buffer P_ ((struct it *));
667static int next_element_from_image P_ ((struct it *));
668static int next_element_from_stretch P_ ((struct it *));
669static void load_overlay_strings P_ ((struct it *));
670static void init_from_display_pos P_ ((struct it *, struct window *,
671 struct display_pos *));
672static void reseat_to_string P_ ((struct it *, unsigned char *,
673 Lisp_Object, int, int, int, int));
674static int charset_at_position P_ ((struct text_pos));
675static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
676 int, int, int));
677void move_it_vertically_backward P_ ((struct it *, int));
678static void init_to_row_start P_ ((struct it *, struct window *,
679 struct glyph_row *));
680static void init_to_row_end P_ ((struct it *, struct window *,
681 struct glyph_row *));
682static void back_to_previous_line_start P_ ((struct it *));
683static void forward_to_next_line_start P_ ((struct it *));
684static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
685 Lisp_Object, int));
686static struct text_pos string_pos P_ ((int, Lisp_Object));
687static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
688static int number_of_chars P_ ((unsigned char *, int));
689static void compute_stop_pos P_ ((struct it *));
690static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
691 Lisp_Object));
692static int face_before_or_after_it_pos P_ ((struct it *, int));
693static int next_overlay_change P_ ((int));
694static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
695 Lisp_Object, struct text_pos *));
696
697#define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
698#define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
ff6c30e5 699
5f5c8ee5 700#ifdef HAVE_WINDOW_SYSTEM
12adba34 701
5f5c8ee5
GM
702static void update_toolbar P_ ((struct frame *, int));
703static void build_desired_toolbar_string P_ ((struct frame *f));
704static int redisplay_toolbar P_ ((struct frame *));
705static void display_toolbar_line P_ ((struct it *));
12adba34 706
5f5c8ee5 707#endif /* HAVE_WINDOW_SYSTEM */
12adba34 708
5f5c8ee5
GM
709\f
710/***********************************************************************
711 Window display dimensions
712 ***********************************************************************/
12adba34 713
5f5c8ee5
GM
714/* Return the window-relative maximum y + 1 for glyph rows displaying
715 text in window W. This is the height of W minus the height of a
716 mode line, if any. */
717
718INLINE int
719window_text_bottom_y (w)
720 struct window *w;
721{
722 struct frame *f = XFRAME (w->frame);
723 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
724
725 if (WINDOW_WANTS_MODELINE_P (w))
726 height -= CURRENT_MODE_LINE_HEIGHT (w);
727 return height;
f88eb0b6
KH
728}
729
f82aff7c 730
5f5c8ee5
GM
731/* Return the pixel width of display area AREA of window W. AREA < 0
732 means return the total width of W, not including bitmap areas to
733 the left and right of the window. */
ff6c30e5 734
5f5c8ee5
GM
735INLINE int
736window_box_width (w, area)
737 struct window *w;
738 int area;
739{
740 struct frame *f = XFRAME (w->frame);
741 int width = XFASTINT (w->width);
742
743 if (!w->pseudo_window_p)
ff6c30e5 744 {
5f5c8ee5
GM
745 width -= FRAME_SCROLL_BAR_WIDTH (f) + 2 * FRAME_FLAGS_AREA_COLS (f);
746
747 if (area == TEXT_AREA)
748 {
749 if (INTEGERP (w->left_margin_width))
750 width -= XFASTINT (w->left_margin_width);
751 if (INTEGERP (w->right_margin_width))
752 width -= XFASTINT (w->right_margin_width);
753 }
754 else if (area == LEFT_MARGIN_AREA)
755 width = (INTEGERP (w->left_margin_width)
756 ? XFASTINT (w->left_margin_width) : 0);
757 else if (area == RIGHT_MARGIN_AREA)
758 width = (INTEGERP (w->right_margin_width)
759 ? XFASTINT (w->right_margin_width) : 0);
ff6c30e5 760 }
5f5c8ee5
GM
761
762 return width * CANON_X_UNIT (f);
ff6c30e5 763}
1adc55de 764
1adc55de 765
5f5c8ee5
GM
766/* Return the pixel height of the display area of window W, not
767 including mode lines of W, if any.. */
f88eb0b6 768
5f5c8ee5
GM
769INLINE int
770window_box_height (w)
771 struct window *w;
f88eb0b6 772{
5f5c8ee5
GM
773 struct frame *f = XFRAME (w->frame);
774 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
775
776 if (WINDOW_WANTS_MODELINE_P (w))
777 height -= CURRENT_MODE_LINE_HEIGHT (w);
778
779 if (WINDOW_WANTS_TOP_LINE_P (w))
780 height -= CURRENT_TOP_LINE_HEIGHT (w);
781
782 return height;
5992c4f7
KH
783}
784
785
5f5c8ee5
GM
786/* Return the frame-relative coordinate of the left edge of display
787 area AREA of window W. AREA < 0 means return the left edge of the
788 whole window, to the right of any bitmap area at the left side of
789 W. */
5992c4f7 790
5f5c8ee5
GM
791INLINE int
792window_box_left (w, area)
793 struct window *w;
794 int area;
90adcf20 795{
5f5c8ee5
GM
796 struct frame *f = XFRAME (w->frame);
797 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
a3788d53 798
5f5c8ee5 799 if (!w->pseudo_window_p)
90adcf20 800 {
5f5c8ee5
GM
801 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
802 + FRAME_FLAGS_AREA_WIDTH (f));
803
804 if (area == TEXT_AREA)
805 x += window_box_width (w, LEFT_MARGIN_AREA);
806 else if (area == RIGHT_MARGIN_AREA)
807 x += (window_box_width (w, LEFT_MARGIN_AREA)
808 + window_box_width (w, TEXT_AREA));
90adcf20 809 }
73af359d 810
5f5c8ee5
GM
811 return x;
812}
90adcf20 813
b6436d4e 814
5f5c8ee5
GM
815/* Return the frame-relative coordinate of the right edge of display
816 area AREA of window W. AREA < 0 means return the left edge of the
817 whole window, to the left of any bitmap area at the right side of
818 W. */
ded34426 819
5f5c8ee5
GM
820INLINE int
821window_box_right (w, area)
822 struct window *w;
823 int area;
824{
825 return window_box_left (w, area) + window_box_width (w, area);
826}
827
828
829/* Get the bounding box of the display area AREA of window W, without
830 mode lines, in frame-relative coordinates. AREA < 0 means the
831 whole window, not including bitmap areas to the left and right of
832 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
833 coordinates of the upper-left corner of the box. Return in
834 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
835
836INLINE void
837window_box (w, area, box_x, box_y, box_width, box_height)
838 struct window *w;
839 int area;
840 int *box_x, *box_y, *box_width, *box_height;
841{
842 struct frame *f = XFRAME (w->frame);
843
844 *box_width = window_box_width (w, area);
845 *box_height = window_box_height (w);
846 *box_x = window_box_left (w, area);
847 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
848 + XFASTINT (w->top) * CANON_Y_UNIT (f));
849 if (WINDOW_WANTS_TOP_LINE_P (w))
850 *box_y += CURRENT_TOP_LINE_HEIGHT (w);
ded34426 851}
1adc55de 852
1adc55de 853
5f5c8ee5
GM
854/* Get the bounding box of the display area AREA of window W, without
855 mode lines. AREA < 0 means the whole window, not including bitmap
856 areas to the left and right of the window. Return in *TOP_LEFT_X
857 and TOP_LEFT_Y the frame-relative pixel coordinates of the
858 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
859 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
860 box. */
ded34426 861
5f5c8ee5
GM
862INLINE void
863window_box_edges (w, area, top_left_x, top_left_y,
864 bottom_right_x, bottom_right_y)
865 struct window *w;
866 int area;
867 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
48ae5f0a 868{
5f5c8ee5
GM
869 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
870 bottom_right_y);
871 *bottom_right_x += *top_left_x;
872 *bottom_right_y += *top_left_y;
48ae5f0a
KH
873}
874
5f5c8ee5
GM
875
876\f
877/***********************************************************************
878 Utilities
879 ***********************************************************************/
880
4fdb80f2
GM
881/* Return the next character from STR which is MAXLEN bytes long.
882 Return in *LEN the length of the character. This is like
883 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
884 we find one, we return a `?', but with the length of the illegal
885 character. */
886
887static INLINE int
7a5b8a93 888string_char_and_length (str, maxlen, len)
4fdb80f2 889 unsigned char *str;
7a5b8a93 890 int maxlen, *len;
4fdb80f2
GM
891{
892 int c;
893
894 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
895 if (!CHAR_VALID_P (c, 1))
896 /* We may not change the length here because other places in Emacs
897 don't use this function, i.e. they silently accept illegal
898 characters. */
899 c = '?';
900
901 return c;
902}
903
904
905
5f5c8ee5
GM
906/* Given a position POS containing a valid character and byte position
907 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
908
909static struct text_pos
910string_pos_nchars_ahead (pos, string, nchars)
911 struct text_pos pos;
912 Lisp_Object string;
913 int nchars;
0b1005ef 914{
5f5c8ee5
GM
915 xassert (STRINGP (string) && nchars >= 0);
916
917 if (STRING_MULTIBYTE (string))
918 {
919 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
920 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
921 int len;
922
923 while (nchars--)
924 {
4fdb80f2 925 string_char_and_length (p, rest, &len);
5f5c8ee5
GM
926 p += len, rest -= len;
927 xassert (rest >= 0);
928 CHARPOS (pos) += 1;
929 BYTEPOS (pos) += len;
930 }
931 }
932 else
933 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
934
935 return pos;
0a9dc68b
RS
936}
937
0a9dc68b 938
5f5c8ee5
GM
939/* Value is the text position, i.e. character and byte position,
940 for character position CHARPOS in STRING. */
941
942static INLINE struct text_pos
943string_pos (charpos, string)
944 int charpos;
0a9dc68b 945 Lisp_Object string;
0a9dc68b 946{
5f5c8ee5
GM
947 struct text_pos pos;
948 xassert (STRINGP (string));
949 xassert (charpos >= 0);
950 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
951 return pos;
952}
953
954
955/* Value is a text position, i.e. character and byte position, for
956 character position CHARPOS in C string S. MULTIBYTE_P non-zero
957 means recognize multibyte characters. */
958
959static struct text_pos
960c_string_pos (charpos, s, multibyte_p)
961 int charpos;
962 unsigned char *s;
963 int multibyte_p;
964{
965 struct text_pos pos;
966
967 xassert (s != NULL);
968 xassert (charpos >= 0);
969
970 if (multibyte_p)
0a9dc68b 971 {
5f5c8ee5
GM
972 int rest = strlen (s), len;
973
974 SET_TEXT_POS (pos, 0, 0);
975 while (charpos--)
0a9dc68b 976 {
4fdb80f2 977 string_char_and_length (s, rest, &len);
5f5c8ee5
GM
978 s += len, rest -= len;
979 xassert (rest >= 0);
980 CHARPOS (pos) += 1;
981 BYTEPOS (pos) += len;
0a9dc68b
RS
982 }
983 }
5f5c8ee5
GM
984 else
985 SET_TEXT_POS (pos, charpos, charpos);
0a9dc68b 986
5f5c8ee5
GM
987 return pos;
988}
0a9dc68b 989
0a9dc68b 990
5f5c8ee5
GM
991/* Value is the number of characters in C string S. MULTIBYTE_P
992 non-zero means recognize multibyte characters. */
0a9dc68b 993
5f5c8ee5
GM
994static int
995number_of_chars (s, multibyte_p)
996 unsigned char *s;
997 int multibyte_p;
998{
999 int nchars;
1000
1001 if (multibyte_p)
1002 {
1003 int rest = strlen (s), len;
1004 unsigned char *p = (unsigned char *) s;
0a9dc68b 1005
5f5c8ee5
GM
1006 for (nchars = 0; rest > 0; ++nchars)
1007 {
4fdb80f2 1008 string_char_and_length (p, rest, &len);
5f5c8ee5 1009 rest -= len, p += len;
0a9dc68b
RS
1010 }
1011 }
5f5c8ee5
GM
1012 else
1013 nchars = strlen (s);
1014
1015 return nchars;
0b1005ef
KH
1016}
1017
5f5c8ee5
GM
1018
1019/* Compute byte position NEWPOS->bytepos corresponding to
1020 NEWPOS->charpos. POS is a known position in string STRING.
1021 NEWPOS->charpos must be >= POS.charpos. */
76412d64 1022
5f5c8ee5
GM
1023static void
1024compute_string_pos (newpos, pos, string)
1025 struct text_pos *newpos, pos;
1026 Lisp_Object string;
76412d64 1027{
5f5c8ee5
GM
1028 xassert (STRINGP (string));
1029 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1030
1031 if (STRING_MULTIBYTE (string))
1032 *newpos = string_pos_nchars_ahead (pos, CHARPOS (*newpos) - CHARPOS (pos),
1033 string);
1034 else
1035 BYTEPOS (*newpos) = CHARPOS (*newpos);
76412d64
RS
1036}
1037
9c74a0dd 1038
5f5c8ee5
GM
1039/* Return the charset of the character at position POS in
1040 current_buffer. */
1adc55de 1041
5f5c8ee5
GM
1042static int
1043charset_at_position (pos)
1044 struct text_pos pos;
a2889657 1045{
5f5c8ee5
GM
1046 int c, multibyte_p;
1047 unsigned char *p = BYTE_POS_ADDR (BYTEPOS (pos));
1048
1049 multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1050 if (multibyte_p)
a2889657 1051 {
5f5c8ee5
GM
1052 int maxlen = ((BYTEPOS (pos) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
1053 - BYTEPOS (pos));
1054 int len;
4fdb80f2 1055 c = string_char_and_length (p, maxlen, &len);
a2889657 1056 }
5f5c8ee5
GM
1057 else
1058 c = *p;
1059
1060 return CHAR_CHARSET (c);
1061}
1062
1063
1064\f
1065/***********************************************************************
1066 Lisp form evaluation
1067 ***********************************************************************/
1068
1069/* Error handler for eval_form. */
1070
1071static Lisp_Object
1072eval_handler (arg)
1073 Lisp_Object arg;
1074{
1075 return Qnil;
1076}
1077
1078
1079/* Evaluate SEXPR and return the result, or nil if something went
1080 wrong. */
1081
1082static Lisp_Object
1083eval_form (sexpr)
1084 Lisp_Object sexpr;
1085{
1086 int count = specpdl_ptr - specpdl;
1087 Lisp_Object val;
1088 specbind (Qinhibit_redisplay, Qt);
1089 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1090 return unbind_to (count, val);
1091}
1092
1093
1094\f
1095/***********************************************************************
1096 Debugging
1097 ***********************************************************************/
1098
1099#if 0
1100
1101/* Define CHECK_IT to perform sanity checks on iterators.
1102 This is for debugging. It is too slow to do unconditionally. */
1103
1104static void
1105check_it (it)
1106 struct it *it;
1107{
1108 if (it->method == next_element_from_string)
a2889657 1109 {
5f5c8ee5
GM
1110 xassert (STRINGP (it->string));
1111 xassert (IT_STRING_CHARPOS (*it) >= 0);
1112 }
1113 else if (it->method == next_element_from_buffer)
1114 {
1115 /* Check that character and byte positions agree. */
1116 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1117 }
73af359d 1118
5f5c8ee5
GM
1119 if (it->dpvec)
1120 xassert (it->current.dpvec_index >= 0);
1121 else
1122 xassert (it->current.dpvec_index < 0);
1123}
1f40cad2 1124
5f5c8ee5
GM
1125#define CHECK_IT(IT) check_it ((IT))
1126
1127#else /* not 0 */
1128
1129#define CHECK_IT(IT) (void) 0
1130
1131#endif /* not 0 */
1132
1133
1134#if GLYPH_DEBUG
1135
1136/* Check that the window end of window W is what we expect it
1137 to be---the last row in the current matrix displaying text. */
1138
1139static void
1140check_window_end (w)
1141 struct window *w;
1142{
1143 if (!MINI_WINDOW_P (w)
1144 && !NILP (w->window_end_valid))
1145 {
1146 struct glyph_row *row;
1147 xassert ((row = MATRIX_ROW (w->current_matrix,
1148 XFASTINT (w->window_end_vpos)),
1149 !row->enabled_p
1150 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1151 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1152 }
1153}
1154
1155#define CHECK_WINDOW_END(W) check_window_end ((W))
1156
1157#else /* not GLYPH_DEBUG */
1158
1159#define CHECK_WINDOW_END(W) (void) 0
1160
1161#endif /* not GLYPH_DEBUG */
1162
1163
1164\f
1165/***********************************************************************
1166 Iterator initialization
1167 ***********************************************************************/
1168
1169/* Initialize IT for displaying current_buffer in window W, starting
1170 at character position CHARPOS. CHARPOS < 0 means that no buffer
1171 position is specified which is useful when the iterator is assigned
1172 a position later. BYTEPOS is the byte position corresponding to
1173 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1174
1175 If ROW is not null, calls to produce_glyphs with IT as parameter
1176 will produce glyphs in that row.
1177
1178 BASE_FACE_ID is the id of a base face to use. It must be one of
1179 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1180 TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
1181 displaying the toolbar.
1182
1183 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1184 TOP_LINE_FACE_ID, the iterator will be initialized to use the
1185 corresponding mode line glyph row of the desired matrix of W. */
1186
1187void
1188init_iterator (it, w, charpos, bytepos, row, base_face_id)
1189 struct it *it;
1190 struct window *w;
1191 int charpos, bytepos;
1192 struct glyph_row *row;
1193 enum face_id base_face_id;
1194{
1195 int highlight_region_p;
5f5c8ee5
GM
1196
1197 /* Some precondition checks. */
1198 xassert (w != NULL && it != NULL);
5f5c8ee5
GM
1199 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1200
1201 /* If face attributes have been changed since the last redisplay,
1202 free realized faces now because they depend on face definitions
1203 that might have changed. */
1204 if (face_change_count)
1205 {
1206 face_change_count = 0;
1207 free_all_realized_faces (Qnil);
1208 }
1209
1210 /* Use one of the mode line rows of W's desired matrix if
1211 appropriate. */
1212 if (row == NULL)
1213 {
1214 if (base_face_id == MODE_LINE_FACE_ID)
1215 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1216 else if (base_face_id == TOP_LINE_FACE_ID)
1217 row = MATRIX_TOP_LINE_ROW (w->desired_matrix);
1218 }
1219
1220 /* Clear IT. */
1221 bzero (it, sizeof *it);
1222 it->current.overlay_string_index = -1;
1223 it->current.dpvec_index = -1;
1224 it->charset = CHARSET_ASCII;
1225 it->base_face_id = base_face_id;
1226
1227 /* The window in which we iterate over current_buffer: */
1228 XSETWINDOW (it->window, w);
1229 it->w = w;
1230 it->f = XFRAME (w->frame);
1231
1232 /* If realized faces have been removed, e.g. because of face
1233 attribute changes of named faces, recompute them. */
1234 if (FRAME_FACE_CACHE (it->f)->used == 0)
1235 recompute_basic_faces (it->f);
1236
5f5c8ee5
GM
1237 /* Current value of the `space-width', and 'height' properties. */
1238 it->space_width = Qnil;
1239 it->font_height = Qnil;
1240
1241 /* Are control characters displayed as `^C'? */
1242 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1243
1244 /* -1 means everything between a CR and the following line end
1245 is invisible. >0 means lines indented more than this value are
1246 invisible. */
1247 it->selective = (INTEGERP (current_buffer->selective_display)
1248 ? XFASTINT (current_buffer->selective_display)
1249 : (!NILP (current_buffer->selective_display)
1250 ? -1 : 0));
1251 it->selective_display_ellipsis_p
1252 = !NILP (current_buffer->selective_display_ellipses);
1253
1254 /* Display table to use. */
1255 it->dp = window_display_table (w);
1256
1257 /* Are multibyte characters enabled in current_buffer? */
1258 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1259
1260 /* Non-zero if we should highlight the region. */
1261 highlight_region_p
1262 = (!NILP (Vtransient_mark_mode)
1263 && !NILP (current_buffer->mark_active)
1264 && XMARKER (current_buffer->mark)->buffer != 0);
1265
1266 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1267 start and end of a visible region in window IT->w. Set both to
1268 -1 to indicate no region. */
1269 if (highlight_region_p
1270 /* Maybe highlight only in selected window. */
1271 && (/* Either show region everywhere. */
1272 highlight_nonselected_windows
1273 /* Or show region in the selected window. */
1274 || w == XWINDOW (selected_window)
1275 /* Or show the region if we are in the mini-buffer and W is
1276 the window the mini-buffer refers to. */
1277 || (MINI_WINDOW_P (XWINDOW (selected_window))
1278 && w == XWINDOW (Vminibuf_scroll_window))))
1279 {
1280 int charpos = marker_position (current_buffer->mark);
1281 it->region_beg_charpos = min (PT, charpos);
1282 it->region_end_charpos = max (PT, charpos);
1283 }
1284 else
1285 it->region_beg_charpos = it->region_end_charpos = -1;
1286
1287 /* Get the position at which the redisplay_end_trigger hook should
1288 be run, if it is to be run at all. */
1289 if (MARKERP (w->redisplay_end_trigger)
1290 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1291 it->redisplay_end_trigger_charpos
1292 = marker_position (w->redisplay_end_trigger);
1293 else if (INTEGERP (w->redisplay_end_trigger))
1294 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1295
1296 /* Correct bogus values of tab_width. */
1297 it->tab_width = XINT (current_buffer->tab_width);
1298 if (it->tab_width <= 0 || it->tab_width > 1000)
1299 it->tab_width = 8;
1300
1301 /* Are lines in the display truncated? */
1302 it->truncate_lines_p
1303 = (base_face_id != DEFAULT_FACE_ID
1304 || XINT (it->w->hscroll)
1305 || (truncate_partial_width_windows
1306 && !WINDOW_FULL_WIDTH_P (it->w))
1307 || !NILP (current_buffer->truncate_lines));
1308
1309 /* Get dimensions of truncation and continuation glyphs. These are
1310 displayed as bitmaps under X, so we don't need them for such
1311 frames. */
1312 if (!FRAME_WINDOW_P (it->f))
1313 {
1314 if (it->truncate_lines_p)
1315 {
1316 /* We will need the truncation glyph. */
1317 xassert (it->glyph_row == NULL);
1318 produce_special_glyphs (it, IT_TRUNCATION);
1319 it->truncation_pixel_width = it->pixel_width;
1320 }
1321 else
1322 {
1323 /* We will need the continuation glyph. */
1324 xassert (it->glyph_row == NULL);
1325 produce_special_glyphs (it, IT_CONTINUATION);
1326 it->continuation_pixel_width = it->pixel_width;
1327 }
1328
1329 /* Reset these values to zero becaue the produce_special_glyphs
1330 above has changed them. */
1331 it->pixel_width = it->ascent = it->descent = 0;
312246d1 1332 it->phys_ascent = it->phys_descent = 0;
5f5c8ee5
GM
1333 }
1334
1335 /* Set this after getting the dimensions of truncation and
1336 continuation glyphs, so that we don't produce glyphs when calling
1337 produce_special_glyphs, above. */
1338 it->glyph_row = row;
1339 it->area = TEXT_AREA;
1340
1341 /* Get the dimensions of the display area. The display area
1342 consists of the visible window area plus a horizontally scrolled
1343 part to the left of the window. All x-values are relative to the
1344 start of this total display area. */
1345 if (base_face_id != DEFAULT_FACE_ID)
1346 {
1347 /* Mode lines, menu bar in terminal frames. */
1348 it->first_visible_x = 0;
1349 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1350 }
1351 else
1352 {
1353 it->first_visible_x
1354 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1355 it->last_visible_x = (it->first_visible_x
1356 + window_box_width (w, TEXT_AREA));
1357
1358 /* If we truncate lines, leave room for the truncator glyph(s) at
1359 the right margin. Otherwise, leave room for the continuation
1360 glyph(s). Truncation and continuation glyphs are not inserted
1361 for window-based redisplay. */
1362 if (!FRAME_WINDOW_P (it->f))
1363 {
1364 if (it->truncate_lines_p)
1365 it->last_visible_x -= it->truncation_pixel_width;
1366 else
1367 it->last_visible_x -= it->continuation_pixel_width;
1368 }
1369
1370 it->top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
1371 it->current_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w) + w->vscroll;
1372 }
1373
1374 /* Leave room for a border glyph. */
1375 if (!FRAME_WINDOW_P (it->f)
1376 && !WINDOW_RIGHTMOST_P (it->w))
1377 it->last_visible_x -= 1;
1378
1379 it->last_visible_y = window_text_bottom_y (w);
1380
1381 /* For mode lines and alike, arrange for the first glyph having a
1382 left box line if the face specifies a box. */
1383 if (base_face_id != DEFAULT_FACE_ID)
1384 {
1385 struct face *face;
1386
1387 it->face_id = base_face_id;
1388
1389 /* If we have a boxed mode line, make the first character appear
1390 with a left box line. */
1391 face = FACE_FROM_ID (it->f, base_face_id);
1392 if (face->box != FACE_NO_BOX)
1393 it->start_of_box_run_p = 1;
1394 }
1395
1396 /* If a buffer position was specified, set the iterator there,
1397 getting overlays and face properties from that position. */
1398 if (charpos > 0)
1399 {
1400 it->end_charpos = ZV;
1401 it->face_id = -1;
1402 IT_CHARPOS (*it) = charpos;
1403
1404 /* Compute byte position if not specified. */
1405 if (bytepos <= 0)
1406 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1407 else
1408 IT_BYTEPOS (*it) = bytepos;
1409
1410 /* Compute faces etc. */
1411 reseat (it, it->current.pos, 1);
1412 }
1413
1414 CHECK_IT (it);
1415}
1416
1417
1418/* Initialize IT for the display of window W with window start POS. */
1419
1420void
1421start_display (it, w, pos)
1422 struct it *it;
1423 struct window *w;
1424 struct text_pos pos;
1425{
1426 int start_at_line_beg_p;
1427 struct glyph_row *row;
1428 int first_vpos = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
1429 int first_y;
1430
1431 row = w->desired_matrix->rows + first_vpos;
1432 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1433 first_y = it->current_y;
1434
1435 /* If window start is not at a line start, move back to the line
1436 start. This makes sure that we take continuation lines into
1437 account. */
1438 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1439 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1440 if (!start_at_line_beg_p)
1441 reseat_at_previous_visible_line_start (it);
1442
5f5c8ee5
GM
1443 /* If window start is not at a line start, skip forward to POS to
1444 get the correct continuation_lines_width and current_x. */
1445 if (!start_at_line_beg_p)
1446 {
1447 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1448
1449 /* If lines are continued, this line may end in the middle of a
1450 multi-glyph character (e.g. a control character displayed as
1451 \003, or in the middle of an overlay string). In this case
1452 move_it_to above will not have taken us to the start of
1453 the continuation line but to the end of the continued line. */
1454 if (!it->truncate_lines_p && it->current_x > 0)
1455 {
1456 if (it->current.dpvec_index >= 0
1457 || it->current.overlay_string_index >= 0)
1458 {
1459 set_iterator_to_next (it);
1460 move_it_in_display_line_to (it, -1, -1, 0);
1461 }
1462 it->continuation_lines_width += it->current_x;
1463 }
1464
1465 it->current_y = first_y;
1466 it->vpos = 0;
1467 it->current_x = it->hpos = 0;
1468 }
1469
1470#if 0 /* Don't assert the following because start_display is sometimes
1471 called intentionally with a window start that is not at a
1472 line start. Please leave this code in as a comment. */
1473
1474 /* Window start should be on a line start, now. */
1475 xassert (it->continuation_lines_width
1476 || IT_CHARPOS (it) == BEGV
1477 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1478#endif /* 0 */
1479}
1480
1481
1482/* Initialize IT for stepping through current_buffer in window W,
1483 starting at position POS that includes overlay string and display
1484 vector/ control character translation position information. */
1485
1486static void
1487init_from_display_pos (it, w, pos)
1488 struct it *it;
1489 struct window *w;
1490 struct display_pos *pos;
1491{
1492 /* Keep in mind: the call to reseat in init_iterator skips invisible
1493 text, so we might end up at a position different from POS. This
1494 is only a problem when POS is a row start after a newline and an
1495 overlay starts there with an after-string, and the overlay has an
1496 invisible property. Since we don't skip invisible text in
1497 display_line and elsewhere immediately after consuming the
1498 newline before the row start, such a POS will not be in a string,
1499 but the call to init_iterator below will move us to the
1500 after-string. */
1501 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1502 NULL, DEFAULT_FACE_ID);
1503
1504 /* If position is within an overlay string, set up IT to
1505 the right overlay string. */
1506 if (pos->overlay_string_index >= 0)
1507 {
1508 int relative_index;
1509
1510 /* We already have the first chunk of overlay strings in
1511 IT->overlay_strings. Load more until the one for
1512 pos->overlay_string_index is in IT->overlay_strings. */
1513 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1514 {
1515 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1516 it->current.overlay_string_index = 0;
1517 while (n--)
1518 {
1519 load_overlay_strings (it);
1520 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1521 }
1522 }
1523
1524 it->current.overlay_string_index = pos->overlay_string_index;
1525 relative_index = (it->current.overlay_string_index
1526 % OVERLAY_STRING_CHUNK_SIZE);
1527 it->string = it->overlay_strings[relative_index];
1528 it->current.string_pos = pos->string_pos;
1529 it->method = next_element_from_string;
1530 }
1531 else if (CHARPOS (pos->string_pos) >= 0)
1532 {
1533 /* Recorded position is not in an overlay string, but in another
1534 string. This can only be a string from a `display' property.
1535 IT should already be filled with that string. */
1536 it->current.string_pos = pos->string_pos;
1537 xassert (STRINGP (it->string));
1538 }
1539
1540 /* Restore position in display vector translations or control
1541 character translations. */
1542 if (pos->dpvec_index >= 0)
1543 {
1544 /* This fills IT->dpvec. */
1545 get_next_display_element (it);
1546 xassert (it->dpvec && it->current.dpvec_index == 0);
1547 it->current.dpvec_index = pos->dpvec_index;
1548 }
1549
1550 CHECK_IT (it);
1551}
1552
1553
1554/* Initialize IT for stepping through current_buffer in window W
1555 starting at ROW->start. */
1556
1557static void
1558init_to_row_start (it, w, row)
1559 struct it *it;
1560 struct window *w;
1561 struct glyph_row *row;
1562{
1563 init_from_display_pos (it, w, &row->start);
1564 it->continuation_lines_width = row->continuation_lines_width;
1565 CHECK_IT (it);
1566}
1567
1568
1569/* Initialize IT for stepping through current_buffer in window W
1570 starting in the line following ROW, i.e. starting at ROW->end. */
1571
1572static void
1573init_to_row_end (it, w, row)
1574 struct it *it;
1575 struct window *w;
1576 struct glyph_row *row;
1577{
1578 init_from_display_pos (it, w, &row->end);
1579
1580 if (row->continued_p)
1581 it->continuation_lines_width = (row->continuation_lines_width
1582 + row->pixel_width);
1583 CHECK_IT (it);
1584}
1585
1586
1587
1588\f
1589/***********************************************************************
1590 Text properties
1591 ***********************************************************************/
1592
1593/* Called when IT reaches IT->stop_charpos. Handle text property and
1594 overlay changes. Set IT->stop_charpos to the next position where
1595 to stop. */
1596
1597static void
1598handle_stop (it)
1599 struct it *it;
1600{
1601 enum prop_handled handled;
1602 int handle_overlay_change_p = 1;
1603 struct props *p;
1604
1605 it->dpvec = NULL;
1606 it->current.dpvec_index = -1;
1607
1608 do
1609 {
1610 handled = HANDLED_NORMALLY;
1611
1612 /* Call text property handlers. */
1613 for (p = it_props; p->handler; ++p)
1614 {
1615 handled = p->handler (it);
1616
1617 if (handled == HANDLED_RECOMPUTE_PROPS)
1618 break;
1619 else if (handled == HANDLED_RETURN)
1620 return;
1621 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1622 handle_overlay_change_p = 0;
1623 }
1624
1625 if (handled != HANDLED_RECOMPUTE_PROPS)
1626 {
1627 /* Don't check for overlay strings below when set to deliver
1628 characters from a display vector. */
1629 if (it->method == next_element_from_display_vector)
1630 handle_overlay_change_p = 0;
1631
1632 /* Handle overlay changes. */
1633 if (handle_overlay_change_p)
1634 handled = handle_overlay_change (it);
1635
1636 /* Determine where to stop next. */
1637 if (handled == HANDLED_NORMALLY)
1638 compute_stop_pos (it);
1639 }
1640 }
1641 while (handled == HANDLED_RECOMPUTE_PROPS);
1642}
1643
1644
1645/* Compute IT->stop_charpos from text property and overlay change
1646 information for IT's current position. */
1647
1648static void
1649compute_stop_pos (it)
1650 struct it *it;
1651{
1652 register INTERVAL iv, next_iv;
1653 Lisp_Object object, limit, position;
1654
1655 /* If nowhere else, stop at the end. */
1656 it->stop_charpos = it->end_charpos;
1657
1658 if (STRINGP (it->string))
1659 {
1660 /* Strings are usually short, so don't limit the search for
1661 properties. */
1662 object = it->string;
1663 limit = Qnil;
1664 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1665 }
1666 else
1667 {
1668 int charpos;
1669
1670 /* If next overlay change is in front of the current stop pos
1671 (which is IT->end_charpos), stop there. Note: value of
1672 next_overlay_change is point-max if no overlay change
1673 follows. */
1674 charpos = next_overlay_change (IT_CHARPOS (*it));
1675 if (charpos < it->stop_charpos)
1676 it->stop_charpos = charpos;
1677
1678 /* If showing the region, we have to stop at the region
1679 start or end because the face might change there. */
1680 if (it->region_beg_charpos > 0)
1681 {
1682 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1683 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1684 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1685 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1686 }
1687
1688 /* Set up variables for computing the stop position from text
1689 property changes. */
1690 XSETBUFFER (object, current_buffer);
1691 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1692 XSETFASTINT (position, IT_CHARPOS (*it));
1693
1694 }
1695
1696 /* Get the interval containing IT's position. Value is a null
1697 interval if there isn't such an interval. */
1698 iv = validate_interval_range (object, &position, &position, 0);
1699 if (!NULL_INTERVAL_P (iv))
1700 {
1701 Lisp_Object values_here[LAST_PROP_IDX];
1702 struct props *p;
1703
1704 /* Get properties here. */
1705 for (p = it_props; p->handler; ++p)
1706 values_here[p->idx] = textget (iv->plist, *p->name);
1707
1708 /* Look for an interval following iv that has different
1709 properties. */
1710 for (next_iv = next_interval (iv);
1711 (!NULL_INTERVAL_P (next_iv)
1712 && (NILP (limit)
1713 || XFASTINT (limit) > next_iv->position));
1714 next_iv = next_interval (next_iv))
1715 {
1716 for (p = it_props; p->handler; ++p)
1717 {
1718 Lisp_Object new_value;
1719
1720 new_value = textget (next_iv->plist, *p->name);
1721 if (!EQ (values_here[p->idx], new_value))
1722 break;
1723 }
1724
1725 if (p->handler)
1726 break;
1727 }
1728
1729 if (!NULL_INTERVAL_P (next_iv))
1730 {
1731 if (INTEGERP (limit)
1732 && next_iv->position >= XFASTINT (limit))
1733 /* No text property change up to limit. */
1734 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1735 else
1736 /* Text properties change in next_iv. */
1737 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1738 }
1739 }
1740
1741 xassert (STRINGP (it->string)
1742 || (it->stop_charpos >= BEGV
1743 && it->stop_charpos >= IT_CHARPOS (*it)));
1744}
1745
1746
1747/* Return the position of the next overlay change after POS in
1748 current_buffer. Value is point-max if no overlay change
1749 follows. This is like `next-overlay-change' but doesn't use
1750 xmalloc. */
1751
1752static int
1753next_overlay_change (pos)
1754 int pos;
1755{
1756 int noverlays;
1757 int endpos;
1758 Lisp_Object *overlays;
1759 int len;
1760 int i;
1761
1762 /* Get all overlays at the given position. */
1763 len = 10;
1764 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1765 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1766 if (noverlays > len)
1767 {
1768 len = noverlays;
1769 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1770 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1771 }
1772
1773 /* If any of these overlays ends before endpos,
1774 use its ending point instead. */
1775 for (i = 0; i < noverlays; ++i)
1776 {
1777 Lisp_Object oend;
1778 int oendpos;
1779
1780 oend = OVERLAY_END (overlays[i]);
1781 oendpos = OVERLAY_POSITION (oend);
1782 endpos = min (endpos, oendpos);
1783 }
1784
1785 return endpos;
1786}
1787
1788
1789\f
1790/***********************************************************************
1791 Fontification
1792 ***********************************************************************/
1793
1794/* Handle changes in the `fontified' property of the current buffer by
1795 calling hook functions from Qfontification_functions to fontify
1796 regions of text. */
1797
1798static enum prop_handled
1799handle_fontified_prop (it)
1800 struct it *it;
1801{
1802 Lisp_Object prop, pos;
1803 enum prop_handled handled = HANDLED_NORMALLY;
1804
1805 /* Get the value of the `fontified' property at IT's current buffer
1806 position. (The `fontified' property doesn't have a special
1807 meaning in strings.) If the value is nil, call functions from
1808 Qfontification_functions. */
1809 if (!STRINGP (it->string)
1810 && it->s == NULL
1811 && !NILP (Vfontification_functions)
1812 && (pos = make_number (IT_CHARPOS (*it)),
1813 prop = Fget_char_property (pos, Qfontified, Qnil),
1814 NILP (prop)))
1815 {
1816 Lisp_Object args[2];
1817
1818 /* Run the hook functions. */
1819 args[0] = Qfontification_functions;
1820 args[1] = pos;
1821 Frun_hook_with_args (make_number (2), args);
1822
1823 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1824 something. This avoids an endless loop if they failed to
1825 fontify the text for which reason ever. */
1826 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1827 handled = HANDLED_RECOMPUTE_PROPS;
1828 }
1829
1830 return handled;
1831}
1832
1833
1834\f
1835/***********************************************************************
1836 Faces
1837 ***********************************************************************/
1838
1839/* Set up iterator IT from face properties at its current position.
1840 Called from handle_stop. */
1841
1842static enum prop_handled
1843handle_face_prop (it)
1844 struct it *it;
1845{
1846 int new_face_id, next_stop;
1847
1848 if (!STRINGP (it->string))
1849 {
1850 new_face_id
1851 = face_at_buffer_position (it->w,
1852 IT_CHARPOS (*it),
1853 it->region_beg_charpos,
1854 it->region_end_charpos,
1855 &next_stop,
1856 (IT_CHARPOS (*it)
1857 + TEXT_PROP_DISTANCE_LIMIT),
1858 0);
1859
1860 /* Is this a start of a run of characters with box face?
1861 Caveat: this can be called for a freshly initialized
1862 iterator; face_id is -1 is this case. We know that the new
1863 face will not change until limit, i.e. if the new face has a
1864 box, all characters up to limit will have one. But, as
1865 usual, we don't know whether limit is really the end. */
1866 if (new_face_id != it->face_id)
1867 {
1868 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1869
1870 /* If new face has a box but old face has not, this is
1871 the start of a run of characters with box, i.e. it has
1872 a shadow on the left side. The value of face_id of the
1873 iterator will be -1 if this is the initial call that gets
1874 the face. In this case, we have to look in front of IT's
1875 position and see whether there is a face != new_face_id. */
1876 it->start_of_box_run_p
1877 = (new_face->box != FACE_NO_BOX
1878 && (it->face_id >= 0
1879 || IT_CHARPOS (*it) == BEG
1880 || new_face_id != face_before_it_pos (it)));
1881 it->face_box_p = new_face->box != FACE_NO_BOX;
1882 }
1883 }
1884 else
1885 {
1886 new_face_id
1887 = face_at_string_position (it->w,
1888 it->string,
1889 IT_STRING_CHARPOS (*it),
1890 (it->current.overlay_string_index >= 0
1891 ? IT_CHARPOS (*it)
1892 : 0),
1893 it->region_beg_charpos,
1894 it->region_end_charpos,
1895 &next_stop,
1896 it->base_face_id);
1897
1898#if 0 /* This shouldn't be neccessary. Let's check it. */
1899 /* If IT is used to display a mode line we would really like to
1900 use the mode line face instead of the frame's default face. */
1901 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1902 && new_face_id == DEFAULT_FACE_ID)
1903 new_face_id = MODE_LINE_FACE_ID;
1904#endif
1905
1906 /* Is this a start of a run of characters with box? Caveat:
1907 this can be called for a freshly allocated iterator; face_id
1908 is -1 is this case. We know that the new face will not
1909 change until the next check pos, i.e. if the new face has a
1910 box, all characters up to that position will have a
1911 box. But, as usual, we don't know whether that position
1912 is really the end. */
1913 if (new_face_id != it->face_id)
1914 {
1915 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1916 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1917
1918 /* If new face has a box but old face hasn't, this is the
1919 start of a run of characters with box, i.e. it has a
1920 shadow on the left side. */
1921 it->start_of_box_run_p
1922 = new_face->box && (old_face == NULL || !old_face->box);
1923 it->face_box_p = new_face->box != FACE_NO_BOX;
1924 }
1925 }
1926
1927 it->face_id = new_face_id;
1928 it->charset = CHARSET_ASCII;
1929 return HANDLED_NORMALLY;
1930}
1931
1932
1933/* Compute the face one character before or after the current position
1934 of IT. BEFORE_P non-zero means get the face in front of IT's
1935 position. Value is the id of the face. */
1936
1937static int
1938face_before_or_after_it_pos (it, before_p)
1939 struct it *it;
1940 int before_p;
1941{
1942 int face_id, limit;
1943 int next_check_charpos;
1944 struct text_pos pos;
1945
1946 xassert (it->s == NULL);
1947
1948 if (STRINGP (it->string))
1949 {
1950 /* No face change past the end of the string (for the case
1951 we are padding with spaces). No face change before the
1952 string start. */
1953 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1954 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1955 return it->face_id;
1956
1957 /* Set pos to the position before or after IT's current position. */
1958 if (before_p)
1959 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1960 else
1961 pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string);
1962
1963 /* Get the face for ASCII, or unibyte. */
1964 face_id
1965 = face_at_string_position (it->w,
1966 it->string,
1967 CHARPOS (pos),
1968 (it->current.overlay_string_index >= 0
1969 ? IT_CHARPOS (*it)
1970 : 0),
1971 it->region_beg_charpos,
1972 it->region_end_charpos,
1973 &next_check_charpos,
1974 it->base_face_id);
1975
1976 /* Correct the face for charsets different from ASCII. Do it
1977 for the multibyte case only. The face returned above is
1978 suitable for unibyte text if IT->string is unibyte. */
1979 if (STRING_MULTIBYTE (it->string))
1980 {
1981 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1982 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1983 int c, len, charset;
1984
4fdb80f2 1985 c = string_char_and_length (p, rest, &len);
5f5c8ee5
GM
1986 charset = CHAR_CHARSET (c);
1987 if (charset != CHARSET_ASCII)
1988 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
1989 }
1990 }
1991 else
1992 {
70851746
GM
1993 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1994 || (IT_CHARPOS (*it) <= BEGV && before_p))
1995 return it->face_id;
1996
5f5c8ee5
GM
1997 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1998 pos = it->current.pos;
1999
2000 if (before_p)
2001 DEC_TEXT_POS (pos);
2002 else
2003 INC_TEXT_POS (pos);
70851746 2004
5f5c8ee5
GM
2005 /* Determine face for CHARSET_ASCII, or unibyte. */
2006 face_id = face_at_buffer_position (it->w,
2007 CHARPOS (pos),
2008 it->region_beg_charpos,
2009 it->region_end_charpos,
2010 &next_check_charpos,
2011 limit, 0);
2012
2013 /* Correct the face for charsets different from ASCII. Do it
2014 for the multibyte case only. The face returned above is
2015 suitable for unibyte text if current_buffer is unibyte. */
2016 if (it->multibyte_p)
2017 {
2018 int charset = charset_at_position (pos);
2019 if (charset != CHARSET_ASCII)
2020 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
2021 }
2022 }
2023
2024 return face_id;
2025}
2026
2027
2028\f
2029/***********************************************************************
2030 Invisible text
2031 ***********************************************************************/
2032
2033/* Set up iterator IT from invisible properties at its current
2034 position. Called from handle_stop. */
2035
2036static enum prop_handled
2037handle_invisible_prop (it)
2038 struct it *it;
2039{
2040 enum prop_handled handled = HANDLED_NORMALLY;
2041
2042 if (STRINGP (it->string))
2043 {
2044 extern Lisp_Object Qinvisible;
2045 Lisp_Object prop, end_charpos, limit, charpos;
2046
2047 /* Get the value of the invisible text property at the
2048 current position. Value will be nil if there is no such
2049 property. */
2050 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2051 prop = Fget_text_property (charpos, Qinvisible, it->string);
2052
2053 if (!NILP (prop))
2054 {
2055 handled = HANDLED_RECOMPUTE_PROPS;
2056
2057 /* Get the position at which the next change of the
2058 invisible text property can be found in IT->string.
2059 Value will be nil if the property value is the same for
2060 all the rest of IT->string. */
2061 XSETINT (limit, XSTRING (it->string)->size);
2062 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2063 it->string, limit);
2064
2065 /* Text at current position is invisible. The next
2066 change in the property is at position end_charpos.
2067 Move IT's current position to that position. */
2068 if (INTEGERP (end_charpos)
2069 && XFASTINT (end_charpos) < XFASTINT (limit))
2070 {
2071 struct text_pos old;
2072 old = it->current.string_pos;
2073 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2074 compute_string_pos (&it->current.string_pos, old, it->string);
2075 }
2076 else
2077 {
2078 /* The rest of the string is invisible. If this is an
2079 overlay string, proceed with the next overlay string
2080 or whatever comes and return a character from there. */
2081 if (it->current.overlay_string_index >= 0)
2082 {
2083 next_overlay_string (it);
2084 /* Don't check for overlay strings when we just
2085 finished processing them. */
2086 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2087 }
2088 else
2089 {
2090 struct Lisp_String *s = XSTRING (it->string);
2091 IT_STRING_CHARPOS (*it) = s->size;
2092 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2093 }
2094 }
2095 }
2096 }
2097 else
2098 {
2099 int visible_p, newpos, next_stop;
2100 Lisp_Object pos, prop;
2101
2102 /* First of all, is there invisible text at this position? */
2103 XSETFASTINT (pos, IT_CHARPOS (*it));
2104 prop = Fget_char_property (pos, Qinvisible, it->window);
2105
2106 /* If we are on invisible text, skip over it. */
2107 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2108 {
2109 /* Record whether we have to display an ellipsis for the
2110 invisible text. */
2111 int display_ellipsis_p
2112 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2113
2114 handled = HANDLED_RECOMPUTE_PROPS;
2115
2116 /* Loop skipping over invisible text. The loop is left at
2117 ZV or with IT on the first char being visible again. */
2118 do
2119 {
2120 /* Try to skip some invisible text. Return value is the
2121 position reached which can be equal to IT's position
2122 if there is nothing invisible here. This skips both
2123 over invisible text properties and overlays with
2124 invisible property. */
2125 newpos = skip_invisible (IT_CHARPOS (*it),
2126 &next_stop, ZV, it->window);
2127
2128 /* If we skipped nothing at all we weren't at invisible
2129 text in the first place. If everything to the end of
2130 the buffer was skipped, end the loop. */
2131 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2132 visible_p = 1;
2133 else
2134 {
2135 /* We skipped some characters but not necessarily
2136 all there are. Check if we ended up on visible
2137 text. Fget_char_property returns the property of
2138 the char before the given position, i.e. if we
2139 get visible_p = 1, this means that the char at
2140 newpos is visible. */
2141 XSETFASTINT (pos, newpos);
2142 prop = Fget_char_property (pos, Qinvisible, it->window);
2143 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2144 }
2145
2146 /* If we ended up on invisible text, proceed to
2147 skip starting with next_stop. */
2148 if (!visible_p)
2149 IT_CHARPOS (*it) = next_stop;
2150 }
2151 while (!visible_p);
2152
2153 /* The position newpos is now either ZV or on visible text. */
2154 IT_CHARPOS (*it) = newpos;
2155 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2156
2157 /* Maybe return `...' next for the end of the invisible text. */
2158 if (display_ellipsis_p)
2159 {
2160 if (it->dp
2161 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2162 {
2163 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2164 it->dpvec = v->contents;
2165 it->dpend = v->contents + v->size;
2166 }
2167 else
2168 {
2169 /* Default `...'. */
2170 it->dpvec = default_invis_vector;
2171 it->dpend = default_invis_vector + 3;
2172 }
2173
2174 /* The ellipsis display does not replace the display of
2175 the character at the new position. Indicate this by
2176 setting IT->dpvec_char_len to zero. */
2177 it->dpvec_char_len = 0;
2178
2179 it->current.dpvec_index = 0;
2180 it->method = next_element_from_display_vector;
2181 }
2182 }
2183 }
2184
2185 return handled;
2186}
2187
2188
2189\f
2190/***********************************************************************
2191 'display' property
2192 ***********************************************************************/
2193
2194/* Set up iterator IT from `display' property at its current position.
2195 Called from handle_stop. */
2196
2197static enum prop_handled
2198handle_display_prop (it)
2199 struct it *it;
2200{
2201 Lisp_Object prop, object;
2202 struct text_pos *position;
2203 int space_or_image_found_p;
2204
2205 if (STRINGP (it->string))
2206 {
2207 object = it->string;
2208 position = &it->current.string_pos;
2209 }
2210 else
2211 {
2212 object = Qnil;
2213 position = &it->current.pos;
2214 }
2215
2216 /* Reset those iterator values set from display property values. */
2217 it->font_height = Qnil;
2218 it->space_width = Qnil;
2219 it->voffset = 0;
2220
2221 /* We don't support recursive `display' properties, i.e. string
2222 values that have a string `display' property, that have a string
2223 `display' property etc. */
2224 if (!it->string_from_display_prop_p)
2225 it->area = TEXT_AREA;
2226
2227 prop = Fget_char_property (make_number (position->charpos),
2228 Qdisplay, object);
2229 if (NILP (prop))
2230 return HANDLED_NORMALLY;
2231
2232 space_or_image_found_p = 0;
2233 if (CONSP (prop) && CONSP (XCAR (prop)))
2234 {
2235 while (CONSP (prop))
2236 {
2237 if (handle_single_display_prop (it, XCAR (prop), object, position))
2238 space_or_image_found_p = 1;
2239 prop = XCDR (prop);
2240 }
2241 }
2242 else if (VECTORP (prop))
2243 {
2244 int i;
2245 for (i = 0; i < XVECTOR (prop)->size; ++i)
2246 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2247 object, position))
2248 space_or_image_found_p = 1;
2249 }
2250 else
2251 {
2252 if (handle_single_display_prop (it, prop, object, position))
2253 space_or_image_found_p = 1;
2254 }
2255
2256 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2257}
2258
2259
2260/* Value is the position of the end of the `display' property stating
2261 at START_POS in OBJECT. */
2262
2263static struct text_pos
2264display_prop_end (it, object, start_pos)
2265 struct it *it;
2266 Lisp_Object object;
2267 struct text_pos start_pos;
2268{
2269 Lisp_Object end;
2270 struct text_pos end_pos;
2271
2272 /* Characters having this form of property are not displayed, so
2273 we have to find the end of the property. */
2274 end = Fnext_single_property_change (make_number (start_pos.charpos),
2275 Qdisplay, object, Qnil);
2276 if (NILP (end))
2277 {
2278 /* A nil value of `end' means there are no changes of the
2279 property to the end of the buffer or string. */
2280 if (it->current.overlay_string_index >= 0)
2281 end_pos.charpos = XSTRING (it->string)->size;
2282 else
2283 end_pos.charpos = it->end_charpos;
2284 }
2285 else
2286 end_pos.charpos = XFASTINT (end);
2287
2288 if (STRINGP (it->string))
2289 compute_string_pos (&end_pos, start_pos, it->string);
2290 else
2291 end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
2292
2293 return end_pos;
2294}
2295
2296
2297/* Set up IT from a single `display' sub-property value PROP. OBJECT
2298 is the object in which the `display' property was found. *POSITION
2299 is the position at which it was found.
2300
2301 If PROP is a `space' or `image' sub-property, set *POSITION to the
2302 end position of the `display' property.
2303
2304 Value is non-zero if a `space' or `image' property value was found. */
2305
2306static int
2307handle_single_display_prop (it, prop, object, position)
2308 struct it *it;
2309 Lisp_Object prop;
2310 Lisp_Object object;
2311 struct text_pos *position;
2312{
2313 Lisp_Object value;
2314 int space_or_image_found_p = 0;
2315
2316 Lisp_Object form;
2317
2318 /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
2319 evaluated. If the result is nil, VALUE is ignored. */
2320 form = Qt;
2321 if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
2322 {
2323 prop = XCDR (prop);
2324 if (!CONSP (prop))
2325 return 0;
2326 form = XCAR (prop);
2327 prop = XCDR (prop);
2328 if (!CONSP (prop))
2329 return 0;
2330 prop = XCAR (prop);
2331 }
2332
2333 if (!NILP (form) && !EQ (form, Qt))
2334 {
2335 struct gcpro gcpro1;
2336 struct text_pos end_pos, pt;
2337
2338 end_pos = display_prop_end (it, object, *position);
2339 GCPRO1 (form);
2340
2341 /* Temporarily set point to the end position, and then evaluate
2342 the form. This makes `(eolp)' work as FORM. */
2343 CHARPOS (pt) = PT;
2344 BYTEPOS (pt) = PT_BYTE;
2345 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2346 form = eval_form (form);
2347 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2348 UNGCPRO;
2349 }
2350
2351 if (NILP (form))
2352 return 0;
2353
2354 if (CONSP (prop)
2355 && EQ (XCAR (prop), Qheight)
2356 && CONSP (XCDR (prop)))
2357 {
2358 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2359 return 0;
2360
2361 /* `(height HEIGHT)'. */
2362 it->font_height = XCAR (XCDR (prop));
2363 if (!NILP (it->font_height))
2364 {
2365 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2366 int new_height = -1;
2367
2368 if (CONSP (it->font_height)
2369 && (EQ (XCAR (it->font_height), Qplus)
2370 || EQ (XCAR (it->font_height), Qminus))
2371 && CONSP (XCDR (it->font_height))
2372 && INTEGERP (XCAR (XCDR (it->font_height))))
2373 {
2374 /* `(+ N)' or `(- N)' where N is an integer. */
2375 int steps = XINT (XCAR (XCDR (it->font_height)));
2376 if (EQ (XCAR (it->font_height), Qplus))
2377 steps = - steps;
2378 it->face_id = smaller_face (it->f, it->face_id, steps);
2379 }
2380 else if (SYMBOLP (it->font_height))
2381 {
2382 /* Call function with current height as argument.
2383 Value is the new height. */
2384 Lisp_Object form, height;
2385 struct gcpro gcpro1;
2386
2387 height = face->lface[LFACE_HEIGHT_INDEX];
2388 form = Fcons (it->font_height, Fcons (height, Qnil));
2389 GCPRO1 (form);
2390 height = eval_form (form);
2391 if (NUMBERP (height))
2392 new_height = XFLOATINT (height);
2393 UNGCPRO;
2394 }
2395 else if (NUMBERP (it->font_height))
2396 {
2397 /* Value is a multiple of the canonical char height. */
2398 struct face *face;
2399
2400 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2401 new_height = (XFLOATINT (it->font_height)
2402 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2403 }
2404 else
2405 {
2406 /* Evaluate IT->font_height with `height' bound to the
2407 current specified height to get the new height. */
2408 Lisp_Object value;
2409 int count = specpdl_ptr - specpdl;
2410
2411 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2412 value = eval_form (it->font_height);
2413 unbind_to (count, Qnil);
2414
2415 if (NUMBERP (value))
2416 new_height = XFLOATINT (value);
2417 }
2418
2419 if (new_height > 0)
2420 it->face_id = face_with_height (it->f, it->face_id, new_height);
2421 }
2422 }
2423 else if (CONSP (prop)
2424 && EQ (XCAR (prop), Qspace_width)
2425 && CONSP (XCDR (prop)))
2426 {
2427 /* `(space_width WIDTH)'. */
2428 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2429 return 0;
2430
2431 value = XCAR (XCDR (prop));
2432 if (NUMBERP (value) && XFLOATINT (value) > 0)
2433 it->space_width = value;
2434 }
2435 else if (CONSP (prop)
2436 && EQ (XCAR (prop), Qraise)
2437 && CONSP (XCDR (prop)))
2438 {
2439#ifdef HAVE_WINDOW_SYSTEM
2440 /* `(raise FACTOR)'. */
2441 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2442 return 0;
2443
2444 value = XCAR (XCDR (prop));
2445 if (NUMBERP (value))
2446 {
2447 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2448 it->voffset = - (XFLOATINT (value)
2449 * (face->font->ascent + face->font->descent));
2450 }
2451#endif /* HAVE_WINDOW_SYSTEM */
2452 }
2453 else if (!it->string_from_display_prop_p)
2454 {
2455 /* `(left-margin VALUE)' or `(right-margin VALUE)
2456 or `(nil VALUE)' or VALUE. */
2457 Lisp_Object location, value;
2458 struct text_pos start_pos;
2459 int valid_p;
2460
2461 /* Characters having this form of property are not displayed, so
2462 we have to find the end of the property. */
2463 space_or_image_found_p = 1;
2464 start_pos = *position;
2465 *position = display_prop_end (it, object, start_pos);
2466
2467 /* Let's stop at the new position and assume that all
2468 text properties change there. */
2469 it->stop_charpos = position->charpos;
2470
2471 if (CONSP (prop)
2472 && !EQ (XCAR (prop), Qspace)
2473 && !EQ (XCAR (prop), Qimage))
2474 {
2475 location = XCAR (prop);
2476 value = XCDR (prop);
2477 }
2478 else
2479 {
2480 location = Qnil;
2481 value = prop;
2482 }
2483
2484#ifdef HAVE_WINDOW_SYSTEM
2485 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2486 valid_p = STRINGP (value);
2487 else
2488 valid_p = (STRINGP (value)
2489 || (CONSP (value) && EQ (XCAR (value), Qspace))
2490 || valid_image_p (value));
2491#else /* not HAVE_WINDOW_SYSTEM */
2492 valid_p = STRINGP (value);
2493#endif /* not HAVE_WINDOW_SYSTEM */
2494
2495 if ((EQ (location, Qleft_margin)
2496 || EQ (location, Qright_margin)
2497 || NILP (location))
2498 && valid_p)
2499 {
2500 /* Save current settings of IT so that we can restore them
2501 when we are finished with the glyph property value. */
2502 push_it (it);
2503
2504 if (NILP (location))
2505 it->area = TEXT_AREA;
2506 else if (EQ (location, Qleft_margin))
2507 it->area = LEFT_MARGIN_AREA;
2508 else
2509 it->area = RIGHT_MARGIN_AREA;
2510
2511 if (STRINGP (value))
2512 {
2513 it->string = value;
2514 it->multibyte_p = STRING_MULTIBYTE (it->string);
2515 it->current.overlay_string_index = -1;
2516 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2517 it->end_charpos = it->string_nchars
2518 = XSTRING (it->string)->size;
2519 it->method = next_element_from_string;
2520 it->stop_charpos = 0;
2521 it->string_from_display_prop_p = 1;
2522 }
2523 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2524 {
2525 it->method = next_element_from_stretch;
2526 it->object = value;
2527 it->current.pos = it->position = start_pos;
2528 }
2529#ifdef HAVE_WINDOW_SYSTEM
2530 else
2531 {
2532 it->what = IT_IMAGE;
2533 it->image_id = lookup_image (it->f, value);
2534 it->position = start_pos;
2535 it->object = NILP (object) ? it->w->buffer : object;
2536 it->method = next_element_from_image;
2537
2538 /* Say that we don't have consumed the characters with
2539 `display' property yet. The call to pop_it in
2540 set_iterator_to_next will clean this up. */
2541 *position = start_pos;
2542 }
2543#endif /* HAVE_WINDOW_SYSTEM */
2544 }
2545 }
2546
2547 return space_or_image_found_p;
2548}
2549
2550
2551\f
2552/***********************************************************************
2553 Overlay strings
2554 ***********************************************************************/
2555
2556/* The following structure is used to record overlay strings for
2557 later sorting in load_overlay_strings. */
2558
2559struct overlay_entry
2560{
2561 Lisp_Object string;
2562 int priority;
2563 int after_string_p;
2564};
2565
2566
2567/* Set up iterator IT from overlay strings at its current position.
2568 Called from handle_stop. */
2569
2570static enum prop_handled
2571handle_overlay_change (it)
2572 struct it *it;
2573{
2574 /* Overlays are handled in current_buffer only. */
2575 if (STRINGP (it->string))
2576 return HANDLED_NORMALLY;
2577 else
2578 return (get_overlay_strings (it)
2579 ? HANDLED_RECOMPUTE_PROPS
2580 : HANDLED_NORMALLY);
2581}
2582
2583
2584/* Set up the next overlay string for delivery by IT, if there is an
2585 overlay string to deliver. Called by set_iterator_to_next when the
2586 end of the current overlay string is reached. If there are more
2587 overlay strings to display, IT->string and
2588 IT->current.overlay_string_index are set appropriately here.
2589 Otherwise IT->string is set to nil. */
2590
2591static void
2592next_overlay_string (it)
2593 struct it *it;
2594{
2595 ++it->current.overlay_string_index;
2596 if (it->current.overlay_string_index == it->n_overlay_strings)
2597 {
2598 /* No more overlay strings. Restore IT's settings to what
2599 they were before overlay strings were processed, and
2600 continue to deliver from current_buffer. */
2601 pop_it (it);
2602 xassert (it->stop_charpos >= BEGV
2603 && it->stop_charpos <= it->end_charpos);
2604 it->string = Qnil;
2605 it->current.overlay_string_index = -1;
2606 SET_TEXT_POS (it->current.string_pos, -1, -1);
2607 it->n_overlay_strings = 0;
2608 it->method = next_element_from_buffer;
2609 }
2610 else
2611 {
2612 /* There are more overlay strings to process. If
2613 IT->current.overlay_string_index has advanced to a position
2614 where we must load IT->overlay_strings with more strings, do
2615 it. */
2616 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2617
2618 if (it->current.overlay_string_index && i == 0)
2619 load_overlay_strings (it);
2620
2621 /* Initialize IT to deliver display elements from the overlay
2622 string. */
2623 it->string = it->overlay_strings[i];
2624 it->multibyte_p = STRING_MULTIBYTE (it->string);
2625 SET_TEXT_POS (it->current.string_pos, 0, 0);
2626 it->method = next_element_from_string;
2627 it->stop_charpos = 0;
2628 }
2629
2630 CHECK_IT (it);
2631}
2632
2633
2634/* Compare two overlay_entry structures E1 and E2. Used as a
2635 comparison function for qsort in load_overlay_strings. Overlay
2636 strings for the same position are sorted so that
2637
2638 1. All after-strings come in front of before-strings.
2639
2640 2. Within after-strings, strings are sorted so that overlay strings
2641 from overlays with higher priorities come first.
2642
2643 2. Within before-strings, strings are sorted so that overlay
2644 strings from overlays with higher priorities come last.
2645
2646 Value is analogous to strcmp. */
2647
2648
2649static int
2650compare_overlay_entries (e1, e2)
2651 void *e1, *e2;
2652{
2653 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2654 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2655 int result;
2656
2657 if (entry1->after_string_p != entry2->after_string_p)
2658 /* Let after-strings appear in front of before-strings. */
2659 result = entry1->after_string_p ? -1 : 1;
2660 else if (entry1->after_string_p)
2661 /* After-strings sorted in order of decreasing priority. */
2662 result = entry2->priority - entry1->priority;
2663 else
2664 /* Before-strings sorted in order of increasing priority. */
2665 result = entry1->priority - entry2->priority;
2666
2667 return result;
2668}
2669
2670
2671/* Load the vector IT->overlay_strings with overlay strings from IT's
2672 current buffer position. Set IT->n_overlays to the total number of
2673 overlay strings found.
2674
2675 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2676 a time. On entry into load_overlay_strings,
2677 IT->current.overlay_string_index gives the number of overlay
2678 strings that have already been loaded by previous calls to this
2679 function.
2680
2681 Overlay strings are sorted so that after-string strings come in
2682 front of before-string strings. Within before and after-strings,
2683 strings are sorted by overlay priority. See also function
2684 compare_overlay_entries. */
2685
2686static void
2687load_overlay_strings (it)
2688 struct it *it;
2689{
2690 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2691 Lisp_Object ov, overlay, window, str;
2692 int start, end;
2693 int size = 20;
2694 int n = 0, i, j;
2695 struct overlay_entry *entries
2696 = (struct overlay_entry *) alloca (size * sizeof *entries);
2697
2698 /* Append the overlay string STRING of overlay OVERLAY to vector
2699 `entries' which has size `size' and currently contains `n'
2700 elements. AFTER_P non-zero means STRING is an after-string of
2701 OVERLAY. */
2702#define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2703 do \
2704 { \
2705 Lisp_Object priority; \
2706 \
2707 if (n == size) \
2708 { \
2709 int new_size = 2 * size; \
2710 struct overlay_entry *old = entries; \
2711 entries = \
2712 (struct overlay_entry *) alloca (new_size \
2713 * sizeof *entries); \
2714 bcopy (old, entries, size * sizeof *entries); \
2715 size = new_size; \
2716 } \
2717 \
2718 entries[n].string = (STRING); \
2719 priority = Foverlay_get ((OVERLAY), Qpriority); \
2720 entries[n].priority \
2721 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2722 entries[n].after_string_p = (AFTER_P); \
2723 ++n; \
2724 } \
2725 while (0)
2726
2727 /* Process overlay before the overlay center. */
2728 for (ov = current_buffer->overlays_before;
2729 CONSP (ov);
2730 ov = XCONS (ov)->cdr)
2731 {
2732 overlay = XCONS (ov)->car;
2733 xassert (OVERLAYP (overlay));
2734 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2735 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2736
2737 if (end < IT_CHARPOS (*it))
2738 break;
2739
2740 /* Skip this overlay if it doesn't start or end at IT's current
2741 position. */
2742 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2743 continue;
2744
2745 /* Skip this overlay if it doesn't apply to IT->w. */
2746 window = Foverlay_get (overlay, Qwindow);
2747 if (WINDOWP (window) && XWINDOW (window) != it->w)
2748 continue;
2749
2750 /* If overlay has a non-empty before-string, record it. */
2751 if (start == IT_CHARPOS (*it)
2752 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2753 && XSTRING (str)->size)
2754 RECORD_OVERLAY_STRING (overlay, str, 0);
2755
2756 /* If overlay has a non-empty after-string, record it. */
2757 if (end == IT_CHARPOS (*it)
2758 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2759 && XSTRING (str)->size)
2760 RECORD_OVERLAY_STRING (overlay, str, 1);
2761 }
2762
2763 /* Process overlays after the overlay center. */
2764 for (ov = current_buffer->overlays_after;
2765 CONSP (ov);
2766 ov = XCONS (ov)->cdr)
2767 {
2768 overlay = XCONS (ov)->car;
2769 xassert (OVERLAYP (overlay));
2770 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2771 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2772
2773 if (start > IT_CHARPOS (*it))
2774 break;
2775
2776 /* Skip this overlay if it doesn't start or end at IT's current
2777 position. */
2778 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2779 continue;
2780
2781 /* Skip this overlay if it doesn't apply to IT->w. */
2782 window = Foverlay_get (overlay, Qwindow);
2783 if (WINDOWP (window) && XWINDOW (window) != it->w)
2784 continue;
2785
2786 /* If overlay has a non-empty before-string, record it. */
2787 if (start == IT_CHARPOS (*it)
2788 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2789 && XSTRING (str)->size)
2790 RECORD_OVERLAY_STRING (overlay, str, 0);
2791
2792 /* If overlay has a non-empty after-string, record it. */
2793 if (end == IT_CHARPOS (*it)
2794 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2795 && XSTRING (str)->size)
2796 RECORD_OVERLAY_STRING (overlay, str, 1);
2797 }
2798
2799#undef RECORD_OVERLAY_STRING
2800
2801 /* Sort entries. */
2802 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2803
2804 /* Record the total number of strings to process. */
2805 it->n_overlay_strings = n;
2806
2807 /* IT->current.overlay_string_index is the number of overlay strings
2808 that have already been consumed by IT. Copy some of the
2809 remaining overlay strings to IT->overlay_strings. */
2810 i = 0;
2811 j = it->current.overlay_string_index;
2812 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2813 it->overlay_strings[i++] = entries[j++].string;
2814
2815 CHECK_IT (it);
2816}
2817
2818
2819/* Get the first chunk of overlay strings at IT's current buffer
2820 position. Value is non-zero if at least one overlay string was
2821 found. */
2822
2823static int
2824get_overlay_strings (it)
2825 struct it *it;
2826{
2827 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2828 process. This fills IT->overlay_strings with strings, and sets
2829 IT->n_overlay_strings to the total number of strings to process.
2830 IT->pos.overlay_string_index has to be set temporarily to zero
2831 because load_overlay_strings needs this; it must be set to -1
2832 when no overlay strings are found because a zero value would
2833 indicate a position in the first overlay string. */
2834 it->current.overlay_string_index = 0;
2835 load_overlay_strings (it);
2836
2837 /* If we found overlay strings, set up IT to deliver display
2838 elements from the first one. Otherwise set up IT to deliver
2839 from current_buffer. */
2840 if (it->n_overlay_strings)
2841 {
2842 /* Make sure we know settings in current_buffer, so that we can
2843 restore meaningful values when we're done with the overlay
2844 strings. */
2845 compute_stop_pos (it);
2846 xassert (it->face_id >= 0);
2847
2848 /* Save IT's settings. They are restored after all overlay
2849 strings have been processed. */
2850 xassert (it->sp == 0);
2851 push_it (it);
2852
2853 /* Set up IT to deliver display elements from the first overlay
2854 string. */
2855 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2856 it->stop_charpos = 0;
2857 it->string = it->overlay_strings[0];
2858 it->multibyte_p = STRING_MULTIBYTE (it->string);
2859 xassert (STRINGP (it->string));
2860 it->method = next_element_from_string;
2861 }
2862 else
2863 {
2864 it->string = Qnil;
2865 it->current.overlay_string_index = -1;
2866 it->method = next_element_from_buffer;
2867 }
2868
2869 CHECK_IT (it);
2870
2871 /* Value is non-zero if we found at least one overlay string. */
2872 return STRINGP (it->string);
2873}
2874
2875
2876\f
2877/***********************************************************************
2878 Saving and restoring state
2879 ***********************************************************************/
2880
2881/* Save current settings of IT on IT->stack. Called, for example,
2882 before setting up IT for an overlay string, to be able to restore
2883 IT's settings to what they were after the overlay string has been
2884 processed. */
2885
2886static void
2887push_it (it)
2888 struct it *it;
2889{
2890 struct iterator_stack_entry *p;
2891
2892 xassert (it->sp < 2);
2893 p = it->stack + it->sp;
2894
2895 p->stop_charpos = it->stop_charpos;
2896 xassert (it->face_id >= 0);
2897 p->face_id = it->face_id;
2898 p->string = it->string;
2899 p->pos = it->current;
2900 p->end_charpos = it->end_charpos;
2901 p->string_nchars = it->string_nchars;
2902 p->area = it->area;
2903 p->multibyte_p = it->multibyte_p;
2904 p->space_width = it->space_width;
2905 p->font_height = it->font_height;
2906 p->voffset = it->voffset;
2907 p->string_from_display_prop_p = it->string_from_display_prop_p;
2908 ++it->sp;
2909}
2910
2911
2912/* Restore IT's settings from IT->stack. Called, for example, when no
2913 more overlay strings must be processed, and we return to delivering
2914 display elements from a buffer, or when the end of a string from a
2915 `display' property is reached and we return to delivering display
2916 elements from an overlay string, or from a buffer. */
2917
2918static void
2919pop_it (it)
2920 struct it *it;
2921{
2922 struct iterator_stack_entry *p;
2923
2924 xassert (it->sp > 0);
2925 --it->sp;
2926 p = it->stack + it->sp;
2927 it->stop_charpos = p->stop_charpos;
2928 it->face_id = p->face_id;
2929 it->string = p->string;
2930 it->current = p->pos;
2931 it->end_charpos = p->end_charpos;
2932 it->string_nchars = p->string_nchars;
2933 it->area = p->area;
2934 it->multibyte_p = p->multibyte_p;
2935 it->space_width = p->space_width;
2936 it->font_height = p->font_height;
2937 it->voffset = p->voffset;
2938 it->string_from_display_prop_p = p->string_from_display_prop_p;
2939}
2940
2941
2942\f
2943/***********************************************************************
2944 Moving over lines
2945 ***********************************************************************/
2946
2947/* Set IT's current position to the previous line start. */
2948
2949static void
2950back_to_previous_line_start (it)
2951 struct it *it;
2952{
2953 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
2954 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2955}
2956
2957
2958/* Set IT's current position to the next line start. */
2959
2960static void
2961forward_to_next_line_start (it)
2962 struct it *it;
2963{
2964 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
2965 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2966}
2967
2968
2969/* Set IT's current position to the previous visible line start. Skip
2970 invisible text that is so either due to text properties or due to
2971 selective display. Caution: this does not change IT->current_x and
2972 IT->hpos. */
2973
2974static void
2975back_to_previous_visible_line_start (it)
2976 struct it *it;
2977{
2978 int visible_p = 0;
2979
2980 /* Go back one newline if not on BEGV already. */
2981 if (IT_CHARPOS (*it) > BEGV)
2982 back_to_previous_line_start (it);
2983
2984 /* Move over lines that are invisible because of selective display
2985 or text properties. */
2986 while (IT_CHARPOS (*it) > BEGV
2987 && !visible_p)
2988 {
2989 visible_p = 1;
2990
2991 /* If selective > 0, then lines indented more than that values
2992 are invisible. */
2993 if (it->selective > 0
2994 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
2995 it->selective))
2996 visible_p = 0;
2997#ifdef USE_TEXT_PROPERTIES
2998 else
2999 {
3000 Lisp_Object prop;
3001
3002 prop = Fget_char_property (IT_CHARPOS (*it), Qinvisible, it->window);
3003 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3004 visible_p = 0;
3005 }
3006#endif /* USE_TEXT_PROPERTIES */
3007
3008 /* Back one more newline if the current one is invisible. */
3009 if (!visible_p)
3010 back_to_previous_line_start (it);
3011 }
3012
3013 xassert (IT_CHARPOS (*it) >= BEGV);
3014 xassert (IT_CHARPOS (*it) == BEGV
3015 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3016 CHECK_IT (it);
3017}
3018
3019
3020/* Reseat iterator IT at the previous visible line start. Skip
3021 invisible text that is so either due to text properties or due to
3022 selective display. At the end, update IT's overlay information,
3023 face information etc. */
3024
3025static void
3026reseat_at_previous_visible_line_start (it)
3027 struct it *it;
3028{
3029 back_to_previous_visible_line_start (it);
3030 reseat (it, it->current.pos, 1);
3031 CHECK_IT (it);
3032}
3033
3034
3035/* Reseat iterator IT on the next visible line start in the current
312246d1
GM
3036 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3037 preceding the line start. Skip over invisible text that is so
3038 because of selective display. Compute faces, overlays etc at the
3039 new position. Note that this function does not skip over text that
3040 is invisible because of text properties. */
5f5c8ee5
GM
3041
3042static void
312246d1 3043reseat_at_next_visible_line_start (it, on_newline_p)
5f5c8ee5 3044 struct it *it;
312246d1 3045 int on_newline_p;
5f5c8ee5
GM
3046{
3047 /* Restore the buffer position when currently not delivering display
3048 elements from the current buffer. This is the case, for example,
3049 when called at the end of a truncated overlay string. */
3050 while (it->sp)
3051 pop_it (it);
3052 it->method = next_element_from_buffer;
3053
3054 /* Otherwise, scan_buffer would not work. */
3055 if (IT_CHARPOS (*it) < ZV)
3056 {
3057 /* If on a newline, advance past it. Otherwise, find the next
3058 newline which automatically gives us the position following
3059 the newline. */
3060 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3061 {
3062 ++IT_CHARPOS (*it);
3063 ++IT_BYTEPOS (*it);
3064 }
3065 else
3066 forward_to_next_line_start (it);
3067
3068 /* We must either have reached the end of the buffer or end up
3069 after a newline. */
3070 xassert (IT_CHARPOS (*it) == ZV
3071 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3072
3073 /* Skip over lines that are invisible because they are indented
3074 more than the value of IT->selective. */
3075 if (it->selective > 0)
3076 while (IT_CHARPOS (*it) < ZV
3077 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3078 it->selective))
3079 forward_to_next_line_start (it);
312246d1
GM
3080
3081 /* Position on the newline if we should. */
3082 if (on_newline_p && IT_CHARPOS (*it) > BEGV)
3083 {
3084 --IT_CHARPOS (*it);
3085 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3086 }
5f5c8ee5
GM
3087
3088 /* Set the iterator there. The 0 as the last parameter of
3089 reseat means don't force a text property lookup. The lookup
3090 is then only done if we've skipped past the iterator's
3091 check_charpos'es. This optimization is important because
3092 text property lookups tend to be expensive. */
3093 reseat (it, it->current.pos, 0);
3094 }
3095
3096 CHECK_IT (it);
3097}
3098
3099
3100\f
3101/***********************************************************************
3102 Changing an iterator's position
3103***********************************************************************/
3104
3105/* Change IT's current position to POS in current_buffer. If FORCE_P
3106 is non-zero, always check for text properties at the new position.
3107 Otherwise, text properties are only looked up if POS >=
3108 IT->check_charpos of a property. */
3109
3110static void
3111reseat (it, pos, force_p)
3112 struct it *it;
3113 struct text_pos pos;
3114 int force_p;
3115{
3116 int original_pos = IT_CHARPOS (*it);
3117
3118 reseat_1 (it, pos, 0);
3119
3120 /* Determine where to check text properties. Avoid doing it
3121 where possible because text property lookup is very expensive. */
3122 if (force_p
3123 || CHARPOS (pos) > it->stop_charpos
3124 || CHARPOS (pos) < original_pos)
3125 handle_stop (it);
3126
3127 CHECK_IT (it);
3128}
3129
3130
3131/* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3132 IT->stop_pos to POS, also. */
3133
3134static void
3135reseat_1 (it, pos, set_stop_p)
3136 struct it *it;
3137 struct text_pos pos;
3138 int set_stop_p;
3139{
3140 /* Don't call this function when scanning a C string. */
3141 xassert (it->s == NULL);
3142
3143 /* POS must be a reasonable value. */
3144 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3145
3146 it->current.pos = it->position = pos;
3147 XSETBUFFER (it->object, current_buffer);
3148 it->dpvec = NULL;
3149 it->current.dpvec_index = -1;
3150 it->current.overlay_string_index = -1;
3151 IT_STRING_CHARPOS (*it) = -1;
3152 IT_STRING_BYTEPOS (*it) = -1;
3153 it->string = Qnil;
3154 it->method = next_element_from_buffer;
3155 it->sp = 0;
3156
3157 if (set_stop_p)
3158 it->stop_charpos = CHARPOS (pos);
3159}
3160
3161
3162/* Set up IT for displaying a string, starting at CHARPOS in window W.
3163 If S is non-null, it is a C string to iterate over. Otherwise,
3164 STRING gives a Lisp string to iterate over.
3165
3166 If PRECISION > 0, don't return more then PRECISION number of
3167 characters from the string.
3168
3169 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3170 characters have been returned. FIELD_WIDTH < 0 means an infinite
3171 field width.
3172
3173 MULTIBYTE = 0 means disable processing of multibyte characters,
3174 MULTIBYTE > 0 means enable it,
3175 MULTIBYTE < 0 means use IT->multibyte_p.
3176
3177 IT must be initialized via a prior call to init_iterator before
3178 calling this function. */
3179
3180static void
3181reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3182 struct it *it;
3183 unsigned char *s;
3184 Lisp_Object string;
3185 int charpos;
3186 int precision, field_width, multibyte;
3187{
3188 /* No region in strings. */
3189 it->region_beg_charpos = it->region_end_charpos = -1;
3190
3191 /* No text property checks performed by default, but see below. */
3192 it->stop_charpos = -1;
3193
3194 /* Set iterator position and end position. */
3195 bzero (&it->current, sizeof it->current);
3196 it->current.overlay_string_index = -1;
3197 it->current.dpvec_index = -1;
3198 it->charset = CHARSET_ASCII;
3199 xassert (charpos >= 0);
3200
3201 /* Use the setting of MULTIBYTE if specified. */
3202 if (multibyte >= 0)
3203 it->multibyte_p = multibyte > 0;
3204
3205 if (s == NULL)
3206 {
3207 xassert (STRINGP (string));
3208 it->string = string;
3209 it->s = NULL;
3210 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3211 it->method = next_element_from_string;
3212 it->current.string_pos = string_pos (charpos, string);
3213 }
3214 else
3215 {
3216 it->s = s;
3217 it->string = Qnil;
3218
3219 /* Note that we use IT->current.pos, not it->current.string_pos,
3220 for displaying C strings. */
3221 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3222 if (it->multibyte_p)
3223 {
3224 it->current.pos = c_string_pos (charpos, s, 1);
3225 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3226 }
3227 else
3228 {
3229 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3230 it->end_charpos = it->string_nchars = strlen (s);
3231 }
3232
3233 it->method = next_element_from_c_string;
3234 }
3235
3236 /* PRECISION > 0 means don't return more than PRECISION characters
3237 from the string. */
3238 if (precision > 0 && it->end_charpos - charpos > precision)
3239 it->end_charpos = it->string_nchars = charpos + precision;
3240
3241 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3242 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3243 FIELD_WIDTH < 0 means infinite field width. This is useful for
3244 padding with `-' at the end of a mode line. */
3245 if (field_width < 0)
3246 field_width = INFINITY;
3247 if (field_width > it->end_charpos - charpos)
3248 it->end_charpos = charpos + field_width;
3249
3250 /* Use the standard display table for displaying strings. */
3251 if (DISP_TABLE_P (Vstandard_display_table))
3252 it->dp = XCHAR_TABLE (Vstandard_display_table);
3253
3254 it->stop_charpos = charpos;
3255 CHECK_IT (it);
3256}
3257
3258
3259\f
3260/***********************************************************************
3261 Iteration
3262 ***********************************************************************/
3263
3264/* Load IT's display element fields with information about the next
3265 display element from the current position of IT. Value is zero if
3266 end of buffer (or C string) is reached. */
3267
3268int
3269get_next_display_element (it)
3270 struct it *it;
3271{
3272 /* Non-zero means that we found an display element. Zero means that
3273 we hit the end of what we iterate over. Performance note: the
3274 function pointer `method' used here turns out to be faster than
3275 using a sequence of if-statements. */
3276 int success_p = (*it->method) (it);
3277 int charset;
3278
3279 if (it->what == IT_CHARACTER)
3280 {
3281 /* Map via display table or translate control characters.
3282 IT->c, IT->len etc. have been set to the next character by
3283 the function call above. If we have a display table, and it
3284 contains an entry for IT->c, translate it. Don't do this if
3285 IT->c itself comes from a display table, otherwise we could
3286 end up in an infinite recursion. (An alternative could be to
3287 count the recursion depth of this function and signal an
3288 error when a certain maximum depth is reached.) Is it worth
3289 it? */
3290 if (success_p && it->dpvec == NULL)
3291 {
3292 Lisp_Object dv;
3293
3294 if (it->dp
3295 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3296 VECTORP (dv)))
3297 {
3298 struct Lisp_Vector *v = XVECTOR (dv);
3299
3300 /* Return the first character from the display table
3301 entry, if not empty. If empty, don't display the
3302 current character. */
3303 if (v->size)
3304 {
3305 it->dpvec_char_len = it->len;
3306 it->dpvec = v->contents;
3307 it->dpend = v->contents + v->size;
3308 it->current.dpvec_index = 0;
3309 it->method = next_element_from_display_vector;
3310 }
3311
3312 success_p = get_next_display_element (it);
3313 }
3314
3315 /* Translate control characters into `\003' or `^C' form.
3316 Control characters coming from a display table entry are
3317 currently not translated because we use IT->dpvec to hold
3318 the translation. This could easily be changed but I
3319 don't believe that it is worth doing. */
3320 else if ((it->c < ' '
3321 && (it->area != TEXT_AREA
c6e89d6c 3322 || (it->c != '\n' && it->c != '\t')))
54c85a23 3323 || (it->c >= 127
5f5c8ee5
GM
3324 && it->len == 1))
3325 {
3326 /* IT->c is a control character which must be displayed
3327 either as '\003' or as `^C' where the '\\' and '^'
3328 can be defined in the display table. Fill
3329 IT->ctl_chars with glyphs for what we have to
3330 display. Then, set IT->dpvec to these glyphs. */
3331 GLYPH g;
3332
54c85a23 3333 if (it->c < 128 && it->ctl_arrow_p)
5f5c8ee5
GM
3334 {
3335 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3336 if (it->dp
3337 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3338 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3339 g = XINT (DISP_CTRL_GLYPH (it->dp));
3340 else
3341 g = FAST_MAKE_GLYPH ('^', 0);
3342 XSETINT (it->ctl_chars[0], g);
3343
3344 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3345 XSETINT (it->ctl_chars[1], g);
3346
3347 /* Set up IT->dpvec and return first character from it. */
3348 it->dpvec_char_len = it->len;
3349 it->dpvec = it->ctl_chars;
3350 it->dpend = it->dpvec + 2;
3351 it->current.dpvec_index = 0;
3352 it->method = next_element_from_display_vector;
3353 get_next_display_element (it);
3354 }
3355 else
3356 {
3357 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3358 if (it->dp
3359 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3360 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3361 g = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3362 else
3363 g = FAST_MAKE_GLYPH ('\\', 0);
3364 XSETINT (it->ctl_chars[0], g);
3365
3366 /* Insert three more glyphs into IT->ctl_chars for
3367 the octal display of the character. */
3368 g = FAST_MAKE_GLYPH (((it->c >> 6) & 7) + '0', 0);
3369 XSETINT (it->ctl_chars[1], g);
3370 g = FAST_MAKE_GLYPH (((it->c >> 3) & 7) + '0', 0);
3371 XSETINT (it->ctl_chars[2], g);
3372 g = FAST_MAKE_GLYPH ((it->c & 7) + '0', 0);
3373 XSETINT (it->ctl_chars[3], g);
3374
3375 /* Set up IT->dpvec and return the first character
3376 from it. */
3377 it->dpvec_char_len = it->len;
3378 it->dpvec = it->ctl_chars;
3379 it->dpend = it->dpvec + 4;
3380 it->current.dpvec_index = 0;
3381 it->method = next_element_from_display_vector;
3382 get_next_display_element (it);
3383 }
3384 }
3385 }
3386
3387 /* Adjust face id if charset changes. There are no charset
3388 changes in unibyte text because Emacs' charsets are not
3389 applicable there. */
3390 if (it->multibyte_p
3391 && success_p
3392 && (charset = CHAR_CHARSET (it->c),
3393 charset != it->charset))
3394 {
3395 it->charset = charset;
3396 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, charset);
3397 }
3398 }
3399
3400 /* Is this character the last one of a run of characters with
3401 box? If yes, set IT->end_of_box_run_p to 1. */
3402 if (it->face_box_p
3403 && it->s == NULL)
3404 {
3405 int face_id;
3406 struct face *face;
3407
3408 it->end_of_box_run_p
3409 = ((face_id = face_after_it_pos (it),
3410 face_id != it->face_id)
3411 && (face = FACE_FROM_ID (it->f, face_id),
3412 face->box == FACE_NO_BOX));
3413 }
3414
3415 /* Value is 0 if end of buffer or string reached. */
3416 return success_p;
3417}
3418
3419
3420/* Move IT to the next display element.
3421
3422 Functions get_next_display_element and set_iterator_to_next are
3423 separate because I find this arrangement easier to handle than a
3424 get_next_display_element function that also increments IT's
3425 position. The way it is we can first look at an iterator's current
3426 display element, decide whether it fits on a line, and if it does,
3427 increment the iterator position. The other way around we probably
3428 would either need a flag indicating whether the iterator has to be
3429 incremented the next time, or we would have to implement a
3430 decrement position function which would not be easy to write. */
3431
3432void
3433set_iterator_to_next (it)
3434 struct it *it;
3435{
3436 if (it->method == next_element_from_buffer)
3437 {
3438 /* The current display element of IT is a character from
3439 current_buffer. Advance in the buffer, and maybe skip over
3440 invisible lines that are so because of selective display. */
3441 if (ITERATOR_AT_END_OF_LINE_P (it))
312246d1 3442 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
3443 else
3444 {
3445 xassert (it->len != 0);
3446 IT_BYTEPOS (*it) += it->len;
3447 IT_CHARPOS (*it) += 1;
3448 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3449 }
3450 }
3451 else if (it->method == next_element_from_c_string)
3452 {
3453 /* Current display element of IT is from a C string. */
3454 IT_BYTEPOS (*it) += it->len;
3455 IT_CHARPOS (*it) += 1;
3456 }
3457 else if (it->method == next_element_from_display_vector)
3458 {
3459 /* Current display element of IT is from a display table entry.
3460 Advance in the display table definition. Reset it to null if
3461 end reached, and continue with characters from buffers/
3462 strings. */
3463 ++it->current.dpvec_index;
286bcbc9
GM
3464
3465 /* Restore face and charset of the iterator to what they were
3466 before the display vector entry (these entries may contain
3467 faces, and of course characters of different charsets). */
5f5c8ee5 3468 it->face_id = it->saved_face_id;
286bcbc9
GM
3469 it->charset = FACE_FROM_ID (it->f, it->face_id)->charset;
3470
5f5c8ee5
GM
3471 if (it->dpvec + it->current.dpvec_index == it->dpend)
3472 {
3473 if (it->s)
3474 it->method = next_element_from_c_string;
3475 else if (STRINGP (it->string))
3476 it->method = next_element_from_string;
3477 else
3478 it->method = next_element_from_buffer;
3479
3480 it->dpvec = NULL;
3481 it->current.dpvec_index = -1;
3482
312246d1
GM
3483 /* Skip over characters which were displayed via IT->dpvec. */
3484 if (it->dpvec_char_len < 0)
3485 reseat_at_next_visible_line_start (it, 1);
3486 else if (it->dpvec_char_len > 0)
5f5c8ee5
GM
3487 {
3488 it->len = it->dpvec_char_len;
3489 set_iterator_to_next (it);
3490 }
3491 }
3492 }
3493 else if (it->method == next_element_from_string)
3494 {
3495 /* Current display element is a character from a Lisp string. */
3496 xassert (it->s == NULL && STRINGP (it->string));
3497 IT_STRING_BYTEPOS (*it) += it->len;
3498 IT_STRING_CHARPOS (*it) += 1;
3499
3500 consider_string_end:
3501
3502 if (it->current.overlay_string_index >= 0)
3503 {
3504 /* IT->string is an overlay string. Advance to the
3505 next, if there is one. */
3506 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3507 next_overlay_string (it);
3508 }
3509 else
3510 {
3511 /* IT->string is not an overlay string. If we reached
3512 its end, and there is something on IT->stack, proceed
3513 with what is on the stack. This can be either another
3514 string, this time an overlay string, or a buffer. */
3515 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3516 && it->sp > 0)
3517 {
3518 pop_it (it);
3519 if (!STRINGP (it->string))
3520 it->method = next_element_from_buffer;
3521 }
3522 }
3523 }
3524 else if (it->method == next_element_from_image
3525 || it->method == next_element_from_stretch)
3526 {
3527 /* The position etc with which we have to proceed are on
3528 the stack. The position may be at the end of a string,
3529 if the `display' property takes up the whole string. */
3530 pop_it (it);
3531 it->image_id = 0;
3532 if (STRINGP (it->string))
3533 {
3534 it->method = next_element_from_string;
3535 goto consider_string_end;
3536 }
3537 else
3538 it->method = next_element_from_buffer;
3539 }
3540 else
3541 /* There are no other methods defined, so this should be a bug. */
3542 abort ();
3543
3544 /* Reset flags indicating start and end of a sequence of
3545 characters with box. */
3546 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3547
3548 xassert (it->method != next_element_from_string
3549 || (STRINGP (it->string)
3550 && IT_STRING_CHARPOS (*it) >= 0));
3551}
3552
3553
3554/* Load IT's display element fields with information about the next
3555 display element which comes from a display table entry or from the
3556 result of translating a control character to one of the forms `^C'
3557 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3558
3559static int
3560next_element_from_display_vector (it)
3561 struct it *it;
3562{
3563 /* Precondition. */
3564 xassert (it->dpvec && it->current.dpvec_index >= 0);
3565
3566 /* Remember the current face id in case glyphs specify faces.
3567 IT's face is restored in set_iterator_to_next. */
3568 it->saved_face_id = it->face_id;
3569
3570 if (INTEGERP (*it->dpvec)
3571 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3572 {
3573 int lface_id;
3574 GLYPH g;
3575
3576 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3577 it->c = FAST_GLYPH_CHAR (g);
3578 it->len = CHAR_LEN (it->c);
3579
3580 /* The entry may contain a face id to use. Such a face id is
3581 the id of a Lisp face, not a realized face. A face id of
3582 zero means no face. */
3583 lface_id = FAST_GLYPH_FACE (g);
3584 if (lface_id)
3585 {
3586 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3587 if (face_id >= 0)
3588 {
3589 it->face_id = face_id;
3590 it->charset = CHARSET_ASCII;
3591 }
3592 }
3593 }
3594 else
3595 /* Display table entry is invalid. Return a space. */
3596 it->c = ' ', it->len = 1;
3597
3598 /* Don't change position and object of the iterator here. They are
3599 still the values of the character that had this display table
3600 entry or was translated, and that's what we want. */
3601 it->what = IT_CHARACTER;
3602 return 1;
3603}
3604
3605
3606/* Load IT with the next display element from Lisp string IT->string.
3607 IT->current.string_pos is the current position within the string.
3608 If IT->current.overlay_string_index >= 0, the Lisp string is an
3609 overlay string. */
3610
3611static int
3612next_element_from_string (it)
3613 struct it *it;
3614{
3615 struct text_pos position;
3616
3617 xassert (STRINGP (it->string));
3618 xassert (IT_STRING_CHARPOS (*it) >= 0);
3619 position = it->current.string_pos;
3620
3621 /* Time to check for invisible text? */
3622 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3623 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3624 {
3625 handle_stop (it);
3626
3627 /* Since a handler may have changed IT->method, we must
3628 recurse here. */
3629 return get_next_display_element (it);
3630 }
3631
3632 if (it->current.overlay_string_index >= 0)
3633 {
3634 /* Get the next character from an overlay string. In overlay
3635 strings, There is no field width or padding with spaces to
3636 do. */
3637 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3638 {
3639 it->what = IT_EOB;
3640 return 0;
3641 }
3642 else if (STRING_MULTIBYTE (it->string))
3643 {
3644 int remaining = (STRING_BYTES (XSTRING (it->string))
3645 - IT_STRING_BYTEPOS (*it));
3646 unsigned char *s = (XSTRING (it->string)->data
3647 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3648 it->c = string_char_and_length (s, remaining, &it->len);
5f5c8ee5
GM
3649 }
3650 else
3651 {
3652 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3653 it->len = 1;
3654 }
3655 }
3656 else
3657 {
3658 /* Get the next character from a Lisp string that is not an
3659 overlay string. Such strings come from the mode line, for
3660 example. We may have to pad with spaces, or truncate the
3661 string. See also next_element_from_c_string. */
3662 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3663 {
3664 it->what = IT_EOB;
3665 return 0;
3666 }
3667 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3668 {
3669 /* Pad with spaces. */
3670 it->c = ' ', it->len = 1;
3671 CHARPOS (position) = BYTEPOS (position) = -1;
3672 }
3673 else if (STRING_MULTIBYTE (it->string))
3674 {
3675 int maxlen = (STRING_BYTES (XSTRING (it->string))
3676 - IT_STRING_BYTEPOS (*it));
3677 unsigned char *s = (XSTRING (it->string)->data
3678 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3679 it->c = string_char_and_length (s, maxlen, &it->len);
5f5c8ee5
GM
3680 }
3681 else
3682 {
3683 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3684 it->len = 1;
3685 }
3686 }
3687
3688 /* Record what we have and where it came from. Note that we store a
3689 buffer position in IT->position although it could arguably be a
3690 string position. */
3691 it->what = IT_CHARACTER;
3692 it->object = it->string;
3693 it->position = position;
3694 return 1;
3695}
3696
3697
3698/* Load IT with next display element from C string IT->s.
3699 IT->string_nchars is the maximum number of characters to return
3700 from the string. IT->end_charpos may be greater than
3701 IT->string_nchars when this function is called, in which case we
3702 may have to return padding spaces. Value is zero if end of string
3703 reached, including padding spaces. */
3704
3705static int
3706next_element_from_c_string (it)
3707 struct it *it;
3708{
3709 int success_p = 1;
3710
3711 xassert (it->s);
3712 it->what = IT_CHARACTER;
3713 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3714 it->object = Qnil;
3715
3716 /* IT's position can be greater IT->string_nchars in case a field
3717 width or precision has been specified when the iterator was
3718 initialized. */
3719 if (IT_CHARPOS (*it) >= it->end_charpos)
3720 {
3721 /* End of the game. */
3722 it->what = IT_EOB;
3723 success_p = 0;
3724 }
3725 else if (IT_CHARPOS (*it) >= it->string_nchars)
3726 {
3727 /* Pad with spaces. */
3728 it->c = ' ', it->len = 1;
3729 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3730 }
3731 else if (it->multibyte_p)
3732 {
3733 /* Implementation note: The calls to strlen apparently aren't a
3734 performance problem because there is no noticeable performance
3735 difference between Emacs running in unibyte or multibyte mode. */
3736 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
4fdb80f2
GM
3737 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3738 maxlen, &it->len);
5f5c8ee5
GM
3739 }
3740 else
3741 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3742
3743 return success_p;
3744}
3745
3746
3747/* Set up IT to return characters from an ellipsis, if appropriate.
3748 The definition of the ellipsis glyphs may come from a display table
3749 entry. This function Fills IT with the first glyph from the
3750 ellipsis if an ellipsis is to be displayed. */
3751
3752static void
3753next_element_from_ellipsis (it)
3754 struct it *it;
3755{
3756 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3757 {
3758 /* Use the display table definition for `...'. Invalid glyphs
3759 will be handled by the method returning elements from dpvec. */
3760 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3761 it->dpvec_char_len = it->len;
3762 it->dpvec = v->contents;
3763 it->dpend = v->contents + v->size;
3764 it->current.dpvec_index = 0;
3765 it->method = next_element_from_display_vector;
3766 get_next_display_element (it);
3767 }
3768 else if (it->selective_display_ellipsis_p)
3769 {
3770 /* Use default `...' which is stored in default_invis_vector. */
3771 it->dpvec_char_len = it->len;
3772 it->dpvec = default_invis_vector;
3773 it->dpend = default_invis_vector + 3;
3774 it->current.dpvec_index = 0;
3775 it->method = next_element_from_display_vector;
3776 get_next_display_element (it);
3777 }
3778}
3779
3780
3781/* Deliver an image display element. The iterator IT is already
3782 filled with image information (done in handle_display_prop). Value
3783 is always 1. */
3784
3785
3786static int
3787next_element_from_image (it)
3788 struct it *it;
3789{
3790 it->what = IT_IMAGE;
3791 return 1;
3792}
3793
3794
3795/* Fill iterator IT with next display element from a stretch glyph
3796 property. IT->object is the value of the text property. Value is
3797 always 1. */
3798
3799static int
3800next_element_from_stretch (it)
3801 struct it *it;
3802{
3803 it->what = IT_STRETCH;
3804 return 1;
3805}
3806
3807
3808/* Load IT with the next display element from current_buffer. Value
3809 is zero if end of buffer reached. IT->stop_charpos is the next
3810 position at which to stop and check for text properties or buffer
3811 end. */
3812
3813static int
3814next_element_from_buffer (it)
3815 struct it *it;
3816{
3817 int success_p = 1;
3818
3819 /* Check this assumption, otherwise, we would never enter the
3820 if-statement, below. */
3821 xassert (IT_CHARPOS (*it) >= BEGV
3822 && IT_CHARPOS (*it) <= it->stop_charpos);
3823
3824 if (IT_CHARPOS (*it) >= it->stop_charpos)
3825 {
3826 if (IT_CHARPOS (*it) >= it->end_charpos)
3827 {
3828 int overlay_strings_follow_p;
3829
3830 /* End of the game, except when overlay strings follow that
3831 haven't been returned yet. */
3832 if (it->overlay_strings_at_end_processed_p)
3833 overlay_strings_follow_p = 0;
3834 else
3835 {
3836 it->overlay_strings_at_end_processed_p = 1;
3837 overlay_strings_follow_p
3838 = get_overlay_strings (it);
3839 }
3840
3841 if (overlay_strings_follow_p)
3842 success_p = get_next_display_element (it);
3843 else
3844 {
3845 it->what = IT_EOB;
3846 it->position = it->current.pos;
3847 success_p = 0;
3848 }
3849 }
3850 else
3851 {
3852 handle_stop (it);
3853 return get_next_display_element (it);
3854 }
3855 }
3856 else
3857 {
3858 /* No face changes, overlays etc. in sight, so just return a
3859 character from current_buffer. */
3860 unsigned char *p;
3861
3862 /* Maybe run the redisplay end trigger hook. Performance note:
3863 This doesn't seem to cost measurable time. */
3864 if (it->redisplay_end_trigger_charpos
3865 && it->glyph_row
3866 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3867 run_redisplay_end_trigger_hook (it);
3868
3869 /* Get the next character, maybe multibyte. */
3870 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3871 if (it->multibyte_p)
3872 {
3873 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3874 - IT_BYTEPOS (*it));
4fdb80f2 3875 it->c = string_char_and_length (p, maxlen, &it->len);
5f5c8ee5
GM
3876 }
3877 else
3878 it->c = *p, it->len = 1;
3879
3880 /* Record what we have and where it came from. */
3881 it->what = IT_CHARACTER;;
3882 it->object = it->w->buffer;
3883 it->position = it->current.pos;
3884
3885 /* Normally we return the character found above, except when we
3886 really want to return an ellipsis for selective display. */
3887 if (it->selective)
3888 {
3889 if (it->c == '\n')
3890 {
3891 /* A value of selective > 0 means hide lines indented more
3892 than that number of columns. */
3893 if (it->selective > 0
3894 && IT_CHARPOS (*it) + 1 < ZV
3895 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3896 IT_BYTEPOS (*it) + 1,
3897 it->selective))
312246d1
GM
3898 {
3899 next_element_from_ellipsis (it);
3900 it->dpvec_char_len = -1;
3901 }
5f5c8ee5
GM
3902 }
3903 else if (it->c == '\r' && it->selective == -1)
3904 {
3905 /* A value of selective == -1 means that everything from the
3906 CR to the end of the line is invisible, with maybe an
3907 ellipsis displayed for it. */
3908 next_element_from_ellipsis (it);
312246d1 3909 it->dpvec_char_len = -1;
5f5c8ee5
GM
3910 }
3911 }
3912 }
3913
3914 /* Value is zero if end of buffer reached. */
3915 xassert (!success_p || it->len > 0);
3916 return success_p;
3917}
3918
3919
3920/* Run the redisplay end trigger hook for IT. */
3921
3922static void
3923run_redisplay_end_trigger_hook (it)
3924 struct it *it;
3925{
3926 Lisp_Object args[3];
3927
3928 /* IT->glyph_row should be non-null, i.e. we should be actually
3929 displaying something, or otherwise we should not run the hook. */
3930 xassert (it->glyph_row);
3931
3932 /* Set up hook arguments. */
3933 args[0] = Qredisplay_end_trigger_functions;
3934 args[1] = it->window;
3935 XSETINT (args[2], it->redisplay_end_trigger_charpos);
3936 it->redisplay_end_trigger_charpos = 0;
3937
3938 /* Since we are *trying* to run these functions, don't try to run
3939 them again, even if they get an error. */
3940 it->w->redisplay_end_trigger = Qnil;
3941 Frun_hook_with_args (3, args);
3942
3943 /* Notice if it changed the face of the character we are on. */
3944 handle_face_prop (it);
3945}
3946
3947
3948\f
3949/***********************************************************************
3950 Moving an iterator without producing glyphs
3951 ***********************************************************************/
3952
3953/* Move iterator IT to a specified buffer or X position within one
3954 line on the display without producing glyphs.
3955
3956 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
3957 whichever is reached first.
3958
3959 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
3960
3961 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
3962 0 <= TO_X <= IT->last_visible_x. This means in particular, that
3963 TO_X includes the amount by which a window is horizontally
3964 scrolled.
3965
3966 Value is
3967
3968 MOVE_POS_MATCH_OR_ZV
3969 - when TO_POS or ZV was reached.
3970
3971 MOVE_X_REACHED
3972 -when TO_X was reached before TO_POS or ZV were reached.
3973
3974 MOVE_LINE_CONTINUED
3975 - when we reached the end of the display area and the line must
3976 be continued.
3977
3978 MOVE_LINE_TRUNCATED
3979 - when we reached the end of the display area and the line is
3980 truncated.
3981
3982 MOVE_NEWLINE_OR_CR
3983 - when we stopped at a line end, i.e. a newline or a CR and selective
3984 display is on. */
3985
3986enum move_it_result
3987move_it_in_display_line_to (it, to_charpos, to_x, op)
3988 struct it *it;
3989 int to_charpos, to_x, op;
3990{
3991 enum move_it_result result = MOVE_UNDEFINED;
3992 struct glyph_row *saved_glyph_row;
3993
3994 /* Don't produce glyphs in produce_glyphs. */
3995 saved_glyph_row = it->glyph_row;
3996 it->glyph_row = NULL;
3997
5f5c8ee5
GM
3998 while (1)
3999 {
4000 int x, i;
4001
4002 /* Stop when ZV or TO_CHARPOS reached. */
4003 if (!get_next_display_element (it)
4004 || ((op & MOVE_TO_POS) != 0
4005 && BUFFERP (it->object)
4006 && IT_CHARPOS (*it) >= to_charpos))
4007 {
4008 result = MOVE_POS_MATCH_OR_ZV;
4009 break;
4010 }
4011
4012 /* The call to produce_glyphs will get the metrics of the
4013 display element IT is loaded with. We record in x the
4014 x-position before this display element in case it does not
4015 fit on the line. */
4016 x = it->current_x;
4017 PRODUCE_GLYPHS (it);
4018
4019 if (it->area != TEXT_AREA)
4020 {
4021 set_iterator_to_next (it);
4022 continue;
4023 }
4024
4025 /* The number of glyphs we get back in IT->nglyphs will normally
4026 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4027 character on a terminal frame, or (iii) a line end. For the
4028 second case, IT->nglyphs - 1 padding glyphs will be present
4029 (on X frames, there is only one glyph produced for a
4030 composite character.
4031
4032 The behavior implemented below means, for continuation lines,
4033 that as many spaces of a TAB as fit on the current line are
4034 displayed there. For terminal frames, as many glyphs of a
4035 multi-glyph character are displayed in the current line, too.
4036 This is what the old redisplay code did, and we keep it that
4037 way. Under X, the whole shape of a complex character must
4038 fit on the line or it will be completely displayed in the
4039 next line.
4040
4041 Note that both for tabs and padding glyphs, all glyphs have
4042 the same width. */
4043 if (it->nglyphs)
4044 {
4045 /* More than one glyph or glyph doesn't fit on line. All
4046 glyphs have the same width. */
4047 int single_glyph_width = it->pixel_width / it->nglyphs;
4048 int new_x;
4049
4050 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4051 {
4052 new_x = x + single_glyph_width;
4053
4054 /* We want to leave anything reaching TO_X to the caller. */
4055 if ((op & MOVE_TO_X) && new_x > to_x)
4056 {
4057 it->current_x = x;
4058 result = MOVE_X_REACHED;
4059 break;
4060 }
4061 else if (/* Lines are continued. */
4062 !it->truncate_lines_p
4063 && (/* And glyph doesn't fit on the line. */
4064 new_x > it->last_visible_x
4065 /* Or it fits exactly and we're on a window
4066 system frame. */
4067 || (new_x == it->last_visible_x
4068 && FRAME_WINDOW_P (it->f))))
4069 {
4070 if (/* IT->hpos == 0 means the very first glyph
4071 doesn't fit on the line, e.g. a wide image. */
4072 it->hpos == 0
4073 || (new_x == it->last_visible_x
4074 && FRAME_WINDOW_P (it->f)))
4075 {
4076 ++it->hpos;
4077 it->current_x = new_x;
4078 if (i == it->nglyphs - 1)
4079 set_iterator_to_next (it);
4080 }
4081 else
4082 it->current_x = x;
4083
4084 result = MOVE_LINE_CONTINUED;
4085 break;
4086 }
4087 else if (new_x > it->first_visible_x)
4088 {
4089 /* Glyph is visible. Increment number of glyphs that
4090 would be displayed. */
4091 ++it->hpos;
4092 }
4093 else
4094 {
4095 /* Glyph is completely off the left margin of the display
4096 area. Nothing to do. */
4097 }
4098 }
4099
4100 if (result != MOVE_UNDEFINED)
4101 break;
4102 }
4103 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4104 {
4105 /* Stop when TO_X specified and reached. This check is
4106 necessary here because of lines consisting of a line end,
4107 only. The line end will not produce any glyphs and we
4108 would never get MOVE_X_REACHED. */
4109 xassert (it->nglyphs == 0);
4110 result = MOVE_X_REACHED;
4111 break;
4112 }
4113
4114 /* Is this a line end? If yes, we're done. */
4115 if (ITERATOR_AT_END_OF_LINE_P (it))
4116 {
4117 result = MOVE_NEWLINE_OR_CR;
4118 break;
4119 }
4120
4121 /* The current display element has been consumed. Advance
4122 to the next. */
4123 set_iterator_to_next (it);
4124
4125 /* Stop if lines are truncated and IT's current x-position is
4126 past the right edge of the window now. */
4127 if (it->truncate_lines_p
4128 && it->current_x >= it->last_visible_x)
4129 {
4130 result = MOVE_LINE_TRUNCATED;
4131 break;
4132 }
4133 }
4134
4135 /* Restore the iterator settings altered at the beginning of this
4136 function. */
4137 it->glyph_row = saved_glyph_row;
4138 return result;
4139}
4140
4141
4142/* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4143 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4144 the description of enum move_operation_enum.
4145
4146 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4147 screen line, this function will set IT to the next position >
4148 TO_CHARPOS. */
4149
4150void
4151move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4152 struct it *it;
4153 int to_charpos, to_x, to_y, to_vpos;
4154 int op;
4155{
4156 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4157 int line_height;
4158
5f5c8ee5
GM
4159 while (1)
4160 {
4161 if (op & MOVE_TO_VPOS)
4162 {
4163 /* If no TO_CHARPOS and no TO_X specified, stop at the
4164 start of the line TO_VPOS. */
4165 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4166 {
4167 if (it->vpos == to_vpos)
4168 break;
4169 skip = move_it_in_display_line_to (it, -1, -1, 0);
4170 }
4171 else
4172 {
4173 /* TO_VPOS >= 0 means stop at TO_X in the line at
4174 TO_VPOS, or at TO_POS, whichever comes first. */
4175 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4176
4177 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4178 break;
4179 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4180 {
4181 /* We have reached TO_X but not in the line we want. */
4182 skip = move_it_in_display_line_to (it, to_charpos,
4183 -1, MOVE_TO_POS);
4184 if (skip == MOVE_POS_MATCH_OR_ZV)
4185 break;
4186 }
4187 }
4188 }
4189 else if (op & MOVE_TO_Y)
4190 {
4191 struct it it_backup;
4192 int done_p;
4193
4194 /* TO_Y specified means stop at TO_X in the line containing
4195 TO_Y---or at TO_CHARPOS if this is reached first. The
4196 problem is that we can't really tell whether the line
4197 contains TO_Y before we have completely scanned it, and
4198 this may skip past TO_X. What we do is to first scan to
4199 TO_X.
4200
4201 If TO_X is not specified, use a TO_X of zero. The reason
4202 is to make the outcome of this function more predictable.
4203 If we didn't use TO_X == 0, we would stop at the end of
4204 the line which is probably not what a caller would expect
4205 to happen. */
4206 skip = move_it_in_display_line_to (it, to_charpos,
4207 ((op & MOVE_TO_X)
4208 ? to_x : 0),
4209 (MOVE_TO_X
4210 | (op & MOVE_TO_POS)));
4211
4212 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4213 if (skip == MOVE_POS_MATCH_OR_ZV)
4214 break;
4215
4216 /* If TO_X was reached, we would like to know whether TO_Y
4217 is in the line. This can only be said if we know the
4218 total line height which requires us to scan the rest of
4219 the line. */
4220 done_p = 0;
4221 if (skip == MOVE_X_REACHED)
4222 {
4223 it_backup = *it;
4224 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4225 op & MOVE_TO_POS);
4226 }
4227
4228 /* Now, decide whether TO_Y is in this line. */
4229 line_height = it->max_ascent + it->max_descent;
4230
4231 if (to_y >= it->current_y
4232 && to_y < it->current_y + line_height)
4233 {
4234 if (skip == MOVE_X_REACHED)
4235 /* If TO_Y is in this line and TO_X was reached above,
4236 we scanned too far. We have to restore IT's settings
4237 to the ones before skipping. */
4238 *it = it_backup;
4239 done_p = 1;
4240 }
4241 else if (skip == MOVE_X_REACHED)
4242 {
4243 skip = skip2;
4244 if (skip == MOVE_POS_MATCH_OR_ZV)
4245 done_p = 1;
4246 }
4247
4248 if (done_p)
4249 break;
4250 }
4251 else
4252 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4253
4254 switch (skip)
4255 {
4256 case MOVE_POS_MATCH_OR_ZV:
4257 return;
4258
4259 case MOVE_NEWLINE_OR_CR:
4260 set_iterator_to_next (it);
4261 it->continuation_lines_width = 0;
4262 break;
4263
4264 case MOVE_LINE_TRUNCATED:
4265 it->continuation_lines_width = 0;
312246d1 4266 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
4267 if ((op & MOVE_TO_POS) != 0
4268 && IT_CHARPOS (*it) > to_charpos)
4269 goto out;
4270 break;
4271
4272 case MOVE_LINE_CONTINUED:
4273 it->continuation_lines_width += it->current_x;
4274 break;
4275
4276 default:
4277 abort ();
4278 }
4279
4280 /* Reset/increment for the next run. */
4281 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4282 it->current_x = it->hpos = 0;
4283 it->current_y += it->max_ascent + it->max_descent;
4284 ++it->vpos;
4285 last_height = it->max_ascent + it->max_descent;
4286 last_max_ascent = it->max_ascent;
4287 it->max_ascent = it->max_descent = 0;
4288 }
4289 out:;
4290}
4291
4292
4293/* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4294
4295 If DY > 0, move IT backward at least that many pixels. DY = 0
4296 means move IT backward to the preceding line start or BEGV. This
4297 function may move over more than DY pixels if IT->current_y - DY
4298 ends up in the middle of a line; in this case IT->current_y will be
4299 set to the top of the line moved to. */
4300
4301void
4302move_it_vertically_backward (it, dy)
4303 struct it *it;
4304 int dy;
4305{
4306 int nlines, h, line_height;
4307 struct it it2;
4308 int start_pos = IT_CHARPOS (*it);
4309
4310 xassert (dy >= 0);
4311
4312 /* Estimate how many newlines we must move back. */
4313 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4314
4315 /* Set the iterator's position that many lines back. */
4316 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4317 back_to_previous_visible_line_start (it);
4318
4319 /* Reseat the iterator here. When moving backward, we don't want
4320 reseat to skip forward over invisible text, set up the iterator
4321 to deliver from overlay strings at the new position etc. So,
4322 use reseat_1 here. */
4323 reseat_1 (it, it->current.pos, 1);
4324
4325 /* We are now surely at a line start. */
4326 it->current_x = it->hpos = 0;
4327
4328 /* Move forward and see what y-distance we moved. First move to the
4329 start of the next line so that we get its height. We need this
4330 height to be able to tell whether we reached the specified
4331 y-distance. */
4332 it2 = *it;
4333 it2.max_ascent = it2.max_descent = 0;
4334 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4335 MOVE_TO_POS | MOVE_TO_VPOS);
4336 xassert (IT_CHARPOS (*it) >= BEGV);
4337 line_height = it2.max_ascent + it2.max_descent;
4338 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4339 xassert (IT_CHARPOS (*it) >= BEGV);
4340 h = it2.current_y - it->current_y;
4341 nlines = it2.vpos - it->vpos;
4342
4343 /* Correct IT's y and vpos position. */
4344 it->vpos -= nlines;
4345 it->current_y -= h;
4346
4347 if (dy == 0)
4348 {
4349 /* DY == 0 means move to the start of the screen line. The
4350 value of nlines is > 0 if continuation lines were involved. */
4351 if (nlines > 0)
4352 move_it_by_lines (it, nlines, 1);
4353 xassert (IT_CHARPOS (*it) <= start_pos);
4354 }
4355 else if (nlines)
4356 {
4357 /* The y-position we try to reach. Note that h has been
4358 subtracted in front of the if-statement. */
4359 int target_y = it->current_y + h - dy;
4360
4361 /* If we did not reach target_y, try to move further backward if
4362 we can. If we moved too far backward, try to move forward. */
4363 if (target_y < it->current_y
4364 && IT_CHARPOS (*it) > BEGV)
4365 {
4366 move_it_vertically (it, target_y - it->current_y);
4367 xassert (IT_CHARPOS (*it) >= BEGV);
4368 }
4369 else if (target_y >= it->current_y + line_height
4370 && IT_CHARPOS (*it) < ZV)
4371 {
4372 move_it_vertically (it, target_y - (it->current_y + line_height));
4373 xassert (IT_CHARPOS (*it) >= BEGV);
4374 }
4375 }
4376}
4377
4378
4379/* Move IT by a specified amount of pixel lines DY. DY negative means
4380 move backwards. DY = 0 means move to start of screen line. At the
4381 end, IT will be on the start of a screen line. */
4382
4383void
4384move_it_vertically (it, dy)
4385 struct it *it;
4386 int dy;
4387{
4388 if (dy <= 0)
4389 move_it_vertically_backward (it, -dy);
4390 else if (dy > 0)
4391 {
4392 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4393 MOVE_TO_POS | MOVE_TO_Y);
4394
4395 /* If buffer ends in ZV without a newline, move to the start of
4396 the line to satisfy the post-condition. */
4397 if (IT_CHARPOS (*it) == ZV
4398 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4399 move_it_by_lines (it, 0, 0);
4400 }
4401}
4402
4403
4404/* Return non-zero if some text between buffer positions START_CHARPOS
4405 and END_CHARPOS is invisible. IT->window is the window for text
4406 property lookup. */
4407
4408static int
4409invisible_text_between_p (it, start_charpos, end_charpos)
4410 struct it *it;
4411 int start_charpos, end_charpos;
4412{
4413#ifdef USE_TEXT_PROPERTIES
4414 Lisp_Object prop, limit;
4415 int invisible_found_p;
4416
4417 xassert (it != NULL && start_charpos <= end_charpos);
4418
4419 /* Is text at START invisible? */
4420 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4421 it->window);
4422 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4423 invisible_found_p = 1;
4424 else
4425 {
4426 limit = Fnext_single_property_change (make_number (start_charpos),
4427 Qinvisible,
4428 Fcurrent_buffer (),
4429 make_number (end_charpos));
4430 invisible_found_p = XFASTINT (limit) < end_charpos;
4431 }
4432
4433 return invisible_found_p;
4434
4435#else /* not USE_TEXT_PROPERTIES */
4436 return 0;
4437#endif /* not USE_TEXT_PROPERTIES */
4438}
4439
4440
4441/* Move IT by a specified number DVPOS of screen lines down. DVPOS
4442 negative means move up. DVPOS == 0 means move to the start of the
4443 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4444 NEED_Y_P is zero, IT->current_y will be left unchanged.
4445
4446 Further optimization ideas: If we would know that IT->f doesn't use
4447 a face with proportional font, we could be faster for
4448 truncate-lines nil. */
4449
4450void
4451move_it_by_lines (it, dvpos, need_y_p)
4452 struct it *it;
4453 int dvpos, need_y_p;
4454{
4455 struct position pos;
4456
4457 if (!FRAME_WINDOW_P (it->f))
4458 {
4459 struct text_pos textpos;
4460
4461 /* We can use vmotion on frames without proportional fonts. */
4462 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4463 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4464 reseat (it, textpos, 1);
4465 it->vpos += pos.vpos;
4466 it->current_y += pos.vpos;
4467 }
4468 else if (dvpos == 0)
4469 {
4470 /* DVPOS == 0 means move to the start of the screen line. */
4471 move_it_vertically_backward (it, 0);
4472 xassert (it->current_x == 0 && it->hpos == 0);
4473 }
4474 else if (dvpos > 0)
4475 {
4476 /* If there are no continuation lines, and if there is no
4477 selective display, try the simple method of moving forward
4478 DVPOS newlines, then see where we are. */
4479 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4480 {
4481 int shortage = 0, charpos;
4482
4483 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4484 charpos = IT_CHARPOS (*it) + 1;
4485 else
4486 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4487 &shortage, 0);
4488
4489 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4490 {
4491 struct text_pos pos;
4492 CHARPOS (pos) = charpos;
4493 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4494 reseat (it, pos, 1);
4495 it->vpos += dvpos - shortage;
4496 it->hpos = it->current_x = 0;
4497 return;
4498 }
4499 }
4500
4501 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4502 }
4503 else
4504 {
4505 struct it it2;
4506 int start_charpos, i;
4507
4508 /* If there are no continuation lines, and if there is no
4509 selective display, try the simple method of moving backward
4510 -DVPOS newlines. */
4511 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4512 {
4513 int shortage;
4514 int charpos = IT_CHARPOS (*it);
4515 int bytepos = IT_BYTEPOS (*it);
4516
4517 /* If in the middle of a line, go to its start. */
4518 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4519 {
4520 charpos = find_next_newline_no_quit (charpos, -1);
4521 bytepos = CHAR_TO_BYTE (charpos);
4522 }
4523
4524 if (charpos == BEGV)
4525 {
4526 struct text_pos pos;
4527 CHARPOS (pos) = charpos;
4528 BYTEPOS (pos) = bytepos;
4529 reseat (it, pos, 1);
4530 it->hpos = it->current_x = 0;
4531 return;
4532 }
4533 else
4534 {
4535 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4536 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4537 {
4538 struct text_pos pos;
4539 CHARPOS (pos) = charpos;
4540 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4541 reseat (it, pos, 1);
4542 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4543 it->hpos = it->current_x = 0;
4544 return;
4545 }
4546 }
4547 }
4548
4549 /* Go back -DVPOS visible lines and reseat the iterator there. */
4550 start_charpos = IT_CHARPOS (*it);
4551 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4552 back_to_previous_visible_line_start (it);
4553 reseat (it, it->current.pos, 1);
4554 it->current_x = it->hpos = 0;
4555
4556 /* Above call may have moved too far if continuation lines
4557 are involved. Scan forward and see if it did. */
4558 it2 = *it;
4559 it2.vpos = it2.current_y = 0;
4560 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4561 it->vpos -= it2.vpos;
4562 it->current_y -= it2.current_y;
4563 it->current_x = it->hpos = 0;
4564
4565 /* If we moved too far, move IT some lines forward. */
4566 if (it2.vpos > -dvpos)
4567 {
4568 int delta = it2.vpos + dvpos;
4569 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4570 }
4571 }
4572}
4573
4574
4575\f
4576/***********************************************************************
4577 Messages
4578 ***********************************************************************/
4579
4580
4581/* Output a newline in the *Messages* buffer if "needs" one. */
4582
4583void
4584message_log_maybe_newline ()
4585{
4586 if (message_log_need_newline)
4587 message_dolog ("", 0, 1, 0);
4588}
4589
4590
4591/* Add a string M of length LEN to the message log, optionally
4592 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4593 nonzero, means interpret the contents of M as multibyte. This
4594 function calls low-level routines in order to bypass text property
4595 hooks, etc. which might not be safe to run. */
4596
4597void
4598message_dolog (m, len, nlflag, multibyte)
4599 char *m;
4600 int len, nlflag, multibyte;
4601{
4602 if (!NILP (Vmessage_log_max))
4603 {
4604 struct buffer *oldbuf;
4605 Lisp_Object oldpoint, oldbegv, oldzv;
4606 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4607 int point_at_end = 0;
4608 int zv_at_end = 0;
4609 Lisp_Object old_deactivate_mark, tem;
4610 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4611
4612 old_deactivate_mark = Vdeactivate_mark;
4613 oldbuf = current_buffer;
4614 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4615 current_buffer->undo_list = Qt;
4616
4617 oldpoint = Fpoint_marker ();
4618 oldbegv = Fpoint_min_marker ();
4619 oldzv = Fpoint_max_marker ();
4620 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4621
4622 if (PT == Z)
4623 point_at_end = 1;
4624 if (ZV == Z)
4625 zv_at_end = 1;
4626
4627 BEGV = BEG;
4628 BEGV_BYTE = BEG_BYTE;
4629 ZV = Z;
4630 ZV_BYTE = Z_BYTE;
4631 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4632
4633 /* Insert the string--maybe converting multibyte to single byte
4634 or vice versa, so that all the text fits the buffer. */
4635 if (multibyte
4636 && NILP (current_buffer->enable_multibyte_characters))
4637 {
4638 int i, c, nbytes;
4639 unsigned char work[1];
4640
4641 /* Convert a multibyte string to single-byte
4642 for the *Message* buffer. */
4643 for (i = 0; i < len; i += nbytes)
4644 {
4fdb80f2 4645 c = string_char_and_length (m + i, len - i, &nbytes);
5f5c8ee5
GM
4646 work[0] = (SINGLE_BYTE_CHAR_P (c)
4647 ? c
4648 : multibyte_char_to_unibyte (c, Qnil));
4649 insert_1_both (work, 1, 1, 1, 0, 0);
4650 }
4651 }
4652 else if (! multibyte
4653 && ! NILP (current_buffer->enable_multibyte_characters))
4654 {
4655 int i, c, nbytes;
4656 unsigned char *msg = (unsigned char *) m;
4657 unsigned char *str, work[4];
4658 /* Convert a single-byte string to multibyte
4659 for the *Message* buffer. */
4660 for (i = 0; i < len; i++)
4661 {
4662 c = unibyte_char_to_multibyte (msg[i]);
4663 nbytes = CHAR_STRING (c, work, str);
4664 insert_1_both (work, 1, nbytes, 1, 0, 0);
4665 }
4666 }
4667 else if (len)
4668 insert_1 (m, len, 1, 0, 0);
4669
4670 if (nlflag)
4671 {
4672 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4673 insert_1 ("\n", 1, 1, 0, 0);
4674
4675 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4676 this_bol = PT;
4677 this_bol_byte = PT_BYTE;
4678
4679 if (this_bol > BEG)
4680 {
4681 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4682 prev_bol = PT;
4683 prev_bol_byte = PT_BYTE;
4684
4685 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4686 this_bol, this_bol_byte);
4687 if (dup)
4688 {
4689 del_range_both (prev_bol, prev_bol_byte,
4690 this_bol, this_bol_byte, 0);
4691 if (dup > 1)
4692 {
4693 char dupstr[40];
4694 int duplen;
4695
4696 /* If you change this format, don't forget to also
4697 change message_log_check_duplicate. */
4698 sprintf (dupstr, " [%d times]", dup);
4699 duplen = strlen (dupstr);
4700 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4701 insert_1 (dupstr, duplen, 1, 0, 1);
4702 }
4703 }
4704 }
4705
4706 if (NATNUMP (Vmessage_log_max))
4707 {
4708 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4709 -XFASTINT (Vmessage_log_max) - 1, 0);
4710 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4711 }
4712 }
4713 BEGV = XMARKER (oldbegv)->charpos;
4714 BEGV_BYTE = marker_byte_position (oldbegv);
4715
4716 if (zv_at_end)
4717 {
4718 ZV = Z;
4719 ZV_BYTE = Z_BYTE;
4720 }
4721 else
4722 {
4723 ZV = XMARKER (oldzv)->charpos;
4724 ZV_BYTE = marker_byte_position (oldzv);
4725 }
4726
4727 if (point_at_end)
4728 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4729 else
4730 /* We can't do Fgoto_char (oldpoint) because it will run some
4731 Lisp code. */
4732 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4733 XMARKER (oldpoint)->bytepos);
4734
4735 UNGCPRO;
4736 free_marker (oldpoint);
4737 free_marker (oldbegv);
4738 free_marker (oldzv);
4739
4740 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4741 set_buffer_internal (oldbuf);
4742 if (NILP (tem))
4743 windows_or_buffers_changed = old_windows_or_buffers_changed;
4744 message_log_need_newline = !nlflag;
4745 Vdeactivate_mark = old_deactivate_mark;
4746 }
4747}
4748
4749
4750/* We are at the end of the buffer after just having inserted a newline.
4751 (Note: We depend on the fact we won't be crossing the gap.)
4752 Check to see if the most recent message looks a lot like the previous one.
4753 Return 0 if different, 1 if the new one should just replace it, or a
4754 value N > 1 if we should also append " [N times]". */
4755
4756static int
4757message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4758 int prev_bol, this_bol;
4759 int prev_bol_byte, this_bol_byte;
4760{
4761 int i;
4762 int len = Z_BYTE - 1 - this_bol_byte;
4763 int seen_dots = 0;
4764 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4765 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4766
4767 for (i = 0; i < len; i++)
4768 {
4769 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4770 && p1[i] != '\n')
4771 seen_dots = 1;
4772 if (p1[i] != p2[i])
4773 return seen_dots;
4774 }
4775 p1 += len;
4776 if (*p1 == '\n')
4777 return 2;
4778 if (*p1++ == ' ' && *p1++ == '[')
4779 {
4780 int n = 0;
4781 while (*p1 >= '0' && *p1 <= '9')
4782 n = n * 10 + *p1++ - '0';
4783 if (strncmp (p1, " times]\n", 8) == 0)
4784 return n+1;
4785 }
4786 return 0;
4787}
4788
4789
4790/* Display an echo area message M with a specified length of LEN
4791 chars. The string may include null characters. If M is 0, clear
4792 out any existing message, and let the mini-buffer text show through.
4793
4794 The buffer M must continue to exist until after the echo area gets
4795 cleared or some other message gets displayed there. This means do
4796 not pass text that is stored in a Lisp string; do not pass text in
4797 a buffer that was alloca'd. */
4798
4799void
4800message2 (m, len, multibyte)
4801 char *m;
4802 int len;
4803 int multibyte;
4804{
4805 /* First flush out any partial line written with print. */
4806 message_log_maybe_newline ();
4807 if (m)
4808 message_dolog (m, len, 1, multibyte);
4809 message2_nolog (m, len, multibyte);
4810}
4811
4812
4813/* The non-logging counterpart of message2. */
4814
4815void
4816message2_nolog (m, len, multibyte)
4817 char *m;
4818 int len;
4819{
4820 message_enable_multibyte = multibyte;
4821
4822 if (noninteractive)
4823 {
4824 if (noninteractive_need_newline)
4825 putc ('\n', stderr);
4826 noninteractive_need_newline = 0;
4827 if (m)
4828 fwrite (m, len, 1, stderr);
4829 if (cursor_in_echo_area == 0)
4830 fprintf (stderr, "\n");
4831 fflush (stderr);
4832 }
4833 /* A null message buffer means that the frame hasn't really been
4834 initialized yet. Error messages get reported properly by
4835 cmd_error, so this must be just an informative message; toss it. */
4836 else if (INTERACTIVE
4837 && selected_frame->glyphs_initialized_p
4838 && FRAME_MESSAGE_BUF (selected_frame))
4839 {
4840 Lisp_Object mini_window;
4841 struct frame *f;
4842
4843 /* Get the frame containing the mini-buffer
4844 that the selected frame is using. */
4845 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4846 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4847
4848 FRAME_SAMPLE_VISIBILITY (f);
4849 if (FRAME_VISIBLE_P (selected_frame)
4850 && ! FRAME_VISIBLE_P (f))
4851 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4852
4853 if (m)
4854 {
c6e89d6c 4855 set_message (m, Qnil, len, multibyte);
5f5c8ee5
GM
4856 if (minibuffer_auto_raise)
4857 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4858 }
4859 else
c6e89d6c 4860 clear_message (1, 1);
5f5c8ee5 4861
c6e89d6c 4862 do_pending_window_change (0);
5f5c8ee5 4863 echo_area_display (1);
c6e89d6c 4864 do_pending_window_change (0);
5f5c8ee5
GM
4865 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4866 (*frame_up_to_date_hook) (f);
4867 }
4868}
4869
4870
c6e89d6c
GM
4871/* Display an echo area message M with a specified length of NBYTES
4872 bytes. The string may include null characters. If M is not a
5f5c8ee5
GM
4873 string, clear out any existing message, and let the mini-buffer
4874 text show through. */
4875
4876void
c6e89d6c 4877message3 (m, nbytes, multibyte)
5f5c8ee5 4878 Lisp_Object m;
c6e89d6c 4879 int nbytes;
5f5c8ee5
GM
4880 int multibyte;
4881{
4882 struct gcpro gcpro1;
4883
4884 GCPRO1 (m);
4885
4886 /* First flush out any partial line written with print. */
4887 message_log_maybe_newline ();
4888 if (STRINGP (m))
c6e89d6c
GM
4889 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
4890 message3_nolog (m, nbytes, multibyte);
5f5c8ee5
GM
4891
4892 UNGCPRO;
4893}
4894
4895
4896/* The non-logging version of message3. */
4897
4898void
c6e89d6c 4899message3_nolog (m, nbytes, multibyte)
5f5c8ee5 4900 Lisp_Object m;
c6e89d6c 4901 int nbytes, multibyte;
5f5c8ee5
GM
4902{
4903 message_enable_multibyte = multibyte;
4904
4905 if (noninteractive)
4906 {
4907 if (noninteractive_need_newline)
4908 putc ('\n', stderr);
4909 noninteractive_need_newline = 0;
4910 if (STRINGP (m))
c6e89d6c 4911 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5f5c8ee5
GM
4912 if (cursor_in_echo_area == 0)
4913 fprintf (stderr, "\n");
4914 fflush (stderr);
4915 }
4916 /* A null message buffer means that the frame hasn't really been
4917 initialized yet. Error messages get reported properly by
4918 cmd_error, so this must be just an informative message; toss it. */
4919 else if (INTERACTIVE
4920 && selected_frame->glyphs_initialized_p
4921 && FRAME_MESSAGE_BUF (selected_frame))
4922 {
4923 Lisp_Object mini_window;
c6e89d6c 4924 Lisp_Object frame;
5f5c8ee5
GM
4925 struct frame *f;
4926
4927 /* Get the frame containing the mini-buffer
4928 that the selected frame is using. */
4929 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
c6e89d6c
GM
4930 frame = XWINDOW (mini_window)->frame;
4931 f = XFRAME (frame);
5f5c8ee5
GM
4932
4933 FRAME_SAMPLE_VISIBILITY (f);
4934 if (FRAME_VISIBLE_P (selected_frame)
c6e89d6c
GM
4935 && !FRAME_VISIBLE_P (f))
4936 Fmake_frame_visible (frame);
5f5c8ee5 4937
c6e89d6c 4938 if (STRINGP (m) && XSTRING (m)->size)
5f5c8ee5 4939 {
c6e89d6c
GM
4940 set_message (NULL, m, nbytes, multibyte);
4941 Fraise_frame (frame);
5f5c8ee5
GM
4942 }
4943 else
c6e89d6c 4944 clear_message (1, 1);
5f5c8ee5 4945
c6e89d6c 4946 do_pending_window_change (0);
5f5c8ee5 4947 echo_area_display (1);
c6e89d6c 4948 do_pending_window_change (0);
5f5c8ee5
GM
4949 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4950 (*frame_up_to_date_hook) (f);
4951 }
4952}
4953
4954
4955/* Display a null-terminated echo area message M. If M is 0, clear
4956 out any existing message, and let the mini-buffer text show through.
4957
4958 The buffer M must continue to exist until after the echo area gets
4959 cleared or some other message gets displayed there. Do not pass
4960 text that is stored in a Lisp string. Do not pass text in a buffer
4961 that was alloca'd. */
4962
4963void
4964message1 (m)
4965 char *m;
4966{
4967 message2 (m, (m ? strlen (m) : 0), 0);
4968}
4969
4970
4971/* The non-logging counterpart of message1. */
4972
4973void
4974message1_nolog (m)
4975 char *m;
4976{
4977 message2_nolog (m, (m ? strlen (m) : 0), 0);
4978}
4979
4980/* Display a message M which contains a single %s
4981 which gets replaced with STRING. */
4982
4983void
4984message_with_string (m, string, log)
4985 char *m;
4986 Lisp_Object string;
4987 int log;
4988{
4989 if (noninteractive)
4990 {
4991 if (m)
4992 {
4993 if (noninteractive_need_newline)
4994 putc ('\n', stderr);
4995 noninteractive_need_newline = 0;
4996 fprintf (stderr, m, XSTRING (string)->data);
4997 if (cursor_in_echo_area == 0)
4998 fprintf (stderr, "\n");
4999 fflush (stderr);
5000 }
5001 }
5002 else if (INTERACTIVE)
5003 {
5004 /* The frame whose minibuffer we're going to display the message on.
5005 It may be larger than the selected frame, so we need
5006 to use its buffer, not the selected frame's buffer. */
5007 Lisp_Object mini_window;
5008 FRAME_PTR f;
5009
5010 /* Get the frame containing the minibuffer
5011 that the selected frame is using. */
5012 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5013 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5014
5015 /* A null message buffer means that the frame hasn't really been
5016 initialized yet. Error messages get reported properly by
5017 cmd_error, so this must be just an informative message; toss it. */
5018 if (FRAME_MESSAGE_BUF (f))
5019 {
5020 int len;
5021 char *a[1];
5022 a[0] = (char *) XSTRING (string)->data;
5023
5024 len = doprnt (FRAME_MESSAGE_BUF (f),
5025 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5026
5027 if (log)
5028 message2 (FRAME_MESSAGE_BUF (f), len,
5029 STRING_MULTIBYTE (string));
5030 else
5031 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5032 STRING_MULTIBYTE (string));
5033
5034 /* Print should start at the beginning of the message
5035 buffer next time. */
5036 message_buf_print = 0;
5037 }
5038 }
5039}
5040
5041
5f5c8ee5
GM
5042/* Dump an informative message to the minibuf. If M is 0, clear out
5043 any existing message, and let the mini-buffer text show through. */
5044
5045/* VARARGS 1 */
5046void
5047message (m, a1, a2, a3)
5048 char *m;
5049 EMACS_INT a1, a2, a3;
5050{
5051 if (noninteractive)
5052 {
5053 if (m)
5054 {
5055 if (noninteractive_need_newline)
5056 putc ('\n', stderr);
5057 noninteractive_need_newline = 0;
5058 fprintf (stderr, m, a1, a2, a3);
5059 if (cursor_in_echo_area == 0)
5060 fprintf (stderr, "\n");
5061 fflush (stderr);
5062 }
5063 }
5064 else if (INTERACTIVE)
5065 {
5066 /* The frame whose mini-buffer we're going to display the message
5067 on. It may be larger than the selected frame, so we need to
5068 use its buffer, not the selected frame's buffer. */
5069 Lisp_Object mini_window;
5070 struct frame *f;
5071
5072 /* Get the frame containing the mini-buffer
5073 that the selected frame is using. */
5074 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5075 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5076
5077 /* A null message buffer means that the frame hasn't really been
5078 initialized yet. Error messages get reported properly by
5079 cmd_error, so this must be just an informative message; toss
5080 it. */
5081 if (FRAME_MESSAGE_BUF (f))
5082 {
5083 if (m)
5084 {
5085 int len;
5086#ifdef NO_ARG_ARRAY
5087 char *a[3];
5088 a[0] = (char *) a1;
5089 a[1] = (char *) a2;
5090 a[2] = (char *) a3;
5091
5092 len = doprnt (FRAME_MESSAGE_BUF (f),
5093 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5094#else
5095 len = doprnt (FRAME_MESSAGE_BUF (f),
5096 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5097 (char **) &a1);
5098#endif /* NO_ARG_ARRAY */
5099
5100 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5101 }
5102 else
5103 message1 (0);
5104
5105 /* Print should start at the beginning of the message
5106 buffer next time. */
5107 message_buf_print = 0;
5108 }
5109 }
5110}
5111
5112
5113/* The non-logging version of message. */
5114
5115void
5116message_nolog (m, a1, a2, a3)
5117 char *m;
5118 EMACS_INT a1, a2, a3;
5119{
5120 Lisp_Object old_log_max;
5121 old_log_max = Vmessage_log_max;
5122 Vmessage_log_max = Qnil;
5123 message (m, a1, a2, a3);
5124 Vmessage_log_max = old_log_max;
5125}
5126
5127
c6e89d6c
GM
5128/* Display the current message in the current mini-buffer. This is
5129 only called from error handlers in process.c, and is not time
5130 critical. */
5f5c8ee5
GM
5131
5132void
5133update_echo_area ()
5134{
c6e89d6c
GM
5135 if (!NILP (echo_area_buffer[0]))
5136 {
5137 Lisp_Object string;
5138 string = Fcurrent_message ();
5139 message3 (string, XSTRING (string)->size,
5140 !NILP (current_buffer->enable_multibyte_characters));
5141 }
5142}
5143
5144
5145/* Call FN with args A1..A5 with either the current or last displayed
5146 echo_area_buffer as current buffer.
5147
5148 WHICH zero means use the current message buffer
5149 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5150 from echo_buffer[] and clear it.
5151
5152 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5153 suitable buffer from echo_buffer[] and clear it.
5154
5155 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5156 that the current message becomes the last displayed one, make
5157 choose a suitable buffer for echo_area_buffer[0], and clear it.
5158
5159 Value is what FN returns. */
5160
5161static int
5162with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5)
5163 struct window *w;
5164 int which;
5165 int (*fn) ();
5166 int a1, a2, a3, a4, a5;
5167{
5168 Lisp_Object buffer;
5169 int i, this_one, the_other, clear_buffer_p, rc;
5170 int count = specpdl_ptr - specpdl;
5171
5172 /* If buffers aren't life, make new ones. */
5173 for (i = 0; i < 2; ++i)
5174 if (!BUFFERP (echo_buffer[i])
5175 || NILP (XBUFFER (echo_buffer[i])->name))
5176 {
5177 char name[30];
5178 sprintf (name, " *Echo Area %d*", i);
5179 echo_buffer[i] = Fget_buffer_create (build_string (name));
5180 }
5181
5182 clear_buffer_p = 0;
5183
5184 if (which == 0)
5185 this_one = 0, the_other = 1;
5186 else if (which > 0)
5187 this_one = 1, the_other = 0;
5f5c8ee5 5188 else
c6e89d6c
GM
5189 {
5190 this_one = 0, the_other = 1;
5191 clear_buffer_p = 1;
5192
5193 /* We need a fresh one in case the current echo buffer equals
5194 the one containing the last displayed echo area message. */
5195 if (!NILP (echo_area_buffer[this_one])
5196 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5197 echo_area_buffer[this_one] = Qnil;
5198
5199 }
5200
5201 /* Choose a suitable buffer from echo_buffer[] is we don't
5202 have one. */
5203 if (NILP (echo_area_buffer[this_one]))
5204 {
5205 echo_area_buffer[this_one]
5206 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5207 ? echo_buffer[the_other]
5208 : echo_buffer[this_one]);
5209 clear_buffer_p = 1;
5210 }
5211
5212 buffer = echo_area_buffer[this_one];
5213
5214 record_unwind_protect (unwind_with_echo_area_buffer,
5215 with_echo_area_buffer_unwind_data (w));
5216
5217 /* Make the echo area buffer current. Note that for display
5218 purposes, it is not necessary that the displayed window's buffer
5219 == current_buffer, except for text property lookup. So, let's
5220 only set that buffer temporarily here without doing a full
5221 Fset_window_buffer. We must also change w->pointm, though,
5222 because otherwise an assertions in unshow_buffer fails, and Emacs
5223 aborts. */
5224 set_buffer_internal (XBUFFER (buffer));
5225 if (w)
5226 {
5227 w->buffer = buffer;
5228 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5229 }
5230 current_buffer->truncate_lines = Qnil;
5231 current_buffer->undo_list = Qt;
5232 current_buffer->read_only = Qnil;
5233
5234 if (clear_buffer_p && Z > BEG)
5235 del_range (BEG, Z);
5236
5237 xassert (BEGV >= BEG);
5238 xassert (ZV <= Z && ZV >= BEGV);
5239
5240 rc = fn (a1, a2, a3, a4, a5);
5241
5242 xassert (BEGV >= BEG);
5243 xassert (ZV <= Z && ZV >= BEGV);
5244
5245 unbind_to (count, Qnil);
5246 return rc;
5f5c8ee5
GM
5247}
5248
5249
c6e89d6c
GM
5250/* Save state that should be preserved around the call to the function
5251 FN called in with_echo_area_buffer. */
5f5c8ee5 5252
c6e89d6c
GM
5253static Lisp_Object
5254with_echo_area_buffer_unwind_data (w)
5255 struct window *w;
5f5c8ee5 5256{
c6e89d6c
GM
5257 int i = 0;
5258 Lisp_Object vector;
5f5c8ee5 5259
c6e89d6c
GM
5260 /* Reduce consing by keeping one vector in
5261 Vwith_echo_area_save_vector. */
5262 vector = Vwith_echo_area_save_vector;
5263 Vwith_echo_area_save_vector = Qnil;
5264
5265 if (NILP (vector))
5266 vector = Fmake_vector (make_number (9), Qnil);
5267
5268 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5269 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5270 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
5271 XVECTOR (vector)->contents[i++] = make_number (beg_unchanged);
5272 XVECTOR (vector)->contents[i++] = make_number (end_unchanged);
5273
5274 if (w)
5275 {
5276 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5277 XVECTOR (vector)->contents[i++] = w->buffer;
5278 XVECTOR (vector)->contents[i++]
5279 = make_number (XMARKER (w->pointm)->charpos);
5280 XVECTOR (vector)->contents[i++]
5281 = make_number (XMARKER (w->pointm)->bytepos);
5282 }
5283 else
5284 {
5285 int end = i + 4;
5286 while (i < end)
5287 XVECTOR (vector)->contents[i++] = Qnil;
5288 }
5f5c8ee5 5289
c6e89d6c
GM
5290 xassert (i == XVECTOR (vector)->size);
5291 return vector;
5292}
5f5c8ee5 5293
5f5c8ee5 5294
c6e89d6c
GM
5295/* Restore global state from VECTOR which was created by
5296 with_echo_area_buffer_unwind_data. */
5297
5298static Lisp_Object
5299unwind_with_echo_area_buffer (vector)
5300 Lisp_Object vector;
5301{
5302 int i = 0;
5303
5304 set_buffer_internal (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
5305 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5306 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5307 beg_unchanged = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5308 end_unchanged = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5309
5310 if (WINDOWP (XVECTOR (vector)->contents[i]))
5311 {
5312 struct window *w;
5313 Lisp_Object buffer, charpos, bytepos;
5314
5315 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5316 buffer = XVECTOR (vector)->contents[i]; ++i;
5317 charpos = XVECTOR (vector)->contents[i]; ++i;
5318 bytepos = XVECTOR (vector)->contents[i]; ++i;
5319
5320 w->buffer = buffer;
5321 set_marker_both (w->pointm, buffer,
5322 XFASTINT (charpos), XFASTINT (bytepos));
5323 }
5324
5325 Vwith_echo_area_save_vector = vector;
5326 return Qnil;
5327}
5328
5329
5330/* Set up the echo area for use by print functions. MULTIBYTE_P
5331 non-zero means we will print multibyte. */
5332
5333void
5334setup_echo_area_for_printing (multibyte_p)
5335 int multibyte_p;
5336{
5337 if (!message_buf_print)
5338 {
5339 /* A message has been output since the last time we printed.
5340 Choose a fresh echo area buffer. */
5341 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5342 echo_area_buffer[0] = echo_buffer[1];
5343 else
5344 echo_area_buffer[0] = echo_buffer[0];
5345
5346 /* Switch to that buffer and clear it. */
5347 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5348 if (Z > BEG)
5349 del_range (BEG, Z);
5350 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5351
5352 /* Set up the buffer for the multibyteness we need. */
5353 if (multibyte_p
5354 != !NILP (current_buffer->enable_multibyte_characters))
5355 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5356
5357 /* Raise the frame containing the echo area. */
5358 if (minibuffer_auto_raise)
5359 {
5360 Lisp_Object mini_window;
5361 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5362 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5363 }
5364
5365 message_buf_print = 1;
5366 }
5367 else if (current_buffer != XBUFFER (echo_area_buffer[0]))
5368 /* Someone switched buffers between print requests. */
5369 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5370}
5371
5372
5373/* Display the current echo area message in window W. Value is
5374 non-zero if W's height is changed. */
5375
5376static int
5377display_echo_area (w)
5378 struct window *w;
5379{
5380 return with_echo_area_buffer (w, display_last_displayed_message_p,
5381 (int (*) ()) display_echo_area_1, w);
5382}
5383
5384
5385/* Helper for display_echo_area. Display the current buffer which
5386 contains the current echo area message in window W, a mini-window.
5387 Change the height of W so that all of the message is displayed.
5388 Value is non-zero if height of W was changed. */
5389
5390static int
5391display_echo_area_1 (w)
5392 struct window *w;
5393{
5394 Lisp_Object window;
5395 struct frame *f = XFRAME (w->frame);
5396 struct text_pos start;
5397 int window_height_changed_p = 0;
5398
5399 /* Do this before displaying, so that we have a large enough glyph
5400 matrix for the display. */
5401 window_height_changed_p = resize_mini_window (w);
5402
5403 /* Display. */
5404 clear_glyph_matrix (w->desired_matrix);
5405 XSETWINDOW (window, w);
5406 SET_TEXT_POS (start, BEG, BEG_BYTE);
5407 try_window (window, start);
5408
5409 /* The current buffer is the one containing the last displayed
5410 echo area message. */
5411 XSETBUFFER (echo_area_buffer[1], current_buffer);
5412
5413 return window_height_changed_p;
5414}
5415
5416
5417/* Resize mini-window W to fit the size of its contents. Value is
5418 non-zero if the window height has been changed. */
5419
5420static int
5421resize_mini_window (w)
5422 struct window *w;
5423{
5424 struct frame *f = XFRAME (w->frame);
5425 int window_height_changed_p = 0;
5426
5427 xassert (MINI_WINDOW_P (w));
5428
5429 if (!FRAME_MINIBUF_ONLY_P (f))
5430 {
5431 struct it it;
5432
5433 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
5434 if (!it.truncate_lines_p)
5435 {
5436 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
5437 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
5438 int height, max_height;
5439 int unit = CANON_Y_UNIT (f);
5440 struct text_pos start;
5441
5442 /* Compute the max. number of lines specified by the user. */
5443 if (FLOATP (Vmax_mini_window_height))
5444 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
5445 else if (INTEGERP (Vmax_mini_window_height))
5446 max_height = XINT (Vmax_mini_window_height);
5447
5448 /* Correct that max. height if it's bogus. */
5449 max_height = max (1, max_height);
5450 max_height = min (total_height, max_height);
5451
5452 /* Find out the height of the text in the window. */
5453 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
5454 height = (unit - 1 + it.current_y + last_height) / unit;
5455 height = max (1, height);
5456
5457 /* Compute a suitable window start. */
5458 if (height > max_height)
5459 {
5460 height = max_height;
5461 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5462 move_it_vertically_backward (&it, (height - 1) * unit);
5463 start = it.current.pos;
5464 }
5465 else
5466 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5467 SET_MARKER_FROM_TEXT_POS (w->start, start);
5468
5469 /* Change window's height, if necessary. */
5470 if (height != XFASTINT (w->height))
5471 {
5472 Lisp_Object old_selected_window;
5473
5474 old_selected_window = selected_window;
5475 XSETWINDOW (selected_window, w);
5476 change_window_height (height - XFASTINT (w->height), 0);
5477 selected_window = old_selected_window;
5478 window_height_changed_p = 1;
5479 }
5480 }
5481 }
5482
5483 return window_height_changed_p;
5484}
5485
5486
5487/* Value is the current message, a string, or nil if there is no
5488 current message. */
5489
5490Lisp_Object
5491current_message ()
5492{
5493 Lisp_Object msg;
5494
5495 if (NILP (echo_area_buffer[0]))
5496 msg = Qnil;
5497 else
5498 {
5499 with_echo_area_buffer (0, 0, (int (*) ()) current_message_1, &msg);
5500 if (NILP (msg))
5501 echo_area_buffer[0] = Qnil;
5502 }
5503
5504 return msg;
5505}
5506
5507
5508static int
5509current_message_1 (msg)
5510 Lisp_Object *msg;
5511{
5512 if (Z > BEG)
5513 *msg = make_buffer_string (BEG, Z, 1);
5514 else
5515 *msg = Qnil;
5516 return 0;
5517}
5518
5519
5520/* Push the current message on Vmessage_stack for later restauration
5521 by restore_message. Value is non-zero if the current message isn't
5522 empty. This is a relatively infrequent operation, so it's not
5523 worth optimizing. */
5524
5525int
5526push_message ()
5527{
5528 Lisp_Object msg;
5529 msg = current_message ();
5530 Vmessage_stack = Fcons (msg, Vmessage_stack);
5531 return STRINGP (msg);
5532}
5533
5534
5535/* Restore message display from the top of Vmessage_stack. */
5536
5537void
5538restore_message ()
5539{
5540 Lisp_Object msg;
5541
5542 xassert (CONSP (Vmessage_stack));
5543 msg = XCAR (Vmessage_stack);
5544 if (STRINGP (msg))
5545 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
5546 else
5547 message3_nolog (msg, 0, 0);
5548}
5549
5550
5551/* Pop the top-most entry off Vmessage_stack. */
5552
5553void
5554pop_message ()
5555{
5556 xassert (CONSP (Vmessage_stack));
5557 Vmessage_stack = XCDR (Vmessage_stack);
5558}
5559
5560
5561/* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
5562 exits. If the stack is not empty, we have a missing pop_message
5563 somewhere. */
5564
5565void
5566check_message_stack ()
5567{
5568 if (!NILP (Vmessage_stack))
5569 abort ();
5570}
5571
5572
5573/* Truncate to NCHARS what will be displayed in the echo area the next
5574 time we display it---but don't redisplay it now. */
5575
5576void
5577truncate_echo_area (nchars)
5578 int nchars;
5579{
5580 if (nchars == 0)
5581 echo_area_buffer[0] = Qnil;
5582 /* A null message buffer means that the frame hasn't really been
5583 initialized yet. Error messages get reported properly by
5584 cmd_error, so this must be just an informative message; toss it. */
5585 else if (!noninteractive
5586 && INTERACTIVE
5587 && FRAME_MESSAGE_BUF (selected_frame)
5588 && !NILP (echo_area_buffer[0]))
5589 with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
5590}
5591
5592
5593/* Helper function for truncate_echo_area. Truncate the current
5594 message to at most NCHARS characters. */
5595
5596static int
5597truncate_message_1 (nchars)
5598 int nchars;
5599{
5600 if (BEG + nchars < Z)
5601 del_range (BEG + nchars, Z);
5602 if (Z == BEG)
5603 echo_area_buffer[0] = Qnil;
5604 return 0;
5605}
5606
5607
5608/* Set the current message to a substring of S or STRING.
5609
5610 If STRING is a Lisp string, set the message to the first NBYTES
5611 bytes from STRING. NBYTES zero means use the whole string. If
5612 STRING is multibyte, the message will be displayed multibyte.
5613
5614 If S is not null, set the message to the first LEN bytes of S. LEN
5615 zero means use the whole string. MULTIBYTE_P non-zero means S is
5616 multibyte. Display the message multibyte in that case. */
5617
5618void
5619set_message (s, string, nbytes, multibyte_p)
5620 char *s;
5621 Lisp_Object string;
5622 int nbytes;
5623{
5624 message_enable_multibyte
5625 = ((s && multibyte_p)
5626 || (STRINGP (string) && STRING_MULTIBYTE (string)));
5627
5628 with_echo_area_buffer (0, -1, (int (*) ()) set_message_1,
5629 s, string, nbytes, multibyte_p);
5630 message_buf_print = 0;
5631}
5632
5633
5634/* Helper function for set_message. Arguments have the same meaning
5635 as there. This function is called with the echo area buffer being
5636 current. */
5637
5638static int
5639set_message_1 (s, string, nbytes, multibyte_p)
5640 char *s;
5641 Lisp_Object string;
5642 int nbytes, multibyte_p;
5643{
5644 xassert (BEG == Z);
5645
5646 /* Change multibyteness of the echo buffer appropriately. */
5647 if (message_enable_multibyte
5648 != !NILP (current_buffer->enable_multibyte_characters))
5649 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
5650
5651 /* Insert new message at BEG. */
5652 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5653
5654 if (STRINGP (string))
5655 {
5656 int nchars;
5657
5658 if (nbytes == 0)
5659 nbytes = XSTRING (string)->size_byte;
5660 nchars = string_byte_to_char (string, nbytes);
5661
5662 /* This function takes care of single/multibyte conversion. We
5663 just have to ensure that the echo area buffer has the right
5664 setting of enable_multibyte_characters. */
5665 insert_from_string (string, 0, 0, nchars, nbytes, 1);
5666 }
5667 else if (s)
5668 {
5669 if (nbytes == 0)
5670 nbytes = strlen (s);
5671
5672 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
5673 {
5674 /* Convert from multi-byte to single-byte. */
5675 int i, c, n;
5676 unsigned char work[1];
5677
5678 /* Convert a multibyte string to single-byte. */
5679 for (i = 0; i < nbytes; i += n)
5680 {
5681 c = string_char_and_length (s + i, nbytes - i, &n);
5682 work[0] = (SINGLE_BYTE_CHAR_P (c)
5683 ? c
5684 : multibyte_char_to_unibyte (c, Qnil));
5685 insert_1_both (work, 1, 1, 1, 0, 0);
5686 }
5687 }
5688 else if (!multibyte_p
5689 && !NILP (current_buffer->enable_multibyte_characters))
5690 {
5691 /* Convert from single-byte to multi-byte. */
5692 int i, c, n;
5693 unsigned char *msg = (unsigned char *) s;
5694 unsigned char *str, work[4];
5695
5696 /* Convert a single-byte string to multibyte. */
5697 for (i = 0; i < nbytes; i++)
5698 {
5699 c = unibyte_char_to_multibyte (msg[i]);
5700 n = CHAR_STRING (c, work, str);
5701 insert_1_both (work, 1, n, 1, 0, 0);
5702 }
5703 }
5704 else
5705 insert_1 (s, nbytes, 1, 0, 0);
5706 }
5707
5708 return 0;
5709}
5710
5711
5712/* Clear messages. CURRENT_P non-zero means clear the current
5713 message. LAST_DISPLAYED_P non-zero means clear the message
5714 last displayed. */
5715
5716void
5717clear_message (current_p, last_displayed_p)
5718 int current_p, last_displayed_p;
5719{
5720 if (current_p)
5721 echo_area_buffer[0] = Qnil;
5722
5723 if (last_displayed_p)
5724 echo_area_buffer[1] = Qnil;
5725
5726 message_buf_print = 0;
5727}
5728
5729/* Clear garbaged frames.
5730
5731 This function is used where the old redisplay called
5732 redraw_garbaged_frames which in turn called redraw_frame which in
5733 turn called clear_frame. The call to clear_frame was a source of
5734 flickering. I believe a clear_frame is not necessary. It should
5735 suffice in the new redisplay to invalidate all current matrices,
5736 and ensure a complete redisplay of all windows. */
5737
5738static void
5739clear_garbaged_frames ()
5740{
5f5c8ee5
GM
5741 if (frame_garbaged)
5742 {
5f5c8ee5
GM
5743 Lisp_Object tail, frame;
5744
5745 FOR_EACH_FRAME (tail, frame)
5746 {
5747 struct frame *f = XFRAME (frame);
5748
5749 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5750 {
5751 clear_current_matrices (f);
5752 f->garbaged = 0;
5753 }
5754 }
5755
5756 frame_garbaged = 0;
5757 ++windows_or_buffers_changed;
5758 }
c6e89d6c 5759}
5f5c8ee5 5760
5f5c8ee5 5761
c6e89d6c
GM
5762/* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
5763 non-zero update selected_frame. Value is non-zero if the
5764 mini-windows height has been changed. */
5f5c8ee5 5765
c6e89d6c
GM
5766static int
5767echo_area_display (update_frame_p)
5768 int update_frame_p;
5769{
5770 Lisp_Object mini_window;
5771 struct window *w;
5772 struct frame *f;
5773 int window_height_changed_p = 0;
5774
5775 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5776 w = XWINDOW (mini_window);
5777 f = XFRAME (WINDOW_FRAME (w));
5778
5779 /* Don't display if frame is invisible or not yet initialized. */
5780 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
5781 return 0;
5f5c8ee5 5782
c6e89d6c
GM
5783 /* When Emacs starts, selected_frame may be a visible terminal
5784 frame, even if we run under a window system. If we let this
5785 through, a message would be displayed on the terminal. */
5786#ifdef HAVE_WINDOW_SYSTEM
5787 if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
5788 return 0;
5789#endif /* HAVE_WINDOW_SYSTEM */
5790
5791 /* Redraw garbaged frames. */
5792 if (frame_garbaged)
5793 clear_garbaged_frames ();
5794
5795 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
5796 {
5797 echo_area_window = mini_window;
5798 window_height_changed_p = display_echo_area (w);
5f5c8ee5 5799 w->must_be_updated_p = 1;
c6e89d6c 5800
5f5c8ee5
GM
5801 if (update_frame_p)
5802 {
5803 /* Calling update_single_window is faster when we can use
5804 window-based redisplay. */
5805 if (FRAME_WINDOW_P (f))
5806 {
5807 update_single_window (w, 1);
5808 rif->flush_display (f);
5809 }
5810 else
5811 update_frame (f, 1, 1);
5812 }
5813 }
5814 else if (!EQ (mini_window, selected_window))
5815 windows_or_buffers_changed++;
5816
c6e89d6c
GM
5817 if (NILP (echo_area_buffer[0]))
5818 clear_message (0, 1);
5819
5f5c8ee5
GM
5820 /* Prevent redisplay optimization in redisplay_internal by resetting
5821 this_line_start_pos. This is done because the mini-buffer now
5822 displays the message instead of its buffer text. */
5823 if (EQ (mini_window, selected_window))
5824 CHARPOS (this_line_start_pos) = 0;
c6e89d6c
GM
5825
5826 return window_height_changed_p;
5f5c8ee5
GM
5827}
5828
5829
5830\f
5831/***********************************************************************
5832 Frame Titles
5833 ***********************************************************************/
5834
5835
5836#ifdef HAVE_WINDOW_SYSTEM
5837
5838/* A buffer for constructing frame titles in it; allocated from the
5839 heap in init_xdisp and resized as needed in store_frame_title_char. */
5840
5841static char *frame_title_buf;
5842
5843/* The buffer's end, and a current output position in it. */
5844
5845static char *frame_title_buf_end;
5846static char *frame_title_ptr;
5847
5848
5849/* Store a single character C for the frame title in frame_title_buf.
5850 Re-allocate frame_title_buf if necessary. */
5851
5852static void
5853store_frame_title_char (c)
5854 char c;
5855{
5856 /* If output position has reached the end of the allocated buffer,
5857 double the buffer's size. */
5858 if (frame_title_ptr == frame_title_buf_end)
5859 {
5860 int len = frame_title_ptr - frame_title_buf;
5861 int new_size = 2 * len * sizeof *frame_title_buf;
5862 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
5863 frame_title_buf_end = frame_title_buf + new_size;
5864 frame_title_ptr = frame_title_buf + len;
5865 }
5866
5867 *frame_title_ptr++ = c;
5868}
5869
5870
5871/* Store part of a frame title in frame_title_buf, beginning at
5872 frame_title_ptr. STR is the string to store. Do not copy more
5873 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
5874 the whole string. Pad with spaces until FIELD_WIDTH number of
5875 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
5876 Called from display_mode_element when it is used to build a frame
5877 title. */
5878
5879static int
5880store_frame_title (str, field_width, precision)
5881 unsigned char *str;
5882 int field_width, precision;
5883{
5884 int n = 0;
5885
5886 /* Copy at most PRECISION chars from STR. */
5887 while ((precision <= 0 || n < precision)
5888 && *str)
5889 {
5890 store_frame_title_char (*str++);
5891 ++n;
5892 }
5893
5894 /* Fill up with spaces until FIELD_WIDTH reached. */
5895 while (field_width > 0
5896 && n < field_width)
5897 {
5898 store_frame_title_char (' ');
5899 ++n;
5900 }
5901
5902 return n;
5903}
5904
5905
5906/* Set the title of FRAME, if it has changed. The title format is
5907 Vicon_title_format if FRAME is iconified, otherwise it is
5908 frame_title_format. */
5909
5910static void
5911x_consider_frame_title (frame)
5912 Lisp_Object frame;
5913{
5914 struct frame *f = XFRAME (frame);
5915
5916 if (FRAME_WINDOW_P (f)
5917 || FRAME_MINIBUF_ONLY_P (f)
5918 || f->explicit_name)
5919 {
5920 /* Do we have more than one visible frame on this X display? */
5921 Lisp_Object tail;
5922 Lisp_Object fmt;
5923 struct buffer *obuf;
5924 int len;
5925 struct it it;
5926
5927 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
5928 {
5929 struct frame *tf = XFRAME (XCONS (tail)->car);
5930
5931 if (tf != f
5932 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
5933 && !FRAME_MINIBUF_ONLY_P (tf)
5934 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
5935 break;
5936 }
5937
5938 /* Set global variable indicating that multiple frames exist. */
5939 multiple_frames = CONSP (tail);
5940
5941 /* Switch to the buffer of selected window of the frame. Set up
5942 frame_title_ptr so that display_mode_element will output into it;
5943 then display the title. */
5944 obuf = current_buffer;
5945 Fset_buffer (XWINDOW (f->selected_window)->buffer);
5946 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
5947 frame_title_ptr = frame_title_buf;
5948 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
5949 NULL, DEFAULT_FACE_ID);
5950 len = display_mode_element (&it, 0, -1, -1, fmt);
5951 frame_title_ptr = NULL;
5952 set_buffer_internal (obuf);
5953
5954 /* Set the title only if it's changed. This avoids consing in
5955 the common case where it hasn't. (If it turns out that we've
5956 already wasted too much time by walking through the list with
5957 display_mode_element, then we might need to optimize at a
5958 higher level than this.) */
5959 if (! STRINGP (f->name)
5960 || STRING_BYTES (XSTRING (f->name)) != len
5961 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
5962 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
5963 }
5964}
5965
5966#else /* not HAVE_WINDOW_SYSTEM */
5967
5968#define frame_title_ptr ((char *)0)
5969#define store_frame_title(str, mincol, maxcol) 0
5970
5971#endif /* not HAVE_WINDOW_SYSTEM */
5972
5973
5974
5975\f
5976/***********************************************************************
5977 Menu Bars
5978 ***********************************************************************/
5979
5980
5981/* Prepare for redisplay by updating menu-bar item lists when
5982 appropriate. This can call eval. */
5983
5984void
5985prepare_menu_bars ()
5986{
5987 int all_windows;
5988 struct gcpro gcpro1, gcpro2;
5989 struct frame *f;
5990 struct frame *tooltip_frame;
5991
5992#ifdef HAVE_X_WINDOWS
5993 tooltip_frame = tip_frame;
5994#else
5995 tooltip_frame = NULL;
5996#endif
5997
5998 /* Update all frame titles based on their buffer names, etc. We do
5999 this before the menu bars so that the buffer-menu will show the
6000 up-to-date frame titles. */
6001#ifdef HAVE_WINDOW_SYSTEM
6002 if (windows_or_buffers_changed || update_mode_lines)
6003 {
6004 Lisp_Object tail, frame;
6005
6006 FOR_EACH_FRAME (tail, frame)
6007 {
6008 f = XFRAME (frame);
6009 if (f != tooltip_frame
6010 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6011 x_consider_frame_title (frame);
6012 }
6013 }
6014#endif /* HAVE_WINDOW_SYSTEM */
6015
6016 /* Update the menu bar item lists, if appropriate. This has to be
6017 done before any actual redisplay or generation of display lines. */
6018 all_windows = (update_mode_lines
6019 || buffer_shared > 1
6020 || windows_or_buffers_changed);
6021 if (all_windows)
6022 {
6023 Lisp_Object tail, frame;
6024 int count = specpdl_ptr - specpdl;
6025
6026 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6027
6028 FOR_EACH_FRAME (tail, frame)
6029 {
6030 f = XFRAME (frame);
6031
6032 /* Ignore tooltip frame. */
6033 if (f == tooltip_frame)
6034 continue;
6035
6036 /* If a window on this frame changed size, report that to
6037 the user and clear the size-change flag. */
6038 if (FRAME_WINDOW_SIZES_CHANGED (f))
6039 {
6040 Lisp_Object functions;
6041
6042 /* Clear flag first in case we get an error below. */
6043 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6044 functions = Vwindow_size_change_functions;
6045 GCPRO2 (tail, functions);
6046
6047 while (CONSP (functions))
6048 {
6049 call1 (XCAR (functions), frame);
6050 functions = XCDR (functions);
6051 }
6052 UNGCPRO;
6053 }
6054
6055 GCPRO1 (tail);
6056 update_menu_bar (f, 0);
6057#ifdef HAVE_WINDOW_SYSTEM
6058 update_toolbar (f, 0);
6059#endif
6060 UNGCPRO;
6061 }
6062
6063 unbind_to (count, Qnil);
6064 }
6065 else
6066 {
6067 update_menu_bar (selected_frame, 1);
6068#ifdef HAVE_WINDOW_SYSTEM
6069 update_toolbar (selected_frame, 1);
6070#endif
6071 }
6072
6073 /* Motif needs this. See comment in xmenu.c. Turn it off when
6074 pending_menu_activation is not defined. */
6075#ifdef USE_X_TOOLKIT
6076 pending_menu_activation = 0;
6077#endif
6078}
6079
6080
6081/* Update the menu bar item list for frame F. This has to be done
6082 before we start to fill in any display lines, because it can call
6083 eval.
6084
6085 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6086
6087static void
6088update_menu_bar (f, save_match_data)
6089 struct frame *f;
6090 int save_match_data;
6091{
6092 Lisp_Object window;
6093 register struct window *w;
6094
6095 window = FRAME_SELECTED_WINDOW (f);
6096 w = XWINDOW (window);
6097
6098 if (update_mode_lines)
6099 w->update_mode_line = Qt;
6100
6101 if (FRAME_WINDOW_P (f)
6102 ?
6103#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6104 FRAME_EXTERNAL_MENU_BAR (f)
6105#else
6106 FRAME_MENU_BAR_LINES (f) > 0
6107#endif
6108 : FRAME_MENU_BAR_LINES (f) > 0)
6109 {
6110 /* If the user has switched buffers or windows, we need to
6111 recompute to reflect the new bindings. But we'll
6112 recompute when update_mode_lines is set too; that means
6113 that people can use force-mode-line-update to request
6114 that the menu bar be recomputed. The adverse effect on
6115 the rest of the redisplay algorithm is about the same as
6116 windows_or_buffers_changed anyway. */
6117 if (windows_or_buffers_changed
6118 || !NILP (w->update_mode_line)
6119 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6120 < BUF_MODIFF (XBUFFER (w->buffer)))
6121 != !NILP (w->last_had_star))
6122 || ((!NILP (Vtransient_mark_mode)
6123 && !NILP (XBUFFER (w->buffer)->mark_active))
6124 != !NILP (w->region_showing)))
6125 {
6126 struct buffer *prev = current_buffer;
6127 int count = specpdl_ptr - specpdl;
6128
6129 set_buffer_internal_1 (XBUFFER (w->buffer));
6130 if (save_match_data)
6131 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6132 if (NILP (Voverriding_local_map_menu_flag))
6133 {
6134 specbind (Qoverriding_terminal_local_map, Qnil);
6135 specbind (Qoverriding_local_map, Qnil);
6136 }
6137
6138 /* Run the Lucid hook. */
6139 call1 (Vrun_hooks, Qactivate_menubar_hook);
6140
6141 /* If it has changed current-menubar from previous value,
6142 really recompute the menu-bar from the value. */
6143 if (! NILP (Vlucid_menu_bar_dirty_flag))
6144 call0 (Qrecompute_lucid_menubar);
6145
6146 safe_run_hooks (Qmenu_bar_update_hook);
6147 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6148
6149 /* Redisplay the menu bar in case we changed it. */
6150#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6151 if (FRAME_WINDOW_P (f))
6152 set_frame_menubar (f, 0, 0);
6153 else
6154 /* On a terminal screen, the menu bar is an ordinary screen
6155 line, and this makes it get updated. */
6156 w->update_mode_line = Qt;
6157#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6158 /* In the non-toolkit version, the menu bar is an ordinary screen
6159 line, and this makes it get updated. */
6160 w->update_mode_line = Qt;
6161#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6162
6163 unbind_to (count, Qnil);
6164 set_buffer_internal_1 (prev);
6165 }
6166 }
6167}
6168
6169
6170\f
6171/***********************************************************************
6172 Toolbars
6173 ***********************************************************************/
6174
6175#ifdef HAVE_WINDOW_SYSTEM
6176
6177/* Update the toolbar item list for frame F. This has to be done
6178 before we start to fill in any display lines. Called from
6179 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
6180 and restore it here. */
6181
6182static void
6183update_toolbar (f, save_match_data)
6184 struct frame *f;
6185 int save_match_data;
6186{
6187 if (WINDOWP (f->toolbar_window)
6188 && XFASTINT (XWINDOW (f->toolbar_window)->height) > 0)
6189 {
6190 Lisp_Object window;
6191 struct window *w;
6192
6193 window = FRAME_SELECTED_WINDOW (f);
6194 w = XWINDOW (window);
6195
6196 /* If the user has switched buffers or windows, we need to
6197 recompute to reflect the new bindings. But we'll
6198 recompute when update_mode_lines is set too; that means
6199 that people can use force-mode-line-update to request
6200 that the menu bar be recomputed. The adverse effect on
6201 the rest of the redisplay algorithm is about the same as
6202 windows_or_buffers_changed anyway. */
6203 if (windows_or_buffers_changed
6204 || !NILP (w->update_mode_line)
6205 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6206 < BUF_MODIFF (XBUFFER (w->buffer)))
6207 != !NILP (w->last_had_star))
6208 || ((!NILP (Vtransient_mark_mode)
6209 && !NILP (XBUFFER (w->buffer)->mark_active))
6210 != !NILP (w->region_showing)))
6211 {
6212 struct buffer *prev = current_buffer;
6213 int count = specpdl_ptr - specpdl;
a2889657 6214
5f5c8ee5
GM
6215 /* Set current_buffer to the buffer of the selected
6216 window of the frame, so that we get the right local
6217 keymaps. */
6218 set_buffer_internal_1 (XBUFFER (w->buffer));
1f40cad2 6219
5f5c8ee5
GM
6220 /* Save match data, if we must. */
6221 if (save_match_data)
6222 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6223
6224 /* Make sure that we don't accidentally use bogus keymaps. */
6225 if (NILP (Voverriding_local_map_menu_flag))
6226 {
6227 specbind (Qoverriding_terminal_local_map, Qnil);
6228 specbind (Qoverriding_local_map, Qnil);
1f40cad2 6229 }
1f40cad2 6230
5f5c8ee5
GM
6231 /* Build desired toolbar items from keymaps. */
6232 f->desired_toolbar_items
6233 = toolbar_items (f->desired_toolbar_items,
6234 &f->n_desired_toolbar_items);
6235
6236 /* Redisplay the toolbar in case we changed it. */
6237 w->update_mode_line = Qt;
6238
6239 unbind_to (count, Qnil);
6240 set_buffer_internal_1 (prev);
81d478f3 6241 }
a2889657
JB
6242 }
6243}
6244
6c4429a5 6245
5f5c8ee5
GM
6246/* Set F->desired_toolbar_string to a Lisp string representing frame
6247 F's desired toolbar contents. F->desired_toolbar_items must have
6248 been set up previously by calling prepare_menu_bars. */
6249
a2889657 6250static void
5f5c8ee5
GM
6251build_desired_toolbar_string (f)
6252 struct frame *f;
a2889657 6253{
5f5c8ee5
GM
6254 int i, size, size_needed, string_idx;
6255 struct gcpro gcpro1, gcpro2, gcpro3;
6256 Lisp_Object image, plist, props;
a2889657 6257
5f5c8ee5
GM
6258 image = plist = props = Qnil;
6259 GCPRO3 (image, plist, props);
a2889657 6260
5f5c8ee5
GM
6261 /* Prepare F->desired_toolbar_string. If we can reuse it, do so.
6262 Otherwise, make a new string. */
6263
6264 /* The size of the string we might be able to reuse. */
6265 size = (STRINGP (f->desired_toolbar_string)
6266 ? XSTRING (f->desired_toolbar_string)->size
6267 : 0);
6268
6269 /* Each image in the string we build is preceded by a space,
6270 and there is a space at the end. */
6271 size_needed = f->n_desired_toolbar_items + 1;
6272
6273 /* Reuse f->desired_toolbar_string, if possible. */
6274 if (size < size_needed)
6275 f->desired_toolbar_string = Fmake_string (make_number (size_needed), ' ');
6276 else
6277 {
6278 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
6279 Fremove_text_properties (make_number (0), make_number (size),
6280 props, f->desired_toolbar_string);
6281 }
a2889657 6282
5f5c8ee5
GM
6283 /* Put a `display' property on the string for the images to display,
6284 put a `menu_item' property on toolbar items with a value that
6285 is the index of the item in F's toolbar item vector. */
6286 for (i = 0, string_idx = 0;
6287 i < f->n_desired_toolbar_items;
6288 ++i, string_idx += 1)
a2889657 6289 {
5f5c8ee5
GM
6290#define PROP(IDX) \
6291 (XVECTOR (f->desired_toolbar_items) \
6292 ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
6293
6294 int enabled_p = !NILP (PROP (TOOLBAR_ITEM_ENABLED_P));
6295 int selected_p = !NILP (PROP (TOOLBAR_ITEM_SELECTED_P));
6296 int margin, relief;
6297 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
6298 extern Lisp_Object Qlaplace;
6299
6300 /* If image is a vector, choose the image according to the
6301 button state. */
6302 image = PROP (TOOLBAR_ITEM_IMAGES);
6303 if (VECTORP (image))
6304 {
6305 enum toolbar_item_image idx;
6306
6307 if (enabled_p)
6308 idx = (selected_p
6309 ? TOOLBAR_IMAGE_ENABLED_SELECTED
6310 : TOOLBAR_IMAGE_ENABLED_DESELECTED);
6311 else
6312 idx = (selected_p
6313 ? TOOLBAR_IMAGE_DISABLED_SELECTED
6314 : TOOLBAR_IMAGE_DISABLED_DESELECTED);
6315
6316 xassert (XVECTOR (image)->size >= idx);
6317 image = XVECTOR (image)->contents[idx];
6318 }
6319
6320 /* Ignore invalid image specifications. */
6321 if (!valid_image_p (image))
6322 continue;
6323
6324 /* Display the toolbar button pressed, or depressed. */
6325 plist = Fcopy_sequence (XCDR (image));
6326
6327 /* Compute margin and relief to draw. */
6328 relief = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
6329 margin = relief + max (0, toolbar_button_margin);
6330
6331 if (auto_raise_toolbar_buttons_p)
6332 {
6333 /* Add a `:relief' property to the image spec if the item is
6334 selected. */
6335 if (selected_p)
6336 {
6337 plist = Fplist_put (plist, QCrelief, make_number (-relief));
6338 margin -= relief;
6339 }
6340 }
6341 else
6342 {
6343 /* If image is selected, display it pressed, i.e. with a
6344 negative relief. If it's not selected, display it with a
6345 raised relief. */
6346 plist = Fplist_put (plist, QCrelief,
6347 (selected_p
6348 ? make_number (-relief)
6349 : make_number (relief)));
6350 margin -= relief;
6351 }
6352
6353 /* Put a margin around the image. */
6354 if (margin)
6355 plist = Fplist_put (plist, QCmargin, make_number (margin));
6356
6357 /* If button is not enabled, make the image appear disabled by
6358 applying an appropriate algorithm to it. */
6359 if (!enabled_p)
6360 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
6361
6362 /* Put a `display' text property on the string for the image to
6363 display. Put a `menu-item' property on the string that gives
6364 the start of this item's properties in the toolbar items
6365 vector. */
6366 image = Fcons (Qimage, plist);
6367 props = list4 (Qdisplay, image,
6368 Qmenu_item, make_number (i * TOOLBAR_ITEM_NSLOTS)),
6369 Fadd_text_properties (make_number (string_idx),
6370 make_number (string_idx + 1),
6371 props, f->desired_toolbar_string);
6372#undef PROP
a2889657
JB
6373 }
6374
5f5c8ee5
GM
6375 UNGCPRO;
6376}
6377
6378
6379/* Display one line of the toolbar of frame IT->f. */
6380
6381static void
6382display_toolbar_line (it)
6383 struct it *it;
6384{
6385 struct glyph_row *row = it->glyph_row;
6386 int max_x = it->last_visible_x;
6387 struct glyph *last;
6388
6389 prepare_desired_row (row);
6390 row->y = it->current_y;
6391
6392 while (it->current_x < max_x)
a2889657 6393 {
5f5c8ee5 6394 int x_before, x, n_glyphs_before, i, nglyphs;
a2f016e3 6395
5f5c8ee5
GM
6396 /* Get the next display element. */
6397 if (!get_next_display_element (it))
6398 break;
73af359d 6399
5f5c8ee5
GM
6400 /* Produce glyphs. */
6401 x_before = it->current_x;
6402 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
6403 PRODUCE_GLYPHS (it);
daa37602 6404
5f5c8ee5
GM
6405 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
6406 i = 0;
6407 x = x_before;
6408 while (i < nglyphs)
6409 {
6410 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
6411
6412 if (x + glyph->pixel_width > max_x)
6413 {
6414 /* Glyph doesn't fit on line. */
6415 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
6416 it->current_x = x;
6417 goto out;
6418 }
daa37602 6419
5f5c8ee5
GM
6420 ++it->hpos;
6421 x += glyph->pixel_width;
6422 ++i;
6423 }
6424
6425 /* Stop at line ends. */
6426 if (ITERATOR_AT_END_OF_LINE_P (it))
6427 break;
6428
6429 set_iterator_to_next (it);
a2889657 6430 }
a2889657 6431
5f5c8ee5 6432 out:;
a2889657 6433
5f5c8ee5
GM
6434 row->displays_text_p = row->used[TEXT_AREA] != 0;
6435 extend_face_to_end_of_line (it);
6436 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
6437 last->right_box_line_p = 1;
6438 compute_line_metrics (it);
6439
6440 /* If line is empty, make it occupy the rest of the toolbar. */
6441 if (!row->displays_text_p)
6442 {
312246d1
GM
6443 row->height = row->phys_height = it->last_visible_y - row->y;
6444 row->ascent = row->phys_ascent = 0;
5f5c8ee5
GM
6445 }
6446
6447 row->full_width_p = 1;
6448 row->continued_p = 0;
6449 row->truncated_on_left_p = 0;
6450 row->truncated_on_right_p = 0;
6451
6452 it->current_x = it->hpos = 0;
6453 it->current_y += row->height;
6454 ++it->vpos;
6455 ++it->glyph_row;
a2889657 6456}
96a410bc 6457
5f5c8ee5
GM
6458
6459/* Value is the number of screen lines needed to make all toolbar
6460 items of frame F visible. */
96a410bc 6461
d39b6696 6462static int
5f5c8ee5
GM
6463toolbar_lines_needed (f)
6464 struct frame *f;
d39b6696 6465{
5f5c8ee5
GM
6466 struct window *w = XWINDOW (f->toolbar_window);
6467 struct it it;
6468
6469 /* Initialize an iterator for iteration over F->desired_toolbar_string
6470 in the toolbar window of frame F. */
6471 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
6472 it.first_visible_x = 0;
6473 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6474 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
6475
6476 while (!ITERATOR_AT_END_P (&it))
6477 {
6478 it.glyph_row = w->desired_matrix->rows;
6479 clear_glyph_row (it.glyph_row);
6480 display_toolbar_line (&it);
6481 }
6482
6483 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
d39b6696 6484}
96a410bc 6485
5f5c8ee5
GM
6486
6487/* Display the toolbar of frame F. Value is non-zero if toolbar's
6488 height should be changed. */
6489
6490static int
6491redisplay_toolbar (f)
6492 struct frame *f;
96a410bc 6493{
5f5c8ee5
GM
6494 struct window *w;
6495 struct it it;
6496 struct glyph_row *row;
6497 int change_height_p = 0;
6498
6499 /* If frame hasn't a toolbar window or if it is zero-height, don't
6500 do anything. This means you must start with toolbar-lines
6501 non-zero to get the auto-sizing effect. Or in other words, you
6502 can turn off toolbars by specifying toolbar-lines zero. */
6503 if (!WINDOWP (f->toolbar_window)
6504 || (w = XWINDOW (f->toolbar_window),
6505 XFASTINT (w->height) == 0))
6506 return 0;
96a410bc 6507
5f5c8ee5
GM
6508 /* Set up an iterator for the toolbar window. */
6509 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
6510 it.first_visible_x = 0;
6511 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6512 row = it.glyph_row;
3450d04c 6513
5f5c8ee5
GM
6514 /* Build a string that represents the contents of the toolbar. */
6515 build_desired_toolbar_string (f);
6516 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
3450d04c 6517
5f5c8ee5
GM
6518 /* Display as many lines as needed to display all toolbar items. */
6519 while (it.current_y < it.last_visible_y)
6520 display_toolbar_line (&it);
3450d04c 6521
5f5c8ee5
GM
6522 /* It doesn't make much sense to try scrolling in the toolbar
6523 window, so don't do it. */
6524 w->desired_matrix->no_scrolling_p = 1;
6525 w->must_be_updated_p = 1;
3450d04c 6526
5f5c8ee5
GM
6527 if (auto_resize_toolbars_p)
6528 {
6529 int nlines;
6530
6531 /* If there are blank lines at the end, except for a partially
6532 visible blank line at the end that is smaller than
6533 CANON_Y_UNIT, change the toolbar's height. */
6534 row = it.glyph_row - 1;
6535 if (!row->displays_text_p
6536 && row->height >= CANON_Y_UNIT (f))
6537 change_height_p = 1;
6538
6539 /* If row displays toolbar items, but is partially visible,
6540 change the toolbar's height. */
6541 if (row->displays_text_p
6542 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6543 change_height_p = 1;
6544
6545 /* Resize windows as needed by changing the `toolbar-lines'
6546 frame parameter. */
6547 if (change_height_p
6548 && (nlines = toolbar_lines_needed (f),
6549 nlines != XFASTINT (w->height)))
6550 {
6551 extern Lisp_Object Qtoolbar_lines;
6552 Lisp_Object frame;
6553
6554 XSETFRAME (frame, f);
6555 clear_glyph_matrix (w->desired_matrix);
6556 Fmodify_frame_parameters (frame,
6557 Fcons (Fcons (Qtoolbar_lines,
6558 make_number (nlines)),
6559 Qnil));
6560 fonts_changed_p = 1;
6561 }
6562 }
3450d04c 6563
5f5c8ee5 6564 return change_height_p;
96a410bc 6565}
90adcf20 6566
5f5c8ee5
GM
6567
6568/* Get information about the toolbar item which is displayed in GLYPH
6569 on frame F. Return in *PROP_IDX the index where toolbar item
6570 properties start in F->current_toolbar_items. Value is zero if
6571 GLYPH doesn't display a toolbar item. */
6572
6573int
6574toolbar_item_info (f, glyph, prop_idx)
6575 struct frame *f;
6576 struct glyph *glyph;
6577 int *prop_idx;
90adcf20 6578{
5f5c8ee5
GM
6579 Lisp_Object prop;
6580 int success_p;
6581
6582 /* Get the text property `menu-item' at pos. The value of that
6583 property is the start index of this item's properties in
6584 F->current_toolbar_items. */
6585 prop = Fget_text_property (make_number (glyph->charpos),
6586 Qmenu_item, f->current_toolbar_string);
6587 if (INTEGERP (prop))
6588 {
6589 *prop_idx = XINT (prop);
6590 success_p = 1;
6591 }
6592 else
6593 success_p = 0;
90adcf20 6594
5f5c8ee5
GM
6595 return success_p;
6596}
6597
6598#endif /* HAVE_WINDOW_SYSTEM */
90adcf20 6599
feb0c42f 6600
5f5c8ee5
GM
6601\f
6602/************************************************************************
6603 Horizontal scrolling
6604 ************************************************************************/
feb0c42f 6605
5f5c8ee5
GM
6606static int hscroll_window_tree P_ ((Lisp_Object));
6607static int hscroll_windows P_ ((Lisp_Object));
feb0c42f 6608
5f5c8ee5
GM
6609/* For all leaf windows in the window tree rooted at WINDOW, set their
6610 hscroll value so that PT is (i) visible in the window, and (ii) so
6611 that it is not within a certain margin at the window's left and
6612 right border. Value is non-zero if any window's hscroll has been
6613 changed. */
6614
6615static int
6616hscroll_window_tree (window)
6617 Lisp_Object window;
6618{
6619 int hscrolled_p = 0;
6620
6621 while (WINDOWP (window))
90adcf20 6622 {
5f5c8ee5
GM
6623 struct window *w = XWINDOW (window);
6624
6625 if (WINDOWP (w->hchild))
6626 hscrolled_p |= hscroll_window_tree (w->hchild);
6627 else if (WINDOWP (w->vchild))
6628 hscrolled_p |= hscroll_window_tree (w->vchild);
6629 else if (w->cursor.vpos >= 0)
6630 {
6631 int hscroll_margin, text_area_x, text_area_y;
6632 int text_area_width, text_area_height;
6633 struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
6634 w->cursor.vpos);
a2725ab2 6635
5f5c8ee5
GM
6636 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6637 &text_area_width, &text_area_height);
90adcf20 6638
5f5c8ee5
GM
6639 /* Scroll when cursor is inside this scroll margin. */
6640 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6641
6642 if ((XFASTINT (w->hscroll)
6643 && w->cursor.x < hscroll_margin)
6644 || (cursor_row->truncated_on_right_p
6645 && (w->cursor.x > text_area_width - hscroll_margin)))
08b610e4 6646 {
5f5c8ee5
GM
6647 struct it it;
6648 int hscroll;
6649 struct buffer *saved_current_buffer;
6650 int pt;
6651
6652 /* Find point in a display of infinite width. */
6653 saved_current_buffer = current_buffer;
6654 current_buffer = XBUFFER (w->buffer);
6655
6656 if (w == XWINDOW (selected_window))
6657 pt = BUF_PT (current_buffer);
6658 else
08b610e4 6659 {
5f5c8ee5
GM
6660 pt = marker_position (w->pointm);
6661 pt = max (BEGV, pt);
6662 pt = min (ZV, pt);
6663 }
6664
6665 /* Move iterator to pt starting at cursor_row->start in
6666 a line with infinite width. */
6667 init_to_row_start (&it, w, cursor_row);
6668 it.last_visible_x = INFINITY;
6669 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6670 current_buffer = saved_current_buffer;
6671
6672 /* Center cursor in window. */
6673 hscroll = (max (0, it.current_x - text_area_width / 2)
6674 / CANON_X_UNIT (it.f));
6675
6676 /* Don't call Fset_window_hscroll if value hasn't
6677 changed because it will prevent redisplay
6678 optimizations. */
6679 if (XFASTINT (w->hscroll) != hscroll)
6680 {
6681 Fset_window_hscroll (window, make_number (hscroll));
6682 hscrolled_p = 1;
08b610e4 6683 }
08b610e4 6684 }
08b610e4 6685 }
a2725ab2 6686
5f5c8ee5 6687 window = w->next;
90adcf20 6688 }
cd6dfed6 6689
5f5c8ee5
GM
6690 /* Value is non-zero if hscroll of any leaf window has been changed. */
6691 return hscrolled_p;
6692}
6693
6694
6695/* Set hscroll so that cursor is visible and not inside horizontal
6696 scroll margins for all windows in the tree rooted at WINDOW. See
6697 also hscroll_window_tree above. Value is non-zero if any window's
6698 hscroll has been changed. If it has, desired matrices on the frame
6699 of WINDOW are cleared. */
6700
6701static int
6702hscroll_windows (window)
6703 Lisp_Object window;
6704{
6705 int hscrolled_p = hscroll_window_tree (window);
6706 if (hscrolled_p)
6707 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6708 return hscrolled_p;
90adcf20 6709}
5f5c8ee5
GM
6710
6711
90adcf20 6712\f
5f5c8ee5
GM
6713/************************************************************************
6714 Redisplay
6715 ************************************************************************/
6716
6717/* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6718 to a non-zero value. This is sometimes handy to have in a debugger
6719 session. */
6720
6721#if GLYPH_DEBUG
a2889657 6722
5f5c8ee5
GM
6723/* Values of beg_unchanged and end_unchanged as of last call to
6724 try_window_id. */
6725
6726int debug_beg_unchanged, debug_end_unchanged;
6727
6728/* First and last unchanged row for try_window_id. */
6729
6730int debug_first_unchanged_at_end_vpos;
6731int debug_last_unchanged_at_beg_vpos;
6732
6733/* Delta vpos and y. */
6734
6735int debug_dvpos, debug_dy;
6736
6737/* Delta in characters and bytes for try_window_id. */
6738
6739int debug_delta, debug_delta_bytes;
6740
6741/* Values of window_end_pos and window_end_vpos at the end of
6742 try_window_id. */
6743
6744int debug_end_pos, debug_end_vpos;
6745
6746/* Append a string to W->desired_matrix->method. FMT is a printf
6747 format string. A1...A9 are a supplement for a variable-length
6748 argument list. If trace_redisplay_p is non-zero also printf the
6749 resulting string to stderr. */
6750
6751static void
6752debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
6753 struct window *w;
6754 char *fmt;
6755 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
6756{
6757 char buffer[512];
6758 char *method = w->desired_matrix->method;
6759 int len = strlen (method);
6760 int size = sizeof w->desired_matrix->method;
6761 int remaining = size - len - 1;
6762
6763 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
6764 if (len && remaining)
6765 {
6766 method[len] = '|';
6767 --remaining, ++len;
6768 }
6769
6770 strncpy (method + len, buffer, remaining);
6771
6772 if (trace_redisplay_p)
6773 fprintf (stderr, "%p (%s): %s\n",
6774 w,
6775 ((BUFFERP (w->buffer)
6776 && STRINGP (XBUFFER (w->buffer)->name))
6777 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
6778 : "no buffer"),
6779 buffer);
6780}
a2889657 6781
5f5c8ee5 6782#endif /* GLYPH_DEBUG */
90adcf20 6783
a2889657 6784
5f5c8ee5
GM
6785/* This counter is used to clear the face cache every once in a while
6786 in redisplay_internal. It is incremented for each redisplay.
6787 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
6788 cleared. */
0d231165 6789
5f5c8ee5 6790#define CLEAR_FACE_CACHE_COUNT 10000
463f6b91
RS
6791static int clear_face_cache_count;
6792
20de20dc 6793/* Record the previous terminal frame we displayed. */
5f5c8ee5
GM
6794
6795static struct frame *previous_terminal_frame;
6796
6797/* Non-zero while redisplay_internal is in progress. */
6798
6799int redisplaying_p;
6800
6801
6802/* Value is non-zero if all changes in window W, which displays
6803 current_buffer, are in the text between START and END. START is a
6804 buffer position, END is given as a distance from Z. Used in
6805 redisplay_internal for display optimization. */
6806
6807static INLINE int
6808text_outside_line_unchanged_p (w, start, end)
6809 struct window *w;
6810 int start, end;
6811{
6812 int unchanged_p = 1;
6813
6814 /* If text or overlays have changed, see where. */
6815 if (XFASTINT (w->last_modified) < MODIFF
6816 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
6817 {
6818 /* Gap in the line? */
6819 if (GPT < start || Z - GPT < end)
6820 unchanged_p = 0;
6821
6822 /* Changes start in front of the line, or end after it? */
6823 if (unchanged_p
6824 && (beg_unchanged < start - 1
6825 || end_unchanged < end))
6826 unchanged_p = 0;
6827
6828 /* If selective display, can't optimize if changes start at the
6829 beginning of the line. */
6830 if (unchanged_p
6831 && INTEGERP (current_buffer->selective_display)
6832 && XINT (current_buffer->selective_display) > 0
6833 && (beg_unchanged < start || GPT <= start))
6834 unchanged_p = 0;
6835 }
6836
6837 return unchanged_p;
6838}
6839
6840
6841/* Do a frame update, taking possible shortcuts into account. This is
6842 the main external entry point for redisplay.
6843
6844 If the last redisplay displayed an echo area message and that message
6845 is no longer requested, we clear the echo area or bring back the
6846 mini-buffer if that is in use. */
20de20dc 6847
a2889657
JB
6848void
6849redisplay ()
e9874cee
RS
6850{
6851 redisplay_internal (0);
6852}
6853
5f5c8ee5
GM
6854
6855/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
6856 response to any user action; therefore, we should preserve the echo
6857 area. (Actually, our caller does that job.) Perhaps in the future
6858 avoid recentering windows if it is not necessary; currently that
6859 causes some problems. */
e9874cee
RS
6860
6861static void
6862redisplay_internal (preserve_echo_area)
6863 int preserve_echo_area;
a2889657 6864{
5f5c8ee5
GM
6865 struct window *w = XWINDOW (selected_window);
6866 struct frame *f = XFRAME (w->frame);
6867 int pause;
a2889657 6868 int must_finish = 0;
5f5c8ee5 6869 struct text_pos tlbufpos, tlendpos;
89819bdd 6870 int number_of_visible_frames;
28514cd9 6871 int count;
a2889657 6872
5f5c8ee5
GM
6873 /* Non-zero means redisplay has to consider all windows on all
6874 frames. Zero means, only selected_window is considered. */
6875 int consider_all_windows_p;
6876
6877 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
6878
6879 /* No redisplay if running in batch mode or frame is not yet fully
6880 initialized, or redisplay is explicitly turned off by setting
6881 Vinhibit_redisplay. */
6882 if (noninteractive
6883 || !NILP (Vinhibit_redisplay)
6884 || !f->glyphs_initialized_p)
a2889657
JB
6885 return;
6886
5f5c8ee5
GM
6887 /* The flag redisplay_performed_directly_p is set by
6888 direct_output_for_insert when it already did the whole screen
6889 update necessary. */
6890 if (redisplay_performed_directly_p)
6891 {
6892 redisplay_performed_directly_p = 0;
6893 if (!hscroll_windows (selected_window))
6894 return;
6895 }
6896
15f0cf78
RS
6897#ifdef USE_X_TOOLKIT
6898 if (popup_activated ())
6899 return;
6900#endif
6901
28514cd9 6902 /* I don't think this happens but let's be paranoid. */
5f5c8ee5 6903 if (redisplaying_p)
735c094c
KH
6904 return;
6905
28514cd9
GM
6906 /* Record a function that resets redisplaying_p to its old value
6907 when we leave this function. */
6908 count = specpdl_ptr - specpdl;
6909 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
6910 ++redisplaying_p;
6911
8b32d885
RS
6912 retry:
6913
5f5c8ee5
GM
6914 /* If new fonts have been loaded that make a glyph matrix adjustment
6915 necessary, do it. */
6916 if (fonts_changed_p)
6917 {
6918 adjust_glyphs (NULL);
6919 ++windows_or_buffers_changed;
6920 fonts_changed_p = 0;
6921 }
6922
fd8ff63d 6923 if (! FRAME_WINDOW_P (selected_frame)
20de20dc
RS
6924 && previous_terminal_frame != selected_frame)
6925 {
5f5c8ee5
GM
6926 /* Since frames on an ASCII terminal share the same display
6927 area, displaying a different frame means redisplay the whole
6928 thing. */
20de20dc
RS
6929 windows_or_buffers_changed++;
6930 SET_FRAME_GARBAGED (selected_frame);
6931 XSETFRAME (Vterminal_frame, selected_frame);
6932 }
6933 previous_terminal_frame = selected_frame;
20de20dc 6934
5f5c8ee5
GM
6935 /* Set the visible flags for all frames. Do this before checking
6936 for resized or garbaged frames; they want to know if their frames
6937 are visible. See the comment in frame.h for
6938 FRAME_SAMPLE_VISIBILITY. */
d724d989 6939 {
35f56f96 6940 Lisp_Object tail, frame;
d724d989 6941
89819bdd
RS
6942 number_of_visible_frames = 0;
6943
35f56f96 6944 FOR_EACH_FRAME (tail, frame)
f82aff7c 6945 {
5f5c8ee5
GM
6946 struct frame *f = XFRAME (frame);
6947
6948 FRAME_SAMPLE_VISIBILITY (f);
6949 if (FRAME_VISIBLE_P (f))
6950 ++number_of_visible_frames;
6951 clear_desired_matrices (f);
f82aff7c 6952 }
d724d989
JB
6953 }
6954
44fa5b1e 6955 /* Notice any pending interrupt request to change frame size. */
c6e89d6c 6956 do_pending_window_change (1);
a2889657 6957
5f5c8ee5 6958 /* Clear frames marked as garbaged. */
44fa5b1e 6959 if (frame_garbaged)
c6e89d6c 6960 clear_garbaged_frames ();
a2889657 6961
5f5c8ee5 6962 /* Build menubar and toolbar items. */
f82aff7c
RS
6963 prepare_menu_bars ();
6964
c6e89d6c
GM
6965 retry_1:
6966
28995e67 6967 if (windows_or_buffers_changed)
a2889657
JB
6968 update_mode_lines++;
6969
538f13d4
RS
6970 /* Detect case that we need to write or remove a star in the mode line. */
6971 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
a2889657
JB
6972 {
6973 w->update_mode_line = Qt;
6974 if (buffer_shared > 1)
6975 update_mode_lines++;
6976 }
6977
5f5c8ee5 6978 /* If %c is in the mode line, update it if needed. */
28995e67
RS
6979 if (!NILP (w->column_number_displayed)
6980 /* This alternative quickly identifies a common case
6981 where no change is needed. */
6982 && !(PT == XFASTINT (w->last_point)
8850a573
RS
6983 && XFASTINT (w->last_modified) >= MODIFF
6984 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
6985 && XFASTINT (w->column_number_displayed) != current_column ())
6986 w->update_mode_line = Qt;
6987
44fa5b1e 6988 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
a2889657 6989
5f5c8ee5
GM
6990 /* The variable buffer_shared is set in redisplay_window and
6991 indicates that we redisplay a buffer in different windows. See
6992 there. */
6993 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
a2889657
JB
6994
6995 /* If specs for an arrow have changed, do thorough redisplay
6996 to ensure we remove any arrow that should no longer exist. */
d45de95b 6997 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
ded34426 6998 || ! EQ (Voverlay_arrow_string, last_arrow_string))
5f5c8ee5 6999 consider_all_windows_p = windows_or_buffers_changed = 1;
a2889657 7000
90adcf20
RS
7001 /* Normally the message* functions will have already displayed and
7002 updated the echo area, but the frame may have been trashed, or
7003 the update may have been preempted, so display the echo area
c6e89d6c
GM
7004 again here. Checking both message buffers captures the case that
7005 the echo area should be cleared. */
7006 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
90adcf20 7007 {
c6e89d6c 7008 int window_height_changed_p = echo_area_display (0);
90adcf20 7009 must_finish = 1;
c6e89d6c
GM
7010 if (fonts_changed_p)
7011 goto retry;
7012 else if (window_height_changed_p)
7013 {
7014 consider_all_windows_p = 1;
7015 ++update_mode_lines;
7016 ++windows_or_buffers_changed;
7017 }
90adcf20 7018 }
c6e89d6c
GM
7019 else if (w == XWINDOW (minibuf_window) && resize_mini_window (w))
7020 {
7021 /* Resized active mini-window to fit the size of what it is
7022 showing. */
7023 ++windows_or_buffers_changed;
7024 goto retry;
7025 }
7026
90adcf20 7027
5f5c8ee5
GM
7028 /* If showing the region, and mark has changed, we must redisplay
7029 the whole window. The assignment to this_line_start_pos prevents
7030 the optimization directly below this if-statement. */
bd66d1ba
RS
7031 if (((!NILP (Vtransient_mark_mode)
7032 && !NILP (XBUFFER (w->buffer)->mark_active))
7033 != !NILP (w->region_showing))
82d04750
JB
7034 || (!NILP (w->region_showing)
7035 && !EQ (w->region_showing,
7036 Fmarker_position (XBUFFER (w->buffer)->mark))))
5f5c8ee5
GM
7037 CHARPOS (this_line_start_pos) = 0;
7038
7039 /* Optimize the case that only the line containing the cursor in the
7040 selected window has changed. Variables starting with this_ are
7041 set in display_line and record information about the line
7042 containing the cursor. */
7043 tlbufpos = this_line_start_pos;
7044 tlendpos = this_line_end_pos;
7045 if (!consider_all_windows_p
7046 && CHARPOS (tlbufpos) > 0
7047 && NILP (w->update_mode_line)
73af359d 7048 && !current_buffer->clip_changed
44fa5b1e 7049 && FRAME_VISIBLE_P (XFRAME (w->frame))
f21ef775 7050 && !FRAME_OBSCURED_P (XFRAME (w->frame))
5f5c8ee5 7051 /* Make sure recorded data applies to current buffer, etc. */
a2889657
JB
7052 && this_line_buffer == current_buffer
7053 && current_buffer == XBUFFER (w->buffer)
265a9e55 7054 && NILP (w->force_start)
5f5c8ee5
GM
7055 /* Point must be on the line that we have info recorded about. */
7056 && PT >= CHARPOS (tlbufpos)
7057 && PT <= Z - CHARPOS (tlendpos)
a2889657
JB
7058 /* All text outside that line, including its final newline,
7059 must be unchanged */
5f5c8ee5
GM
7060 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7061 CHARPOS (tlendpos)))
7062 {
7063 if (CHARPOS (tlbufpos) > BEGV
7064 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
7065 && (CHARPOS (tlbufpos) == ZV
7066 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
a2889657
JB
7067 /* Former continuation line has disappeared by becoming empty */
7068 goto cancel;
7069 else if (XFASTINT (w->last_modified) < MODIFF
8850a573 7070 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
a2889657
JB
7071 || MINI_WINDOW_P (w))
7072 {
1c9241f5
KH
7073 /* We have to handle the case of continuation around a
7074 wide-column character (See the comment in indent.c around
7075 line 885).
7076
7077 For instance, in the following case:
7078
7079 -------- Insert --------
7080 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
7081 J_I_ ==> J_I_ `^^' are cursors.
7082 ^^ ^^
7083 -------- --------
7084
7085 As we have to redraw the line above, we should goto cancel. */
7086
5f5c8ee5
GM
7087 struct it it;
7088 int line_height_before = this_line_pixel_height;
7089
7090 /* Note that start_display will handle the case that the
7091 line starting at tlbufpos is a continuation lines. */
7092 start_display (&it, w, tlbufpos);
7093
7094 /* Implementation note: It this still necessary? */
7095 if (it.current_x != this_line_start_x)
1c9241f5
KH
7096 goto cancel;
7097
5f5c8ee5
GM
7098 TRACE ((stderr, "trying display optimization 1\n"));
7099 w->cursor.vpos = -1;
a2889657 7100 overlay_arrow_seen = 0;
5f5c8ee5
GM
7101 it.vpos = this_line_vpos;
7102 it.current_y = this_line_y;
7103 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
7104 display_line (&it);
7105
a2889657 7106 /* If line contains point, is not continued,
5f5c8ee5
GM
7107 and ends at same distance from eob as before, we win */
7108 if (w->cursor.vpos >= 0
7109 /* Line is not continued, otherwise this_line_start_pos
7110 would have been set to 0 in display_line. */
7111 && CHARPOS (this_line_start_pos)
7112 /* Line ends as before. */
7113 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
7114 /* Line has same height as before. Otherwise other lines
7115 would have to be shifted up or down. */
7116 && this_line_pixel_height == line_height_before)
a2889657 7117 {
5f5c8ee5
GM
7118 /* If this is not the window's last line, we must adjust
7119 the charstarts of the lines below. */
7120 if (it.current_y < it.last_visible_y)
7121 {
7122 struct glyph_row *row
7123 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
7124 int delta, delta_bytes;
7125
7126 if (Z - CHARPOS (tlendpos) == ZV)
7127 {
7128 /* This line ends at end of (accessible part of)
7129 buffer. There is no newline to count. */
7130 delta = (Z
7131 - CHARPOS (tlendpos)
7132 - MATRIX_ROW_START_CHARPOS (row));
7133 delta_bytes = (Z_BYTE
7134 - BYTEPOS (tlendpos)
7135 - MATRIX_ROW_START_BYTEPOS (row));
7136 }
7137 else
7138 {
7139 /* This line ends in a newline. Must take
7140 account of the newline and the rest of the
7141 text that follows. */
7142 delta = (Z
7143 - CHARPOS (tlendpos)
7144 - MATRIX_ROW_START_CHARPOS (row));
7145 delta_bytes = (Z_BYTE
7146 - BYTEPOS (tlendpos)
7147 - MATRIX_ROW_START_BYTEPOS (row));
7148 }
7149
7150 increment_glyph_matrix_buffer_positions (w->current_matrix,
7151 this_line_vpos + 1,
7152 w->current_matrix->nrows,
7153 delta, delta_bytes);
85bcef6c 7154 }
46db8486 7155
5f5c8ee5
GM
7156 /* If this row displays text now but previously didn't,
7157 or vice versa, w->window_end_vpos may have to be
7158 adjusted. */
7159 if ((it.glyph_row - 1)->displays_text_p)
7160 {
7161 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
7162 XSETINT (w->window_end_vpos, this_line_vpos);
7163 }
7164 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
7165 && this_line_vpos > 0)
7166 XSETINT (w->window_end_vpos, this_line_vpos - 1);
7167 w->window_end_valid = Qnil;
7168
7169 /* Update hint: No need to try to scroll in update_window. */
7170 w->desired_matrix->no_scrolling_p = 1;
7171
7172#if GLYPH_DEBUG
7173 *w->desired_matrix->method = 0;
7174 debug_method_add (w, "optimization 1");
7175#endif
a2889657
JB
7176 goto update;
7177 }
7178 else
7179 goto cancel;
7180 }
5f5c8ee5
GM
7181 else if (/* Cursor position hasn't changed. */
7182 PT == XFASTINT (w->last_point)
b6f0fe04
RS
7183 /* Make sure the cursor was last displayed
7184 in this window. Otherwise we have to reposition it. */
5f5c8ee5
GM
7185 && 0 <= w->cursor.vpos
7186 && XINT (w->height) > w->cursor.vpos)
a2889657
JB
7187 {
7188 if (!must_finish)
7189 {
c6e89d6c 7190 do_pending_window_change (1);
5f5c8ee5
GM
7191
7192 /* We used to always goto end_of_redisplay here, but this
7193 isn't enough if we have a blinking cursor. */
7194 if (w->cursor_off_p == w->last_cursor_off_p)
7195 goto end_of_redisplay;
a2889657
JB
7196 }
7197 goto update;
7198 }
8b51f1e3
KH
7199 /* If highlighting the region, or if the cursor is in the echo area,
7200 then we can't just move the cursor. */
bd66d1ba
RS
7201 else if (! (!NILP (Vtransient_mark_mode)
7202 && !NILP (current_buffer->mark_active))
293a54ce
RS
7203 && (w == XWINDOW (current_buffer->last_selected_window)
7204 || highlight_nonselected_windows)
8b51f1e3 7205 && NILP (w->region_showing)
8f897821 7206 && NILP (Vshow_trailing_whitespace)
8b51f1e3 7207 && !cursor_in_echo_area)
a2889657 7208 {
5f5c8ee5
GM
7209 struct it it;
7210 struct glyph_row *row;
7211
7212 /* Skip from tlbufpos to PT and see where it is. Note that
7213 PT may be in invisible text. If so, we will end at the
7214 next visible position. */
7215 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
7216 NULL, DEFAULT_FACE_ID);
7217 it.current_x = this_line_start_x;
7218 it.current_y = this_line_y;
7219 it.vpos = this_line_vpos;
7220
7221 /* The call to move_it_to stops in front of PT, but
7222 moves over before-strings. */
7223 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
7224
7225 if (it.vpos == this_line_vpos
7226 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
7227 row->enabled_p))
a2889657 7228 {
5f5c8ee5
GM
7229 xassert (this_line_vpos == it.vpos);
7230 xassert (this_line_y == it.current_y);
7231 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
a2889657
JB
7232 goto update;
7233 }
7234 else
7235 goto cancel;
7236 }
5f5c8ee5 7237
a2889657 7238 cancel:
5f5c8ee5
GM
7239 /* Text changed drastically or point moved off of line. */
7240 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
a2889657
JB
7241 }
7242
5f5c8ee5
GM
7243 CHARPOS (this_line_start_pos) = 0;
7244 consider_all_windows_p |= buffer_shared > 1;
7245 ++clear_face_cache_count;
a2889657 7246
5f5c8ee5
GM
7247
7248 /* Build desired matrices. If consider_all_windows_p is non-zero,
7249 do it for all windows on all frames. Otherwise do it for
7250 selected_window, only. */
463f6b91 7251
5f5c8ee5 7252 if (consider_all_windows_p)
a2889657 7253 {
35f56f96 7254 Lisp_Object tail, frame;
a2889657 7255
5f5c8ee5
GM
7256 /* Clear the face cache eventually. */
7257 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
463f6b91 7258 {
5f5c8ee5 7259 clear_face_cache (0);
463f6b91
RS
7260 clear_face_cache_count = 0;
7261 }
31b24551 7262
5f5c8ee5
GM
7263 /* Recompute # windows showing selected buffer. This will be
7264 incremented each time such a window is displayed. */
a2889657
JB
7265 buffer_shared = 0;
7266
35f56f96 7267 FOR_EACH_FRAME (tail, frame)
30c566e4 7268 {
5f5c8ee5 7269 struct frame *f = XFRAME (frame);
fd8ff63d 7270 if (FRAME_WINDOW_P (f) || f == selected_frame)
9769686d 7271 {
5f5c8ee5
GM
7272 /* Mark all the scroll bars to be removed; we'll redeem
7273 the ones we want when we redisplay their windows. */
9769686d
RS
7274 if (condemn_scroll_bars_hook)
7275 (*condemn_scroll_bars_hook) (f);
30c566e4 7276
f21ef775 7277 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
5f5c8ee5 7278 redisplay_windows (FRAME_ROOT_WINDOW (f));
30c566e4 7279
5f5c8ee5
GM
7280 /* Any scroll bars which redisplay_windows should have
7281 nuked should now go away. */
9769686d
RS
7282 if (judge_scroll_bars_hook)
7283 (*judge_scroll_bars_hook) (f);
7284 }
30c566e4 7285 }
a2889657 7286 }
5f5c8ee5
GM
7287 else if (FRAME_VISIBLE_P (selected_frame)
7288 && !FRAME_OBSCURED_P (selected_frame))
7289 redisplay_window (selected_window, 1);
7290
7291
7292 /* Compare desired and current matrices, perform output. */
7293
7294update:
7295
7296 /* If fonts changed, display again. */
7297 if (fonts_changed_p)
7298 goto retry;
a2889657 7299
a2889657
JB
7300 /* Prevent various kinds of signals during display update.
7301 stdio is not robust about handling signals,
7302 which can cause an apparent I/O error. */
7303 if (interrupt_input)
7304 unrequest_sigio ();
7305 stop_polling ();
7306
5f5c8ee5 7307 if (consider_all_windows_p)
a2889657
JB
7308 {
7309 Lisp_Object tail;
7310
7311 pause = 0;
7312
44fa5b1e 7313 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
a2889657 7314 {
5f5c8ee5 7315 struct frame *f;
a2889657 7316
e24c997d 7317 if (!FRAMEP (XCONS (tail)->car))
a2889657
JB
7318 continue;
7319
44fa5b1e 7320 f = XFRAME (XCONS (tail)->car);
1af9f229 7321
fd8ff63d 7322 if ((FRAME_WINDOW_P (f) || f == selected_frame)
f21ef775 7323 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
a2889657 7324 {
5f5c8ee5
GM
7325 /* Mark all windows as to be updated. */
7326 set_window_update_flags (XWINDOW (f->root_window), 1);
44fa5b1e 7327 pause |= update_frame (f, 0, 0);
a2889657 7328 if (!pause)
efc63ef0 7329 {
5f5c8ee5
GM
7330 if (hscroll_windows (f->root_window))
7331 goto retry;
7332
efc63ef0
RS
7333 mark_window_display_accurate (f->root_window, 1);
7334 if (frame_up_to_date_hook != 0)
7335 (*frame_up_to_date_hook) (f);
7336 }
a2889657
JB
7337 }
7338 }
7339 }
7340 else
6e8290aa 7341 {
5f5c8ee5
GM
7342 if (FRAME_VISIBLE_P (selected_frame)
7343 && !FRAME_OBSCURED_P (selected_frame))
7344 {
7345 XWINDOW (selected_window)->must_be_updated_p = 1;
7346 pause = update_frame (selected_frame, 0, 0);
7347 if (!pause && hscroll_windows (selected_window))
7348 goto retry;
7349 }
4d641a15
KH
7350 else
7351 pause = 0;
d724d989 7352
8de2d90b 7353 /* We may have called echo_area_display at the top of this
44fa5b1e
JB
7354 function. If the echo area is on another frame, that may
7355 have put text on a frame other than the selected one, so the
7356 above call to update_frame would not have caught it. Catch
8de2d90b
JB
7357 it here. */
7358 {
84faf44c 7359 Lisp_Object mini_window;
5f5c8ee5 7360 struct frame *mini_frame;
84faf44c
RS
7361
7362 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
7363 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8de2d90b 7364
fd8ff63d 7365 if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
5f5c8ee5
GM
7366 {
7367 XWINDOW (mini_window)->must_be_updated_p = 1;
7368 pause |= update_frame (mini_frame, 0, 0);
7369 if (!pause && hscroll_windows (mini_window))
7370 goto retry;
7371 }
8de2d90b 7372 }
6e8290aa 7373 }
a2889657 7374
5f5c8ee5
GM
7375 /* If display was paused because of pending input, make sure we do a
7376 thorough update the next time. */
a2889657
JB
7377 if (pause)
7378 {
5f5c8ee5
GM
7379 /* Prevent the optimization at the beginning of
7380 redisplay_internal that tries a single-line update of the
7381 line containing the cursor in the selected window. */
7382 CHARPOS (this_line_start_pos) = 0;
7383
7384 /* Let the overlay arrow be updated the next time. */
265a9e55 7385 if (!NILP (last_arrow_position))
a2889657
JB
7386 {
7387 last_arrow_position = Qt;
7388 last_arrow_string = Qt;
7389 }
5f5c8ee5
GM
7390
7391 /* If we pause after scrolling, some rows in the current
7392 matrices of some windows are not valid. */
7393 if (!WINDOW_FULL_WIDTH_P (w)
7394 && !FRAME_WINDOW_P (XFRAME (w->frame)))
a2889657
JB
7395 update_mode_lines = 1;
7396 }
7397
5f5c8ee5
GM
7398 /* Now text on frame agrees with windows, so put info into the
7399 windows for partial redisplay to follow. */
a2889657
JB
7400 if (!pause)
7401 {
7402 register struct buffer *b = XBUFFER (w->buffer);
7403
a2889657 7404 unchanged_modified = BUF_MODIFF (b);
8850a573 7405 overlay_unchanged_modified = BUF_OVERLAY_MODIFF (b);
a2889657
JB
7406 beg_unchanged = BUF_GPT (b) - BUF_BEG (b);
7407 end_unchanged = BUF_Z (b) - BUF_GPT (b);
7408
5f5c8ee5 7409 if (consider_all_windows_p)
11e82b76 7410 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
a2889657
JB
7411 else
7412 {
5f5c8ee5
GM
7413 XSETFASTINT (w->last_point, BUF_PT (b));
7414 w->last_cursor = w->cursor;
7415 w->last_cursor_off_p = w->cursor_off_p;
7416
28995e67 7417 b->clip_changed = 0;
a2889657 7418 w->update_mode_line = Qnil;
c2213350 7419 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
8850a573 7420 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
538f13d4
RS
7421 w->last_had_star
7422 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7423 ? Qt : Qnil);
3ee4159a
RS
7424
7425 /* Record if we are showing a region, so can make sure to
7426 update it fully at next redisplay. */
7427 w->region_showing = (!NILP (Vtransient_mark_mode)
293a54ce
RS
7428 && (w == XWINDOW (current_buffer->last_selected_window)
7429 || highlight_nonselected_windows)
3ee4159a
RS
7430 && !NILP (XBUFFER (w->buffer)->mark_active)
7431 ? Fmarker_position (XBUFFER (w->buffer)->mark)
7432 : Qnil);
7433
d2f84654 7434 w->window_end_valid = w->buffer;
d45de95b 7435 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657 7436 last_arrow_string = Voverlay_arrow_string;
efc63ef0
RS
7437 if (frame_up_to_date_hook != 0)
7438 (*frame_up_to_date_hook) (selected_frame);
a2889657 7439 }
5f5c8ee5 7440
a2889657
JB
7441 update_mode_lines = 0;
7442 windows_or_buffers_changed = 0;
7443 }
7444
5f5c8ee5
GM
7445 /* Start SIGIO interrupts coming again. Having them off during the
7446 code above makes it less likely one will discard output, but not
7447 impossible, since there might be stuff in the system buffer here.
a2889657 7448 But it is much hairier to try to do anything about that. */
a2889657
JB
7449 if (interrupt_input)
7450 request_sigio ();
7451 start_polling ();
7452
5f5c8ee5
GM
7453 /* If a frame has become visible which was not before, redisplay
7454 again, so that we display it. Expose events for such a frame
7455 (which it gets when becoming visible) don't call the parts of
7456 redisplay constructing glyphs, so simply exposing a frame won't
7457 display anything in this case. So, we have to display these
7458 frames here explicitly. */
11c52c4f
RS
7459 if (!pause)
7460 {
7461 Lisp_Object tail, frame;
7462 int new_count = 0;
7463
7464 FOR_EACH_FRAME (tail, frame)
7465 {
7466 int this_is_visible = 0;
8e83f802
RS
7467
7468 if (XFRAME (frame)->visible)
7469 this_is_visible = 1;
7470 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
7471 if (XFRAME (frame)->visible)
7472 this_is_visible = 1;
11c52c4f
RS
7473
7474 if (this_is_visible)
7475 new_count++;
7476 }
7477
89819bdd 7478 if (new_count != number_of_visible_frames)
11c52c4f
RS
7479 windows_or_buffers_changed++;
7480 }
7481
44fa5b1e 7482 /* Change frame size now if a change is pending. */
c6e89d6c 7483 do_pending_window_change (1);
d8e242fd 7484
8b32d885
RS
7485 /* If we just did a pending size change, or have additional
7486 visible frames, redisplay again. */
3c8c72e0 7487 if (windows_or_buffers_changed && !pause)
8b32d885 7488 goto retry;
5f5c8ee5
GM
7489
7490 end_of_redisplay:;
c6e89d6c 7491
28514cd9 7492 unbind_to (count, Qnil);
a2889657
JB
7493}
7494
5f5c8ee5
GM
7495
7496/* Redisplay, but leave alone any recent echo area message unless
7497 another message has been requested in its place.
a2889657
JB
7498
7499 This is useful in situations where you need to redisplay but no
7500 user action has occurred, making it inappropriate for the message
7501 area to be cleared. See tracking_off and
7502 wait_reading_process_input for examples of these situations. */
7503
8991bb31 7504void
a2889657
JB
7505redisplay_preserve_echo_area ()
7506{
c6e89d6c 7507 if (!NILP (echo_area_buffer[1]))
a2889657 7508 {
c6e89d6c
GM
7509 /* We have a previously displayed message, but no current
7510 message. Redisplay the previous message. */
7511 display_last_displayed_message_p = 1;
e9874cee 7512 redisplay_internal (1);
c6e89d6c 7513 display_last_displayed_message_p = 0;
a2889657
JB
7514 }
7515 else
e9874cee 7516 redisplay_internal (1);
a2889657
JB
7517}
7518
5f5c8ee5 7519
28514cd9
GM
7520/* Function registered with record_unwind_protect in
7521 redisplay_internal. Clears the flag indicating that a redisplay is
7522 in progress. */
7523
7524static Lisp_Object
7525unwind_redisplay (old_redisplaying_p)
7526 Lisp_Object old_redisplaying_p;
7527{
7528 redisplaying_p = XFASTINT (old_redisplaying_p);
c6e89d6c 7529 return Qnil;
28514cd9
GM
7530}
7531
7532
5f5c8ee5
GM
7533/* Mark the display of windows in the window tree rooted at WINDOW as
7534 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7535 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7536 the next time redisplay_internal is called. */
7537
a2889657 7538void
5f5c8ee5 7539mark_window_display_accurate (window, accurate_p)
a2889657 7540 Lisp_Object window;
5f5c8ee5 7541 int accurate_p;
a2889657 7542{
5f5c8ee5
GM
7543 struct window *w;
7544
7545 for (; !NILP (window); window = w->next)
a2889657
JB
7546 {
7547 w = XWINDOW (window);
7548
5f5c8ee5 7549 if (BUFFERP (w->buffer))
bd66d1ba 7550 {
5f5c8ee5
GM
7551 struct buffer *b = XBUFFER (w->buffer);
7552
c2213350 7553 XSETFASTINT (w->last_modified,
5f5c8ee5 7554 accurate_p ? BUF_MODIFF (b) : 0);
8850a573 7555 XSETFASTINT (w->last_overlay_modified,
5f5c8ee5
GM
7556 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7557 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7558 ? Qt : Qnil);
bd66d1ba 7559
5f5c8ee5
GM
7560#if 0 /* I don't think this is necessary because display_line does it.
7561 Let's check it. */
bd66d1ba
RS
7562 /* Record if we are showing a region, so can make sure to
7563 update it fully at next redisplay. */
5f5c8ee5
GM
7564 w->region_showing
7565 = (!NILP (Vtransient_mark_mode)
7566 && (w == XWINDOW (current_buffer->last_selected_window)
7567 || highlight_nonselected_windows)
7568 && (!NILP (b->mark_active)
7569 ? Fmarker_position (b->mark)
7570 : Qnil));
7571#endif
7572
7573 if (accurate_p)
7574 {
7575 b->clip_changed = 0;
7576 w->last_cursor = w->cursor;
7577 w->last_cursor_off_p = w->cursor_off_p;
7578 if (w == XWINDOW (selected_window))
7579 w->last_point = BUF_PT (b);
7580 else
7581 w->last_point = XMARKER (w->pointm)->charpos;
7582 }
bd66d1ba
RS
7583 }
7584
d2f84654 7585 w->window_end_valid = w->buffer;
a2889657
JB
7586 w->update_mode_line = Qnil;
7587
265a9e55 7588 if (!NILP (w->vchild))
5f5c8ee5 7589 mark_window_display_accurate (w->vchild, accurate_p);
265a9e55 7590 if (!NILP (w->hchild))
5f5c8ee5 7591 mark_window_display_accurate (w->hchild, accurate_p);
a2889657
JB
7592 }
7593
5f5c8ee5 7594 if (accurate_p)
a2889657 7595 {
d45de95b 7596 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657
JB
7597 last_arrow_string = Voverlay_arrow_string;
7598 }
7599 else
7600 {
5f5c8ee5
GM
7601 /* Force a thorough redisplay the next time by setting
7602 last_arrow_position and last_arrow_string to t, which is
7603 unequal to any useful value of Voverlay_arrow_... */
a2889657
JB
7604 last_arrow_position = Qt;
7605 last_arrow_string = Qt;
7606 }
7607}
5f5c8ee5
GM
7608
7609
7610/* Return value in display table DP (Lisp_Char_Table *) for character
7611 C. Since a display table doesn't have any parent, we don't have to
7612 follow parent. Do not call this function directly but use the
7613 macro DISP_CHAR_VECTOR. */
7614
7615Lisp_Object
7616disp_char_vector (dp, c)
7617 struct Lisp_Char_Table *dp;
7618 int c;
7619{
7620 int code[4], i;
7621 Lisp_Object val;
7622
7623 if (SINGLE_BYTE_CHAR_P (c))
7624 return (dp->contents[c]);
7625
7626 SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
7627 if (code[0] != CHARSET_COMPOSITION)
7628 {
7629 if (code[1] < 32)
7630 code[1] = -1;
7631 else if (code[2] < 32)
7632 code[2] = -1;
7633 }
7634
7635 /* Here, the possible range of code[0] (== charset ID) is
7636 128..max_charset. Since the top level char table contains data
7637 for multibyte characters after 256th element, we must increment
7638 code[0] by 128 to get a correct index. */
7639 code[0] += 128;
7640 code[3] = -1; /* anchor */
7641
7642 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
7643 {
7644 val = dp->contents[code[i]];
7645 if (!SUB_CHAR_TABLE_P (val))
7646 return (NILP (val) ? dp->defalt : val);
7647 }
7648
7649 /* Here, val is a sub char table. We return the default value of
7650 it. */
7651 return (dp->defalt);
7652}
7653
7654
a2889657 7655\f
5f5c8ee5
GM
7656/***********************************************************************
7657 Window Redisplay
7658 ***********************************************************************/
a2725ab2 7659
5f5c8ee5 7660/* Redisplay all leaf windows in the window tree rooted at WINDOW. */
90adcf20
RS
7661
7662static void
5f5c8ee5
GM
7663redisplay_windows (window)
7664 Lisp_Object window;
90adcf20 7665{
5f5c8ee5
GM
7666 while (!NILP (window))
7667 {
7668 struct window *w = XWINDOW (window);
7669
7670 if (!NILP (w->hchild))
7671 redisplay_windows (w->hchild);
7672 else if (!NILP (w->vchild))
7673 redisplay_windows (w->vchild);
7674 else
7675 redisplay_window (window, 0);
a2725ab2 7676
5f5c8ee5
GM
7677 window = w->next;
7678 }
7679}
7680
7681
7682/* Set cursor position of W. PT is assumed to be displayed in ROW.
7683 DELTA is the number of bytes by which positions recorded in ROW
7684 differ from current buffer positions. */
7685
7686void
7687set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
7688 struct window *w;
7689 struct glyph_row *row;
7690 struct glyph_matrix *matrix;
7691 int delta, delta_bytes, dy, dvpos;
7692{
7693 struct glyph *glyph = row->glyphs[TEXT_AREA];
7694 struct glyph *end = glyph + row->used[TEXT_AREA];
7695 int x = row->x;
7696 int pt_old = PT - delta;
7697
7698 /* Skip over glyphs not having an object at the start of the row.
7699 These are special glyphs like truncation marks on terminal
7700 frames. */
7701 if (row->displays_text_p)
7702 while (glyph < end
7703 && !glyph->object
7704 && glyph->charpos < 0)
7705 {
7706 x += glyph->pixel_width;
7707 ++glyph;
7708 }
7709
7710 while (glyph < end
7711 && glyph->object
7712 && (!BUFFERP (glyph->object)
7713 || glyph->charpos < pt_old))
7714 {
7715 x += glyph->pixel_width;
7716 ++glyph;
7717 }
7718
7719 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
7720 w->cursor.x = x;
7721 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
7722 w->cursor.y = row->y + dy;
7723
7724 if (w == XWINDOW (selected_window))
7725 {
7726 if (!row->continued_p
7727 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
7728 && row->x == 0)
7729 {
7730 this_line_buffer = XBUFFER (w->buffer);
7731
7732 CHARPOS (this_line_start_pos)
7733 = MATRIX_ROW_START_CHARPOS (row) + delta;
7734 BYTEPOS (this_line_start_pos)
7735 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
7736
7737 CHARPOS (this_line_end_pos)
7738 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
7739 BYTEPOS (this_line_end_pos)
7740 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
7741
7742 this_line_y = w->cursor.y;
7743 this_line_pixel_height = row->height;
7744 this_line_vpos = w->cursor.vpos;
7745 this_line_start_x = row->x;
7746 }
7747 else
7748 CHARPOS (this_line_start_pos) = 0;
7749 }
7750}
7751
7752
7753/* Run window scroll functions, if any, for WINDOW with new window
7754 start STARTP. Sets the window start of WINDOW to that position. */
7755
7756static INLINE struct text_pos
7757run_window_scroll_functions (window, startp)
7758 Lisp_Object window;
7759 struct text_pos startp;
7760{
7761 struct window *w = XWINDOW (window);
7762 SET_MARKER_FROM_TEXT_POS (w->start, startp);
90adcf20 7763
5f5c8ee5
GM
7764 if (!NILP (Vwindow_scroll_functions))
7765 {
7766 run_hook_with_args_2 (Qwindow_scroll_functions, window,
7767 make_number (CHARPOS (startp)));
7768 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7769 }
90adcf20 7770
5f5c8ee5
GM
7771 return startp;
7772}
7773
7774
7775/* Modify the desired matrix of window W and W->vscroll so that the
7776 line containing the cursor is fully visible. */
7777
7778static void
7779make_cursor_line_fully_visible (w)
7780 struct window *w;
7781{
7782 struct glyph_matrix *matrix;
7783 struct glyph_row *row;
7784 int top_line_height;
7785
7786 /* It's not always possible to find the cursor, e.g, when a window
7787 is full of overlay strings. Don't do anything in that case. */
7788 if (w->cursor.vpos < 0)
7789 return;
7790
7791 matrix = w->desired_matrix;
7792 row = MATRIX_ROW (matrix, w->cursor.vpos);
7793
7794 /* If row->y == top y of window display area, the window isn't tall
7795 enough to display a single line. There is nothing we can do
7796 about it. */
7797 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
7798 if (row->y == top_line_height)
7799 return;
7800
7801 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
7802 {
7803 int dy = row->height - row->visible_height;
7804 w->vscroll = 0;
7805 w->cursor.y += dy;
7806 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7807 }
7808 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
7809 {
7810 int dy = - (row->height - row->visible_height);
7811 w->vscroll = dy;
7812 w->cursor.y += dy;
7813 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7814 }
7815
7816 /* When we change the cursor y-position of the selected window,
7817 change this_line_y as well so that the display optimization for
7818 the cursor line of the selected window in redisplay_internal uses
7819 the correct y-position. */
7820 if (w == XWINDOW (selected_window))
7821 this_line_y = w->cursor.y;
7822}
7823
7824
7825/* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
7826 non-zero means only WINDOW is redisplayed in redisplay_internal.
7827 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
7828 in redisplay_window to bring a partially visible line into view in
7829 the case that only the cursor has moved.
7830
7831 Value is
7832
7833 1 if scrolling succeeded
7834
7835 0 if scrolling didn't find point.
7836
7837 -1 if new fonts have been loaded so that we must interrupt
7838 redisplay, adjust glyph matrices, and try again. */
7839
7840static int
7841try_scrolling (window, just_this_one_p, scroll_conservatively,
7842 scroll_step, temp_scroll_step)
7843 Lisp_Object window;
7844 int just_this_one_p;
7845 int scroll_conservatively, scroll_step;
7846 int temp_scroll_step;
7847{
7848 struct window *w = XWINDOW (window);
7849 struct frame *f = XFRAME (w->frame);
7850 struct text_pos scroll_margin_pos;
7851 struct text_pos pos;
7852 struct text_pos startp;
7853 struct it it;
7854 Lisp_Object window_end;
7855 int this_scroll_margin;
7856 int dy = 0;
7857 int scroll_max;
7858 int line_height, rc;
7859 int amount_to_scroll = 0;
7860 Lisp_Object aggressive;
7861 int height;
7862
7863#if GLYPH_DEBUG
7864 debug_method_add (w, "try_scrolling");
78614721 7865#endif
5f5c8ee5
GM
7866
7867 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7868
7869 /* Compute scroll margin height in pixels. We scroll when point is
7870 within this distance from the top or bottom of the window. */
7871 if (scroll_margin > 0)
90adcf20 7872 {
5f5c8ee5
GM
7873 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
7874 this_scroll_margin *= CANON_Y_UNIT (f);
7875 }
7876 else
7877 this_scroll_margin = 0;
7878
7879 /* Compute how much we should try to scroll maximally to bring point
7880 into view. */
7881 if (scroll_step)
7882 scroll_max = scroll_step;
7883 else if (scroll_conservatively)
7884 scroll_max = scroll_conservatively;
7885 else if (temp_scroll_step)
7886 scroll_max = temp_scroll_step;
7887 else if (NUMBERP (current_buffer->scroll_down_aggressively)
7888 || NUMBERP (current_buffer->scroll_up_aggressively))
7889 /* We're trying to scroll because of aggressive scrolling
7890 but no scroll_step is set. Choose an arbitrary one. Maybe
7891 there should be a variable for this. */
7892 scroll_max = 10;
7893 else
7894 scroll_max = 0;
7895 scroll_max *= CANON_Y_UNIT (f);
7896
7897 /* Decide whether we have to scroll down. Start at the window end
7898 and move this_scroll_margin up to find the position of the scroll
7899 margin. */
7900 window_end = Fwindow_end (window, Qt);
7901 CHARPOS (scroll_margin_pos) = XINT (window_end);
7902 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
7903 if (this_scroll_margin)
7904 {
7905 start_display (&it, w, scroll_margin_pos);
7906 move_it_vertically (&it, - this_scroll_margin);
7907 scroll_margin_pos = it.current.pos;
7908 }
7909
7910 if (PT >= CHARPOS (scroll_margin_pos))
7911 {
7912 int y0;
7913
7914 /* Point is in the scroll margin at the bottom of the window, or
7915 below. Compute a new window start that makes point visible. */
7916
7917 /* Compute the distance from the scroll margin to PT.
7918 Give up if the distance is greater than scroll_max. */
7919 start_display (&it, w, scroll_margin_pos);
7920 y0 = it.current_y;
7921 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7922 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7923 line_height = (it.max_ascent + it.max_descent
7924 ? it.max_ascent + it.max_descent
7925 : last_height);
7926 dy = it.current_y + line_height - y0;
7927 if (dy > scroll_max)
7928 return 0;
7929
7930 /* Move the window start down. If scrolling conservatively,
7931 move it just enough down to make point visible. If
7932 scroll_step is set, move it down by scroll_step. */
7933 start_display (&it, w, startp);
7934
7935 if (scroll_conservatively)
7936 amount_to_scroll = dy;
7937 else if (scroll_step || temp_scroll_step)
7938 amount_to_scroll = scroll_max;
7939 else
90adcf20 7940 {
5f5c8ee5
GM
7941 aggressive = current_buffer->scroll_down_aggressively;
7942 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7943 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7944 if (NUMBERP (aggressive))
7945 amount_to_scroll = XFLOATINT (aggressive) * height;
7946 }
a2725ab2 7947
5f5c8ee5
GM
7948 if (amount_to_scroll <= 0)
7949 return 0;
a2725ab2 7950
5f5c8ee5
GM
7951 move_it_vertically (&it, amount_to_scroll);
7952 startp = it.current.pos;
7953 }
7954 else
7955 {
7956 /* See if point is inside the scroll margin at the top of the
7957 window. */
7958 scroll_margin_pos = startp;
7959 if (this_scroll_margin)
7960 {
7961 start_display (&it, w, startp);
7962 move_it_vertically (&it, this_scroll_margin);
7963 scroll_margin_pos = it.current.pos;
7964 }
7965
7966 if (PT < CHARPOS (scroll_margin_pos))
7967 {
7968 /* Point is in the scroll margin at the top of the window or
7969 above what is displayed in the window. */
7970 int y0;
7971
7972 /* Compute the vertical distance from PT to the scroll
7973 margin position. Give up if distance is greater than
7974 scroll_max. */
7975 SET_TEXT_POS (pos, PT, PT_BYTE);
7976 start_display (&it, w, pos);
7977 y0 = it.current_y;
7978 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
7979 it.last_visible_y, -1,
7980 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7981 dy = it.current_y - y0;
7982 if (dy > scroll_max)
7983 return 0;
7984
7985 /* Compute new window start. */
7986 start_display (&it, w, startp);
7987
7988 if (scroll_conservatively)
7989 amount_to_scroll = dy;
7990 else if (scroll_step || temp_scroll_step)
7991 amount_to_scroll = scroll_max;
538f13d4 7992 else
5f5c8ee5
GM
7993 {
7994 aggressive = current_buffer->scroll_up_aggressively;
7995 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7996 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7997 if (NUMBERP (aggressive))
7998 amount_to_scroll = XFLOATINT (aggressive) * height;
7999 }
a2725ab2 8000
5f5c8ee5
GM
8001 if (amount_to_scroll <= 0)
8002 return 0;
8003
8004 move_it_vertically (&it, - amount_to_scroll);
8005 startp = it.current.pos;
90adcf20
RS
8006 }
8007 }
a2889657 8008
5f5c8ee5
GM
8009 /* Run window scroll functions. */
8010 startp = run_window_scroll_functions (window, startp);
90adcf20 8011
5f5c8ee5
GM
8012 /* Display the window. Give up if new fonts are loaded, or if point
8013 doesn't appear. */
8014 if (!try_window (window, startp))
8015 rc = -1;
8016 else if (w->cursor.vpos < 0)
8017 {
8018 clear_glyph_matrix (w->desired_matrix);
8019 rc = 0;
8020 }
8021 else
8022 {
8023 /* Maybe forget recorded base line for line number display. */
8024 if (!just_this_one_p
8025 || current_buffer->clip_changed
8026 || beg_unchanged < CHARPOS (startp))
8027 w->base_line_number = Qnil;
8028
8029 /* If cursor ends up on a partially visible line, shift display
8030 lines up or down. */
8031 make_cursor_line_fully_visible (w);
8032 rc = 1;
8033 }
8034
8035 return rc;
a2889657
JB
8036}
8037
5f5c8ee5
GM
8038
8039/* Compute a suitable window start for window W if display of W starts
8040 on a continuation line. Value is non-zero if a new window start
8041 was computed.
8042
8043 The new window start will be computed, based on W's width, starting
8044 from the start of the continued line. It is the start of the
8045 screen line with the minimum distance from the old start W->start. */
8046
8047static int
8048compute_window_start_on_continuation_line (w)
8049 struct window *w;
1f1ff51d 8050{
5f5c8ee5
GM
8051 struct text_pos pos, start_pos;
8052 int window_start_changed_p = 0;
1f1ff51d 8053
5f5c8ee5 8054 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
1f1ff51d 8055
5f5c8ee5
GM
8056 /* If window start is on a continuation line... Window start may be
8057 < BEGV in case there's invisible text at the start of the
8058 buffer (M-x rmail, for example). */
8059 if (CHARPOS (start_pos) > BEGV
8060 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
1f1ff51d 8061 {
5f5c8ee5
GM
8062 struct it it;
8063 struct glyph_row *row;
8064
8065 /* Find the start of the continued line. This should be fast
8066 because scan_buffer is fast (newline cache). */
8067 row = w->desired_matrix->rows + (WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0);
8068 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
8069 row, DEFAULT_FACE_ID);
8070 reseat_at_previous_visible_line_start (&it);
8071
8072 /* If the line start is "too far" away from the window start,
8073 say it takes too much time to compute a new window start. */
8074 if (CHARPOS (start_pos) - IT_CHARPOS (it)
8075 < XFASTINT (w->height) * XFASTINT (w->width))
8076 {
8077 int min_distance, distance;
8078
8079 /* Move forward by display lines to find the new window
8080 start. If window width was enlarged, the new start can
8081 be expected to be > the old start. If window width was
8082 decreased, the new window start will be < the old start.
8083 So, we're looking for the display line start with the
8084 minimum distance from the old window start. */
8085 pos = it.current.pos;
8086 min_distance = INFINITY;
8087 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
8088 distance < min_distance)
8089 {
8090 min_distance = distance;
8091 pos = it.current.pos;
8092 move_it_by_lines (&it, 1, 0);
8093 }
8094
8095 /* Set the window start there. */
8096 SET_MARKER_FROM_TEXT_POS (w->start, pos);
8097 window_start_changed_p = 1;
8098 }
1f1ff51d 8099 }
5f5c8ee5
GM
8100
8101 return window_start_changed_p;
1f1ff51d
KH
8102}
8103
5f5c8ee5
GM
8104
8105/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
8106 selected_window is redisplayed. */
90adcf20 8107
a2889657 8108static void
5f5c8ee5 8109redisplay_window (window, just_this_one_p)
a2889657 8110 Lisp_Object window;
5f5c8ee5 8111 int just_this_one_p;
a2889657 8112{
5f5c8ee5
GM
8113 struct window *w = XWINDOW (window);
8114 struct frame *f = XFRAME (w->frame);
8115 struct buffer *buffer = XBUFFER (w->buffer);
a2889657 8116 struct buffer *old = current_buffer;
5f5c8ee5 8117 struct text_pos lpoint, opoint, startp;
e481f960 8118 int update_mode_line;
5f5c8ee5
GM
8119 int tem;
8120 struct it it;
8121 /* Record it now because it's overwritten. */
8122 int current_matrix_up_to_date_p = 0;
5ba50c51 8123 int really_switched_buffer = 0;
5f5c8ee5 8124 int temp_scroll_step = 0;
2e54982e 8125 int count = specpdl_ptr - specpdl;
a2889657 8126
5f5c8ee5
GM
8127 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8128 opoint = lpoint;
a2889657 8129
5f5c8ee5
GM
8130 /* W must be a leaf window here. */
8131 xassert (!NILP (w->buffer));
8132#if GLYPH_DEBUG
8133 *w->desired_matrix->method = 0;
8134#endif
2e54982e
RS
8135
8136 specbind (Qinhibit_point_motion_hooks, Qt);
5f5c8ee5
GM
8137
8138 /* Has the mode line to be updated? */
8139 update_mode_line = (!NILP (w->update_mode_line)
8140 || update_mode_lines
8141 || buffer->clip_changed);
8de2d90b
JB
8142
8143 if (MINI_WINDOW_P (w))
8144 {
5f5c8ee5 8145 if (w == XWINDOW (echo_area_window)
c6e89d6c 8146 && !NILP (echo_area_buffer[0]))
5f5c8ee5
GM
8147 {
8148 if (update_mode_line)
8149 /* We may have to update a tty frame's menu bar or a
8150 toolbar. Example `M-x C-h C-h C-g'. */
8151 goto finish_menu_bars;
8152 else
8153 /* We've already displayed the echo area glyphs in this window. */
8154 goto finish_scroll_bars;
8155 }
73af359d 8156 else if (w != XWINDOW (minibuf_window))
8de2d90b 8157 {
5f5c8ee5
GM
8158 /* W is a mini-buffer window, but it's not the currently
8159 active one, so clear it. */
8160 int yb = window_text_bottom_y (w);
8161 struct glyph_row *row;
8162 int y;
8163
8164 for (y = 0, row = w->desired_matrix->rows;
8165 y < yb;
8166 y += row->height, ++row)
8167 blank_row (w, row, y);
88f22aff 8168 goto finish_scroll_bars;
8de2d90b
JB
8169 }
8170 }
a2889657 8171
5f5c8ee5
GM
8172 /* Otherwise set up data on this window; select its buffer and point
8173 value. */
e481f960 8174 if (update_mode_line)
5ba50c51 8175 {
5f5c8ee5
GM
8176 /* Really select the buffer, for the sake of buffer-local
8177 variables. */
5ba50c51
RS
8178 set_buffer_internal_1 (XBUFFER (w->buffer));
8179 really_switched_buffer = 1;
8180 }
e481f960
RS
8181 else
8182 set_buffer_temp (XBUFFER (w->buffer));
5f5c8ee5
GM
8183 SET_TEXT_POS (opoint, PT, PT_BYTE);
8184
8185 current_matrix_up_to_date_p
8186 = (!NILP (w->window_end_valid)
8187 && !current_buffer->clip_changed
8188 && XFASTINT (w->last_modified) >= MODIFF
8189 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
e481f960 8190
5f5c8ee5
GM
8191 /* When windows_or_buffers_changed is non-zero, we can't rely on
8192 the window end being valid, so set it to nil there. */
8193 if (windows_or_buffers_changed)
8194 {
8195 /* If window starts on a continuation line, maybe adjust the
8196 window start in case the window's width changed. */
8197 if (XMARKER (w->start)->buffer == current_buffer)
8198 compute_window_start_on_continuation_line (w);
8199
8200 w->window_end_valid = Qnil;
8201 }
12adba34 8202
5f5c8ee5
GM
8203 /* Some sanity checks. */
8204 CHECK_WINDOW_END (w);
8205 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12adba34 8206 abort ();
5f5c8ee5 8207 if (BYTEPOS (opoint) < CHARPOS (opoint))
12adba34 8208 abort ();
a2889657 8209
28995e67
RS
8210 /* If %c is in mode line, update it if needed. */
8211 if (!NILP (w->column_number_displayed)
8212 /* This alternative quickly identifies a common case
8213 where no change is needed. */
8214 && !(PT == XFASTINT (w->last_point)
8850a573
RS
8215 && XFASTINT (w->last_modified) >= MODIFF
8216 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
8217 && XFASTINT (w->column_number_displayed) != current_column ())
8218 update_mode_line = 1;
8219
5f5c8ee5
GM
8220 /* Count number of windows showing the selected buffer. An indirect
8221 buffer counts as its base buffer. */
8222 if (!just_this_one_p)
42640f83
RS
8223 {
8224 struct buffer *current_base, *window_base;
8225 current_base = current_buffer;
8226 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
8227 if (current_base->base_buffer)
8228 current_base = current_base->base_buffer;
8229 if (window_base->base_buffer)
8230 window_base = window_base->base_buffer;
8231 if (current_base == window_base)
8232 buffer_shared++;
8233 }
a2889657 8234
5f5c8ee5
GM
8235 /* Point refers normally to the selected window. For any other
8236 window, set up appropriate value. */
a2889657
JB
8237 if (!EQ (window, selected_window))
8238 {
12adba34
RS
8239 int new_pt = XMARKER (w->pointm)->charpos;
8240 int new_pt_byte = marker_byte_position (w->pointm);
f67a0f51 8241 if (new_pt < BEGV)
a2889657 8242 {
f67a0f51 8243 new_pt = BEGV;
12adba34
RS
8244 new_pt_byte = BEGV_BYTE;
8245 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
a2889657 8246 }
f67a0f51 8247 else if (new_pt > (ZV - 1))
a2889657 8248 {
f67a0f51 8249 new_pt = ZV;
12adba34
RS
8250 new_pt_byte = ZV_BYTE;
8251 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
a2889657 8252 }
5f5c8ee5 8253
f67a0f51 8254 /* We don't use SET_PT so that the point-motion hooks don't run. */
12adba34 8255 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
a2889657
JB
8256 }
8257
f4faa47c 8258 /* If any of the character widths specified in the display table
5f5c8ee5
GM
8259 have changed, invalidate the width run cache. It's true that
8260 this may be a bit late to catch such changes, but the rest of
f4faa47c
JB
8261 redisplay goes (non-fatally) haywire when the display table is
8262 changed, so why should we worry about doing any better? */
8263 if (current_buffer->width_run_cache)
8264 {
f908610f 8265 struct Lisp_Char_Table *disptab = buffer_display_table ();
f4faa47c
JB
8266
8267 if (! disptab_matches_widthtab (disptab,
8268 XVECTOR (current_buffer->width_table)))
8269 {
8270 invalidate_region_cache (current_buffer,
8271 current_buffer->width_run_cache,
8272 BEG, Z);
8273 recompute_width_table (current_buffer, disptab);
8274 }
8275 }
8276
a2889657 8277 /* If window-start is screwed up, choose a new one. */
a2889657
JB
8278 if (XMARKER (w->start)->buffer != current_buffer)
8279 goto recenter;
8280
5f5c8ee5 8281 SET_TEXT_POS_FROM_MARKER (startp, w->start);
a2889657 8282
cf0df6ab
RS
8283 /* If someone specified a new starting point but did not insist,
8284 check whether it can be used. */
5f5c8ee5 8285 if (!NILP (w->optional_new_start))
cf0df6ab
RS
8286 {
8287 w->optional_new_start = Qnil;
5f5c8ee5
GM
8288 /* This takes a mini-buffer prompt into account. */
8289 start_display (&it, w, startp);
8290 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8291 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8292 if (IT_CHARPOS (it) == PT)
cf0df6ab
RS
8293 w->force_start = Qt;
8294 }
8295
8de2d90b 8296 /* Handle case where place to start displaying has been specified,
aa6d10fa 8297 unless the specified location is outside the accessible range. */
265a9e55 8298 if (!NILP (w->force_start))
a2889657 8299 {
e63574d7 8300 w->force_start = Qnil;
5f5c8ee5 8301 w->vscroll = 0;
b5174a51 8302 w->window_end_valid = Qnil;
5f5c8ee5
GM
8303
8304 /* Forget any recorded base line for line number display. */
8305 if (!current_matrix_up_to_date_p
8306 || current_buffer->clip_changed)
8307 w->base_line_number = Qnil;
8308
75c43375
RS
8309 /* Redisplay the mode line. Select the buffer properly for that.
8310 Also, run the hook window-scroll-functions
8311 because we have scrolled. */
e63574d7
RS
8312 /* Note, we do this after clearing force_start because
8313 if there's an error, it is better to forget about force_start
8314 than to get into an infinite loop calling the hook functions
8315 and having them get more errors. */
75c43375
RS
8316 if (!update_mode_line
8317 || ! NILP (Vwindow_scroll_functions))
e481f960 8318 {
5ba50c51
RS
8319 if (!really_switched_buffer)
8320 {
8321 set_buffer_temp (old);
8322 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 8323 really_switched_buffer = 1;
5ba50c51 8324 }
5f5c8ee5 8325
e481f960
RS
8326 update_mode_line = 1;
8327 w->update_mode_line = Qt;
5f5c8ee5 8328 startp = run_window_scroll_functions (window, startp);
e481f960 8329 }
5f5c8ee5 8330
c2213350 8331 XSETFASTINT (w->last_modified, 0);
8850a573 8332 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5
GM
8333 if (CHARPOS (startp) < BEGV)
8334 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
8335 else if (CHARPOS (startp) > ZV)
8336 SET_TEXT_POS (startp, ZV, ZV_BYTE);
8337
8338 /* Redisplay, then check if cursor has been set during the
8339 redisplay. Give up if new fonts were loaded. */
8340 if (!try_window (window, startp))
8341 {
8342 w->force_start = Qt;
8343 clear_glyph_matrix (w->desired_matrix);
8344 goto restore_buffers;
8345 }
8346
8347 if (w->cursor.vpos < 0)
8348 {
8349 /* If point does not appear, or on a line that is not fully
8350 visible, move point so it does appear. The desired
8351 matrix has been built above, so we can use it. */
8352 int height = window_box_height (w) / 2;
8353 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
8354
8355 while (row->y < height)
8356 ++row;
8357
8358 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
8359 MATRIX_ROW_START_BYTEPOS (row));
8360
90adcf20 8361 if (w != XWINDOW (selected_window))
12adba34 8362 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5f5c8ee5
GM
8363 else if (current_buffer == old)
8364 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8365
8366 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
8367
8368 /* If we are highlighting the region, then we just changed
8369 the region, so redisplay to show it. */
df0b5ea1
RS
8370 if (!NILP (Vtransient_mark_mode)
8371 && !NILP (current_buffer->mark_active))
6f27fa9b 8372 {
5f5c8ee5
GM
8373 clear_glyph_matrix (w->desired_matrix);
8374 if (!try_window (window, startp))
8375 goto restore_buffers;
6f27fa9b 8376 }
a2889657 8377 }
5f5c8ee5
GM
8378
8379 make_cursor_line_fully_visible (w);
8380#if GLYPH_DEBUG
8381 debug_method_add (w, "forced window start");
8382#endif
a2889657
JB
8383 goto done;
8384 }
8385
5f5c8ee5
GM
8386 /* Handle case where text has not changed, only point, and it has
8387 not moved off the frame. */
8388 if (current_matrix_up_to_date_p
8389 /* Point may be in this window. */
8390 && PT >= CHARPOS (startp)
8391 /* If we don't check this, we are called to move the cursor in a
8392 horizontally split window with a current matrix that doesn't
8393 fit the display. */
8394 && !windows_or_buffers_changed
8395 /* Selective display hasn't changed. */
8396 && !current_buffer->clip_changed
b1aa6cb3
RS
8397 /* If force-mode-line-update was called, really redisplay;
8398 that's how redisplay is forced after e.g. changing
8399 buffer-invisibility-spec. */
632ab665 8400 && NILP (w->update_mode_line)
5f5c8ee5
GM
8401 /* Can't use this case if highlighting a region. When a
8402 region exists, cursor movement has to do more than just
8403 set the cursor. */
8404 && !(!NILP (Vtransient_mark_mode)
8405 && !NILP (current_buffer->mark_active))
bd66d1ba 8406 && NILP (w->region_showing)
8f897821 8407 && NILP (Vshow_trailing_whitespace)
5f5c8ee5
GM
8408 /* Right after splitting windows, last_point may be nil. */
8409 && INTEGERP (w->last_point)
8410 /* This code is not used for mini-buffer for the sake of the case
8411 of redisplaying to replace an echo area message; since in
8412 that case the mini-buffer contents per se are usually
8413 unchanged. This code is of no real use in the mini-buffer
8414 since the handling of this_line_start_pos, etc., in redisplay
8415 handles the same cases. */
d45de95b 8416 && !EQ (window, minibuf_window)
5f5c8ee5
GM
8417 /* When splitting windows or for new windows, it happens that
8418 redisplay is called with a nil window_end_vpos or one being
8419 larger than the window. This should really be fixed in
8420 window.c. I don't have this on my list, now, so we do
8421 approximately the same as the old redisplay code. --gerd. */
8422 && INTEGERP (w->window_end_vpos)
8423 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
8424 && (FRAME_WINDOW_P (f)
8425 || !MARKERP (Voverlay_arrow_position)
377dbd97 8426 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
a2889657 8427 {
5f5c8ee5
GM
8428 int this_scroll_margin;
8429 struct glyph_row *row;
8430 int scroll_p;
a2889657 8431
5f5c8ee5
GM
8432#if GLYPH_DEBUG
8433 debug_method_add (w, "cursor movement");
8434#endif
9afd2168 8435
5f5c8ee5
GM
8436 /* Scroll if point within this distance from the top or bottom
8437 of the window. This is a pixel value. */
8438 this_scroll_margin = max (0, scroll_margin);
8439 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
8440 this_scroll_margin *= CANON_Y_UNIT (f);
8441
8442 /* Start with the row the cursor was displayed during the last
8443 not paused redisplay. Give up if that row is not valid. */
8444 if (w->last_cursor.vpos >= w->current_matrix->nrows)
8445 goto try_to_scroll;
8446 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
8447 if (row->mode_line_p)
8448 ++row;
8449 if (!row->enabled_p)
8450 goto try_to_scroll;
8451
8452 scroll_p = 0;
8453 if (PT > XFASTINT (w->last_point))
8454 {
8455 /* Point has moved forward. */
8456 int last_y = window_text_bottom_y (w) - this_scroll_margin;
8457
8458 while ((MATRIX_ROW_END_CHARPOS (row) < PT
8459 /* The end position of a row equals the start
8460 position of the next row. If PT is there, we
8461 would rather display it in the next line, except
8462 when this line ends in ZV. */
8463 || (MATRIX_ROW_END_CHARPOS (row) == PT
8464 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
8465 || !row->ends_at_zv_p)))
8466 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
8467 {
8468 xassert (row->enabled_p);
8469 ++row;
8470 }
9afd2168 8471
5f5c8ee5
GM
8472 /* If within the scroll margin, scroll. Note that
8473 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
8474 next line would be drawn, and that this_scroll_margin can
8475 be zero. */
8476 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
8477 || PT > MATRIX_ROW_END_CHARPOS (row)
8478 /* Line is completely visible last line in window and PT
8479 is to be set in the next line. */
8480 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
8481 && PT == MATRIX_ROW_END_CHARPOS (row)
8482 && !row->ends_at_zv_p
8483 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
8484 scroll_p = 1;
8485 }
8486 else if (PT < XFASTINT (w->last_point))
a2889657 8487 {
5f5c8ee5
GM
8488 /* Cursor has to be moved backward. Note that PT >=
8489 CHARPOS (startp) because of the outer if-statement. */
8490 while (!row->mode_line_p
8491 && (MATRIX_ROW_START_CHARPOS (row) > PT
8492 || (MATRIX_ROW_START_CHARPOS (row) == PT
8493 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
8494 && (row->y > this_scroll_margin
8495 || CHARPOS (startp) == BEGV))
a2889657 8496 {
5f5c8ee5
GM
8497 xassert (row->enabled_p);
8498 --row;
a2889657 8499 }
abb4c08f 8500
5f5c8ee5
GM
8501 /* Consider the following case: Window starts at BEGV, there
8502 is invisible, intangible text at BEGV, so that display
8503 starts at some point START > BEGV. It can happen that
8504 we are called with PT somewhere between BEGV and START.
8505 Try to handle that case. */
8506 if (row < w->current_matrix->rows
8507 || row->mode_line_p)
8508 {
8509 row = w->current_matrix->rows;
8510 if (row->mode_line_p)
8511 ++row;
8512 }
8513
8514 /* Due to newlines in overlay strings, we may have to skip
8515 forward over overlay strings. */
8516 while (MATRIX_ROW_END_CHARPOS (row) == PT
8517 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8518 && !row->ends_at_zv_p)
8519 ++row;
8520
8521 /* If within the scroll margin, scroll. */
8522 if (row->y < this_scroll_margin
8523 && CHARPOS (startp) != BEGV)
8524 scroll_p = 1;
8525 }
8526
8527 /* if PT is not in the glyph row, give up. */
8528 if (PT < MATRIX_ROW_START_CHARPOS (row)
8529 || PT > MATRIX_ROW_END_CHARPOS (row))
8530 goto try_to_scroll;
8531
8532 /* If we end up in a partially visible line, let's make it fully
8533 visible. This can be done most easily by using the existing
8534 scrolling code. */
8535 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8536 {
8537 temp_scroll_step = 1;
8538 goto try_to_scroll;
a2889657 8539 }
5f5c8ee5
GM
8540 else if (scroll_p)
8541 goto try_to_scroll;
8542
8543 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8544 goto done;
a2889657 8545 }
5f5c8ee5 8546
a2889657
JB
8547 /* If current starting point was originally the beginning of a line
8548 but no longer is, find a new starting point. */
265a9e55 8549 else if (!NILP (w->start_at_line_beg)
5f5c8ee5
GM
8550 && !(CHARPOS (startp) <= BEGV
8551 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
a2889657 8552 {
5f5c8ee5
GM
8553#if GLYPH_DEBUG
8554 debug_method_add (w, "recenter 1");
8555#endif
a2889657
JB
8556 goto recenter;
8557 }
5f5c8ee5
GM
8558
8559 /* Try scrolling with try_window_id. */
8560 else if (!windows_or_buffers_changed
8561 /* Window must be either use window-based redisplay or
8562 be full width. */
8563 && (FRAME_WINDOW_P (f)
8564 || ((line_ins_del_ok && WINDOW_FULL_WIDTH_P (w))
8565 && just_this_one_p))
8566 && !MINI_WINDOW_P (w)
8567 /* Point is not known NOT to appear in window. */
8568 && PT >= CHARPOS (startp)
a2889657 8569 && XFASTINT (w->last_modified)
5f5c8ee5
GM
8570 /* Window is not hscrolled. */
8571 && XFASTINT (w->hscroll) == 0
8572 /* Selective display has not changed. */
8573 && !current_buffer->clip_changed
8574 /* Current matrix is up to date. */
8575 && !NILP (w->window_end_valid)
8576 /* Can't use this case if highlighting a region because
8577 a cursor movement will do more than just set the cursor. */
bd66d1ba
RS
8578 && !(!NILP (Vtransient_mark_mode)
8579 && !NILP (current_buffer->mark_active))
8580 && NILP (w->region_showing)
8f897821 8581 && NILP (Vshow_trailing_whitespace)
5f5c8ee5 8582 /* Overlay arrow position and string not changed. */
d45de95b 8583 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
a2889657 8584 && EQ (last_arrow_string, Voverlay_arrow_string)
5f5c8ee5
GM
8585 /* Value is > 0 if update has been done, it is -1 if we
8586 know that the same window start will not work. It is 0
8587 if unsuccessful for some other reason. */
8588 && (tem = try_window_id (w)) != 0)
a2889657 8589 {
5f5c8ee5
GM
8590#if GLYPH_DEBUG
8591 debug_method_add (w, "try_window_id");
8592#endif
8593
8594 if (fonts_changed_p)
8595 goto restore_buffers;
a2889657
JB
8596 if (tem > 0)
8597 goto done;
5f5c8ee5
GM
8598 /* Otherwise try_window_id has returned -1 which means that we
8599 don't want the alternative below this comment to execute. */
a2889657 8600 }
5f5c8ee5
GM
8601 else if (CHARPOS (startp) >= BEGV
8602 && CHARPOS (startp) <= ZV
8603 && PT >= CHARPOS (startp)
8604 && (CHARPOS (startp) < ZV
e9874cee 8605 /* Avoid starting at end of buffer. */
5f5c8ee5 8606 || CHARPOS (startp) == BEGV
8850a573
RS
8607 || (XFASTINT (w->last_modified) >= MODIFF
8608 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
a2889657 8609 {
5f5c8ee5
GM
8610#if GLYPH_DEBUG
8611 debug_method_add (w, "same window start");
8612#endif
8613
8614 /* Try to redisplay starting at same place as before.
8615 If point has not moved off frame, accept the results. */
8616 if (!current_matrix_up_to_date_p
8617 /* Don't use try_window_reusing_current_matrix in this case
8618 because it can have changed the buffer. */
8619 || !NILP (Vwindow_scroll_functions)
8620 || MINI_WINDOW_P (w)
8621 || !try_window_reusing_current_matrix (w))
8622 {
8623 IF_DEBUG (debug_method_add (w, "1"));
8624 try_window (window, startp);
8625 }
8626
8627 if (fonts_changed_p)
8628 goto restore_buffers;
8629
8630 if (w->cursor.vpos >= 0)
aa6d10fa 8631 {
5f5c8ee5
GM
8632 if (!just_this_one_p
8633 || current_buffer->clip_changed
8634 || beg_unchanged < CHARPOS (startp))
aa6d10fa
RS
8635 /* Forget any recorded base line for line number display. */
8636 w->base_line_number = Qnil;
5f5c8ee5
GM
8637
8638 make_cursor_line_fully_visible (w);
aa6d10fa
RS
8639 goto done;
8640 }
a2889657 8641 else
5f5c8ee5 8642 clear_glyph_matrix (w->desired_matrix);
a2889657
JB
8643 }
8644
5f5c8ee5
GM
8645 try_to_scroll:
8646
c2213350 8647 XSETFASTINT (w->last_modified, 0);
8850a573 8648 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5 8649
e481f960
RS
8650 /* Redisplay the mode line. Select the buffer properly for that. */
8651 if (!update_mode_line)
8652 {
5ba50c51
RS
8653 if (!really_switched_buffer)
8654 {
8655 set_buffer_temp (old);
8656 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 8657 really_switched_buffer = 1;
5ba50c51 8658 }
e481f960
RS
8659 update_mode_line = 1;
8660 w->update_mode_line = Qt;
8661 }
a2889657 8662
5f5c8ee5
GM
8663 /* Try to scroll by specified few lines. */
8664 if ((scroll_conservatively
8665 || scroll_step
8666 || temp_scroll_step
8667 || NUMBERP (current_buffer->scroll_up_aggressively)
8668 || NUMBERP (current_buffer->scroll_down_aggressively))
09cacf9c 8669 && !current_buffer->clip_changed
5f5c8ee5
GM
8670 && CHARPOS (startp) >= BEGV
8671 && CHARPOS (startp) <= ZV)
0789adb2 8672 {
5f5c8ee5
GM
8673 /* The function returns -1 if new fonts were loaded, 1 if
8674 successful, 0 if not successful. */
8675 int rc = try_scrolling (window, just_this_one_p,
8676 scroll_conservatively,
8677 scroll_step,
8678 temp_scroll_step);
8679 if (rc > 0)
8680 goto done;
8681 else if (rc < 0)
8682 goto restore_buffers;
8683 }
f9c8af06 8684
5f5c8ee5 8685 /* Finally, just choose place to start which centers point */
5936754e 8686
5f5c8ee5 8687 recenter:
44173109 8688
5f5c8ee5
GM
8689#if GLYPH_DEBUG
8690 debug_method_add (w, "recenter");
8691#endif
0789adb2 8692
5f5c8ee5 8693 /* w->vscroll = 0; */
0789adb2 8694
5f5c8ee5
GM
8695 /* Forget any previously recorded base line for line number display. */
8696 if (!current_matrix_up_to_date_p
8697 || current_buffer->clip_changed)
8698 w->base_line_number = Qnil;
8699
8700 /* Move backward half the height of the window. */
8701 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8702 it.current_y = it.last_visible_y;
8703 move_it_vertically_backward (&it, it.last_visible_y / 2);
8704 xassert (IT_CHARPOS (it) >= BEGV);
8705
8706 /* The function move_it_vertically_backward may move over more
8707 than the specified y-distance. If it->w is small, e.g. a
8708 mini-buffer window, we may end up in front of the window's
8709 display area. Start displaying at the start of the line
8710 containing PT in this case. */
8711 if (it.current_y <= 0)
8712 {
8713 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8714 move_it_vertically (&it, 0);
8715 xassert (IT_CHARPOS (it) <= PT);
8716 it.current_y = 0;
0789adb2
RS
8717 }
8718
5f5c8ee5
GM
8719 it.current_x = it.hpos = 0;
8720
8721 /* Set startp here explicitly in case that helps avoid an infinite loop
8722 in case the window-scroll-functions functions get errors. */
8723 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
8724
8725 /* Run scroll hooks. */
8726 startp = run_window_scroll_functions (window, it.current.pos);
8727
8728 /* Redisplay the window. */
8729 if (!current_matrix_up_to_date_p
8730 || windows_or_buffers_changed
8731 /* Don't use try_window_reusing_current_matrix in this case
8732 because it can have changed the buffer. */
8733 || !NILP (Vwindow_scroll_functions)
8734 || !just_this_one_p
8735 || MINI_WINDOW_P (w)
8736 || !try_window_reusing_current_matrix (w))
8737 try_window (window, startp);
8738
8739 /* If new fonts have been loaded (due to fontsets), give up. We
8740 have to start a new redisplay since we need to re-adjust glyph
8741 matrices. */
8742 if (fonts_changed_p)
8743 goto restore_buffers;
8744
8745 /* If cursor did not appear assume that the middle of the window is
8746 in the first line of the window. Do it again with the next line.
8747 (Imagine a window of height 100, displaying two lines of height
8748 60. Moving back 50 from it->last_visible_y will end in the first
8749 line.) */
8750 if (w->cursor.vpos < 0)
a2889657 8751 {
5f5c8ee5
GM
8752 if (!NILP (w->window_end_valid)
8753 && PT >= Z - XFASTINT (w->window_end_pos))
a2889657 8754 {
5f5c8ee5
GM
8755 clear_glyph_matrix (w->desired_matrix);
8756 move_it_by_lines (&it, 1, 0);
8757 try_window (window, it.current.pos);
a2889657 8758 }
5f5c8ee5 8759 else if (PT < IT_CHARPOS (it))
a2889657 8760 {
5f5c8ee5
GM
8761 clear_glyph_matrix (w->desired_matrix);
8762 move_it_by_lines (&it, -1, 0);
8763 try_window (window, it.current.pos);
8764 }
8765 else
8766 {
8767 /* Not much we can do about it. */
a2889657 8768 }
a2889657 8769 }
010494d0 8770
5f5c8ee5
GM
8771 /* Consider the following case: Window starts at BEGV, there is
8772 invisible, intangible text at BEGV, so that display starts at
8773 some point START > BEGV. It can happen that we are called with
8774 PT somewhere between BEGV and START. Try to handle that case. */
8775 if (w->cursor.vpos < 0)
835766b6 8776 {
5f5c8ee5
GM
8777 struct glyph_row *row = w->current_matrix->rows;
8778 if (row->mode_line_p)
8779 ++row;
8780 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
835766b6 8781 }
5f5c8ee5
GM
8782
8783 make_cursor_line_fully_visible (w);
b5174a51 8784
5f5c8ee5
GM
8785 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8786 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
8787 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
8788 ? Qt : Qnil);
a2889657 8789
5f5c8ee5 8790 done:
a2889657 8791
5f5c8ee5 8792 /* Display the mode line, if we must. */
e481f960 8793 if ((update_mode_line
aa6d10fa 8794 /* If window not full width, must redo its mode line
5f5c8ee5
GM
8795 if (a) the window to its side is being redone and
8796 (b) we do a frame-based redisplay. This is a consequence
8797 of how inverted lines are drawn in frame-based redisplay. */
8798 || (!just_this_one_p
8799 && !FRAME_WINDOW_P (f)
8800 && !WINDOW_FULL_WIDTH_P (w))
8801 /* Line number to display. */
155ef550 8802 || INTEGERP (w->base_line_pos)
5f5c8ee5 8803 /* Column number is displayed and different from the one displayed. */
155ef550
KH
8804 || (!NILP (w->column_number_displayed)
8805 && XFASTINT (w->column_number_displayed) != current_column ()))
5f5c8ee5
GM
8806 /* This means that the window has a mode line. */
8807 && (WINDOW_WANTS_MODELINE_P (w)
8808 || WINDOW_WANTS_TOP_LINE_P (w)))
5ba50c51 8809 {
5f5c8ee5
GM
8810 display_mode_lines (w);
8811
8812 /* If mode line height has changed, arrange for a thorough
8813 immediate redisplay using the correct mode line height. */
8814 if (WINDOW_WANTS_MODELINE_P (w)
8815 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
5ba50c51 8816 {
5f5c8ee5
GM
8817 fonts_changed_p = 1;
8818 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
8819 = DESIRED_MODE_LINE_HEIGHT (w);
5ba50c51 8820 }
5f5c8ee5
GM
8821
8822 /* If top line height has changed, arrange for a thorough
8823 immediate redisplay using the correct mode line height. */
8824 if (WINDOW_WANTS_TOP_LINE_P (w)
8825 && CURRENT_TOP_LINE_HEIGHT (w) != DESIRED_TOP_LINE_HEIGHT (w))
8826 {
8827 fonts_changed_p = 1;
8828 MATRIX_TOP_LINE_ROW (w->current_matrix)->height
8829 = DESIRED_TOP_LINE_HEIGHT (w);
8830 }
8831
8832 if (fonts_changed_p)
8833 goto restore_buffers;
5ba50c51 8834 }
5f5c8ee5
GM
8835
8836 if (!line_number_displayed
8837 && !BUFFERP (w->base_line_pos))
aa6d10fa
RS
8838 {
8839 w->base_line_pos = Qnil;
8840 w->base_line_number = Qnil;
8841 }
a2889657 8842
5f5c8ee5
GM
8843 finish_menu_bars:
8844
7ce2c095 8845 /* When we reach a frame's selected window, redo the frame's menu bar. */
e481f960 8846 if (update_mode_line
5f5c8ee5
GM
8847 && EQ (FRAME_SELECTED_WINDOW (f), window))
8848 {
8849 int redisplay_menu_p = 0;
8850
8851 if (FRAME_WINDOW_P (f))
8852 {
dc937613 8853#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5f5c8ee5 8854 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
76412d64 8855#else
5f5c8ee5 8856 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
76412d64 8857#endif
5f5c8ee5
GM
8858 }
8859 else
8860 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
8861
8862 if (redisplay_menu_p)
8863 display_menu_bar (w);
8864
8865#ifdef HAVE_WINDOW_SYSTEM
8866 if (WINDOWP (f->toolbar_window)
8867 && (FRAME_TOOLBAR_LINES (f) > 0
8868 || auto_resize_toolbars_p))
8869 redisplay_toolbar (f);
8870#endif
8871 }
7ce2c095 8872
88f22aff 8873 finish_scroll_bars:
5f5c8ee5 8874
88f22aff 8875 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
30c566e4 8876 {
b1d1124b 8877 int start, end, whole;
30c566e4 8878
b1d1124b 8879 /* Calculate the start and end positions for the current window.
3505ea70
JB
8880 At some point, it would be nice to choose between scrollbars
8881 which reflect the whole buffer size, with special markers
8882 indicating narrowing, and scrollbars which reflect only the
8883 visible region.
8884
5f5c8ee5 8885 Note that mini-buffers sometimes aren't displaying any text. */
c6e89d6c 8886 if (!MINI_WINDOW_P (w)
5f5c8ee5 8887 || (w == XWINDOW (minibuf_window)
c6e89d6c 8888 && NILP (echo_area_buffer[0])))
b1d1124b 8889 {
8a9311d7 8890 whole = ZV - BEGV;
4d641a15 8891 start = marker_position (w->start) - BEGV;
b1d1124b
JB
8892 /* I don't think this is guaranteed to be right. For the
8893 moment, we'll pretend it is. */
5f5c8ee5 8894 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
3505ea70 8895
5f5c8ee5
GM
8896 if (end < start)
8897 end = start;
8898 if (whole < (end - start))
8899 whole = end - start;
b1d1124b
JB
8900 }
8901 else
8902 start = end = whole = 0;
30c566e4 8903
88f22aff 8904 /* Indicate what this scroll bar ought to be displaying now. */
7eb9ba41 8905 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
30c566e4 8906
5f5c8ee5
GM
8907 /* Note that we actually used the scroll bar attached to this
8908 window, so it shouldn't be deleted at the end of redisplay. */
88f22aff 8909 (*redeem_scroll_bar_hook) (w);
30c566e4 8910 }
b1d1124b 8911
5f5c8ee5
GM
8912 restore_buffers:
8913
8914 /* Restore current_buffer and value of point in it. */
8915 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
5ba50c51 8916 if (really_switched_buffer)
f72df6ac 8917 set_buffer_internal_1 (old);
e481f960
RS
8918 else
8919 set_buffer_temp (old);
5f5c8ee5 8920 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
2e54982e
RS
8921
8922 unbind_to (count, Qnil);
a2889657 8923}
a2889657 8924
5f5c8ee5
GM
8925
8926/* Build the complete desired matrix of WINDOW with a window start
8927 buffer position POS. Value is non-zero if successful. It is zero
8928 if fonts were loaded during redisplay which makes re-adjusting
8929 glyph matrices necessary. */
8930
8931int
a2889657
JB
8932try_window (window, pos)
8933 Lisp_Object window;
5f5c8ee5
GM
8934 struct text_pos pos;
8935{
8936 struct window *w = XWINDOW (window);
8937 struct it it;
8938 struct glyph_row *last_text_row = NULL;
9cbab4ff 8939
5f5c8ee5
GM
8940 /* Make POS the new window start. */
8941 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12adba34 8942
5f5c8ee5
GM
8943 /* Mark cursor position as unknown. No overlay arrow seen. */
8944 w->cursor.vpos = -1;
a2889657 8945 overlay_arrow_seen = 0;
642eefc6 8946
5f5c8ee5
GM
8947 /* Initialize iterator and info to start at POS. */
8948 start_display (&it, w, pos);
a2889657 8949
5f5c8ee5
GM
8950 /* Display all lines of W. */
8951 while (it.current_y < it.last_visible_y)
8952 {
8953 if (display_line (&it))
8954 last_text_row = it.glyph_row - 1;
8955 if (fonts_changed_p)
8956 return 0;
8957 }
a2889657 8958
5f5c8ee5
GM
8959 /* If bottom moved off end of frame, change mode line percentage. */
8960 if (XFASTINT (w->window_end_pos) <= 0
8961 && Z != IT_CHARPOS (it))
a2889657
JB
8962 w->update_mode_line = Qt;
8963
5f5c8ee5
GM
8964 /* Set window_end_pos to the offset of the last character displayed
8965 on the window from the end of current_buffer. Set
8966 window_end_vpos to its row number. */
8967 if (last_text_row)
8968 {
8969 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
8970 w->window_end_bytepos
8971 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8972 XSETFASTINT (w->window_end_pos,
8973 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8974 XSETFASTINT (w->window_end_vpos,
8975 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8976 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
8977 ->displays_text_p);
8978 }
8979 else
8980 {
8981 w->window_end_bytepos = 0;
8982 XSETFASTINT (w->window_end_pos, 0);
8983 XSETFASTINT (w->window_end_vpos, 0);
8984 }
8985
a2889657
JB
8986 /* But that is not valid info until redisplay finishes. */
8987 w->window_end_valid = Qnil;
5f5c8ee5 8988 return 1;
a2889657 8989}
5f5c8ee5
GM
8990
8991
a2889657 8992\f
5f5c8ee5
GM
8993/************************************************************************
8994 Window redisplay reusing current matrix when buffer has not changed
8995 ************************************************************************/
8996
8997/* Try redisplay of window W showing an unchanged buffer with a
8998 different window start than the last time it was displayed by
8999 reusing its current matrix. Value is non-zero if successful.
9000 W->start is the new window start. */
a2889657
JB
9001
9002static int
5f5c8ee5
GM
9003try_window_reusing_current_matrix (w)
9004 struct window *w;
a2889657 9005{
5f5c8ee5
GM
9006 struct frame *f = XFRAME (w->frame);
9007 struct glyph_row *row, *bottom_row;
9008 struct it it;
9009 struct run run;
9010 struct text_pos start, new_start;
9011 int nrows_scrolled, i;
9012 struct glyph_row *last_text_row;
9013 struct glyph_row *last_reused_text_row;
9014 struct glyph_row *start_row;
9015 int start_vpos, min_y, max_y;
9016
9017 /* Right now this function doesn't handle terminal frames. */
9018 if (!FRAME_WINDOW_P (f))
9019 return 0;
a2889657 9020
5f5c8ee5
GM
9021 /* Can't do this if region may have changed. */
9022 if ((!NILP (Vtransient_mark_mode)
9023 && !NILP (current_buffer->mark_active))
8f897821
GM
9024 || !NILP (w->region_showing)
9025 || !NILP (Vshow_trailing_whitespace))
5f5c8ee5 9026 return 0;
a2889657 9027
5f5c8ee5
GM
9028 /* If top-line visibility has changed, give up. */
9029 if (WINDOW_WANTS_TOP_LINE_P (w)
9030 != MATRIX_TOP_LINE_ROW (w->current_matrix)->mode_line_p)
9031 return 0;
9032
9033 /* Give up if old or new display is scrolled vertically. We could
9034 make this function handle this, but right now it doesn't. */
9035 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9036 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
9037 return 0;
9038
9039 /* The variable new_start now holds the new window start. The old
9040 start `start' can be determined from the current matrix. */
9041 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
9042 start = start_row->start.pos;
9043 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
a2889657 9044
5f5c8ee5
GM
9045 /* Clear the desired matrix for the display below. */
9046 clear_glyph_matrix (w->desired_matrix);
9047
9048 if (CHARPOS (new_start) <= CHARPOS (start))
9049 {
9050 int first_row_y;
9051
9052 IF_DEBUG (debug_method_add (w, "twu1"));
9053
9054 /* Display up to a row that can be reused. The variable
9055 last_text_row is set to the last row displayed that displays
9056 text. */
9057 start_display (&it, w, new_start);
9058 first_row_y = it.current_y;
9059 w->cursor.vpos = -1;
9060 last_text_row = last_reused_text_row = NULL;
9061 while (it.current_y < it.last_visible_y
9062 && IT_CHARPOS (it) < CHARPOS (start)
9063 && !fonts_changed_p)
9064 if (display_line (&it))
9065 last_text_row = it.glyph_row - 1;
9066
9067 /* A value of current_y < last_visible_y means that we stopped
9068 at the previous window start, which in turn means that we
9069 have at least one reusable row. */
9070 if (it.current_y < it.last_visible_y)
a2889657 9071 {
5f5c8ee5
GM
9072 nrows_scrolled = it.vpos;
9073
9074 /* Find PT if not already found in the lines displayed. */
9075 if (w->cursor.vpos < 0)
a2889657 9076 {
5f5c8ee5
GM
9077 int dy = it.current_y - first_row_y;
9078
9079 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9080 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9081 {
9082 if (PT >= MATRIX_ROW_START_CHARPOS (row)
9083 && PT < MATRIX_ROW_END_CHARPOS (row))
9084 {
9085 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
9086 dy, nrows_scrolled);
9087 break;
9088 }
9089
9090 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
9091 break;
9092
9093 ++row;
9094 }
9095
9096 /* Give up if point was not found. This shouldn't
9097 happen often; not more often than with try_window
9098 itself. */
9099 if (w->cursor.vpos < 0)
9100 {
9101 clear_glyph_matrix (w->desired_matrix);
9102 return 0;
9103 }
a2889657 9104 }
5f5c8ee5
GM
9105
9106 /* Scroll the display. Do it before the current matrix is
9107 changed. The problem here is that update has not yet
9108 run, i.e. part of the current matrix is not up to date.
9109 scroll_run_hook will clear the cursor, and use the
9110 current matrix to get the height of the row the cursor is
9111 in. */
9112 run.current_y = first_row_y;
9113 run.desired_y = it.current_y;
9114 run.height = it.last_visible_y - it.current_y;
9115 if (run.height > 0)
a2889657 9116 {
5f5c8ee5
GM
9117 update_begin (f);
9118 rif->update_window_begin_hook (w);
9119 rif->scroll_run_hook (w, &run);
9120 rif->update_window_end_hook (w, 0);
9121 update_end (f);
a2889657 9122 }
5f5c8ee5
GM
9123
9124 /* Shift current matrix down by nrows_scrolled lines. */
9125 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9126 rotate_matrix (w->current_matrix,
9127 start_vpos,
9128 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9129 nrows_scrolled);
9130
9131 /* Disable lines not reused. */
9132 for (i = 0; i < it.vpos; ++i)
9133 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
9134
9135 /* Re-compute Y positions. */
9136 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
9137 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
9138 max_y = it.last_visible_y;
9139 while (row < bottom_row)
d2f84654 9140 {
5f5c8ee5
GM
9141 row->y = it.current_y;
9142
9143 if (row->y < min_y)
9144 row->visible_height = row->height - (min_y - row->y);
9145 else if (row->y + row->height > max_y)
9146 row->visible_height
9147 = row->height - (row->y + row->height - max_y);
9148 else
9149 row->visible_height = row->height;
9150
9151 it.current_y += row->height;
9152 ++it.vpos;
9153
9154 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9155 last_reused_text_row = row;
9156 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
9157 break;
9158 ++row;
d2f84654 9159 }
a2889657 9160 }
5f5c8ee5
GM
9161
9162 /* Update window_end_pos etc.; last_reused_text_row is the last
9163 reused row from the current matrix containing text, if any.
9164 The value of last_text_row is the last displayed line
9165 containing text. */
9166 if (last_reused_text_row)
a2889657 9167 {
5f5c8ee5
GM
9168 w->window_end_bytepos
9169 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
9170 XSETFASTINT (w->window_end_pos,
9171 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
9172 XSETFASTINT (w->window_end_vpos,
9173 MATRIX_ROW_VPOS (last_reused_text_row,
9174 w->current_matrix));
a2889657 9175 }
5f5c8ee5
GM
9176 else if (last_text_row)
9177 {
9178 w->window_end_bytepos
9179 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9180 XSETFASTINT (w->window_end_pos,
9181 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9182 XSETFASTINT (w->window_end_vpos,
9183 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9184 }
9185 else
9186 {
9187 /* This window must be completely empty. */
9188 w->window_end_bytepos = 0;
9189 XSETFASTINT (w->window_end_pos, 0);
9190 XSETFASTINT (w->window_end_vpos, 0);
9191 }
9192 w->window_end_valid = Qnil;
a2889657 9193
5f5c8ee5
GM
9194 /* Update hint: don't try scrolling again in update_window. */
9195 w->desired_matrix->no_scrolling_p = 1;
9196
9197#if GLYPH_DEBUG
9198 debug_method_add (w, "try_window_reusing_current_matrix 1");
9199#endif
9200 return 1;
a2889657 9201 }
5f5c8ee5
GM
9202 else if (CHARPOS (new_start) > CHARPOS (start))
9203 {
9204 struct glyph_row *pt_row, *row;
9205 struct glyph_row *first_reusable_row;
9206 struct glyph_row *first_row_to_display;
9207 int dy;
9208 int yb = window_text_bottom_y (w);
9209
9210 IF_DEBUG (debug_method_add (w, "twu2"));
9211
9212 /* Find the row starting at new_start, if there is one. Don't
9213 reuse a partially visible line at the end. */
9214 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9215 while (first_reusable_row->enabled_p
9216 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
9217 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9218 < CHARPOS (new_start)))
9219 ++first_reusable_row;
9220
9221 /* Give up if there is no row to reuse. */
9222 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
28514cd9
GM
9223 || !first_reusable_row->enabled_p
9224 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9225 != CHARPOS (new_start)))
5f5c8ee5
GM
9226 return 0;
9227
5f5c8ee5
GM
9228 /* We can reuse fully visible rows beginning with
9229 first_reusable_row to the end of the window. Set
9230 first_row_to_display to the first row that cannot be reused.
9231 Set pt_row to the row containing point, if there is any. */
9232 first_row_to_display = first_reusable_row;
9233 pt_row = NULL;
9234 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
9235 {
9236 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
9237 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
9238 pt_row = first_row_to_display;
a2889657 9239
5f5c8ee5
GM
9240 ++first_row_to_display;
9241 }
a2889657 9242
5f5c8ee5
GM
9243 /* Start displaying at the start of first_row_to_display. */
9244 xassert (first_row_to_display->y < yb);
9245 init_to_row_start (&it, w, first_row_to_display);
9246 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
9247 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
9248 - nrows_scrolled);
9249 it.current_y = first_row_to_display->y - first_reusable_row->y;
9250
9251 /* Display lines beginning with first_row_to_display in the
9252 desired matrix. Set last_text_row to the last row displayed
9253 that displays text. */
9254 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
9255 if (pt_row == NULL)
9256 w->cursor.vpos = -1;
9257 last_text_row = NULL;
9258 while (it.current_y < it.last_visible_y && !fonts_changed_p)
9259 if (display_line (&it))
9260 last_text_row = it.glyph_row - 1;
9261
9262 /* Give up If point isn't in a row displayed or reused. */
9263 if (w->cursor.vpos < 0)
9264 {
9265 clear_glyph_matrix (w->desired_matrix);
9266 return 0;
9267 }
12adba34 9268
5f5c8ee5
GM
9269 /* If point is in a reused row, adjust y and vpos of the cursor
9270 position. */
9271 if (pt_row)
9272 {
9273 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
9274 w->current_matrix);
9275 w->cursor.y -= first_reusable_row->y;
a2889657
JB
9276 }
9277
5f5c8ee5
GM
9278 /* Scroll the display. */
9279 run.current_y = first_reusable_row->y;
9280 run.desired_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
9281 run.height = it.last_visible_y - run.current_y;
9282 if (run.height)
9283 {
9284 struct frame *f = XFRAME (WINDOW_FRAME (w));
9285 update_begin (f);
9286 rif->update_window_begin_hook (w);
9287 rif->scroll_run_hook (w, &run);
9288 rif->update_window_end_hook (w, 0);
9289 update_end (f);
9290 }
a2889657 9291
5f5c8ee5
GM
9292 /* Adjust Y positions of reused rows. */
9293 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9294 row = first_reusable_row;
9295 dy = first_reusable_row->y;
9296 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
9297 max_y = it.last_visible_y;
9298 while (row < first_row_to_display)
9299 {
9300 row->y -= dy;
9301 if (row->y < min_y)
9302 row->visible_height = row->height - (min_y - row->y);
9303 else if (row->y + row->height > max_y)
9304 row->visible_height
9305 = row->height - (row->y + row->height - max_y);
9306 else
9307 row->visible_height = row->height;
9308 ++row;
9309 }
a2889657 9310
5f5c8ee5
GM
9311 /* Disable rows not reused. */
9312 while (row < bottom_row)
9313 {
9314 row->enabled_p = 0;
9315 ++row;
9316 }
9317
9318 /* Scroll the current matrix. */
9319 xassert (nrows_scrolled > 0);
9320 rotate_matrix (w->current_matrix,
9321 start_vpos,
9322 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9323 -nrows_scrolled);
9324
9325 /* Adjust window end. A null value of last_text_row means that
9326 the window end is in reused rows which in turn means that
9327 only its vpos can have changed. */
9328 if (last_text_row)
9329 {
9330 w->window_end_bytepos
9331 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9332 XSETFASTINT (w->window_end_pos,
9333 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9334 XSETFASTINT (w->window_end_vpos,
9335 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9336 }
9337 else
a2889657 9338 {
e8e536a9 9339 XSETFASTINT (w->window_end_vpos,
5f5c8ee5 9340 XFASTINT (w->window_end_vpos) - nrows_scrolled);
a2889657 9341 }
5f5c8ee5
GM
9342
9343 w->window_end_valid = Qnil;
9344 w->desired_matrix->no_scrolling_p = 1;
9345
9346#if GLYPH_DEBUG
9347 debug_method_add (w, "try_window_reusing_current_matrix 2");
9348#endif
9349 return 1;
a2889657 9350 }
5f5c8ee5
GM
9351
9352 return 0;
9353}
a2889657 9354
a2889657 9355
5f5c8ee5
GM
9356\f
9357/************************************************************************
9358 Window redisplay reusing current matrix when buffer has changed
9359 ************************************************************************/
9360
9361static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
9362static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
9363 int *, int *));
9364static struct glyph_row *
9365find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
9366 struct glyph_row *));
9367
9368
9369/* Return the last row in MATRIX displaying text. If row START is
9370 non-null, start searching with that row. IT gives the dimensions
9371 of the display. Value is null if matrix is empty; otherwise it is
9372 a pointer to the row found. */
9373
9374static struct glyph_row *
9375find_last_row_displaying_text (matrix, it, start)
9376 struct glyph_matrix *matrix;
9377 struct it *it;
9378 struct glyph_row *start;
9379{
9380 struct glyph_row *row, *row_found;
9381
9382 /* Set row_found to the last row in IT->w's current matrix
9383 displaying text. The loop looks funny but think of partially
9384 visible lines. */
9385 row_found = NULL;
9386 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
9387 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9388 {
9389 xassert (row->enabled_p);
9390 row_found = row;
9391 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
9392 break;
9393 ++row;
a2889657 9394 }
5f5c8ee5
GM
9395
9396 return row_found;
9397}
9398
a2889657 9399
5f5c8ee5
GM
9400/* Return the last row in the current matrix of W that is not affected
9401 by changes at the start of current_buffer that occurred since the
9402 last time W was redisplayed. Value is null if no such row exists.
a2889657 9403
5f5c8ee5
GM
9404 The global variable beg_unchanged has to contain the number of
9405 bytes unchanged at the start of current_buffer. BEG +
9406 beg_unchanged is the buffer position of the first changed byte in
9407 current_buffer. Characters at positions < BEG + beg_unchanged are
9408 at the same buffer positions as they were when the current matrix
9409 was built. */
9410
9411static struct glyph_row *
9412get_last_unchanged_at_beg_row (w)
9413 struct window *w;
9414{
9415 int first_changed_pos = BEG + beg_unchanged;
9416 struct glyph_row *row;
9417 struct glyph_row *row_found = NULL;
9418 int yb = window_text_bottom_y (w);
9419
9420 /* Find the last row displaying unchanged text. */
9421 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9422 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
9423 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
a2889657 9424 {
5f5c8ee5
GM
9425 if (/* If row ends before first_changed_pos, it is unchanged,
9426 except in some case. */
9427 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
9428 /* When row ends in ZV and we write at ZV it is not
9429 unchanged. */
9430 && !row->ends_at_zv_p
9431 /* When first_changed_pos is the end of a continued line,
9432 row is not unchanged because it may be no longer
9433 continued. */
9434 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
9435 && row->continued_p))
9436 row_found = row;
9437
9438 /* Stop if last visible row. */
9439 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
9440 break;
9441
9442 ++row;
a2889657
JB
9443 }
9444
5f5c8ee5 9445 return row_found;
a2889657 9446}
5f5c8ee5
GM
9447
9448
9449/* Find the first glyph row in the current matrix of W that is not
9450 affected by changes at the end of current_buffer since the last
9451 time the window was redisplayed. Return in *DELTA the number of
9452 bytes by which buffer positions in unchanged text at the end of
9453 current_buffer must be adjusted. Value is null if no such row
9454 exists, i.e. all rows are affected by changes.
9455
9456 The global variable end_unchanged is assumed to contain the number
9457 of unchanged bytes at the end of current_buffer. The buffer
9458 position of the last changed byte in current_buffer is then Z -
9459 end_unchanged. */
9460
9461static struct glyph_row *
9462get_first_unchanged_at_end_row (w, delta, delta_bytes)
9463 struct window *w;
9464 int *delta, *delta_bytes;
a2889657 9465{
5f5c8ee5
GM
9466 struct glyph_row *row;
9467 struct glyph_row *row_found = NULL;
c581d710 9468
5f5c8ee5 9469 *delta = *delta_bytes = 0;
b2a76982 9470
5f5c8ee5
GM
9471 /* A value of window_end_pos >= end_unchanged means that the window
9472 end is in the range of changed text. If so, there is no
9473 unchanged row at the end of W's current matrix. */
9474 xassert (!NILP (w->window_end_valid));
9475 if (XFASTINT (w->window_end_pos) >= end_unchanged)
9476 return NULL;
9477
9478 /* Set row to the last row in W's current matrix displaying text. */
9479 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9480
5f5c8ee5
GM
9481 /* If matrix is entirely empty, no unchanged row exists. */
9482 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9483 {
9484 /* The value of row is the last glyph row in the matrix having a
9485 meaningful buffer position in it. The end position of row
9486 corresponds to window_end_pos. This allows us to translate
9487 buffer positions in the current matrix to current buffer
9488 positions for characters not in changed text. */
9489 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
9490 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
9491 int last_unchanged_pos, last_unchanged_pos_old;
9492 struct glyph_row *first_text_row
9493 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9494
9495 *delta = Z - Z_old;
9496 *delta_bytes = Z_BYTE - Z_BYTE_old;
9497
9498 /* Set last_unchanged_pos to the buffer position of the last
9499 character in the buffer that has not been changed. Z is the
9500 index + 1 of the last byte in current_buffer, i.e. by
9501 subtracting end_unchanged we get the index of the last
9502 unchanged character, and we have to add BEG to get its buffer
9503 position. */
9504 last_unchanged_pos = Z - end_unchanged + BEG;
9505 last_unchanged_pos_old = last_unchanged_pos - *delta;
9506
9507 /* Search backward from ROW for a row displaying a line that
9508 starts at a minimum position >= last_unchanged_pos_old. */
9509 while (row >= first_text_row)
9510 {
9511 xassert (row->enabled_p);
9512 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9513
9514 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9515 row_found = row;
9516 --row;
9517 }
9518 }
9519
9520 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9521 return row_found;
c581d710
RS
9522}
9523
c581d710 9524
5f5c8ee5
GM
9525/* Make sure that glyph rows in the current matrix of window W
9526 reference the same glyph memory as corresponding rows in the
9527 frame's frame matrix. This function is called after scrolling W's
9528 current matrix on a terminal frame in try_window_id and
9529 try_window_reusing_current_matrix. */
9530
9531static void
9532sync_frame_with_window_matrix_rows (w)
9533 struct window *w;
c581d710 9534{
5f5c8ee5
GM
9535 struct frame *f = XFRAME (w->frame);
9536 struct glyph_row *window_row, *window_row_end, *frame_row;
9537
9538 /* Preconditions: W must be a leaf window and full-width. Its frame
9539 must have a frame matrix. */
9540 xassert (NILP (w->hchild) && NILP (w->vchild));
9541 xassert (WINDOW_FULL_WIDTH_P (w));
9542 xassert (!FRAME_WINDOW_P (f));
9543
9544 /* If W is a full-width window, glyph pointers in W's current matrix
9545 have, by definition, to be the same as glyph pointers in the
9546 corresponding frame matrix. */
9547 window_row = w->current_matrix->rows;
9548 window_row_end = window_row + w->current_matrix->nrows;
9549 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9550 while (window_row < window_row_end)
659a218f 9551 {
5f5c8ee5
GM
9552 int area;
9553 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9554 frame_row->glyphs[area] = window_row->glyphs[area];
9555 ++window_row, ++frame_row;
659a218f 9556 }
a2889657 9557}
5f5c8ee5
GM
9558
9559
9560/* Try to redisplay window W by reusing its existing display. W's
9561 current matrix must be up to date when this function is called,
9562 i.e. window_end_valid must not be nil.
9563
9564 Value is
9565
9566 1 if display has been updated
9567 0 if otherwise unsuccessful
9568 -1 if redisplay with same window start is known not to succeed
9569
9570 The following steps are performed:
9571
9572 1. Find the last row in the current matrix of W that is not
9573 affected by changes at the start of current_buffer. If no such row
9574 is found, give up.
9575
9576 2. Find the first row in W's current matrix that is not affected by
9577 changes at the end of current_buffer. Maybe there is no such row.
9578
9579 3. Display lines beginning with the row + 1 found in step 1 to the
9580 row found in step 2 or, if step 2 didn't find a row, to the end of
9581 the window.
9582
9583 4. If cursor is not known to appear on the window, give up.
9584
9585 5. If display stopped at the row found in step 2, scroll the
9586 display and current matrix as needed.
9587
9588 6. Maybe display some lines at the end of W, if we must. This can
9589 happen under various circumstances, like a partially visible line
9590 becoming fully visible, or because newly displayed lines are displayed
9591 in smaller font sizes.
9592
9593 7. Update W's window end information. */
9594
9595 /* Check that window end is what we expect it to be. */
12adba34
RS
9596
9597static int
5f5c8ee5 9598try_window_id (w)
12adba34 9599 struct window *w;
12adba34 9600{
5f5c8ee5
GM
9601 struct frame *f = XFRAME (w->frame);
9602 struct glyph_matrix *current_matrix = w->current_matrix;
9603 struct glyph_matrix *desired_matrix = w->desired_matrix;
9604 struct glyph_row *last_unchanged_at_beg_row;
9605 struct glyph_row *first_unchanged_at_end_row;
9606 struct glyph_row *row;
9607 struct glyph_row *bottom_row;
9608 int bottom_vpos;
9609 struct it it;
9610 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
9611 struct text_pos start_pos;
9612 struct run run;
9613 int first_unchanged_at_end_vpos = 0;
9614 struct glyph_row *last_text_row, *last_text_row_at_end;
9615 struct text_pos start;
9616
9617 SET_TEXT_POS_FROM_MARKER (start, w->start);
9618
9619 /* Check pre-conditions. Window end must be valid, otherwise
9620 the current matrix would not be up to date. */
9621 xassert (!NILP (w->window_end_valid));
9622 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
9623 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
9624
9625 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
9626 only if buffer has really changed. The reason is that the gap is
9627 initially at Z for freshly visited files. The code below would
9628 set end_unchanged to 0 in that case. */
9629 if (MODIFF > SAVE_MODIFF)
9630 {
9631 if (GPT - BEG < beg_unchanged)
9632 beg_unchanged = GPT - BEG;
9633 if (Z - GPT < end_unchanged)
9634 end_unchanged = Z - GPT;
9635 }
9636
9637 /* If window starts after a line end, and the last change is in
9638 front of that newline, then changes don't affect the display.
9639 This case happens with stealth-fontification. */
9640 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9641 if (CHARPOS (start) > BEGV
9642 && Z - end_unchanged < CHARPOS (start) - 1
9643 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
9644 && PT < MATRIX_ROW_END_CHARPOS (row))
9645 {
9646 /* We have to update window end positions because the buffer's
9647 size has changed. */
9648 w->window_end_pos
9649 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9650 w->window_end_bytepos
9651 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9652 return 1;
9653 }
9654
9655 /* Return quickly if changes are all below what is displayed in the
9656 window, and if PT is in the window. */
9657 if (beg_unchanged > MATRIX_ROW_END_CHARPOS (row)
9658 && PT < MATRIX_ROW_END_CHARPOS (row))
9659 {
9660 /* We have to update window end positions because the buffer's
9661 size has changed. */
9662 w->window_end_pos
9663 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9664 w->window_end_bytepos
9665 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9666 return 1;
9667 }
9668
9669 /* Check that window start agrees with the start of the first glyph
9670 row in its current matrix. Check this after we know the window
9671 start is not in changed text, otherwise positions would not be
9672 comparable. */
9673 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9674 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
9675 return 0;
9676
9677 /* Remember beg_unchanged and end_unchanged for debugging purposes. */
9678 IF_DEBUG (debug_beg_unchanged = beg_unchanged;
9679 debug_end_unchanged = end_unchanged);
9680
9681 /* Compute the position at which we have to start displaying new
9682 lines. Some of the lines at the top of the window might be
9683 reusable because they are not displaying changed text. Find the
9684 last row in W's current matrix not affected by changes at the
9685 start of current_buffer. Value is null if changes start in the
9686 first line of window. */
9687 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
9688 if (last_unchanged_at_beg_row)
9689 {
9690 init_to_row_end (&it, w, last_unchanged_at_beg_row);
9691 start_pos = it.current.pos;
9692
9693 /* Start displaying new lines in the desired matrix at the same
9694 vpos we would use in the current matrix, i.e. below
9695 last_unchanged_at_beg_row. */
9696 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
9697 current_matrix);
9698 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9699 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
9700
9701 xassert (it.hpos == 0 && it.current_x == 0);
9702 }
9703 else
9704 {
9705 /* There are no reusable lines at the start of the window.
9706 Start displaying in the first line. */
9707 start_display (&it, w, start);
9708 start_pos = it.current.pos;
9709 }
9710
9711 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
9712 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
9713
9714 /* Find the first row that is not affected by changes at the end of
9715 the buffer. Value will be null if there is no unchanged row, in
9716 which case we must redisplay to the end of the window. delta
9717 will be set to the value by which buffer positions beginning with
9718 first_unchanged_at_end_row have to be adjusted due to text
9719 changes. */
9720 first_unchanged_at_end_row
9721 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
9722 IF_DEBUG (debug_delta = delta);
9723 IF_DEBUG (debug_delta_bytes = delta_bytes);
9724
9725 /* Set stop_pos to the buffer position up to which we will have to
9726 display new lines. If first_unchanged_at_end_row != NULL, this
9727 is the buffer position of the start of the line displayed in that
9728 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
9729 that we don't stop at a buffer position. */
9730 stop_pos = 0;
9731 if (first_unchanged_at_end_row)
9732 {
9733 xassert (last_unchanged_at_beg_row == NULL
9734 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
9735
9736 /* If this is a continuation line, move forward to the next one
9737 that isn't. Changes in lines above affect this line.
9738 Caution: this may move first_unchanged_at_end_row to a row
9739 not displaying text. */
9740 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
9741 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9742 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9743 < it.last_visible_y))
9744 ++first_unchanged_at_end_row;
9745
9746 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9747 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9748 >= it.last_visible_y))
9749 first_unchanged_at_end_row = NULL;
9750 else
9751 {
9752 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
9753 + delta);
9754 first_unchanged_at_end_vpos
9755 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
9756 xassert (stop_pos >= Z - end_unchanged);
9757 }
9758 }
9759 else if (last_unchanged_at_beg_row == NULL)
9760 return 0;
9761
9762
9763#if GLYPH_DEBUG
9764
9765 /* Either there is no unchanged row at the end, or the one we have
9766 now displays text. This is a necessary condition for the window
9767 end pos calculation at the end of this function. */
9768 xassert (first_unchanged_at_end_row == NULL
9769 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
9770
9771 debug_last_unchanged_at_beg_vpos
9772 = (last_unchanged_at_beg_row
9773 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
9774 : -1);
9775 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
9776
9777#endif /* GLYPH_DEBUG != 0 */
9778
9779
9780 /* Display new lines. Set last_text_row to the last new line
9781 displayed which has text on it, i.e. might end up as being the
9782 line where the window_end_vpos is. */
9783 w->cursor.vpos = -1;
9784 last_text_row = NULL;
9785 overlay_arrow_seen = 0;
9786 while (it.current_y < it.last_visible_y
9787 && !fonts_changed_p
9788 && (first_unchanged_at_end_row == NULL
9789 || IT_CHARPOS (it) < stop_pos))
9790 {
9791 if (display_line (&it))
9792 last_text_row = it.glyph_row - 1;
9793 }
9794
9795 if (fonts_changed_p)
9796 return -1;
9797
9798
9799 /* Compute differences in buffer positions, y-positions etc. for
9800 lines reused at the bottom of the window. Compute what we can
9801 scroll. */
9802 if (first_unchanged_at_end_row)
9803 {
9804 dvpos = (it.vpos
9805 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
9806 current_matrix));
9807 dy = it.current_y - first_unchanged_at_end_row->y;
9808 run.current_y = first_unchanged_at_end_row->y;
9809 run.desired_y = run.current_y + dy;
9810 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
9811 }
9812 else
9813 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
9814 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
9815
9816
9817 /* Find the cursor if not already found. We have to decide whether
9818 PT will appear on this window (it sometimes doesn't, but this is
9819 not a very frequent case.) This decision has to be made before
9820 the current matrix is altered. A value of cursor.vpos < 0 means
9821 that PT is either in one of the lines beginning at
9822 first_unchanged_at_end_row or below the window. Don't care for
9823 lines that might be displayed later at the window end; as
9824 mentioned, this is not a frequent case. */
9825 if (w->cursor.vpos < 0)
9826 {
9827 int last_y = min (it.last_visible_y, it.last_visible_y + dy);
9828
9829 /* Cursor in unchanged rows at the top? */
9830 if (PT < CHARPOS (start_pos)
9831 && last_unchanged_at_beg_row)
9832 {
9833 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9834 while (row <= last_unchanged_at_beg_row
9835 && MATRIX_ROW_END_CHARPOS (row) <= PT)
9836 ++row;
9837 xassert (row <= last_unchanged_at_beg_row);
9838 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9839 }
9840
9841 /* Start from first_unchanged_at_end_row looking for PT. */
9842 else if (first_unchanged_at_end_row)
9843 {
9844 row = first_unchanged_at_end_row;
9845 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9846 {
9847 if (PT - delta >= MATRIX_ROW_START_CHARPOS (row)
9848 && PT - delta < MATRIX_ROW_END_CHARPOS (row))
9849 {
9850 set_cursor_from_row (w, row, w->current_matrix, delta,
9851 delta_bytes, dy, dvpos);
9852 break;
9853 }
9854 else if (MATRIX_ROW_BOTTOM_Y (row) >= last_y)
9855 break;
9856 ++row;
9857 }
9858 }
9859
9860 /* Give up if cursor was not found. */
9861 if (w->cursor.vpos < 0)
9862 {
9863 clear_glyph_matrix (w->desired_matrix);
9864 return -1;
9865 }
9866 }
9867
9868 /* Don't let the cursor end in the scroll margins. */
9869 {
9870 int this_scroll_margin, cursor_height;
9871
9872 this_scroll_margin = max (0, scroll_margin);
9873 this_scroll_margin = min (this_scroll_margin,
9874 XFASTINT (w->height) / 4);
9875 this_scroll_margin *= CANON_Y_UNIT (it.f);
9876 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
9877
9878 if ((w->cursor.y < this_scroll_margin
9879 && CHARPOS (start) > BEGV)
9880 /* Don't take scroll margin into account at the bottom because
9881 old redisplay didn't do it either. */
9882 || w->cursor.y + cursor_height > it.last_visible_y)
9883 {
9884 w->cursor.vpos = -1;
9885 clear_glyph_matrix (w->desired_matrix);
9886 return -1;
9887 }
9888 }
9889
9890 /* Scroll the display. Do it before changing the current matrix so
9891 that xterm.c doesn't get confused about where the cursor glyph is
9892 found. */
9893 if (dy)
9894 {
9895 update_begin (f);
9896
9897 if (FRAME_WINDOW_P (f))
9898 {
9899 rif->update_window_begin_hook (w);
9900 rif->scroll_run_hook (w, &run);
9901 rif->update_window_end_hook (w, 0);
9902 }
9903 else
9904 {
9905 /* Terminal frame. In this case, dvpos gives the number of
9906 lines to scroll by; dvpos < 0 means scroll up. */
9907 int first_unchanged_at_end_vpos
9908 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
9909 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
9910 int end = XFASTINT (w->top) + window_internal_height (w);
9911
9912 /* Perform the operation on the screen. */
9913 if (dvpos > 0)
9914 {
9915 /* Scroll last_unchanged_at_beg_row to the end of the
9916 window down dvpos lines. */
9917 set_terminal_window (end);
9918
9919 /* On dumb terminals delete dvpos lines at the end
9920 before inserting dvpos empty lines. */
9921 if (!scroll_region_ok)
9922 ins_del_lines (end - dvpos, -dvpos);
9923
9924 /* Insert dvpos empty lines in front of
9925 last_unchanged_at_beg_row. */
9926 ins_del_lines (from, dvpos);
9927 }
9928 else if (dvpos < 0)
9929 {
9930 /* Scroll up last_unchanged_at_beg_vpos to the end of
9931 the window to last_unchanged_at_beg_vpos - |dvpos|. */
9932 set_terminal_window (end);
9933
9934 /* Delete dvpos lines in front of
9935 last_unchanged_at_beg_vpos. ins_del_lines will set
9936 the cursor to the given vpos and emit |dvpos| delete
9937 line sequences. */
9938 ins_del_lines (from + dvpos, dvpos);
9939
9940 /* On a dumb terminal insert dvpos empty lines at the
9941 end. */
9942 if (!scroll_region_ok)
9943 ins_del_lines (end + dvpos, -dvpos);
9944 }
9945
9946 set_terminal_window (0);
9947 }
9948
9949 update_end (f);
9950 }
9951
9952 /* Shift reused rows of the current matrix to the right position. */
9953 if (dvpos < 0)
9954 {
9955 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
9956 bottom_vpos, dvpos);
9957 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
9958 bottom_vpos, 0);
9959 }
9960 else if (dvpos > 0)
9961 {
9962 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
9963 bottom_vpos, dvpos);
9964 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
9965 first_unchanged_at_end_vpos + dvpos, 0);
9966 }
9967
9968 /* For frame-based redisplay, make sure that current frame and window
9969 matrix are in sync with respect to glyph memory. */
9970 if (!FRAME_WINDOW_P (f))
9971 sync_frame_with_window_matrix_rows (w);
9972
9973 /* Adjust buffer positions in reused rows. */
9974 if (delta)
9975 increment_glyph_matrix_buffer_positions (current_matrix,
9976 first_unchanged_at_end_vpos + dvpos,
9977 bottom_vpos, delta, delta_bytes);
9978
9979 /* Adjust Y positions. */
9980 if (dy)
9981 shift_glyph_matrix (w, current_matrix,
9982 first_unchanged_at_end_vpos + dvpos,
9983 bottom_vpos, dy);
9984
9985 if (first_unchanged_at_end_row)
9986 first_unchanged_at_end_row += dvpos;
9987
9988 /* If scrolling up, there may be some lines to display at the end of
9989 the window. */
9990 last_text_row_at_end = NULL;
9991 if (dy < 0)
9992 {
9993 /* Set last_row to the glyph row in the current matrix where the
9994 window end line is found. It has been moved up or down in
9995 the matrix by dvpos. */
9996 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
9997 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
9998
9999 /* If last_row is the window end line, it should display text. */
10000 xassert (last_row->displays_text_p);
10001
10002 /* If window end line was partially visible before, begin
10003 displaying at that line. Otherwise begin displaying with the
10004 line following it. */
10005 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
10006 {
10007 init_to_row_start (&it, w, last_row);
10008 it.vpos = last_vpos;
10009 it.current_y = last_row->y;
10010 }
10011 else
10012 {
10013 init_to_row_end (&it, w, last_row);
10014 it.vpos = 1 + last_vpos;
10015 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
10016 ++last_row;
10017 }
12adba34 10018
5f5c8ee5
GM
10019 /* We may start in a continuation line. If so, we have to get
10020 the right continuation_lines_width and current_x. */
10021 it.continuation_lines_width = last_row->continuation_lines_width;
10022 it.hpos = it.current_x = 0;
10023
10024 /* Display the rest of the lines at the window end. */
10025 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10026 while (it.current_y < it.last_visible_y
10027 && !fonts_changed_p)
10028 {
10029 /* Is it always sure that the display agrees with lines in
10030 the current matrix? I don't think so, so we mark rows
10031 displayed invalid in the current matrix by setting their
10032 enabled_p flag to zero. */
10033 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
10034 if (display_line (&it))
10035 last_text_row_at_end = it.glyph_row - 1;
10036 }
10037 }
12adba34 10038
5f5c8ee5
GM
10039 /* Update window_end_pos and window_end_vpos. */
10040 if (first_unchanged_at_end_row
10041 && first_unchanged_at_end_row->y < it.last_visible_y
10042 && !last_text_row_at_end)
10043 {
10044 /* Window end line if one of the preserved rows from the current
10045 matrix. Set row to the last row displaying text in current
10046 matrix starting at first_unchanged_at_end_row, after
10047 scrolling. */
10048 xassert (first_unchanged_at_end_row->displays_text_p);
10049 row = find_last_row_displaying_text (w->current_matrix, &it,
10050 first_unchanged_at_end_row);
10051 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
10052
10053 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
10054 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10055 XSETFASTINT (w->window_end_vpos,
10056 MATRIX_ROW_VPOS (row, w->current_matrix));
10057 }
10058 else if (last_text_row_at_end)
10059 {
10060 XSETFASTINT (w->window_end_pos,
10061 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
10062 w->window_end_bytepos
10063 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
10064 XSETFASTINT (w->window_end_vpos,
10065 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
10066 }
10067 else if (last_text_row)
10068 {
10069 /* We have displayed either to the end of the window or at the
10070 end of the window, i.e. the last row with text is to be found
10071 in the desired matrix. */
10072 XSETFASTINT (w->window_end_pos,
10073 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10074 w->window_end_bytepos
10075 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10076 XSETFASTINT (w->window_end_vpos,
10077 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
10078 }
10079 else if (first_unchanged_at_end_row == NULL
10080 && last_text_row == NULL
10081 && last_text_row_at_end == NULL)
10082 {
10083 /* Displayed to end of window, but no line containing text was
10084 displayed. Lines were deleted at the end of the window. */
10085 int vpos;
10086 int top_line_p = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
10087
10088 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
10089 if ((w->desired_matrix->rows[vpos + top_line_p].enabled_p
10090 && w->desired_matrix->rows[vpos + top_line_p].displays_text_p)
10091 || (!w->desired_matrix->rows[vpos + top_line_p].enabled_p
10092 && w->current_matrix->rows[vpos + top_line_p].displays_text_p))
10093 break;
12adba34 10094
5f5c8ee5
GM
10095 w->window_end_vpos = make_number (vpos);
10096 }
10097 else
10098 abort ();
10099
10100 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
10101 debug_end_vpos = XFASTINT (w->window_end_vpos));
12adba34 10102
5f5c8ee5
GM
10103 /* Record that display has not been completed. */
10104 w->window_end_valid = Qnil;
10105 w->desired_matrix->no_scrolling_p = 1;
10106 return 1;
12adba34 10107}
0f9c0ff0 10108
a2889657 10109
5f5c8ee5
GM
10110\f
10111/***********************************************************************
10112 More debugging support
10113 ***********************************************************************/
a2889657 10114
5f5c8ee5 10115#if GLYPH_DEBUG
a2889657 10116
5f5c8ee5
GM
10117 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
10118static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
1c9241f5 10119
31b24551 10120
5f5c8ee5
GM
10121/* Dump the contents of glyph matrix MATRIX on stderr. If
10122 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
ca26e1c8 10123
5f5c8ee5
GM
10124void
10125dump_glyph_matrix (matrix, with_glyphs_p)
10126 struct glyph_matrix *matrix;
10127 int with_glyphs_p;
10128{
efc63ef0 10129 int i;
5f5c8ee5
GM
10130 for (i = 0; i < matrix->nrows; ++i)
10131 dump_glyph_row (matrix, i, with_glyphs_p);
10132}
31b24551 10133
68a37fa8 10134
5f5c8ee5
GM
10135/* Dump the contents of glyph row at VPOS in MATRIX to stderr.
10136 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
a2889657 10137
5f5c8ee5
GM
10138void
10139dump_glyph_row (matrix, vpos, with_glyphs_p)
10140 struct glyph_matrix *matrix;
10141 int vpos, with_glyphs_p;
10142{
10143 struct glyph_row *row;
10144
10145 if (vpos < 0 || vpos >= matrix->nrows)
10146 return;
10147
10148 row = MATRIX_ROW (matrix, vpos);
10149
10150 fprintf (stderr, "Row Start End Used oEI><O\\CTZF X Y W\n");
10151 fprintf (stderr, "=============================================\n");
10152
10153 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",
10154 row - matrix->rows,
10155 MATRIX_ROW_START_CHARPOS (row),
10156 MATRIX_ROW_END_CHARPOS (row),
10157 row->used[TEXT_AREA],
10158 row->contains_overlapping_glyphs_p,
10159 row->enabled_p,
10160 row->inverse_p,
10161 row->truncated_on_left_p,
10162 row->truncated_on_right_p,
10163 row->overlay_arrow_p,
10164 row->continued_p,
10165 MATRIX_ROW_CONTINUATION_LINE_P (row),
10166 row->displays_text_p,
10167 row->ends_at_zv_p,
10168 row->fill_line_p,
10169 row->x,
10170 row->y,
10171 row->pixel_width);
10172 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
10173 row->end.overlay_string_index);
10174 fprintf (stderr, "%9d %5d\n",
10175 CHARPOS (row->start.string_pos),
10176 CHARPOS (row->end.string_pos));
10177 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
10178 row->end.dpvec_index);
10179
10180 if (with_glyphs_p)
bd66d1ba 10181 {
5f5c8ee5
GM
10182 struct glyph *glyph, *glyph_end;
10183 int prev_had_glyphs_p;
10184
10185 glyph = row->glyphs[TEXT_AREA];
10186 glyph_end = glyph + row->used[TEXT_AREA];
10187
10188 /* Glyph for a line end in text. */
10189 if (glyph == glyph_end && glyph->charpos > 0)
10190 ++glyph_end;
10191
10192 if (glyph < glyph_end)
bd66d1ba 10193 {
5f5c8ee5
GM
10194 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
10195 prev_had_glyphs_p = 1;
bd66d1ba
RS
10196 }
10197 else
5f5c8ee5
GM
10198 prev_had_glyphs_p = 0;
10199
10200 while (glyph < glyph_end)
f7b4b63a 10201 {
5f5c8ee5
GM
10202 if (glyph->type == CHAR_GLYPH)
10203 {
10204 fprintf (stderr,
10205 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10206 glyph - row->glyphs[TEXT_AREA],
10207 'C',
10208 glyph->charpos,
10209 glyph->pixel_width,
10210 glyph->u.ch.code,
10211 (glyph->u.ch.code < 0x80 && glyph->u.ch.code >= ' '
10212 ? glyph->u.ch.code
10213 : '.'),
10214 glyph->u.ch.face_id,
10215 glyph->left_box_line_p,
10216 glyph->right_box_line_p);
10217 }
10218 else if (glyph->type == STRETCH_GLYPH)
10219 {
10220 fprintf (stderr,
10221 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10222 glyph - row->glyphs[TEXT_AREA],
10223 'S',
10224 glyph->charpos,
10225 glyph->pixel_width,
10226 0,
10227 '.',
10228 glyph->u.stretch.face_id,
10229 glyph->left_box_line_p,
10230 glyph->right_box_line_p);
10231 }
10232 else if (glyph->type == IMAGE_GLYPH)
10233 {
10234 fprintf (stderr,
10235 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10236 glyph - row->glyphs[TEXT_AREA],
10237 'I',
10238 glyph->charpos,
10239 glyph->pixel_width,
10240 glyph->u.img.id,
10241 '.',
10242 glyph->u.img.face_id,
10243 glyph->left_box_line_p,
10244 glyph->right_box_line_p);
10245 }
10246 ++glyph;
f7b4b63a 10247 }
f4faa47c 10248 }
5f5c8ee5 10249}
f4faa47c 10250
a2889657 10251
5f5c8ee5
GM
10252DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
10253 Sdump_glyph_matrix, 0, 1, "p",
10254 "Dump the current matrix of the selected window to stderr.\n\
10255Shows contents of glyph row structures. With non-nil optional\n\
10256parameter WITH-GLYPHS-P, dump glyphs as well.")
10257 (with_glyphs_p)
10258{
10259 struct window *w = XWINDOW (selected_window);
10260 struct buffer *buffer = XBUFFER (w->buffer);
10261
10262 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
10263 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
10264 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
10265 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
10266 fprintf (stderr, "=============================================\n");
10267 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
10268 return Qnil;
10269}
1c2250c2 10270
1fca3fae 10271
5f5c8ee5
GM
10272DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
10273 "Dump glyph row ROW to stderr.")
10274 (row)
10275 Lisp_Object row;
10276{
10277 CHECK_NUMBER (row, 0);
10278 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
10279 return Qnil;
10280}
1fca3fae 10281
67481ae5 10282
5f5c8ee5
GM
10283DEFUN ("dump-toolbar-row", Fdump_toolbar_row, Sdump_toolbar_row,
10284 0, 0, "", "")
10285 ()
10286{
10287 struct glyph_matrix *m = (XWINDOW (selected_frame->toolbar_window)
10288 ->current_matrix);
10289 dump_glyph_row (m, 0, 1);
10290 return Qnil;
10291}
ca26e1c8 10292
0f9c0ff0 10293
5f5c8ee5
GM
10294DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
10295 Strace_redisplay_toggle, 0, 0, "",
10296 "Toggle tracing of redisplay.")
10297 ()
10298{
10299 trace_redisplay_p = !trace_redisplay_p;
10300 return Qnil;
10301}
10302
10303
10304#endif /* GLYPH_DEBUG */
ca26e1c8 10305
ca26e1c8 10306
5f5c8ee5
GM
10307\f
10308/***********************************************************************
10309 Building Desired Matrix Rows
10310 ***********************************************************************/
a2889657 10311
5f5c8ee5
GM
10312/* Return a temporary glyph row holding the glyphs of an overlay
10313 arrow. Only used for non-window-redisplay windows. */
ca26e1c8 10314
5f5c8ee5
GM
10315static struct glyph_row *
10316get_overlay_arrow_glyph_row (w)
10317 struct window *w;
10318{
10319 struct frame *f = XFRAME (WINDOW_FRAME (w));
10320 struct buffer *buffer = XBUFFER (w->buffer);
10321 struct buffer *old = current_buffer;
10322 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
10323 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
10324 unsigned char *arrow_end = arrow_string + arrow_len;
10325 unsigned char *p;
10326 struct it it;
10327 int multibyte_p;
10328 int n_glyphs_before;
10329
10330 set_buffer_temp (buffer);
10331 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
10332 it.glyph_row->used[TEXT_AREA] = 0;
10333 SET_TEXT_POS (it.position, 0, 0);
10334
10335 multibyte_p = !NILP (buffer->enable_multibyte_characters);
10336 p = arrow_string;
10337 while (p < arrow_end)
10338 {
10339 Lisp_Object face, ilisp;
10340
10341 /* Get the next character. */
10342 if (multibyte_p)
4fdb80f2 10343 it.c = string_char_and_length (p, arrow_len, &it.len);
5f5c8ee5
GM
10344 else
10345 it.c = *p, it.len = 1;
10346 p += it.len;
10347
10348 /* Get its face. */
10349 XSETFASTINT (ilisp, p - arrow_string);
10350 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
10351 it.face_id = compute_char_face (f, it.c, face);
10352
10353 /* Compute its width, get its glyphs. */
10354 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
337042a9 10355 SET_TEXT_POS (it.position, -1, -1);
5f5c8ee5
GM
10356 PRODUCE_GLYPHS (&it);
10357
10358 /* If this character doesn't fit any more in the line, we have
10359 to remove some glyphs. */
10360 if (it.current_x > it.last_visible_x)
10361 {
10362 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
10363 break;
10364 }
10365 }
10366
10367 set_buffer_temp (old);
10368 return it.glyph_row;
10369}
ca26e1c8 10370
b0a0fbda 10371
5f5c8ee5
GM
10372/* Insert truncation glyphs at the start of IT->glyph_row. Truncation
10373 glyphs are only inserted for terminal frames since we can't really
10374 win with truncation glyphs when partially visible glyphs are
10375 involved. Which glyphs to insert is determined by
10376 produce_special_glyphs. */
67481ae5 10377
5f5c8ee5
GM
10378static void
10379insert_left_trunc_glyphs (it)
10380 struct it *it;
10381{
10382 struct it truncate_it;
10383 struct glyph *from, *end, *to, *toend;
10384
10385 xassert (!FRAME_WINDOW_P (it->f));
10386
10387 /* Get the truncation glyphs. */
10388 truncate_it = *it;
10389 truncate_it.charset = -1;
10390 truncate_it.current_x = 0;
10391 truncate_it.face_id = DEFAULT_FACE_ID;
10392 truncate_it.glyph_row = &scratch_glyph_row;
10393 truncate_it.glyph_row->used[TEXT_AREA] = 0;
10394 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
10395 truncate_it.object = 0;
10396 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
10397
10398 /* Overwrite glyphs from IT with truncation glyphs. */
10399 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
10400 end = from + truncate_it.glyph_row->used[TEXT_AREA];
10401 to = it->glyph_row->glyphs[TEXT_AREA];
10402 toend = to + it->glyph_row->used[TEXT_AREA];
10403
10404 while (from < end)
10405 *to++ = *from++;
10406
10407 /* There may be padding glyphs left over. Remove them. */
10408 from = to;
10409 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
10410 ++from;
10411 while (from < toend)
10412 *to++ = *from++;
10413
10414 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
10415}
e0bfbde6 10416
e0bfbde6 10417
5f5c8ee5 10418/* Compute the pixel height and width of IT->glyph_row.
9c49d3d7 10419
5f5c8ee5
GM
10420 Most of the time, ascent and height of a display line will be equal
10421 to the max_ascent and max_height values of the display iterator
10422 structure. This is not the case if
67481ae5 10423
5f5c8ee5
GM
10424 1. We hit ZV without displaying anything. In this case, max_ascent
10425 and max_height will be zero.
1c9241f5 10426
5f5c8ee5
GM
10427 2. We have some glyphs that don't contribute to the line height.
10428 (The glyph row flag contributes_to_line_height_p is for future
10429 pixmap extensions).
f6fd109b 10430
5f5c8ee5
GM
10431 The first case is easily covered by using default values because in
10432 these cases, the line height does not really matter, except that it
10433 must not be zero. */
67481ae5 10434
5f5c8ee5
GM
10435static void
10436compute_line_metrics (it)
10437 struct it *it;
10438{
10439 struct glyph_row *row = it->glyph_row;
10440 int area, i;
1c2250c2 10441
5f5c8ee5
GM
10442 if (FRAME_WINDOW_P (it->f))
10443 {
10444 int i, top_line_height;
1c2250c2 10445
5f5c8ee5
GM
10446 /* The line may consist of one space only, that was added to
10447 place the cursor on it. If so, the row's height hasn't been
10448 computed yet. */
10449 if (row->height == 0)
10450 {
10451 if (it->max_ascent + it->max_descent == 0)
312246d1 10452 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
5f5c8ee5
GM
10453 row->ascent = it->max_ascent;
10454 row->height = it->max_ascent + it->max_descent;
312246d1
GM
10455 row->phys_ascent = it->max_phys_ascent;
10456 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
10457 }
10458
10459 /* Compute the width of this line. */
10460 row->pixel_width = row->x;
10461 for (i = 0; i < row->used[TEXT_AREA]; ++i)
10462 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
10463
10464 xassert (row->pixel_width >= 0);
10465 xassert (row->ascent >= 0 && row->height > 0);
10466
312246d1
GM
10467 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
10468 || MATRIX_ROW_OVERLAPS_PRED_P (row));
10469
10470 /* If first line's physical ascent is larger than its logical
10471 ascent, use the physical ascent, and make the row taller.
10472 This makes accented characters fully visible. */
10473 if (row == it->w->desired_matrix->rows
10474 && row->phys_ascent > row->ascent)
10475 {
10476 row->height += row->phys_ascent - row->ascent;
10477 row->ascent = row->phys_ascent;
10478 }
10479
5f5c8ee5
GM
10480 /* Compute how much of the line is visible. */
10481 row->visible_height = row->height;
10482
10483 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w);
10484 if (row->y < top_line_height)
10485 row->visible_height -= top_line_height - row->y;
10486 else
10487 {
10488 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
10489 if (row->y + row->height > max_y)
10490 row->visible_height -= row->y + row->height - max_y;
10491 }
10492 }
10493 else
10494 {
10495 row->pixel_width = row->used[TEXT_AREA];
312246d1
GM
10496 row->ascent = row->phys_ascent = 0;
10497 row->height = row->phys_height = row->visible_height = 1;
5f5c8ee5 10498 }
67481ae5 10499
5f5c8ee5
GM
10500 /* Compute a hash code for this row. */
10501 row->hash = 0;
10502 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
10503 for (i = 0; i < row->used[area]; ++i)
10504 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
10505 + row->glyphs[area][i].u.val
10506 + (row->glyphs[area][i].type << 2));
a2889657 10507
5f5c8ee5 10508 it->max_ascent = it->max_descent = 0;
312246d1 10509 it->max_phys_ascent = it->max_phys_descent = 0;
5f5c8ee5 10510}
12adba34 10511
ca26e1c8 10512
5f5c8ee5
GM
10513/* Append one space to the glyph row of iterator IT if doing a
10514 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10515 space have the default face, otherwise let it have the same face as
c6e89d6c
GM
10516 IT->face_id.
10517
10518 This function is called to make sure that there is always one glyph
10519 at the end of a glyph row that the cursor can be set on under
10520 window-systems. (If there weren't such a glyph we would not know
10521 how wide and tall a box cursor should be displayed).
10522
10523 At the same time this space let's a nicely handle clearing to the
10524 end of the line if the row ends in italic text. */
ca26e1c8 10525
5f5c8ee5
GM
10526static void
10527append_space (it, default_face_p)
10528 struct it *it;
10529 int default_face_p;
10530{
10531 if (FRAME_WINDOW_P (it->f))
10532 {
10533 int n = it->glyph_row->used[TEXT_AREA];
ca26e1c8 10534
5f5c8ee5
GM
10535 if (it->glyph_row->glyphs[TEXT_AREA] + n
10536 < it->glyph_row->glyphs[1 + TEXT_AREA])
a2889657 10537 {
5f5c8ee5
GM
10538 /* Save some values that must not be changed. */
10539 int saved_x = it->current_x;
10540 struct text_pos saved_pos;
10541 int saved_what = it->what;
10542 int saved_face_id = it->face_id;
10543 int saved_charset = it->charset;
10544 Lisp_Object saved_object;
10545
10546 saved_object = it->object;
10547 saved_pos = it->position;
10548
10549 it->what = IT_CHARACTER;
10550 bzero (&it->position, sizeof it->position);
10551 it->object = 0;
10552 it->c = ' ';
10553 it->len = 1;
10554 it->charset = CHARSET_ASCII;
10555
10556 if (default_face_p)
10557 it->face_id = DEFAULT_FACE_ID;
10558 if (it->multibyte_p)
10559 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, CHARSET_ASCII);
10560 else
10561 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, -1);
1842fc1a 10562
5f5c8ee5
GM
10563 PRODUCE_GLYPHS (it);
10564
10565 it->current_x = saved_x;
10566 it->object = saved_object;
10567 it->position = saved_pos;
10568 it->what = saved_what;
10569 it->face_id = saved_face_id;
10570 it->charset = saved_charset;
10571 }
10572 }
10573}
12adba34 10574
1842fc1a 10575
5f5c8ee5
GM
10576/* Extend the face of the last glyph in the text area of IT->glyph_row
10577 to the end of the display line. Called from display_line.
10578 If the glyph row is empty, add a space glyph to it so that we
10579 know the face to draw. Set the glyph row flag fill_line_p. */
10580
10581static void
10582extend_face_to_end_of_line (it)
10583 struct it *it;
10584{
10585 struct face *face;
10586 struct frame *f = it->f;
1842fc1a 10587
5f5c8ee5
GM
10588 /* If line is already filled, do nothing. */
10589 if (it->current_x >= it->last_visible_x)
10590 return;
10591
10592 /* Face extension extends the background and box of IT->face_id
10593 to the end of the line. If the background equals the background
10594 of the frame, we haven't to do anything. */
10595 face = FACE_FROM_ID (f, it->face_id);
10596 if (FRAME_WINDOW_P (f)
10597 && face->box == FACE_NO_BOX
10598 && face->background == FRAME_BACKGROUND_PIXEL (f)
10599 && !face->stipple)
10600 return;
1842fc1a 10601
5f5c8ee5
GM
10602 /* Set the glyph row flag indicating that the face of the last glyph
10603 in the text area has to be drawn to the end of the text area. */
10604 it->glyph_row->fill_line_p = 1;
545e04f6 10605
5f5c8ee5
GM
10606 /* If current charset of IT is not ASCII, make sure we have the
10607 ASCII face. This will be automatically undone the next time
10608 get_next_display_element returns a character from a different
10609 charset. Note that the charset will always be ASCII in unibyte
10610 text. */
10611 if (it->charset != CHARSET_ASCII)
10612 {
10613 it->charset = CHARSET_ASCII;
10614 it->face_id = FACE_FOR_CHARSET (f, it->face_id, CHARSET_ASCII);
10615 }
545e04f6 10616
5f5c8ee5
GM
10617 if (FRAME_WINDOW_P (f))
10618 {
10619 /* If the row is empty, add a space with the current face of IT,
10620 so that we know which face to draw. */
10621 if (it->glyph_row->used[TEXT_AREA] == 0)
a2889657 10622 {
5f5c8ee5
GM
10623 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
10624 it->glyph_row->glyphs[TEXT_AREA][0].u.ch.face_id = it->face_id;
10625 it->glyph_row->used[TEXT_AREA] = 1;
a2889657 10626 }
5f5c8ee5
GM
10627 }
10628 else
10629 {
10630 /* Save some values that must not be changed. */
10631 int saved_x = it->current_x;
10632 struct text_pos saved_pos;
10633 Lisp_Object saved_object;
10634 int saved_what = it->what;
10635
10636 saved_object = it->object;
10637 saved_pos = it->position;
10638
10639 it->what = IT_CHARACTER;
10640 bzero (&it->position, sizeof it->position);
10641 it->object = 0;
10642 it->c = ' ';
10643 it->len = 1;
10644
10645 PRODUCE_GLYPHS (it);
10646
10647 while (it->current_x <= it->last_visible_x)
10648 PRODUCE_GLYPHS (it);
10649
10650 /* Don't count these blanks really. It would let us insert a left
10651 truncation glyph below and make us set the cursor on them, maybe. */
10652 it->current_x = saved_x;
10653 it->object = saved_object;
10654 it->position = saved_pos;
10655 it->what = saved_what;
10656 }
10657}
12adba34 10658
545e04f6 10659
5f5c8ee5
GM
10660/* Value is non-zero if text starting at CHARPOS in current_buffer is
10661 trailing whitespace. */
1c9241f5 10662
5f5c8ee5
GM
10663static int
10664trailing_whitespace_p (charpos)
10665 int charpos;
10666{
10667 int bytepos = CHAR_TO_BYTE (charpos);
10668 int c = 0;
7bbe686f 10669
5f5c8ee5
GM
10670 while (bytepos < ZV_BYTE
10671 && (c = FETCH_CHAR (bytepos),
10672 c == ' ' || c == '\t'))
10673 ++bytepos;
0d09d1e6 10674
8f897821
GM
10675 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
10676 {
10677 if (bytepos != PT_BYTE)
10678 return 1;
10679 }
10680 return 0;
5f5c8ee5 10681}
31b24551 10682
545e04f6 10683
5f5c8ee5 10684/* Highlight trailing whitespace, if any, in ROW. */
545e04f6 10685
5f5c8ee5
GM
10686void
10687highlight_trailing_whitespace (f, row)
10688 struct frame *f;
10689 struct glyph_row *row;
10690{
10691 int used = row->used[TEXT_AREA];
10692
10693 if (used)
10694 {
10695 struct glyph *start = row->glyphs[TEXT_AREA];
10696 struct glyph *glyph = start + used - 1;
10697
10698 /* Skip over the space glyph inserted to display the
10699 cursor at the end of a line. */
10700 if (glyph->type == CHAR_GLYPH
10701 && glyph->u.ch.code == ' '
10702 && glyph->object == 0)
10703 --glyph;
10704
10705 /* If last glyph is a space or stretch, and it's trailing
10706 whitespace, set the face of all trailing whitespace glyphs in
10707 IT->glyph_row to `trailing-whitespace'. */
10708 if (glyph >= start
10709 && BUFFERP (glyph->object)
10710 && (glyph->type == STRETCH_GLYPH
10711 || (glyph->type == CHAR_GLYPH
10712 && glyph->u.ch.code == ' '))
10713 && trailing_whitespace_p (glyph->charpos))
545e04f6 10714 {
5f5c8ee5
GM
10715 int face_id = lookup_named_face (f, Qtrailing_whitespace,
10716 CHARSET_ASCII);
10717
10718 while (glyph >= start
10719 && BUFFERP (glyph->object)
10720 && (glyph->type == STRETCH_GLYPH
10721 || (glyph->type == CHAR_GLYPH
10722 && glyph->u.ch.code == ' ')))
545e04f6 10723 {
5f5c8ee5
GM
10724 if (glyph->type == STRETCH_GLYPH)
10725 glyph->u.stretch.face_id = face_id;
10726 else
10727 glyph->u.ch.face_id = face_id;
10728 --glyph;
545e04f6
KH
10729 }
10730 }
a2889657 10731 }
5f5c8ee5 10732}
a2889657 10733
5fcbb24d 10734
5f5c8ee5
GM
10735/* Construct the glyph row IT->glyph_row in the desired matrix of
10736 IT->w from text at the current position of IT. See dispextern.h
10737 for an overview of struct it. Value is non-zero if
10738 IT->glyph_row displays text, as opposed to a line displaying ZV
10739 only. */
10740
10741static int
10742display_line (it)
10743 struct it *it;
10744{
10745 struct glyph_row *row = it->glyph_row;
10746
10747 /* We always start displaying at hpos zero even if hscrolled. */
10748 xassert (it->hpos == 0 && it->current_x == 0);
a2889657 10749
5f5c8ee5
GM
10750 /* We must not display in a row that's not a text row. */
10751 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
10752 < it->w->desired_matrix->nrows);
12adba34 10753
5f5c8ee5
GM
10754 /* Is IT->w showing the region? */
10755 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
12adba34 10756
5f5c8ee5
GM
10757 /* Clear the result glyph row and enable it. */
10758 prepare_desired_row (row);
12adba34 10759
5f5c8ee5
GM
10760 row->y = it->current_y;
10761 row->start = it->current;
10762 row->continuation_lines_width = it->continuation_lines_width;
10763 row->displays_text_p = 1;
10764
10765 /* Arrange the overlays nicely for our purposes. Usually, we call
10766 display_line on only one line at a time, in which case this
10767 can't really hurt too much, or we call it on lines which appear
10768 one after another in the buffer, in which case all calls to
10769 recenter_overlay_lists but the first will be pretty cheap. */
10770 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
10771
5f5c8ee5
GM
10772 /* Move over display elements that are not visible because we are
10773 hscrolled. This may stop at an x-position < IT->first_visible_x
10774 if the first glyph is partially visible or if we hit a line end. */
10775 if (it->current_x < it->first_visible_x)
10776 move_it_in_display_line_to (it, ZV, it->first_visible_x,
10777 MOVE_TO_POS | MOVE_TO_X);
10778
10779 /* Get the initial row height. This is either the height of the
10780 text hscrolled, if there is any, or zero. */
10781 row->ascent = it->max_ascent;
10782 row->height = it->max_ascent + it->max_descent;
312246d1
GM
10783 row->phys_ascent = it->max_phys_ascent;
10784 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
10785
10786 /* Loop generating characters. The loop is left with IT on the next
10787 character to display. */
10788 while (1)
10789 {
10790 int n_glyphs_before, hpos_before, x_before;
10791 int x, i, nglyphs;
10792
10793 /* Retrieve the next thing to display. Value is zero if end of
10794 buffer reached. */
10795 if (!get_next_display_element (it))
10796 {
10797 /* Maybe add a space at the end of this line that is used to
10798 display the cursor there under X. */
10799 append_space (it, 1);
10800
10801 /* The position -1 below indicates a blank line not
10802 corresponding to any text, as opposed to an empty line
10803 corresponding to a line end. */
10804 if (row->used[TEXT_AREA] <= 1)
a2889657 10805 {
5f5c8ee5
GM
10806 row->glyphs[TEXT_AREA]->charpos = -1;
10807 row->displays_text_p = 0;
10808
10809 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
10810 row->indicate_empty_line_p = 1;
a2889657 10811 }
5f5c8ee5
GM
10812
10813 it->continuation_lines_width = 0;
10814 row->ends_at_zv_p = 1;
10815 break;
a2889657 10816 }
a2889657 10817
5f5c8ee5
GM
10818 /* Now, get the metrics of what we want to display. This also
10819 generates glyphs in `row' (which is IT->glyph_row). */
10820 n_glyphs_before = row->used[TEXT_AREA];
10821 x = it->current_x;
10822 PRODUCE_GLYPHS (it);
a2889657 10823
5f5c8ee5
GM
10824 /* If this display element was in marginal areas, continue with
10825 the next one. */
10826 if (it->area != TEXT_AREA)
a2889657 10827 {
5f5c8ee5
GM
10828 row->ascent = max (row->ascent, it->max_ascent);
10829 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10830 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10831 row->phys_height = max (row->phys_height,
10832 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10833 set_iterator_to_next (it);
10834 continue;
10835 }
5936754e 10836
5f5c8ee5
GM
10837 /* Does the display element fit on the line? If we truncate
10838 lines, we should draw past the right edge of the window. If
10839 we don't truncate, we want to stop so that we can display the
10840 continuation glyph before the right margin. If lines are
10841 continued, there are two possible strategies for characters
10842 resulting in more than 1 glyph (e.g. tabs): Display as many
10843 glyphs as possible in this line and leave the rest for the
10844 continuation line, or display the whole element in the next
10845 line. Original redisplay did the former, so we do it also. */
10846 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10847 hpos_before = it->hpos;
10848 x_before = x;
10849
10850 if (nglyphs == 1
10851 && it->current_x < it->last_visible_x)
10852 {
10853 ++it->hpos;
10854 row->ascent = max (row->ascent, it->max_ascent);
10855 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10856 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10857 row->phys_height = max (row->phys_height,
10858 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10859 if (it->current_x - it->pixel_width < it->first_visible_x)
10860 row->x = x - it->first_visible_x;
10861 }
10862 else
10863 {
10864 int new_x;
10865 struct glyph *glyph;
10866
10867 for (i = 0; i < nglyphs; ++i, x = new_x)
b5bbc9a5 10868 {
5f5c8ee5
GM
10869 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10870 new_x = x + glyph->pixel_width;
10871
10872 if (/* Lines are continued. */
10873 !it->truncate_lines_p
10874 && (/* Glyph doesn't fit on the line. */
10875 new_x > it->last_visible_x
10876 /* Or it fits exactly on a window system frame. */
10877 || (new_x == it->last_visible_x
10878 && FRAME_WINDOW_P (it->f))))
a2889657 10879 {
5f5c8ee5
GM
10880 /* End of a continued line. */
10881
10882 if (it->hpos == 0
10883 || (new_x == it->last_visible_x
10884 && FRAME_WINDOW_P (it->f)))
10885 {
10886 /* Current glyph fits exactly on the line. We
10887 must continue the line because we can't draw
10888 the cursor after the glyph. */
10889 row->continued_p = 1;
10890 it->current_x = new_x;
10891 it->continuation_lines_width += new_x;
10892 ++it->hpos;
10893 if (i == nglyphs - 1)
10894 set_iterator_to_next (it);
10895 }
10896 else
5936754e 10897 {
5f5c8ee5
GM
10898 /* Display element draws past the right edge of
10899 the window. Restore positions to values
10900 before the element. The next line starts
10901 with current_x before the glyph that could
10902 not be displayed, so that TAB works right. */
10903 row->used[TEXT_AREA] = n_glyphs_before + i;
10904
10905 /* Display continuation glyphs. */
10906 if (!FRAME_WINDOW_P (it->f))
10907 produce_special_glyphs (it, IT_CONTINUATION);
10908 row->continued_p = 1;
10909
10910 it->current_x = x;
10911 it->continuation_lines_width += x;
5936754e 10912 }
5f5c8ee5
GM
10913 break;
10914 }
10915 else if (new_x > it->first_visible_x)
10916 {
10917 /* Increment number of glyphs actually displayed. */
10918 ++it->hpos;
10919
10920 if (x < it->first_visible_x)
10921 /* Glyph is partially visible, i.e. row starts at
10922 negative X position. */
10923 row->x = x - it->first_visible_x;
10924 }
10925 else
10926 {
10927 /* Glyph is completely off the left margin of the
10928 window. This should not happen because of the
10929 move_it_in_display_line at the start of
10930 this function. */
10931 abort ();
a2889657 10932 }
a2889657 10933 }
5f5c8ee5
GM
10934
10935 row->ascent = max (row->ascent, it->max_ascent);
10936 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10937 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10938 row->phys_height = max (row->phys_height,
10939 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10940
10941 /* End of this display line if row is continued. */
10942 if (row->continued_p)
10943 break;
a2889657 10944 }
a2889657 10945
5f5c8ee5
GM
10946 /* Is this a line end? If yes, we're also done, after making
10947 sure that a non-default face is extended up to the right
10948 margin of the window. */
10949 if (ITERATOR_AT_END_OF_LINE_P (it))
1c9241f5 10950 {
5f5c8ee5
GM
10951 int used_before = row->used[TEXT_AREA];
10952
10953 /* Add a space at the end of the line that is used to
10954 display the cursor there. */
10955 append_space (it, 0);
10956
10957 /* Extend the face to the end of the line. */
10958 extend_face_to_end_of_line (it);
10959
10960 /* Make sure we have the position. */
10961 if (used_before == 0)
10962 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
10963
10964 /* Consume the line end. This skips over invisible lines. */
10965 set_iterator_to_next (it);
10966 it->continuation_lines_width = 0;
10967 break;
1c9241f5 10968 }
a2889657 10969
5f5c8ee5
GM
10970 /* Proceed with next display element. Note that this skips
10971 over lines invisible because of selective display. */
10972 set_iterator_to_next (it);
b1d1124b 10973
5f5c8ee5
GM
10974 /* If we truncate lines, we are done when the last displayed
10975 glyphs reach past the right margin of the window. */
10976 if (it->truncate_lines_p
10977 && (FRAME_WINDOW_P (it->f)
10978 ? (it->current_x >= it->last_visible_x)
10979 : (it->current_x > it->last_visible_x)))
75d13c64 10980 {
5f5c8ee5
GM
10981 /* Maybe add truncation glyphs. */
10982 if (!FRAME_WINDOW_P (it->f))
10983 {
10984 --it->glyph_row->used[TEXT_AREA];
10985 produce_special_glyphs (it, IT_TRUNCATION);
10986 }
10987
10988 row->truncated_on_right_p = 1;
10989 it->continuation_lines_width = 0;
312246d1 10990 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
10991 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
10992 it->hpos = hpos_before;
10993 it->current_x = x_before;
10994 break;
75d13c64 10995 }
a2889657 10996 }
a2889657 10997
5f5c8ee5
GM
10998 /* If line is not empty and hscrolled, maybe insert truncation glyphs
10999 at the left window margin. */
11000 if (it->first_visible_x
11001 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
11002 {
11003 if (!FRAME_WINDOW_P (it->f))
11004 insert_left_trunc_glyphs (it);
11005 row->truncated_on_left_p = 1;
11006 }
a2889657 11007
5f5c8ee5
GM
11008 /* If the start of this line is the overlay arrow-position, then
11009 mark this glyph row as the one containing the overlay arrow.
11010 This is clearly a mess with variable size fonts. It would be
11011 better to let it be displayed like cursors under X. */
e24c997d 11012 if (MARKERP (Voverlay_arrow_position)
a2889657 11013 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
5f5c8ee5
GM
11014 && (MATRIX_ROW_START_CHARPOS (row)
11015 == marker_position (Voverlay_arrow_position))
e24c997d 11016 && STRINGP (Voverlay_arrow_string)
a2889657
JB
11017 && ! overlay_arrow_seen)
11018 {
5f5c8ee5
GM
11019 /* Overlay arrow in window redisplay is a bitmap. */
11020 if (!FRAME_WINDOW_P (it->f))
c4628384 11021 {
5f5c8ee5
GM
11022 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
11023 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
11024 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
11025 struct glyph *p = row->glyphs[TEXT_AREA];
11026 struct glyph *p2, *end;
11027
11028 /* Copy the arrow glyphs. */
11029 while (glyph < arrow_end)
11030 *p++ = *glyph++;
11031
11032 /* Throw away padding glyphs. */
11033 p2 = p;
11034 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
11035 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
11036 ++p2;
11037 if (p2 > p)
212e4f87 11038 {
5f5c8ee5
GM
11039 while (p2 < end)
11040 *p++ = *p2++;
11041 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
c4628384 11042 }
c4628384 11043 }
5f5c8ee5 11044
a2889657 11045 overlay_arrow_seen = 1;
5f5c8ee5 11046 row->overlay_arrow_p = 1;
a2889657
JB
11047 }
11048
5f5c8ee5
GM
11049 /* Compute pixel dimensions of this line. */
11050 compute_line_metrics (it);
11051
11052 /* Remember the position at which this line ends. */
11053 row->end = it->current;
11054
11055 /* Maybe set the cursor. If you change this, it's probably a good
11056 idea to also change the code in redisplay_window for cursor
11057 movement in an unchanged window. */
11058 if (it->w->cursor.vpos < 0
11059 && PT >= MATRIX_ROW_START_CHARPOS (row)
11060 && MATRIX_ROW_END_CHARPOS (row) >= PT
11061 && !(MATRIX_ROW_END_CHARPOS (row) == PT
11062 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
11063 || !row->ends_at_zv_p)))
11064 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
11065
11066 /* Highlight trailing whitespace. */
8f897821 11067 if (!NILP (Vshow_trailing_whitespace))
5f5c8ee5
GM
11068 highlight_trailing_whitespace (it->f, it->glyph_row);
11069
11070 /* Prepare for the next line. This line starts horizontally at (X
11071 HPOS) = (0 0). Vertical positions are incremented. As a
11072 convenience for the caller, IT->glyph_row is set to the next
11073 row to be used. */
11074 it->current_x = it->hpos = 0;
11075 it->current_y += row->height;
11076 ++it->vpos;
11077 ++it->glyph_row;
11078 return row->displays_text_p;
a2889657 11079}
5f5c8ee5
GM
11080
11081
a2889657 11082\f
5f5c8ee5
GM
11083/***********************************************************************
11084 Menu Bar
11085 ***********************************************************************/
11086
11087/* Redisplay the menu bar in the frame for window W.
11088
11089 The menu bar of X frames that don't have X toolkit support is
11090 displayed in a special window W->frame->menu_bar_window.
11091
11092 The menu bar of terminal frames is treated specially as far as
11093 glyph matrices are concerned. Menu bar lines are not part of
11094 windows, so the update is done directly on the frame matrix rows
11095 for the menu bar. */
7ce2c095
RS
11096
11097static void
11098display_menu_bar (w)
11099 struct window *w;
11100{
5f5c8ee5
GM
11101 struct frame *f = XFRAME (WINDOW_FRAME (w));
11102 struct it it;
11103 Lisp_Object items;
8351baf2 11104 int i;
7ce2c095 11105
5f5c8ee5 11106 /* Don't do all this for graphical frames. */
dc937613 11107#ifdef HAVE_NTGUI
d129c4c2
KH
11108 if (!NILP (Vwindow_system))
11109 return;
dc937613 11110#endif
dc937613 11111#ifdef USE_X_TOOLKIT
d3413a53 11112 if (FRAME_X_P (f))
7ce2c095 11113 return;
5f5c8ee5
GM
11114#endif
11115
11116#ifdef USE_X_TOOLKIT
11117 xassert (!FRAME_WINDOW_P (f));
11118 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
11119 it.first_visible_x = 0;
11120 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11121#else /* not USE_X_TOOLKIT */
11122 if (FRAME_WINDOW_P (f))
11123 {
11124 /* Menu bar lines are displayed in the desired matrix of the
11125 dummy window menu_bar_window. */
11126 struct window *menu_w;
11127 xassert (WINDOWP (f->menu_bar_window));
11128 menu_w = XWINDOW (f->menu_bar_window);
11129 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
11130 MODE_LINE_FACE_ID);
11131 it.first_visible_x = 0;
11132 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11133 }
11134 else
11135 {
11136 /* This is a TTY frame, i.e. character hpos/vpos are used as
11137 pixel x/y. */
11138 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
11139 MODE_LINE_FACE_ID);
11140 it.first_visible_x = 0;
11141 it.last_visible_x = FRAME_WIDTH (f);
11142 }
11143#endif /* not USE_X_TOOLKIT */
11144
11145 /* Clear all rows of the menu bar. */
11146 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
11147 {
11148 struct glyph_row *row = it.glyph_row + i;
11149 clear_glyph_row (row);
11150 row->enabled_p = 1;
11151 row->full_width_p = 1;
11152 }
7ce2c095 11153
5f5c8ee5
GM
11154 /* Make the first line of the menu bar appear in reverse video. */
11155 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
7ce2c095 11156
5f5c8ee5
GM
11157 /* Display all items of the menu bar. */
11158 items = FRAME_MENU_BAR_ITEMS (it.f);
469937ac 11159 for (i = 0; i < XVECTOR (items)->size; i += 4)
7ce2c095 11160 {
5f5c8ee5
GM
11161 Lisp_Object string;
11162
11163 /* Stop at nil string. */
8351baf2
RS
11164 string = XVECTOR (items)->contents[i + 1];
11165 if (NILP (string))
11166 break;
2d66ad19 11167
5f5c8ee5
GM
11168 /* Remember where item was displayed. */
11169 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
7ce2c095 11170
5f5c8ee5
GM
11171 /* Display the item, pad with one space. */
11172 if (it.current_x < it.last_visible_x)
11173 display_string (NULL, string, Qnil, 0, 0, &it,
11174 XSTRING (string)->size + 1, 0, 0, -1);
7ce2c095
RS
11175 }
11176
2d66ad19 11177 /* Fill out the line with spaces. */
5f5c8ee5
GM
11178 if (it.current_x < it.last_visible_x)
11179 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
db6f348c 11180
5f5c8ee5
GM
11181 /* Compute the total height of the lines. */
11182 compute_line_metrics (&it);
7ce2c095 11183}
5f5c8ee5
GM
11184
11185
7ce2c095 11186\f
5f5c8ee5
GM
11187/***********************************************************************
11188 Mode Line
11189 ***********************************************************************/
11190
11191/* Display the mode and/or top line of window W. */
a2889657
JB
11192
11193static void
5f5c8ee5 11194display_mode_lines (w)
a2889657
JB
11195 struct window *w;
11196{
5f5c8ee5 11197 /* These will be set while the mode line specs are processed. */
aa6d10fa 11198 line_number_displayed = 0;
155ef550 11199 w->column_number_displayed = Qnil;
aa6d10fa 11200
5f5c8ee5
GM
11201 if (WINDOW_WANTS_MODELINE_P (w))
11202 display_mode_line (w, MODE_LINE_FACE_ID, current_buffer->mode_line_format);
11203
11204 if (WINDOW_WANTS_TOP_LINE_P (w))
11205 display_mode_line (w, TOP_LINE_FACE_ID, current_buffer->top_line_format);
11206}
03b294dc 11207
03b294dc 11208
5f5c8ee5
GM
11209/* Display mode or top line of window W. FACE_ID specifies which line
11210 to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
11211 FORMAT is the mode line format to display. */
03b294dc 11212
5f5c8ee5
GM
11213static void
11214display_mode_line (w, face_id, format)
11215 struct window *w;
11216 enum face_id face_id;
11217 Lisp_Object format;
11218{
11219 struct it it;
11220 struct face *face;
03b294dc 11221
5f5c8ee5
GM
11222 init_iterator (&it, w, -1, -1, NULL, face_id);
11223 prepare_desired_row (it.glyph_row);
11224
11225 /* Temporarily make frame's keyboard the current kboard so that
11226 kboard-local variables in the mode_line_format will get the right
11227 values. */
11228 push_frame_kboard (it.f);
11229 display_mode_element (&it, 0, 0, 0, format);
11230 pop_frame_kboard ();
a2889657 11231
5f5c8ee5
GM
11232 /* Fill up with spaces. */
11233 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
11234
11235 compute_line_metrics (&it);
11236 it.glyph_row->full_width_p = 1;
11237 it.glyph_row->mode_line_p = 1;
11238 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11239 it.glyph_row->continued_p = 0;
11240 it.glyph_row->truncated_on_left_p = 0;
11241 it.glyph_row->truncated_on_right_p = 0;
11242
11243 /* Make a 3D mode-line have a shadow at its right end. */
11244 face = FACE_FROM_ID (it.f, face_id);
11245 extend_face_to_end_of_line (&it);
11246 if (face->box != FACE_NO_BOX)
d7eb09a0 11247 {
5f5c8ee5
GM
11248 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
11249 + it.glyph_row->used[TEXT_AREA] - 1);
11250 last->right_box_line_p = 1;
d7eb09a0 11251 }
a2889657
JB
11252}
11253
a2889657 11254
5f5c8ee5
GM
11255/* Contribute ELT to the mode line for window IT->w. How it
11256 translates into text depends on its data type.
a2889657 11257
5f5c8ee5 11258 IT describes the display environment in which we display, as usual.
a2889657
JB
11259
11260 DEPTH is the depth in recursion. It is used to prevent
11261 infinite recursion here.
11262
5f5c8ee5
GM
11263 FIELD_WIDTH is the number of characters the display of ELT should
11264 occupy in the mode line, and PRECISION is the maximum number of
11265 characters to display from ELT's representation. See
11266 display_string for details. *
a2889657 11267
5f5c8ee5 11268 Returns the hpos of the end of the text generated by ELT. */
a2889657
JB
11269
11270static int
5f5c8ee5
GM
11271display_mode_element (it, depth, field_width, precision, elt)
11272 struct it *it;
a2889657 11273 int depth;
5f5c8ee5
GM
11274 int field_width, precision;
11275 Lisp_Object elt;
a2889657 11276{
5f5c8ee5
GM
11277 int n = 0, field, prec;
11278
a2889657
JB
11279 tail_recurse:
11280 if (depth > 10)
11281 goto invalid;
11282
11283 depth++;
11284
0220c518 11285 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
a2889657
JB
11286 {
11287 case Lisp_String:
11288 {
11289 /* A string: output it and check for %-constructs within it. */
5f5c8ee5
GM
11290 unsigned char c;
11291 unsigned char *this = XSTRING (elt)->data;
11292 unsigned char *lisp_string = this;
11293
11294 while ((precision <= 0 || n < precision)
11295 && *this
11296 && (frame_title_ptr
11297 || it->current_x < it->last_visible_x))
a2889657
JB
11298 {
11299 unsigned char *last = this;
5f5c8ee5
GM
11300
11301 /* Advance to end of string or next format specifier. */
a2889657
JB
11302 while ((c = *this++) != '\0' && c != '%')
11303 ;
5f5c8ee5 11304
a2889657
JB
11305 if (this - 1 != last)
11306 {
5f5c8ee5
GM
11307 /* Output to end of string or up to '%'. Field width
11308 is length of string. Don't output more than
11309 PRECISION allows us. */
11310 prec = --this - last;
11311 if (precision > 0 && prec > precision - n)
11312 prec = precision - n;
11313
d39b6696 11314 if (frame_title_ptr)
5f5c8ee5 11315 n += store_frame_title (last, prec, prec);
d39b6696 11316 else
5f5c8ee5
GM
11317 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
11318 it, 0, prec, 0, -1);
a2889657
JB
11319 }
11320 else /* c == '%' */
11321 {
5f5c8ee5
GM
11322 unsigned char *percent_position = this;
11323
11324 /* Get the specified minimum width. Zero means
11325 don't pad. */
11326 field = 0;
a2889657 11327 while ((c = *this++) >= '0' && c <= '9')
5f5c8ee5 11328 field = field * 10 + c - '0';
a2889657 11329
5f5c8ee5
GM
11330 /* Don't pad beyond the total padding allowed. */
11331 if (field_width - n > 0 && field > field_width - n)
11332 field = field_width - n;
a2889657 11333
5f5c8ee5
GM
11334 /* Note that either PRECISION <= 0 or N < PRECISION. */
11335 prec = precision - n;
11336
a2889657 11337 if (c == 'M')
5f5c8ee5
GM
11338 n += display_mode_element (it, depth, field, prec,
11339 Vglobal_mode_string);
a2889657 11340 else if (c != 0)
d39b6696 11341 {
5f5c8ee5
GM
11342 unsigned char *spec
11343 = decode_mode_spec (it->w, c, field, prec);
11344
d39b6696 11345 if (frame_title_ptr)
5f5c8ee5 11346 n += store_frame_title (spec, field, prec);
d39b6696 11347 else
5f5c8ee5
GM
11348 {
11349 int nglyphs_before
11350 = it->glyph_row->used[TEXT_AREA];
11351 int charpos
11352 = percent_position - XSTRING (elt)->data;
11353 int nwritten
11354 = display_string (spec, Qnil, elt, charpos, 0, it,
11355 field, prec, 0, -1);
11356
11357 /* Assign to the glyphs written above the
11358 string where the `%x' came from, position
11359 of the `%'. */
11360 if (nwritten > 0)
11361 {
11362 struct glyph *glyph
11363 = (it->glyph_row->glyphs[TEXT_AREA]
11364 + nglyphs_before);
11365 int i;
11366
11367 for (i = 0; i < nwritten; ++i)
11368 {
11369 glyph[i].object = elt;
11370 glyph[i].charpos = charpos;
11371 }
11372
11373 n += nwritten;
11374 }
11375 }
d39b6696 11376 }
a2889657
JB
11377 }
11378 }
11379 }
11380 break;
11381
11382 case Lisp_Symbol:
11383 /* A symbol: process the value of the symbol recursively
11384 as if it appeared here directly. Avoid error if symbol void.
11385 Special case: if value of symbol is a string, output the string
11386 literally. */
11387 {
11388 register Lisp_Object tem;
11389 tem = Fboundp (elt);
265a9e55 11390 if (!NILP (tem))
a2889657
JB
11391 {
11392 tem = Fsymbol_value (elt);
11393 /* If value is a string, output that string literally:
11394 don't check for % within it. */
e24c997d 11395 if (STRINGP (tem))
d39b6696 11396 {
5f5c8ee5
GM
11397 prec = XSTRING (tem)->size;
11398 if (precision > 0 && prec > precision - n)
11399 prec = precision - n;
d39b6696 11400 if (frame_title_ptr)
5f5c8ee5 11401 n += store_frame_title (XSTRING (tem)->data, -1, prec);
d39b6696 11402 else
5f5c8ee5
GM
11403 n += display_string (NULL, tem, Qnil, 0, 0, it,
11404 0, prec, 0, -1);
d39b6696 11405 }
a2889657 11406 else if (!EQ (tem, elt))
5f5c8ee5
GM
11407 {
11408 /* Give up right away for nil or t. */
11409 elt = tem;
11410 goto tail_recurse;
11411 }
a2889657
JB
11412 }
11413 }
11414 break;
11415
11416 case Lisp_Cons:
11417 {
11418 register Lisp_Object car, tem;
11419
11420 /* A cons cell: three distinct cases.
11421 If first element is a string or a cons, process all the elements
11422 and effectively concatenate them.
11423 If first element is a negative number, truncate displaying cdr to
11424 at most that many characters. If positive, pad (with spaces)
11425 to at least that many characters.
11426 If first element is a symbol, process the cadr or caddr recursively
11427 according to whether the symbol's value is non-nil or nil. */
11428 car = XCONS (elt)->car;
5f5c8ee5
GM
11429 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
11430 {
11431 /* An element of the form (:eval FORM) means evaluate FORM
11432 and use the result as mode line elements. */
11433 struct gcpro gcpro1;
11434 Lisp_Object spec;
11435
11436 spec = eval_form (XCAR (XCDR (elt)));
11437 GCPRO1 (spec);
11438 n += display_mode_element (it, depth, field_width - n,
11439 precision - n, spec);
11440 UNGCPRO;
11441 }
11442 else if (SYMBOLP (car))
a2889657
JB
11443 {
11444 tem = Fboundp (car);
11445 elt = XCONS (elt)->cdr;
e24c997d 11446 if (!CONSP (elt))
a2889657
JB
11447 goto invalid;
11448 /* elt is now the cdr, and we know it is a cons cell.
11449 Use its car if CAR has a non-nil value. */
265a9e55 11450 if (!NILP (tem))
a2889657
JB
11451 {
11452 tem = Fsymbol_value (car);
265a9e55 11453 if (!NILP (tem))
a2889657
JB
11454 { elt = XCONS (elt)->car; goto tail_recurse; }
11455 }
11456 /* Symbol's value is nil (or symbol is unbound)
11457 Get the cddr of the original list
11458 and if possible find the caddr and use that. */
11459 elt = XCONS (elt)->cdr;
265a9e55 11460 if (NILP (elt))
a2889657 11461 break;
e24c997d 11462 else if (!CONSP (elt))
a2889657
JB
11463 goto invalid;
11464 elt = XCONS (elt)->car;
11465 goto tail_recurse;
11466 }
e24c997d 11467 else if (INTEGERP (car))
a2889657
JB
11468 {
11469 register int lim = XINT (car);
11470 elt = XCONS (elt)->cdr;
11471 if (lim < 0)
5f5c8ee5
GM
11472 {
11473 /* Negative int means reduce maximum width. */
11474 if (precision <= 0)
11475 precision = -lim;
11476 else
11477 precision = min (precision, -lim);
11478 }
a2889657
JB
11479 else if (lim > 0)
11480 {
11481 /* Padding specified. Don't let it be more than
11482 current maximum. */
5f5c8ee5
GM
11483 if (precision > 0)
11484 lim = min (precision, lim);
11485
a2889657
JB
11486 /* If that's more padding than already wanted, queue it.
11487 But don't reduce padding already specified even if
11488 that is beyond the current truncation point. */
5f5c8ee5 11489 field_width = max (lim, field_width);
a2889657
JB
11490 }
11491 goto tail_recurse;
11492 }
e24c997d 11493 else if (STRINGP (car) || CONSP (car))
a2889657
JB
11494 {
11495 register int limit = 50;
5f5c8ee5
GM
11496 /* Limit is to protect against circular lists. */
11497 while (CONSP (elt)
11498 && --limit > 0
11499 && (precision <= 0 || n < precision))
a2889657 11500 {
5f5c8ee5
GM
11501 n += display_mode_element (it, depth, field_width - n,
11502 precision - n, XCONS (elt)->car);
a2889657
JB
11503 elt = XCONS (elt)->cdr;
11504 }
11505 }
11506 }
11507 break;
11508
11509 default:
11510 invalid:
d39b6696 11511 if (frame_title_ptr)
5f5c8ee5 11512 n += store_frame_title ("*invalid*", 0, precision - n);
d39b6696 11513 else
5f5c8ee5
GM
11514 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
11515 precision - n, 0, 0);
11516 return n;
a2889657
JB
11517 }
11518
5f5c8ee5
GM
11519 /* Pad to FIELD_WIDTH. */
11520 if (field_width > 0 && n < field_width)
11521 {
11522 if (frame_title_ptr)
11523 n += store_frame_title ("", field_width - n, 0);
11524 else
11525 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
11526 0, 0, 0);
11527 }
11528
11529 return n;
a2889657 11530}
5f5c8ee5
GM
11531
11532
766525bc
RS
11533/* Write a null-terminated, right justified decimal representation of
11534 the positive integer D to BUF using a minimal field width WIDTH. */
11535
11536static void
11537pint2str (buf, width, d)
11538 register char *buf;
11539 register int width;
11540 register int d;
11541{
11542 register char *p = buf;
11543
11544 if (d <= 0)
5f5c8ee5 11545 *p++ = '0';
766525bc 11546 else
5f5c8ee5 11547 {
766525bc 11548 while (d > 0)
5f5c8ee5 11549 {
766525bc
RS
11550 *p++ = d % 10 + '0';
11551 d /= 10;
5f5c8ee5
GM
11552 }
11553 }
11554
11555 for (width -= (int) (p - buf); width > 0; --width)
11556 *p++ = ' ';
766525bc
RS
11557 *p-- = '\0';
11558 while (p > buf)
5f5c8ee5 11559 {
766525bc
RS
11560 d = *buf;
11561 *buf++ = *p;
11562 *p-- = d;
5f5c8ee5 11563 }
766525bc
RS
11564}
11565
5f5c8ee5 11566/* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
1c9241f5
KH
11567 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
11568 type of CODING_SYSTEM. Return updated pointer into BUF. */
11569
6693a99a 11570static unsigned char invalid_eol_type[] = "(*invalid*)";
d24715e8 11571
1c9241f5
KH
11572static char *
11573decode_mode_spec_coding (coding_system, buf, eol_flag)
11574 Lisp_Object coding_system;
11575 register char *buf;
11576 int eol_flag;
11577{
1e1078d6 11578 Lisp_Object val;
916848d8 11579 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
302f2b38
EZ
11580 unsigned char *eol_str;
11581 int eol_str_len;
11582 /* The EOL conversion we are using. */
11583 Lisp_Object eoltype;
1e1078d6
RS
11584
11585 val = coding_system;
1c9241f5
KH
11586
11587 if (NILP (val)) /* Not yet decided. */
11588 {
916848d8
RS
11589 if (multibyte)
11590 *buf++ = '-';
21e989e3 11591 if (eol_flag)
302f2b38 11592 eoltype = eol_mnemonic_undecided;
1e1078d6 11593 /* Don't mention EOL conversion if it isn't decided. */
1c9241f5
KH
11594 }
11595 else
11596 {
1e1078d6
RS
11597 Lisp_Object eolvalue;
11598
11599 eolvalue = Fget (coding_system, Qeol_type);
11600
1c9241f5 11601 while (!NILP (val) && SYMBOLP (val))
1e1078d6
RS
11602 {
11603 val = Fget (val, Qcoding_system);
11604 if (NILP (eolvalue))
b070c1d7 11605 eolvalue = Fget (val, Qeol_type);
1e1078d6
RS
11606 }
11607
916848d8
RS
11608 if (multibyte)
11609 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
11610
1c9241f5
KH
11611 if (eol_flag)
11612 {
1e1078d6
RS
11613 /* The EOL conversion that is normal on this system. */
11614
11615 if (NILP (eolvalue)) /* Not yet decided. */
11616 eoltype = eol_mnemonic_undecided;
11617 else if (VECTORP (eolvalue)) /* Not yet decided. */
11618 eoltype = eol_mnemonic_undecided;
11619 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
11620 eoltype = (XFASTINT (eolvalue) == 0
11621 ? eol_mnemonic_unix
11622 : (XFASTINT (eolvalue) == 1
11623 ? eol_mnemonic_dos : eol_mnemonic_mac));
302f2b38
EZ
11624 }
11625 }
5f5c8ee5 11626
302f2b38
EZ
11627 if (eol_flag)
11628 {
11629 /* Mention the EOL conversion if it is not the usual one. */
11630 if (STRINGP (eoltype))
11631 {
11632 eol_str = XSTRING (eoltype)->data;
11633 eol_str_len = XSTRING (eoltype)->size;
11634 }
f30b3499
KH
11635 else if (INTEGERP (eoltype)
11636 && CHAR_VALID_P (XINT (eoltype), 0))
11637 {
f30b3499
KH
11638 unsigned char work[4];
11639
11640 eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
11641 }
302f2b38
EZ
11642 else
11643 {
11644 eol_str = invalid_eol_type;
11645 eol_str_len = sizeof (invalid_eol_type) - 1;
1c9241f5 11646 }
f30b3499 11647 bcopy (eol_str, buf, eol_str_len);
302f2b38 11648 buf += eol_str_len;
1c9241f5 11649 }
302f2b38 11650
1c9241f5
KH
11651 return buf;
11652}
11653
a2889657 11654/* Return a string for the output of a mode line %-spec for window W,
5f5c8ee5
GM
11655 generated by character C. PRECISION >= 0 means don't return a
11656 string longer than that value. FIELD_WIDTH > 0 means pad the
11657 string returned with spaces to that value. */
a2889657 11658
11e82b76
JB
11659static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
11660
a2889657 11661static char *
5f5c8ee5 11662decode_mode_spec (w, c, field_width, precision)
a2889657
JB
11663 struct window *w;
11664 register char c;
5f5c8ee5 11665 int field_width, precision;
a2889657 11666{
0b67772d 11667 Lisp_Object obj;
5f5c8ee5
GM
11668 struct frame *f = XFRAME (WINDOW_FRAME (w));
11669 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
d39b6696 11670 struct buffer *b = XBUFFER (w->buffer);
a2889657 11671
0b67772d 11672 obj = Qnil;
a2889657
JB
11673
11674 switch (c)
11675 {
1af9f229
RS
11676 case '*':
11677 if (!NILP (b->read_only))
11678 return "%";
11679 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11680 return "*";
11681 return "-";
11682
11683 case '+':
11684 /* This differs from %* only for a modified read-only buffer. */
11685 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11686 return "*";
11687 if (!NILP (b->read_only))
11688 return "%";
11689 return "-";
11690
11691 case '&':
11692 /* This differs from %* in ignoring read-only-ness. */
11693 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11694 return "*";
11695 return "-";
11696
11697 case '%':
11698 return "%";
11699
11700 case '[':
11701 {
11702 int i;
11703 char *p;
11704
11705 if (command_loop_level > 5)
11706 return "[[[... ";
11707 p = decode_mode_spec_buf;
11708 for (i = 0; i < command_loop_level; i++)
11709 *p++ = '[';
11710 *p = 0;
11711 return decode_mode_spec_buf;
11712 }
11713
11714 case ']':
11715 {
11716 int i;
11717 char *p;
11718
11719 if (command_loop_level > 5)
11720 return " ...]]]";
11721 p = decode_mode_spec_buf;
11722 for (i = 0; i < command_loop_level; i++)
11723 *p++ = ']';
11724 *p = 0;
11725 return decode_mode_spec_buf;
11726 }
11727
11728 case '-':
11729 {
1af9f229 11730 register int i;
5f5c8ee5
GM
11731
11732 /* Let lots_of_dashes be a string of infinite length. */
11733 if (field_width <= 0
11734 || field_width > sizeof (lots_of_dashes))
1af9f229 11735 {
5f5c8ee5
GM
11736 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
11737 decode_mode_spec_buf[i] = '-';
11738 decode_mode_spec_buf[i] = '\0';
11739 return decode_mode_spec_buf;
1af9f229 11740 }
5f5c8ee5
GM
11741 else
11742 return lots_of_dashes;
1af9f229
RS
11743 }
11744
a2889657 11745 case 'b':
d39b6696 11746 obj = b->name;
a2889657
JB
11747 break;
11748
1af9f229
RS
11749 case 'c':
11750 {
11751 int col = current_column ();
11752 XSETFASTINT (w->column_number_displayed, col);
5f5c8ee5 11753 pint2str (decode_mode_spec_buf, field_width, col);
1af9f229
RS
11754 return decode_mode_spec_buf;
11755 }
11756
11757 case 'F':
11758 /* %F displays the frame name. */
5f5c8ee5 11759 if (!NILP (f->title))
95184b48 11760 return (char *) XSTRING (f->title)->data;
fd8ff63d 11761 if (f->explicit_name || ! FRAME_WINDOW_P (f))
95184b48 11762 return (char *) XSTRING (f->name)->data;
9c6da96f 11763 return "Emacs";
1af9f229 11764
a2889657 11765 case 'f':
d39b6696 11766 obj = b->filename;
a2889657
JB
11767 break;
11768
aa6d10fa
RS
11769 case 'l':
11770 {
12adba34
RS
11771 int startpos = XMARKER (w->start)->charpos;
11772 int startpos_byte = marker_byte_position (w->start);
11773 int line, linepos, linepos_byte, topline;
aa6d10fa 11774 int nlines, junk;
aa6d10fa
RS
11775 int height = XFASTINT (w->height);
11776
11777 /* If we decided that this buffer isn't suitable for line numbers,
11778 don't forget that too fast. */
11779 if (EQ (w->base_line_pos, w->buffer))
766525bc 11780 goto no_value;
5300fd39
RS
11781 /* But do forget it, if the window shows a different buffer now. */
11782 else if (BUFFERP (w->base_line_pos))
11783 w->base_line_pos = Qnil;
aa6d10fa
RS
11784
11785 /* If the buffer is very big, don't waste time. */
d39b6696 11786 if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit)
aa6d10fa
RS
11787 {
11788 w->base_line_pos = Qnil;
11789 w->base_line_number = Qnil;
766525bc 11790 goto no_value;
aa6d10fa
RS
11791 }
11792
11793 if (!NILP (w->base_line_number)
11794 && !NILP (w->base_line_pos)
12adba34 11795 && XFASTINT (w->base_line_pos) <= startpos)
aa6d10fa
RS
11796 {
11797 line = XFASTINT (w->base_line_number);
11798 linepos = XFASTINT (w->base_line_pos);
12adba34 11799 linepos_byte = buf_charpos_to_bytepos (b, linepos);
aa6d10fa
RS
11800 }
11801 else
11802 {
11803 line = 1;
d39b6696 11804 linepos = BUF_BEGV (b);
12adba34 11805 linepos_byte = BUF_BEGV_BYTE (b);
aa6d10fa
RS
11806 }
11807
11808 /* Count lines from base line to window start position. */
12adba34
RS
11809 nlines = display_count_lines (linepos, linepos_byte,
11810 startpos_byte,
11811 startpos, &junk);
aa6d10fa
RS
11812
11813 topline = nlines + line;
11814
11815 /* Determine a new base line, if the old one is too close
11816 or too far away, or if we did not have one.
11817 "Too close" means it's plausible a scroll-down would
11818 go back past it. */
d39b6696 11819 if (startpos == BUF_BEGV (b))
aa6d10fa 11820 {
c2213350
KH
11821 XSETFASTINT (w->base_line_number, topline);
11822 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
aa6d10fa
RS
11823 }
11824 else if (nlines < height + 25 || nlines > height * 3 + 50
d39b6696 11825 || linepos == BUF_BEGV (b))
aa6d10fa 11826 {
d39b6696 11827 int limit = BUF_BEGV (b);
12adba34 11828 int limit_byte = BUF_BEGV_BYTE (b);
aa6d10fa 11829 int position;
5d121aec 11830 int distance = (height * 2 + 30) * line_number_display_limit_width;
aa6d10fa
RS
11831
11832 if (startpos - distance > limit)
12adba34
RS
11833 {
11834 limit = startpos - distance;
11835 limit_byte = CHAR_TO_BYTE (limit);
11836 }
aa6d10fa 11837
12adba34
RS
11838 nlines = display_count_lines (startpos, startpos_byte,
11839 limit_byte,
11840 - (height * 2 + 30),
aa6d10fa
RS
11841 &position);
11842 /* If we couldn't find the lines we wanted within
5d121aec 11843 line_number_display_limit_width chars per line,
aa6d10fa 11844 give up on line numbers for this window. */
12adba34 11845 if (position == limit_byte && limit == startpos - distance)
aa6d10fa
RS
11846 {
11847 w->base_line_pos = w->buffer;
11848 w->base_line_number = Qnil;
766525bc 11849 goto no_value;
aa6d10fa
RS
11850 }
11851
c2213350 11852 XSETFASTINT (w->base_line_number, topline - nlines);
12adba34 11853 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
aa6d10fa
RS
11854 }
11855
11856 /* Now count lines from the start pos to point. */
12adba34
RS
11857 nlines = display_count_lines (startpos, startpos_byte,
11858 PT_BYTE, PT, &junk);
aa6d10fa
RS
11859
11860 /* Record that we did display the line number. */
11861 line_number_displayed = 1;
11862
11863 /* Make the string to show. */
5f5c8ee5 11864 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
aa6d10fa 11865 return decode_mode_spec_buf;
766525bc
RS
11866 no_value:
11867 {
11868 char* p = decode_mode_spec_buf;
5f5c8ee5
GM
11869 int pad = field_width - 2;
11870 while (pad-- > 0)
11871 *p++ = ' ';
11872 *p++ = '?';
11873 *p = '?';
766525bc
RS
11874 return decode_mode_spec_buf;
11875 }
aa6d10fa
RS
11876 }
11877 break;
11878
a2889657 11879 case 'm':
d39b6696 11880 obj = b->mode_name;
a2889657
JB
11881 break;
11882
11883 case 'n':
d39b6696 11884 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
a2889657
JB
11885 return " Narrow";
11886 break;
11887
a2889657
JB
11888 case 'p':
11889 {
11890 int pos = marker_position (w->start);
d39b6696 11891 int total = BUF_ZV (b) - BUF_BEGV (b);
a2889657 11892
d39b6696 11893 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
a2889657 11894 {
d39b6696 11895 if (pos <= BUF_BEGV (b))
a2889657
JB
11896 return "All";
11897 else
11898 return "Bottom";
11899 }
d39b6696 11900 else if (pos <= BUF_BEGV (b))
a2889657
JB
11901 return "Top";
11902 else
11903 {
3c7d31b9
RS
11904 if (total > 1000000)
11905 /* Do it differently for a large value, to avoid overflow. */
11906 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11907 else
11908 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
a2889657
JB
11909 /* We can't normally display a 3-digit number,
11910 so get us a 2-digit number that is close. */
11911 if (total == 100)
11912 total = 99;
11913 sprintf (decode_mode_spec_buf, "%2d%%", total);
11914 return decode_mode_spec_buf;
11915 }
11916 }
11917
8ffcb79f
RS
11918 /* Display percentage of size above the bottom of the screen. */
11919 case 'P':
11920 {
11921 int toppos = marker_position (w->start);
d39b6696
KH
11922 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
11923 int total = BUF_ZV (b) - BUF_BEGV (b);
8ffcb79f 11924
d39b6696 11925 if (botpos >= BUF_ZV (b))
8ffcb79f 11926 {
d39b6696 11927 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11928 return "All";
11929 else
11930 return "Bottom";
11931 }
11932 else
11933 {
3c7d31b9
RS
11934 if (total > 1000000)
11935 /* Do it differently for a large value, to avoid overflow. */
11936 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11937 else
11938 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
8ffcb79f
RS
11939 /* We can't normally display a 3-digit number,
11940 so get us a 2-digit number that is close. */
11941 if (total == 100)
11942 total = 99;
d39b6696 11943 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11944 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
11945 else
11946 sprintf (decode_mode_spec_buf, "%2d%%", total);
11947 return decode_mode_spec_buf;
11948 }
11949 }
11950
1af9f229
RS
11951 case 's':
11952 /* status of process */
11953 obj = Fget_buffer_process (w->buffer);
11954 if (NILP (obj))
11955 return "no process";
11956#ifdef subprocesses
11957 obj = Fsymbol_name (Fprocess_status (obj));
11958#endif
11959 break;
d39b6696 11960
1af9f229
RS
11961 case 't': /* indicate TEXT or BINARY */
11962#ifdef MODE_LINE_BINARY_TEXT
11963 return MODE_LINE_BINARY_TEXT (b);
11964#else
11965 return "T";
11966#endif
1c9241f5
KH
11967
11968 case 'z':
11969 /* coding-system (not including end-of-line format) */
11970 case 'Z':
11971 /* coding-system (including end-of-line type) */
11972 {
11973 int eol_flag = (c == 'Z');
539b4d41 11974 char *p = decode_mode_spec_buf;
1c9241f5 11975
d30e754b 11976 if (! FRAME_WINDOW_P (f))
1c9241f5 11977 {
11c52c4f
RS
11978 /* No need to mention EOL here--the terminal never needs
11979 to do EOL conversion. */
11980 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
11981 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
1c9241f5 11982 }
f13c925f 11983 p = decode_mode_spec_coding (b->buffer_file_coding_system,
539b4d41 11984 p, eol_flag);
f13c925f 11985
11c52c4f 11986#if 0 /* This proves to be annoying; I think we can do without. -- rms. */
1c9241f5
KH
11987#ifdef subprocesses
11988 obj = Fget_buffer_process (Fcurrent_buffer ());
11989 if (PROCESSP (obj))
11990 {
11991 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
11992 p, eol_flag);
11993 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
11994 p, eol_flag);
11995 }
11996#endif /* subprocesses */
11c52c4f 11997#endif /* 0 */
1c9241f5
KH
11998 *p = 0;
11999 return decode_mode_spec_buf;
12000 }
a2889657 12001 }
d39b6696 12002
e24c997d 12003 if (STRINGP (obj))
a2889657
JB
12004 return (char *) XSTRING (obj)->data;
12005 else
12006 return "";
12007}
5f5c8ee5
GM
12008
12009
12adba34
RS
12010/* Count up to COUNT lines starting from START / START_BYTE.
12011 But don't go beyond LIMIT_BYTE.
12012 Return the number of lines thus found (always nonnegative).
59b49f63 12013
12adba34 12014 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
59b49f63
RS
12015
12016static int
12adba34
RS
12017display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
12018 int start, start_byte, limit_byte, count;
12019 int *byte_pos_ptr;
59b49f63 12020{
59b49f63
RS
12021 register unsigned char *cursor;
12022 unsigned char *base;
12023
12024 register int ceiling;
12025 register unsigned char *ceiling_addr;
12adba34 12026 int orig_count = count;
59b49f63
RS
12027
12028 /* If we are not in selective display mode,
12029 check only for newlines. */
12adba34
RS
12030 int selective_display = (!NILP (current_buffer->selective_display)
12031 && !INTEGERP (current_buffer->selective_display));
59b49f63
RS
12032
12033 if (count > 0)
12adba34
RS
12034 {
12035 while (start_byte < limit_byte)
12036 {
12037 ceiling = BUFFER_CEILING_OF (start_byte);
12038 ceiling = min (limit_byte - 1, ceiling);
12039 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
12040 base = (cursor = BYTE_POS_ADDR (start_byte));
12041 while (1)
12042 {
12043 if (selective_display)
12044 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
12045 ;
12046 else
12047 while (*cursor != '\n' && ++cursor != ceiling_addr)
12048 ;
12049
12050 if (cursor != ceiling_addr)
12051 {
12052 if (--count == 0)
12053 {
12054 start_byte += cursor - base + 1;
12055 *byte_pos_ptr = start_byte;
12056 return orig_count;
12057 }
12058 else
12059 if (++cursor == ceiling_addr)
12060 break;
12061 }
12062 else
12063 break;
12064 }
12065 start_byte += cursor - base;
12066 }
12067 }
59b49f63
RS
12068 else
12069 {
12adba34
RS
12070 while (start_byte > limit_byte)
12071 {
12072 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
12073 ceiling = max (limit_byte, ceiling);
12074 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
12075 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
59b49f63
RS
12076 while (1)
12077 {
12adba34
RS
12078 if (selective_display)
12079 while (--cursor != ceiling_addr
12080 && *cursor != '\n' && *cursor != 015)
12081 ;
12082 else
12083 while (--cursor != ceiling_addr && *cursor != '\n')
12084 ;
12085
59b49f63
RS
12086 if (cursor != ceiling_addr)
12087 {
12088 if (++count == 0)
12089 {
12adba34
RS
12090 start_byte += cursor - base + 1;
12091 *byte_pos_ptr = start_byte;
12092 /* When scanning backwards, we should
12093 not count the newline posterior to which we stop. */
12094 return - orig_count - 1;
59b49f63
RS
12095 }
12096 }
12097 else
12098 break;
12099 }
12adba34
RS
12100 /* Here we add 1 to compensate for the last decrement
12101 of CURSOR, which took it past the valid range. */
12102 start_byte += cursor - base + 1;
59b49f63
RS
12103 }
12104 }
12105
12adba34 12106 *byte_pos_ptr = limit_byte;
aa6d10fa 12107
12adba34
RS
12108 if (count < 0)
12109 return - orig_count + count;
12110 return orig_count - count;
aa6d10fa 12111
12adba34 12112}
a2889657 12113
a2889657 12114
5f5c8ee5
GM
12115\f
12116/***********************************************************************
12117 Displaying strings
12118 ***********************************************************************/
278feba9 12119
5f5c8ee5 12120/* Display a NUL-terminated string, starting with index START.
a3788d53 12121
5f5c8ee5
GM
12122 If STRING is non-null, display that C string. Otherwise, the Lisp
12123 string LISP_STRING is displayed.
a2889657 12124
5f5c8ee5
GM
12125 If FACE_STRING is not nil, FACE_STRING_POS is a position in
12126 FACE_STRING. Display STRING or LISP_STRING with the face at
12127 FACE_STRING_POS in FACE_STRING:
a2889657 12128
5f5c8ee5
GM
12129 Display the string in the environment given by IT, but use the
12130 standard display table, temporarily.
a3788d53 12131
5f5c8ee5
GM
12132 FIELD_WIDTH is the minimum number of output glyphs to produce.
12133 If STRING has fewer characters than FIELD_WIDTH, pad to the right
12134 with spaces. If STRING has more characters, more than FIELD_WIDTH
12135 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
12136
12137 PRECISION is the maximum number of characters to output from
12138 STRING. PRECISION < 0 means don't truncate the string.
a2889657 12139
5f5c8ee5 12140 This is roughly equivalent to printf format specifiers:
a2889657 12141
5f5c8ee5
GM
12142 FIELD_WIDTH PRECISION PRINTF
12143 ----------------------------------------
12144 -1 -1 %s
12145 -1 10 %.10s
12146 10 -1 %10s
12147 20 10 %20.10s
a2889657 12148
5f5c8ee5
GM
12149 MULTIBYTE zero means do not display multibyte chars, > 0 means do
12150 display them, and < 0 means obey the current buffer's value of
12151 enable_multibyte_characters.
278feba9 12152
5f5c8ee5 12153 Value is the number of glyphs produced. */
b1d1124b 12154
5f5c8ee5
GM
12155static int
12156display_string (string, lisp_string, face_string, face_string_pos,
12157 start, it, field_width, precision, max_x, multibyte)
12158 unsigned char *string;
12159 Lisp_Object lisp_string;
12160 int start;
12161 struct it *it;
12162 int field_width, precision, max_x;
12163 int multibyte;
12164{
12165 int hpos_at_start = it->hpos;
12166 int saved_face_id = it->face_id;
12167 struct glyph_row *row = it->glyph_row;
12168
12169 /* Initialize the iterator IT for iteration over STRING beginning
12170 with index START. We assume that IT may be modified here (which
12171 means that display_line has to do something when displaying a
12172 mini-buffer prompt, which it does). */
12173 reseat_to_string (it, string, lisp_string, start,
12174 precision, field_width, multibyte);
12175
12176 /* If displaying STRING, set up the face of the iterator
12177 from LISP_STRING, if that's given. */
12178 if (STRINGP (face_string))
12179 {
12180 int endptr;
12181 struct face *face;
12182
12183 it->face_id
12184 = face_at_string_position (it->w, face_string, face_string_pos,
12185 0, it->region_beg_charpos,
12186 it->region_end_charpos,
12187 &endptr, it->base_face_id);
12188 face = FACE_FROM_ID (it->f, it->face_id);
12189 it->face_box_p = face->box != FACE_NO_BOX;
b1d1124b 12190 }
a2889657 12191
5f5c8ee5
GM
12192 /* Set max_x to the maximum allowed X position. Don't let it go
12193 beyond the right edge of the window. */
12194 if (max_x <= 0)
12195 max_x = it->last_visible_x;
12196 else
12197 max_x = min (max_x, it->last_visible_x);
efc63ef0 12198
5f5c8ee5
GM
12199 /* Skip over display elements that are not visible. because IT->w is
12200 hscrolled. */
12201 if (it->current_x < it->first_visible_x)
12202 move_it_in_display_line_to (it, 100000, it->first_visible_x,
12203 MOVE_TO_POS | MOVE_TO_X);
a2889657 12204
5f5c8ee5
GM
12205 row->ascent = it->max_ascent;
12206 row->height = it->max_ascent + it->max_descent;
312246d1
GM
12207 row->phys_ascent = it->max_phys_ascent;
12208 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
1c9241f5 12209
5f5c8ee5
GM
12210 /* This condition is for the case that we are called with current_x
12211 past last_visible_x. */
12212 while (it->current_x < max_x)
a2889657 12213 {
5f5c8ee5 12214 int x_before, x, n_glyphs_before, i, nglyphs;
1c9241f5 12215
5f5c8ee5
GM
12216 /* Get the next display element. */
12217 if (!get_next_display_element (it))
90adcf20 12218 break;
1c9241f5 12219
5f5c8ee5
GM
12220 /* Produce glyphs. */
12221 x_before = it->current_x;
12222 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
12223 PRODUCE_GLYPHS (it);
90adcf20 12224
5f5c8ee5
GM
12225 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
12226 i = 0;
12227 x = x_before;
12228 while (i < nglyphs)
a2889657 12229 {
5f5c8ee5
GM
12230 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12231
12232 if (!it->truncate_lines_p
12233 && x + glyph->pixel_width > max_x)
12234 {
12235 /* End of continued line or max_x reached. */
12236 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
12237 it->current_x = x;
12238 break;
12239 }
12240 else if (x + glyph->pixel_width > it->first_visible_x)
12241 {
12242 /* Glyph is at least partially visible. */
12243 ++it->hpos;
12244 if (x < it->first_visible_x)
12245 it->glyph_row->x = x - it->first_visible_x;
12246 }
12247 else
a2889657 12248 {
5f5c8ee5
GM
12249 /* Glyph is off the left margin of the display area.
12250 Should not happen. */
12251 abort ();
a2889657 12252 }
5f5c8ee5
GM
12253
12254 row->ascent = max (row->ascent, it->max_ascent);
12255 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
12256 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12257 row->phys_height = max (row->phys_height,
12258 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
12259 x += glyph->pixel_width;
12260 ++i;
a2889657 12261 }
5f5c8ee5
GM
12262
12263 /* Stop if max_x reached. */
12264 if (i < nglyphs)
12265 break;
12266
12267 /* Stop at line ends. */
12268 if (ITERATOR_AT_END_OF_LINE_P (it))
a2889657 12269 {
5f5c8ee5
GM
12270 it->continuation_lines_width = 0;
12271 break;
a2889657 12272 }
1c9241f5 12273
5f5c8ee5 12274 set_iterator_to_next (it);
a688bb24 12275
5f5c8ee5
GM
12276 /* Stop if truncating at the right edge. */
12277 if (it->truncate_lines_p
12278 && it->current_x >= it->last_visible_x)
12279 {
12280 /* Add truncation mark, but don't do it if the line is
12281 truncated at a padding space. */
12282 if (IT_CHARPOS (*it) < it->string_nchars)
1c9241f5 12283 {
5f5c8ee5
GM
12284 if (!FRAME_WINDOW_P (it->f))
12285 produce_special_glyphs (it, IT_TRUNCATION);
12286 it->glyph_row->truncated_on_right_p = 1;
1c9241f5 12287 }
5f5c8ee5 12288 break;
1c9241f5 12289 }
a2889657
JB
12290 }
12291
5f5c8ee5
GM
12292 /* Maybe insert a truncation at the left. */
12293 if (it->first_visible_x
12294 && IT_CHARPOS (*it) > 0)
a2889657 12295 {
5f5c8ee5
GM
12296 if (!FRAME_WINDOW_P (it->f))
12297 insert_left_trunc_glyphs (it);
12298 it->glyph_row->truncated_on_left_p = 1;
a2889657
JB
12299 }
12300
5f5c8ee5
GM
12301 it->face_id = saved_face_id;
12302
12303 /* Value is number of columns displayed. */
12304 return it->hpos - hpos_at_start;
12305}
a2889657 12306
a2889657 12307
a2889657 12308\f
5f5c8ee5
GM
12309/* This is like a combination of memq and assq. Return 1 if PROPVAL
12310 appears as an element of LIST or as the car of an element of LIST.
12311 If PROPVAL is a list, compare each element against LIST in that
12312 way, and return 1 if any element of PROPVAL is found in LIST.
12313 Otherwise return 0. This function cannot quit. */
642eefc6
RS
12314
12315int
12316invisible_p (propval, list)
12317 register Lisp_Object propval;
12318 Lisp_Object list;
12319{
af460d46
RS
12320 register Lisp_Object tail, proptail;
12321 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
12322 {
12323 register Lisp_Object tem;
af460d46 12324 tem = XCONS (tail)->car;
642eefc6
RS
12325 if (EQ (propval, tem))
12326 return 1;
12327 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
12328 return 1;
12329 }
af460d46
RS
12330 if (CONSP (propval))
12331 for (proptail = propval; CONSP (proptail);
12332 proptail = XCONS (proptail)->cdr)
12333 {
12334 Lisp_Object propelt;
12335 propelt = XCONS (proptail)->car;
12336 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
12337 {
12338 register Lisp_Object tem;
12339 tem = XCONS (tail)->car;
12340 if (EQ (propelt, tem))
12341 return 1;
12342 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
12343 return 1;
12344 }
12345 }
642eefc6
RS
12346 return 0;
12347}
12348
5f5c8ee5
GM
12349
12350/* Return 1 if PROPVAL appears as the car of an element of LIST and
12351 the cdr of that element is non-nil. If PROPVAL is a list, check
12352 each element of PROPVAL in that way, and the first time some
12353 element is found, return 1 if the cdr of that element is non-nil.
12354 Otherwise return 0. This function cannot quit. */
642eefc6
RS
12355
12356int
12357invisible_ellipsis_p (propval, list)
12358 register Lisp_Object propval;
12359 Lisp_Object list;
12360{
af460d46
RS
12361 register Lisp_Object tail, proptail;
12362 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
12363 {
12364 register Lisp_Object tem;
af460d46 12365 tem = XCONS (tail)->car;
642eefc6
RS
12366 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
12367 return ! NILP (XCONS (tem)->cdr);
12368 }
af460d46
RS
12369 if (CONSP (propval))
12370 for (proptail = propval; CONSP (proptail);
12371 proptail = XCONS (proptail)->cdr)
12372 {
12373 Lisp_Object propelt;
12374 propelt = XCONS (proptail)->car;
12375 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
12376 {
12377 register Lisp_Object tem;
12378 tem = XCONS (tail)->car;
12379 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
12380 return ! NILP (XCONS (tem)->cdr);
12381 }
12382 }
642eefc6
RS
12383 return 0;
12384}
5f5c8ee5
GM
12385
12386
642eefc6 12387\f
5f5c8ee5
GM
12388/***********************************************************************
12389 Initialization
12390 ***********************************************************************/
12391
a2889657
JB
12392void
12393syms_of_xdisp ()
12394{
c6e89d6c
GM
12395 Vwith_echo_area_save_vector = Qnil;
12396 staticpro (&Vwith_echo_area_save_vector);
5f5c8ee5 12397
c6e89d6c
GM
12398 Vmessage_stack = Qnil;
12399 staticpro (&Vmessage_stack);
12400
735c094c 12401 Qinhibit_redisplay = intern ("inhibit-redisplay");
c6e89d6c 12402 staticpro (&Qinhibit_redisplay);
735c094c 12403
5f5c8ee5
GM
12404#if GLYPH_DEBUG
12405 defsubr (&Sdump_glyph_matrix);
12406 defsubr (&Sdump_glyph_row);
12407 defsubr (&Sdump_toolbar_row);
12408 defsubr (&Strace_redisplay_toggle);
12409#endif
12410
cf074754
RS
12411 staticpro (&Qmenu_bar_update_hook);
12412 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
12413
d46fb96a 12414 staticpro (&Qoverriding_terminal_local_map);
7079aefa 12415 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
d46fb96a 12416
399164b4
KH
12417 staticpro (&Qoverriding_local_map);
12418 Qoverriding_local_map = intern ("overriding-local-map");
12419
75c43375
RS
12420 staticpro (&Qwindow_scroll_functions);
12421 Qwindow_scroll_functions = intern ("window-scroll-functions");
12422
e0bfbde6
RS
12423 staticpro (&Qredisplay_end_trigger_functions);
12424 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
5f5c8ee5 12425
2e54982e
RS
12426 staticpro (&Qinhibit_point_motion_hooks);
12427 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
12428
5f5c8ee5
GM
12429 staticpro (&Qdisplay);
12430 Qdisplay = intern ("display");
12431 staticpro (&Qleft_margin);
12432 Qspace_width = intern ("space-width");
12433 staticpro (&Qspace_width);
12434 Qheight = intern ("height");
12435 staticpro (&Qheight);
12436 Qraise = intern ("raise");
12437 staticpro (&Qraise);
12438 Qspace = intern ("space");
12439 staticpro (&Qspace);
12440 Qleft_margin = intern ("left-margin");
12441 staticpro (&Qright_margin);
12442 Qright_margin = intern ("right-margin");
12443 Qalign_to = intern ("align-to");
12444 staticpro (&Qalign_to);
12445 QCalign_to = intern (":align-to");
12446 staticpro (&QCalign_to);
12447 Qwidth = intern ("width");
12448 staticpro (&Qwidth);
12449 Qrelative_width = intern ("relative-width");
12450 staticpro (&Qrelative_width);
12451 QCrelative_width = intern (":relative-width");
12452 staticpro (&QCrelative_width);
12453 QCrelative_height = intern (":relative-height");
12454 staticpro (&QCrelative_height);
12455 QCeval = intern (":eval");
12456 staticpro (&QCeval);
12457 QCwhen = intern (":when");
12458 staticpro (&QCwhen);
12459 Qfontified = intern ("fontified");
12460 staticpro (&Qfontified);
12461 Qfontification_functions = intern ("fontification-functions");
12462 staticpro (&Qfontification_functions);
5f5c8ee5
GM
12463 Qtrailing_whitespace = intern ("trailing-whitespace");
12464 staticpro (&Qtrailing_whitespace);
12465 Qimage = intern ("image");
12466 staticpro (&Qimage);
12467
a2889657
JB
12468 staticpro (&last_arrow_position);
12469 staticpro (&last_arrow_string);
12470 last_arrow_position = Qnil;
12471 last_arrow_string = Qnil;
c6e89d6c
GM
12472
12473 echo_buffer[0] = echo_buffer[1] = Qnil;
12474 staticpro (&echo_buffer[0]);
12475 staticpro (&echo_buffer[1]);
12476
12477 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
12478 staticpro (&echo_area_buffer[0]);
12479 staticpro (&echo_area_buffer[1]);
a2889657 12480
8f897821
GM
12481 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
12482 "Non-nil means highlight trailing whitespace.\n\
12483The face used for trailing whitespace is `trailing-whitespace'.");
12484 Vshow_trailing_whitespace = Qnil;
12485
735c094c
KH
12486 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
12487 "Non-nil means don't actually do any redisplay.\n\
12488This is used for internal purposes.");
12489 Vinhibit_redisplay = Qnil;
12490
a2889657 12491 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
8c45d522 12492 "String (or mode line construct) included (normally) in `mode-line-format'.");
a2889657
JB
12493 Vglobal_mode_string = Qnil;
12494
12495 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
12496 "Marker for where to display an arrow on top of the buffer text.\n\
12497This must be the beginning of a line in order to work.\n\
12498See also `overlay-arrow-string'.");
12499 Voverlay_arrow_position = Qnil;
12500
12501 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
12502 "String to display as an arrow. See also `overlay-arrow-position'.");
12503 Voverlay_arrow_string = Qnil;
12504
12505 DEFVAR_INT ("scroll-step", &scroll_step,
12506 "*The number of lines to try scrolling a window by when point moves out.\n\
44fa5b1e
JB
12507If that fails to bring point back on frame, point is centered instead.\n\
12508If this is zero, point is always centered after it moves off frame.");
a2889657 12509
0789adb2
RS
12510 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
12511 "*Scroll up to this many lines, to bring point back on screen.");
12512 scroll_conservatively = 0;
12513
9afd2168
RS
12514 DEFVAR_INT ("scroll-margin", &scroll_margin,
12515 "*Number of lines of margin at the top and bottom of a window.\n\
12516Recenter the window whenever point gets within this many lines\n\
12517of the top or bottom of the window.");
12518 scroll_margin = 0;
12519
5f5c8ee5 12520#if GLYPH_DEBUG
a2889657 12521 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
5f5c8ee5 12522#endif
a2889657
JB
12523
12524 DEFVAR_BOOL ("truncate-partial-width-windows",
12525 &truncate_partial_width_windows,
44fa5b1e 12526 "*Non-nil means truncate lines in all windows less than full frame wide.");
a2889657
JB
12527 truncate_partial_width_windows = 1;
12528
12529 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
12530 "*Non-nil means use inverse video for the mode line.");
12531 mode_line_inverse_video = 1;
aa6d10fa
RS
12532
12533 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
5f5c8ee5 12534 "*Maximum buffer size for which line number should be displayed.\n\
db4f2bfa 12535If the buffer is bigger than this, the line number does not appear\n\
9f027393 12536in the mode line.");
aa6d10fa 12537 line_number_display_limit = 1000000;
fba9ce76 12538
5d121aec
KH
12539 DEFVAR_INT ("line-number-display-limit-width", &line_number_display_limit_width,
12540 "*Maximum line width (in characters) for line number display.\n\
12541If the average length of the lines near point is bigger than this, then the\n\
12542line number may be omitted from the mode line.");
12543 line_number_display_limit_width = 200;
12544
fba9ce76
RS
12545 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
12546 "*Non-nil means highlight region even in nonselected windows.");
293a54ce 12547 highlight_nonselected_windows = 0;
d39b6696
KH
12548
12549 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
3450d04c
KH
12550 "Non-nil if more than one frame is visible on this display.\n\
12551Minibuffer-only frames don't count, but iconified frames do.\n\
4c2eb242
RS
12552This variable is not guaranteed to be accurate except while processing\n\
12553`frame-title-format' and `icon-title-format'.");
d39b6696
KH
12554
12555 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
5f5c8ee5 12556 "Template for displaying the title bar of visible frames.\n\
d39b6696
KH
12557\(Assuming the window manager supports this feature.)\n\
12558This variable has the same structure as `mode-line-format' (which see),\n\
12559and is used only on frames for which no explicit name has been set\n\
12560\(see `modify-frame-parameters').");
12561 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
5f5c8ee5 12562 "Template for displaying the title bar of an iconified frame.\n\
d39b6696
KH
12563\(Assuming the window manager supports this feature.)\n\
12564This variable has the same structure as `mode-line-format' (which see),\n\
12565and is used only on frames for which no explicit name has been set\n\
12566\(see `modify-frame-parameters').");
12567 Vicon_title_format
12568 = Vframe_title_format
12569 = Fcons (intern ("multiple-frames"),
12570 Fcons (build_string ("%b"),
12571 Fcons (Fcons (build_string (""),
12572 Fcons (intern ("invocation-name"),
12573 Fcons (build_string ("@"),
12574 Fcons (intern ("system-name"),
12575 Qnil)))),
12576 Qnil)));
5992c4f7
KH
12577
12578 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
12579 "Maximum number of lines to keep in the message log buffer.\n\
12580If nil, disable message logging. If t, log messages but don't truncate\n\
12581the buffer when it becomes large.");
12582 XSETFASTINT (Vmessage_log_max, 50);
08b610e4
RS
12583
12584 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
12585 "Functions called before redisplay, if window sizes have changed.\n\
12586The value should be a list of functions that take one argument.\n\
12587Just before redisplay, for each frame, if any of its windows have changed\n\
12588size since the last redisplay, or have been split or deleted,\n\
12589all the functions in the list are called, with the frame as argument.");
12590 Vwindow_size_change_functions = Qnil;
75c43375
RS
12591
12592 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
5f5c8ee5 12593 "List of Functions to call before redisplaying a window with scrolling.\n\
75c43375 12594Each function is called with two arguments, the window\n\
8d9583b0
RS
12595and its new display-start position. Note that the value of `window-end'\n\
12596is not valid when these functions are called.");
75c43375 12597 Vwindow_scroll_functions = Qnil;
5f5c8ee5
GM
12598
12599 DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p,
12600 "*Non-nil means automatically resize toolbars.\n\
12601This increases a toolbar's height if not all toolbar items are visible.\n\
12602It decreases a toolbar's height when it would display blank lines\n\
12603otherwise.");
12604 auto_resize_toolbars_p = 1;
12605
12606 DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p,
12607 "*Non-nil means raise toolbar buttons when the mouse moves over them.");
12608 auto_raise_toolbar_buttons_p = 1;
12609
12610 DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin,
12611 "*Margin around toolbar buttons in pixels.");
12612 toolbar_button_margin = 1;
12613
12614 DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief,
12615 "Relief thickness of toolbar buttons.");
12616 toolbar_button_relief = 3;
12617
12618 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
12619 "List of functions to call to fontify regions of text.\n\
12620Each function is called with one argument POS. Functions must\n\
12621fontify a region starting at POS in the current buffer, and give\n\
12622fontified regions the property `fontified'.\n\
12623This variable automatically becomes buffer-local when set.");
12624 Vfontification_functions = Qnil;
12625 Fmake_local_variable (Qfontification_functions);
7bbe686f
AI
12626
12627 DEFVAR_BOOL ("unibyte-display-via-language-environment",
5f5c8ee5
GM
12628 &unibyte_display_via_language_environment,
12629 "*Non-nil means display unibyte text according to language environment.\n\
7bbe686f
AI
12630Specifically this means that unibyte non-ASCII characters\n\
12631are displayed by converting them to the equivalent multibyte characters\n\
12632according to the current language environment. As a result, they are\n\
12633displayed according to the current fontset.");
12634 unibyte_display_via_language_environment = 0;
c6e89d6c
GM
12635
12636 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
12637 "*Maximum height for resizing mini-windows.\n\
12638If a float, it specifies a fraction of the mini-window frame's height.\n\
12639If an integer, it specifies a number of lines.");
12640 Vmax_mini_window_height = make_float (0.25);
a2889657
JB
12641}
12642
5f5c8ee5
GM
12643
12644/* Initialize this module when Emacs starts. */
12645
dfcf069d 12646void
a2889657
JB
12647init_xdisp ()
12648{
12649 Lisp_Object root_window;
5f5c8ee5 12650 struct window *mini_w;
a2889657 12651
5f5c8ee5 12652 CHARPOS (this_line_start_pos) = 0;
a2889657
JB
12653
12654 mini_w = XWINDOW (minibuf_window);
11e82b76 12655 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
a2889657 12656
a2889657
JB
12657 if (!noninteractive)
12658 {
5f5c8ee5
GM
12659 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
12660 int i;
12661
12662 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
12c226c5 12663 set_window_height (root_window,
5f5c8ee5 12664 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
12c226c5 12665 0);
c2213350 12666 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
a2889657
JB
12667 set_window_height (minibuf_window, 1, 0);
12668
c2213350
KH
12669 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
12670 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
5f5c8ee5
GM
12671
12672 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
12673 scratch_glyph_row.glyphs[TEXT_AREA + 1]
12674 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
12675
12676 /* The default ellipsis glyphs `...'. */
12677 for (i = 0; i < 3; ++i)
12678 XSETFASTINT (default_invis_vector[i], '.');
a2889657 12679 }
5f5c8ee5
GM
12680
12681#ifdef HAVE_WINDOW_SYSTEM
12682 {
12683 /* Allocate the buffer for frame titles. */
12684 int size = 100;
12685 frame_title_buf = (char *) xmalloc (size);
12686 frame_title_buf_end = frame_title_buf + size;
12687 frame_title_ptr = NULL;
12688 }
12689#endif /* HAVE_WINDOW_SYSTEM */
a2889657 12690}
5f5c8ee5
GM
12691
12692