(Fset_window_point): Reset Vresize_mini_config.
[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/* Nonzero if window sizes or contents have changed since last
431 redisplay that finished */
432
a2889657
JB
433int windows_or_buffers_changed;
434
5f5c8ee5
GM
435/* Nonzero after display_mode_line if %l was used and it displayed a
436 line number. */
437
aa6d10fa
RS
438int line_number_displayed;
439
440/* Maximum buffer size for which to display line numbers. */
5f5c8ee5 441
14510fee 442static int line_number_display_limit;
5992c4f7 443
5d121aec
KH
444/* line width to consider when repostioning for line number display */
445
446static int line_number_display_limit_width;
447
5f5c8ee5
GM
448/* Number of lines to keep in the message log buffer. t means
449 infinite. nil means don't log at all. */
450
5992c4f7 451Lisp_Object Vmessage_log_max;
d45de95b 452
c6e89d6c
GM
453/* Current, index 0, and last displayed echo area message. Either
454 buffers from echo_buffers, or nil to indicate no message. */
455
456Lisp_Object echo_area_buffer[2];
457
458/* The buffers referenced from echo_area_buffer. */
459
460static Lisp_Object echo_buffer[2];
461
462/* A vector saved used in with_area_buffer to reduce consing. */
463
464static Lisp_Object Vwith_echo_area_save_vector;
465
466/* Non-zero means display_echo_area should display the last echo area
467 message again. Set by redisplay_preserve_echo_area. */
468
469static int display_last_displayed_message_p;
470
471/* Nonzero if echo area is being used by print; zero if being used by
472 message. */
473
474int message_buf_print;
475
9142dd5b
GM
476/* Maximum height for resizing mini-windows. Either a float
477 specifying a fraction of the available height, or an integer
478 specifying a number of lines. */
c6e89d6c
GM
479
480static Lisp_Object Vmax_mini_window_height;
481
9142dd5b
GM
482/* Window configuration saved in resize_mini_window. */
483
484static Lisp_Object Vresize_mini_config;
485
5f5c8ee5
GM
486/* A scratch glyph row with contents used for generating truncation
487 glyphs. Also used in direct_output_for_insert. */
12adba34 488
5f5c8ee5
GM
489#define MAX_SCRATCH_GLYPHS 100
490struct glyph_row scratch_glyph_row;
491static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
1adc55de 492
5f5c8ee5
GM
493/* Ascent and height of the last line processed by move_it_to. */
494
495static int last_max_ascent, last_height;
496
497/* The maximum distance to look ahead for text properties. Values
498 that are too small let us call compute_char_face and similar
499 functions too often which is expensive. Values that are too large
500 let us call compute_char_face and alike too often because we
501 might not be interested in text properties that far away. */
502
503#define TEXT_PROP_DISTANCE_LIMIT 100
504
505/* Non-zero means print traces of redisplay if compiled with
506 GLYPH_DEBUG != 0. */
507
508#if GLYPH_DEBUG
509int trace_redisplay_p;
510#endif
511
512/* Value returned from text property handlers (see below). */
513
514enum prop_handled
3c6595e0 515{
5f5c8ee5
GM
516 HANDLED_NORMALLY,
517 HANDLED_RECOMPUTE_PROPS,
518 HANDLED_OVERLAY_STRING_CONSUMED,
519 HANDLED_RETURN
520};
3c6595e0 521
5f5c8ee5
GM
522/* A description of text properties that redisplay is interested
523 in. */
3c6595e0 524
5f5c8ee5
GM
525struct props
526{
527 /* The name of the property. */
528 Lisp_Object *name;
90adcf20 529
5f5c8ee5
GM
530 /* A unique index for the property. */
531 enum prop_idx idx;
532
533 /* A handler function called to set up iterator IT from the property
534 at IT's current position. Value is used to steer handle_stop. */
535 enum prop_handled (*handler) P_ ((struct it *it));
536};
537
538static enum prop_handled handle_face_prop P_ ((struct it *));
539static enum prop_handled handle_invisible_prop P_ ((struct it *));
540static enum prop_handled handle_display_prop P_ ((struct it *));
541static enum prop_handled handle_overlay_change P_ ((struct it *));
542static enum prop_handled handle_fontified_prop P_ ((struct it *));
543
544/* Properties handled by iterators. */
545
546static struct props it_props[] =
5992c4f7 547{
5f5c8ee5
GM
548 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
549 /* Handle `face' before `display' because some sub-properties of
550 `display' need to know the face. */
551 {&Qface, FACE_PROP_IDX, handle_face_prop},
552 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
553 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
554 {NULL, 0, NULL}
555};
5992c4f7 556
5f5c8ee5
GM
557/* Value is the position described by X. If X is a marker, value is
558 the marker_position of X. Otherwise, value is X. */
12adba34 559
5f5c8ee5 560#define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
12adba34 561
5f5c8ee5 562/* Enumeration returned by some move_it_.* functions internally. */
12adba34 563
5f5c8ee5
GM
564enum move_it_result
565{
566 /* Not used. Undefined value. */
567 MOVE_UNDEFINED,
bab29e15 568
5f5c8ee5
GM
569 /* Move ended at the requested buffer position or ZV. */
570 MOVE_POS_MATCH_OR_ZV,
bab29e15 571
5f5c8ee5
GM
572 /* Move ended at the requested X pixel position. */
573 MOVE_X_REACHED,
12adba34 574
5f5c8ee5
GM
575 /* Move within a line ended at the end of a line that must be
576 continued. */
577 MOVE_LINE_CONTINUED,
578
579 /* Move within a line ended at the end of a line that would
580 be displayed truncated. */
581 MOVE_LINE_TRUNCATED,
ff6c30e5 582
5f5c8ee5
GM
583 /* Move within a line ended at a line end. */
584 MOVE_NEWLINE_OR_CR
585};
12adba34 586
ff6c30e5 587
5f5c8ee5
GM
588\f
589/* Function prototypes. */
590
c6e89d6c
GM
591static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
592static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
593static int resize_mini_window P_ ((struct window *));
594static void clear_garbaged_frames P_ ((void));
595static int current_message_1 P_ ((Lisp_Object *));
596static int truncate_message_1 P_ ((int));
597static int set_message_1 P_ ((char *s, Lisp_Object, int, int));
598static int display_echo_area P_ ((struct window *));
599static int display_echo_area_1 P_ ((struct window *));
28514cd9 600static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
4fdb80f2 601static int string_char_and_length P_ ((unsigned char *, int, int *));
5f5c8ee5
GM
602static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
603 struct text_pos));
604static int compute_window_start_on_continuation_line P_ ((struct window *));
605static Lisp_Object eval_handler P_ ((Lisp_Object));
606static Lisp_Object eval_form P_ ((Lisp_Object));
607static void insert_left_trunc_glyphs P_ ((struct it *));
608static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
609static void extend_face_to_end_of_line P_ ((struct it *));
610static void append_space P_ ((struct it *, int));
611static void make_cursor_line_fully_visible P_ ((struct window *));
612static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
613static int trailing_whitespace_p P_ ((int));
614static int message_log_check_duplicate P_ ((int, int, int, int));
615int invisible_p P_ ((Lisp_Object, Lisp_Object));
616int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
617static void push_it P_ ((struct it *));
618static void pop_it P_ ((struct it *));
619static void sync_frame_with_window_matrix_rows P_ ((struct window *));
620static void redisplay_internal P_ ((int));
c6e89d6c 621static int echo_area_display P_ ((int));
5f5c8ee5
GM
622static void redisplay_windows P_ ((Lisp_Object));
623static void redisplay_window P_ ((Lisp_Object, int));
624static void update_menu_bar P_ ((struct frame *, int));
625static int try_window_reusing_current_matrix P_ ((struct window *));
626static int try_window_id P_ ((struct window *));
627static int display_line P_ ((struct it *));
628static void display_mode_lines P_ ((struct window *));
629static void display_mode_line P_ ((struct window *, enum face_id,
630 Lisp_Object));
631static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
632static char *decode_mode_spec P_ ((struct window *, char, int, int));
633static void display_menu_bar P_ ((struct window *));
634static int display_count_lines P_ ((int, int, int, int, int *));
635static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
636 int, int, struct it *, int, int, int, int));
637static void compute_line_metrics P_ ((struct it *));
638static void run_redisplay_end_trigger_hook P_ ((struct it *));
639static int get_overlay_strings P_ ((struct it *));
640static void next_overlay_string P_ ((struct it *));
641void set_iterator_to_next P_ ((struct it *));
642static void reseat P_ ((struct it *, struct text_pos, int));
643static void reseat_1 P_ ((struct it *, struct text_pos, int));
644static void back_to_previous_visible_line_start P_ ((struct it *));
645static void reseat_at_previous_visible_line_start P_ ((struct it *));
312246d1 646static void reseat_at_next_visible_line_start P_ ((struct it *, int));
5f5c8ee5
GM
647static int next_element_from_display_vector P_ ((struct it *));
648static int next_element_from_string P_ ((struct it *));
649static int next_element_from_c_string P_ ((struct it *));
650static int next_element_from_buffer P_ ((struct it *));
651static int next_element_from_image P_ ((struct it *));
652static int next_element_from_stretch P_ ((struct it *));
653static void load_overlay_strings P_ ((struct it *));
654static void init_from_display_pos P_ ((struct it *, struct window *,
655 struct display_pos *));
656static void reseat_to_string P_ ((struct it *, unsigned char *,
657 Lisp_Object, int, int, int, int));
658static int charset_at_position P_ ((struct text_pos));
659static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
660 int, int, int));
661void move_it_vertically_backward P_ ((struct it *, int));
662static void init_to_row_start P_ ((struct it *, struct window *,
663 struct glyph_row *));
664static void init_to_row_end P_ ((struct it *, struct window *,
665 struct glyph_row *));
666static void back_to_previous_line_start P_ ((struct it *));
667static void forward_to_next_line_start P_ ((struct it *));
668static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
669 Lisp_Object, int));
670static struct text_pos string_pos P_ ((int, Lisp_Object));
671static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
672static int number_of_chars P_ ((unsigned char *, int));
673static void compute_stop_pos P_ ((struct it *));
674static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
675 Lisp_Object));
676static int face_before_or_after_it_pos P_ ((struct it *, int));
677static int next_overlay_change P_ ((int));
678static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
679 Lisp_Object, struct text_pos *));
680
681#define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
682#define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
ff6c30e5 683
5f5c8ee5 684#ifdef HAVE_WINDOW_SYSTEM
12adba34 685
5f5c8ee5
GM
686static void update_toolbar P_ ((struct frame *, int));
687static void build_desired_toolbar_string P_ ((struct frame *f));
688static int redisplay_toolbar P_ ((struct frame *));
689static void display_toolbar_line P_ ((struct it *));
12adba34 690
5f5c8ee5 691#endif /* HAVE_WINDOW_SYSTEM */
12adba34 692
5f5c8ee5
GM
693\f
694/***********************************************************************
695 Window display dimensions
696 ***********************************************************************/
12adba34 697
5f5c8ee5
GM
698/* Return the window-relative maximum y + 1 for glyph rows displaying
699 text in window W. This is the height of W minus the height of a
700 mode line, if any. */
701
702INLINE int
703window_text_bottom_y (w)
704 struct window *w;
705{
706 struct frame *f = XFRAME (w->frame);
707 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
708
709 if (WINDOW_WANTS_MODELINE_P (w))
710 height -= CURRENT_MODE_LINE_HEIGHT (w);
711 return height;
f88eb0b6
KH
712}
713
f82aff7c 714
5f5c8ee5
GM
715/* Return the pixel width of display area AREA of window W. AREA < 0
716 means return the total width of W, not including bitmap areas to
717 the left and right of the window. */
ff6c30e5 718
5f5c8ee5
GM
719INLINE int
720window_box_width (w, area)
721 struct window *w;
722 int area;
723{
724 struct frame *f = XFRAME (w->frame);
725 int width = XFASTINT (w->width);
726
727 if (!w->pseudo_window_p)
ff6c30e5 728 {
5f5c8ee5
GM
729 width -= FRAME_SCROLL_BAR_WIDTH (f) + 2 * FRAME_FLAGS_AREA_COLS (f);
730
731 if (area == TEXT_AREA)
732 {
733 if (INTEGERP (w->left_margin_width))
734 width -= XFASTINT (w->left_margin_width);
735 if (INTEGERP (w->right_margin_width))
736 width -= XFASTINT (w->right_margin_width);
737 }
738 else if (area == LEFT_MARGIN_AREA)
739 width = (INTEGERP (w->left_margin_width)
740 ? XFASTINT (w->left_margin_width) : 0);
741 else if (area == RIGHT_MARGIN_AREA)
742 width = (INTEGERP (w->right_margin_width)
743 ? XFASTINT (w->right_margin_width) : 0);
ff6c30e5 744 }
5f5c8ee5
GM
745
746 return width * CANON_X_UNIT (f);
ff6c30e5 747}
1adc55de 748
1adc55de 749
5f5c8ee5
GM
750/* Return the pixel height of the display area of window W, not
751 including mode lines of W, if any.. */
f88eb0b6 752
5f5c8ee5
GM
753INLINE int
754window_box_height (w)
755 struct window *w;
f88eb0b6 756{
5f5c8ee5
GM
757 struct frame *f = XFRAME (w->frame);
758 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
759
760 if (WINDOW_WANTS_MODELINE_P (w))
761 height -= CURRENT_MODE_LINE_HEIGHT (w);
762
763 if (WINDOW_WANTS_TOP_LINE_P (w))
764 height -= CURRENT_TOP_LINE_HEIGHT (w);
765
766 return height;
5992c4f7
KH
767}
768
769
5f5c8ee5
GM
770/* Return the frame-relative coordinate of the left edge of display
771 area AREA of window W. AREA < 0 means return the left edge of the
772 whole window, to the right of any bitmap area at the left side of
773 W. */
5992c4f7 774
5f5c8ee5
GM
775INLINE int
776window_box_left (w, area)
777 struct window *w;
778 int area;
90adcf20 779{
5f5c8ee5
GM
780 struct frame *f = XFRAME (w->frame);
781 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
a3788d53 782
5f5c8ee5 783 if (!w->pseudo_window_p)
90adcf20 784 {
5f5c8ee5
GM
785 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
786 + FRAME_FLAGS_AREA_WIDTH (f));
787
788 if (area == TEXT_AREA)
789 x += window_box_width (w, LEFT_MARGIN_AREA);
790 else if (area == RIGHT_MARGIN_AREA)
791 x += (window_box_width (w, LEFT_MARGIN_AREA)
792 + window_box_width (w, TEXT_AREA));
90adcf20 793 }
73af359d 794
5f5c8ee5
GM
795 return x;
796}
90adcf20 797
b6436d4e 798
5f5c8ee5
GM
799/* Return the frame-relative coordinate of the right edge of display
800 area AREA of window W. AREA < 0 means return the left edge of the
801 whole window, to the left of any bitmap area at the right side of
802 W. */
ded34426 803
5f5c8ee5
GM
804INLINE int
805window_box_right (w, area)
806 struct window *w;
807 int area;
808{
809 return window_box_left (w, area) + window_box_width (w, area);
810}
811
812
813/* Get the bounding box of the display area AREA of window W, without
814 mode lines, in frame-relative coordinates. AREA < 0 means the
815 whole window, not including bitmap areas to the left and right of
816 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
817 coordinates of the upper-left corner of the box. Return in
818 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
819
820INLINE void
821window_box (w, area, box_x, box_y, box_width, box_height)
822 struct window *w;
823 int area;
824 int *box_x, *box_y, *box_width, *box_height;
825{
826 struct frame *f = XFRAME (w->frame);
827
828 *box_width = window_box_width (w, area);
829 *box_height = window_box_height (w);
830 *box_x = window_box_left (w, area);
831 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
832 + XFASTINT (w->top) * CANON_Y_UNIT (f));
833 if (WINDOW_WANTS_TOP_LINE_P (w))
834 *box_y += CURRENT_TOP_LINE_HEIGHT (w);
ded34426 835}
1adc55de 836
1adc55de 837
5f5c8ee5
GM
838/* Get the bounding box of the display area AREA of window W, without
839 mode lines. AREA < 0 means the whole window, not including bitmap
840 areas to the left and right of the window. Return in *TOP_LEFT_X
841 and TOP_LEFT_Y the frame-relative pixel coordinates of the
842 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
843 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
844 box. */
ded34426 845
5f5c8ee5
GM
846INLINE void
847window_box_edges (w, area, top_left_x, top_left_y,
848 bottom_right_x, bottom_right_y)
849 struct window *w;
850 int area;
851 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
48ae5f0a 852{
5f5c8ee5
GM
853 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
854 bottom_right_y);
855 *bottom_right_x += *top_left_x;
856 *bottom_right_y += *top_left_y;
48ae5f0a
KH
857}
858
5f5c8ee5
GM
859
860\f
861/***********************************************************************
862 Utilities
863 ***********************************************************************/
864
4fdb80f2
GM
865/* Return the next character from STR which is MAXLEN bytes long.
866 Return in *LEN the length of the character. This is like
867 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
868 we find one, we return a `?', but with the length of the illegal
869 character. */
870
871static INLINE int
7a5b8a93 872string_char_and_length (str, maxlen, len)
4fdb80f2 873 unsigned char *str;
7a5b8a93 874 int maxlen, *len;
4fdb80f2
GM
875{
876 int c;
877
878 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
879 if (!CHAR_VALID_P (c, 1))
880 /* We may not change the length here because other places in Emacs
881 don't use this function, i.e. they silently accept illegal
882 characters. */
883 c = '?';
884
885 return c;
886}
887
888
889
5f5c8ee5
GM
890/* Given a position POS containing a valid character and byte position
891 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
892
893static struct text_pos
894string_pos_nchars_ahead (pos, string, nchars)
895 struct text_pos pos;
896 Lisp_Object string;
897 int nchars;
0b1005ef 898{
5f5c8ee5
GM
899 xassert (STRINGP (string) && nchars >= 0);
900
901 if (STRING_MULTIBYTE (string))
902 {
903 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
904 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
905 int len;
906
907 while (nchars--)
908 {
4fdb80f2 909 string_char_and_length (p, rest, &len);
5f5c8ee5
GM
910 p += len, rest -= len;
911 xassert (rest >= 0);
912 CHARPOS (pos) += 1;
913 BYTEPOS (pos) += len;
914 }
915 }
916 else
917 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
918
919 return pos;
0a9dc68b
RS
920}
921
0a9dc68b 922
5f5c8ee5
GM
923/* Value is the text position, i.e. character and byte position,
924 for character position CHARPOS in STRING. */
925
926static INLINE struct text_pos
927string_pos (charpos, string)
928 int charpos;
0a9dc68b 929 Lisp_Object string;
0a9dc68b 930{
5f5c8ee5
GM
931 struct text_pos pos;
932 xassert (STRINGP (string));
933 xassert (charpos >= 0);
934 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
935 return pos;
936}
937
938
939/* Value is a text position, i.e. character and byte position, for
940 character position CHARPOS in C string S. MULTIBYTE_P non-zero
941 means recognize multibyte characters. */
942
943static struct text_pos
944c_string_pos (charpos, s, multibyte_p)
945 int charpos;
946 unsigned char *s;
947 int multibyte_p;
948{
949 struct text_pos pos;
950
951 xassert (s != NULL);
952 xassert (charpos >= 0);
953
954 if (multibyte_p)
0a9dc68b 955 {
5f5c8ee5
GM
956 int rest = strlen (s), len;
957
958 SET_TEXT_POS (pos, 0, 0);
959 while (charpos--)
0a9dc68b 960 {
4fdb80f2 961 string_char_and_length (s, rest, &len);
5f5c8ee5
GM
962 s += len, rest -= len;
963 xassert (rest >= 0);
964 CHARPOS (pos) += 1;
965 BYTEPOS (pos) += len;
0a9dc68b
RS
966 }
967 }
5f5c8ee5
GM
968 else
969 SET_TEXT_POS (pos, charpos, charpos);
0a9dc68b 970
5f5c8ee5
GM
971 return pos;
972}
0a9dc68b 973
0a9dc68b 974
5f5c8ee5
GM
975/* Value is the number of characters in C string S. MULTIBYTE_P
976 non-zero means recognize multibyte characters. */
0a9dc68b 977
5f5c8ee5
GM
978static int
979number_of_chars (s, multibyte_p)
980 unsigned char *s;
981 int multibyte_p;
982{
983 int nchars;
984
985 if (multibyte_p)
986 {
987 int rest = strlen (s), len;
988 unsigned char *p = (unsigned char *) s;
0a9dc68b 989
5f5c8ee5
GM
990 for (nchars = 0; rest > 0; ++nchars)
991 {
4fdb80f2 992 string_char_and_length (p, rest, &len);
5f5c8ee5 993 rest -= len, p += len;
0a9dc68b
RS
994 }
995 }
5f5c8ee5
GM
996 else
997 nchars = strlen (s);
998
999 return nchars;
0b1005ef
KH
1000}
1001
5f5c8ee5
GM
1002
1003/* Compute byte position NEWPOS->bytepos corresponding to
1004 NEWPOS->charpos. POS is a known position in string STRING.
1005 NEWPOS->charpos must be >= POS.charpos. */
76412d64 1006
5f5c8ee5
GM
1007static void
1008compute_string_pos (newpos, pos, string)
1009 struct text_pos *newpos, pos;
1010 Lisp_Object string;
76412d64 1011{
5f5c8ee5
GM
1012 xassert (STRINGP (string));
1013 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1014
1015 if (STRING_MULTIBYTE (string))
1016 *newpos = string_pos_nchars_ahead (pos, CHARPOS (*newpos) - CHARPOS (pos),
1017 string);
1018 else
1019 BYTEPOS (*newpos) = CHARPOS (*newpos);
76412d64
RS
1020}
1021
9c74a0dd 1022
5f5c8ee5
GM
1023/* Return the charset of the character at position POS in
1024 current_buffer. */
1adc55de 1025
5f5c8ee5
GM
1026static int
1027charset_at_position (pos)
1028 struct text_pos pos;
a2889657 1029{
5f5c8ee5
GM
1030 int c, multibyte_p;
1031 unsigned char *p = BYTE_POS_ADDR (BYTEPOS (pos));
1032
1033 multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1034 if (multibyte_p)
a2889657 1035 {
5f5c8ee5
GM
1036 int maxlen = ((BYTEPOS (pos) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
1037 - BYTEPOS (pos));
1038 int len;
4fdb80f2 1039 c = string_char_and_length (p, maxlen, &len);
a2889657 1040 }
5f5c8ee5
GM
1041 else
1042 c = *p;
1043
1044 return CHAR_CHARSET (c);
1045}
1046
1047
1048\f
1049/***********************************************************************
1050 Lisp form evaluation
1051 ***********************************************************************/
1052
1053/* Error handler for eval_form. */
1054
1055static Lisp_Object
1056eval_handler (arg)
1057 Lisp_Object arg;
1058{
1059 return Qnil;
1060}
1061
1062
1063/* Evaluate SEXPR and return the result, or nil if something went
1064 wrong. */
1065
1066static Lisp_Object
1067eval_form (sexpr)
1068 Lisp_Object sexpr;
1069{
1070 int count = specpdl_ptr - specpdl;
1071 Lisp_Object val;
1072 specbind (Qinhibit_redisplay, Qt);
1073 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1074 return unbind_to (count, val);
1075}
1076
1077
1078\f
1079/***********************************************************************
1080 Debugging
1081 ***********************************************************************/
1082
1083#if 0
1084
1085/* Define CHECK_IT to perform sanity checks on iterators.
1086 This is for debugging. It is too slow to do unconditionally. */
1087
1088static void
1089check_it (it)
1090 struct it *it;
1091{
1092 if (it->method == next_element_from_string)
a2889657 1093 {
5f5c8ee5
GM
1094 xassert (STRINGP (it->string));
1095 xassert (IT_STRING_CHARPOS (*it) >= 0);
1096 }
1097 else if (it->method == next_element_from_buffer)
1098 {
1099 /* Check that character and byte positions agree. */
1100 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1101 }
73af359d 1102
5f5c8ee5
GM
1103 if (it->dpvec)
1104 xassert (it->current.dpvec_index >= 0);
1105 else
1106 xassert (it->current.dpvec_index < 0);
1107}
1f40cad2 1108
5f5c8ee5
GM
1109#define CHECK_IT(IT) check_it ((IT))
1110
1111#else /* not 0 */
1112
1113#define CHECK_IT(IT) (void) 0
1114
1115#endif /* not 0 */
1116
1117
1118#if GLYPH_DEBUG
1119
1120/* Check that the window end of window W is what we expect it
1121 to be---the last row in the current matrix displaying text. */
1122
1123static void
1124check_window_end (w)
1125 struct window *w;
1126{
1127 if (!MINI_WINDOW_P (w)
1128 && !NILP (w->window_end_valid))
1129 {
1130 struct glyph_row *row;
1131 xassert ((row = MATRIX_ROW (w->current_matrix,
1132 XFASTINT (w->window_end_vpos)),
1133 !row->enabled_p
1134 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1135 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1136 }
1137}
1138
1139#define CHECK_WINDOW_END(W) check_window_end ((W))
1140
1141#else /* not GLYPH_DEBUG */
1142
1143#define CHECK_WINDOW_END(W) (void) 0
1144
1145#endif /* not GLYPH_DEBUG */
1146
1147
1148\f
1149/***********************************************************************
1150 Iterator initialization
1151 ***********************************************************************/
1152
1153/* Initialize IT for displaying current_buffer in window W, starting
1154 at character position CHARPOS. CHARPOS < 0 means that no buffer
1155 position is specified which is useful when the iterator is assigned
1156 a position later. BYTEPOS is the byte position corresponding to
1157 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1158
1159 If ROW is not null, calls to produce_glyphs with IT as parameter
1160 will produce glyphs in that row.
1161
1162 BASE_FACE_ID is the id of a base face to use. It must be one of
1163 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1164 TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
1165 displaying the toolbar.
1166
1167 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1168 TOP_LINE_FACE_ID, the iterator will be initialized to use the
1169 corresponding mode line glyph row of the desired matrix of W. */
1170
1171void
1172init_iterator (it, w, charpos, bytepos, row, base_face_id)
1173 struct it *it;
1174 struct window *w;
1175 int charpos, bytepos;
1176 struct glyph_row *row;
1177 enum face_id base_face_id;
1178{
1179 int highlight_region_p;
5f5c8ee5
GM
1180
1181 /* Some precondition checks. */
1182 xassert (w != NULL && it != NULL);
5f5c8ee5
GM
1183 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1184
1185 /* If face attributes have been changed since the last redisplay,
1186 free realized faces now because they depend on face definitions
1187 that might have changed. */
1188 if (face_change_count)
1189 {
1190 face_change_count = 0;
1191 free_all_realized_faces (Qnil);
1192 }
1193
1194 /* Use one of the mode line rows of W's desired matrix if
1195 appropriate. */
1196 if (row == NULL)
1197 {
1198 if (base_face_id == MODE_LINE_FACE_ID)
1199 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1200 else if (base_face_id == TOP_LINE_FACE_ID)
1201 row = MATRIX_TOP_LINE_ROW (w->desired_matrix);
1202 }
1203
1204 /* Clear IT. */
1205 bzero (it, sizeof *it);
1206 it->current.overlay_string_index = -1;
1207 it->current.dpvec_index = -1;
1208 it->charset = CHARSET_ASCII;
1209 it->base_face_id = base_face_id;
1210
1211 /* The window in which we iterate over current_buffer: */
1212 XSETWINDOW (it->window, w);
1213 it->w = w;
1214 it->f = XFRAME (w->frame);
1215
1216 /* If realized faces have been removed, e.g. because of face
1217 attribute changes of named faces, recompute them. */
1218 if (FRAME_FACE_CACHE (it->f)->used == 0)
1219 recompute_basic_faces (it->f);
1220
5f5c8ee5
GM
1221 /* Current value of the `space-width', and 'height' properties. */
1222 it->space_width = Qnil;
1223 it->font_height = Qnil;
1224
1225 /* Are control characters displayed as `^C'? */
1226 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1227
1228 /* -1 means everything between a CR and the following line end
1229 is invisible. >0 means lines indented more than this value are
1230 invisible. */
1231 it->selective = (INTEGERP (current_buffer->selective_display)
1232 ? XFASTINT (current_buffer->selective_display)
1233 : (!NILP (current_buffer->selective_display)
1234 ? -1 : 0));
1235 it->selective_display_ellipsis_p
1236 = !NILP (current_buffer->selective_display_ellipses);
1237
1238 /* Display table to use. */
1239 it->dp = window_display_table (w);
1240
1241 /* Are multibyte characters enabled in current_buffer? */
1242 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1243
1244 /* Non-zero if we should highlight the region. */
1245 highlight_region_p
1246 = (!NILP (Vtransient_mark_mode)
1247 && !NILP (current_buffer->mark_active)
1248 && XMARKER (current_buffer->mark)->buffer != 0);
1249
1250 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1251 start and end of a visible region in window IT->w. Set both to
1252 -1 to indicate no region. */
1253 if (highlight_region_p
1254 /* Maybe highlight only in selected window. */
1255 && (/* Either show region everywhere. */
1256 highlight_nonselected_windows
1257 /* Or show region in the selected window. */
1258 || w == XWINDOW (selected_window)
1259 /* Or show the region if we are in the mini-buffer and W is
1260 the window the mini-buffer refers to. */
1261 || (MINI_WINDOW_P (XWINDOW (selected_window))
1262 && w == XWINDOW (Vminibuf_scroll_window))))
1263 {
1264 int charpos = marker_position (current_buffer->mark);
1265 it->region_beg_charpos = min (PT, charpos);
1266 it->region_end_charpos = max (PT, charpos);
1267 }
1268 else
1269 it->region_beg_charpos = it->region_end_charpos = -1;
1270
1271 /* Get the position at which the redisplay_end_trigger hook should
1272 be run, if it is to be run at all. */
1273 if (MARKERP (w->redisplay_end_trigger)
1274 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1275 it->redisplay_end_trigger_charpos
1276 = marker_position (w->redisplay_end_trigger);
1277 else if (INTEGERP (w->redisplay_end_trigger))
1278 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1279
1280 /* Correct bogus values of tab_width. */
1281 it->tab_width = XINT (current_buffer->tab_width);
1282 if (it->tab_width <= 0 || it->tab_width > 1000)
1283 it->tab_width = 8;
1284
1285 /* Are lines in the display truncated? */
1286 it->truncate_lines_p
1287 = (base_face_id != DEFAULT_FACE_ID
1288 || XINT (it->w->hscroll)
1289 || (truncate_partial_width_windows
1290 && !WINDOW_FULL_WIDTH_P (it->w))
1291 || !NILP (current_buffer->truncate_lines));
1292
1293 /* Get dimensions of truncation and continuation glyphs. These are
1294 displayed as bitmaps under X, so we don't need them for such
1295 frames. */
1296 if (!FRAME_WINDOW_P (it->f))
1297 {
1298 if (it->truncate_lines_p)
1299 {
1300 /* We will need the truncation glyph. */
1301 xassert (it->glyph_row == NULL);
1302 produce_special_glyphs (it, IT_TRUNCATION);
1303 it->truncation_pixel_width = it->pixel_width;
1304 }
1305 else
1306 {
1307 /* We will need the continuation glyph. */
1308 xassert (it->glyph_row == NULL);
1309 produce_special_glyphs (it, IT_CONTINUATION);
1310 it->continuation_pixel_width = it->pixel_width;
1311 }
1312
1313 /* Reset these values to zero becaue the produce_special_glyphs
1314 above has changed them. */
1315 it->pixel_width = it->ascent = it->descent = 0;
312246d1 1316 it->phys_ascent = it->phys_descent = 0;
5f5c8ee5
GM
1317 }
1318
1319 /* Set this after getting the dimensions of truncation and
1320 continuation glyphs, so that we don't produce glyphs when calling
1321 produce_special_glyphs, above. */
1322 it->glyph_row = row;
1323 it->area = TEXT_AREA;
1324
1325 /* Get the dimensions of the display area. The display area
1326 consists of the visible window area plus a horizontally scrolled
1327 part to the left of the window. All x-values are relative to the
1328 start of this total display area. */
1329 if (base_face_id != DEFAULT_FACE_ID)
1330 {
1331 /* Mode lines, menu bar in terminal frames. */
1332 it->first_visible_x = 0;
1333 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1334 }
1335 else
1336 {
1337 it->first_visible_x
1338 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1339 it->last_visible_x = (it->first_visible_x
1340 + window_box_width (w, TEXT_AREA));
1341
1342 /* If we truncate lines, leave room for the truncator glyph(s) at
1343 the right margin. Otherwise, leave room for the continuation
1344 glyph(s). Truncation and continuation glyphs are not inserted
1345 for window-based redisplay. */
1346 if (!FRAME_WINDOW_P (it->f))
1347 {
1348 if (it->truncate_lines_p)
1349 it->last_visible_x -= it->truncation_pixel_width;
1350 else
1351 it->last_visible_x -= it->continuation_pixel_width;
1352 }
1353
1354 it->top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
1355 it->current_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w) + w->vscroll;
1356 }
1357
1358 /* Leave room for a border glyph. */
1359 if (!FRAME_WINDOW_P (it->f)
1360 && !WINDOW_RIGHTMOST_P (it->w))
1361 it->last_visible_x -= 1;
1362
1363 it->last_visible_y = window_text_bottom_y (w);
1364
1365 /* For mode lines and alike, arrange for the first glyph having a
1366 left box line if the face specifies a box. */
1367 if (base_face_id != DEFAULT_FACE_ID)
1368 {
1369 struct face *face;
1370
1371 it->face_id = base_face_id;
1372
1373 /* If we have a boxed mode line, make the first character appear
1374 with a left box line. */
1375 face = FACE_FROM_ID (it->f, base_face_id);
1376 if (face->box != FACE_NO_BOX)
1377 it->start_of_box_run_p = 1;
1378 }
1379
1380 /* If a buffer position was specified, set the iterator there,
1381 getting overlays and face properties from that position. */
1382 if (charpos > 0)
1383 {
1384 it->end_charpos = ZV;
1385 it->face_id = -1;
1386 IT_CHARPOS (*it) = charpos;
1387
1388 /* Compute byte position if not specified. */
1389 if (bytepos <= 0)
1390 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1391 else
1392 IT_BYTEPOS (*it) = bytepos;
1393
1394 /* Compute faces etc. */
1395 reseat (it, it->current.pos, 1);
1396 }
1397
1398 CHECK_IT (it);
1399}
1400
1401
1402/* Initialize IT for the display of window W with window start POS. */
1403
1404void
1405start_display (it, w, pos)
1406 struct it *it;
1407 struct window *w;
1408 struct text_pos pos;
1409{
1410 int start_at_line_beg_p;
1411 struct glyph_row *row;
1412 int first_vpos = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
1413 int first_y;
1414
1415 row = w->desired_matrix->rows + first_vpos;
1416 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1417 first_y = it->current_y;
1418
1419 /* If window start is not at a line start, move back to the line
1420 start. This makes sure that we take continuation lines into
1421 account. */
1422 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1423 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1424 if (!start_at_line_beg_p)
1425 reseat_at_previous_visible_line_start (it);
1426
5f5c8ee5
GM
1427 /* If window start is not at a line start, skip forward to POS to
1428 get the correct continuation_lines_width and current_x. */
1429 if (!start_at_line_beg_p)
1430 {
1431 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1432
1433 /* If lines are continued, this line may end in the middle of a
1434 multi-glyph character (e.g. a control character displayed as
1435 \003, or in the middle of an overlay string). In this case
1436 move_it_to above will not have taken us to the start of
1437 the continuation line but to the end of the continued line. */
1438 if (!it->truncate_lines_p && it->current_x > 0)
1439 {
1440 if (it->current.dpvec_index >= 0
1441 || it->current.overlay_string_index >= 0)
1442 {
1443 set_iterator_to_next (it);
1444 move_it_in_display_line_to (it, -1, -1, 0);
1445 }
1446 it->continuation_lines_width += it->current_x;
1447 }
1448
1449 it->current_y = first_y;
1450 it->vpos = 0;
1451 it->current_x = it->hpos = 0;
1452 }
1453
1454#if 0 /* Don't assert the following because start_display is sometimes
1455 called intentionally with a window start that is not at a
1456 line start. Please leave this code in as a comment. */
1457
1458 /* Window start should be on a line start, now. */
1459 xassert (it->continuation_lines_width
1460 || IT_CHARPOS (it) == BEGV
1461 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1462#endif /* 0 */
1463}
1464
1465
1466/* Initialize IT for stepping through current_buffer in window W,
1467 starting at position POS that includes overlay string and display
1468 vector/ control character translation position information. */
1469
1470static void
1471init_from_display_pos (it, w, pos)
1472 struct it *it;
1473 struct window *w;
1474 struct display_pos *pos;
1475{
1476 /* Keep in mind: the call to reseat in init_iterator skips invisible
1477 text, so we might end up at a position different from POS. This
1478 is only a problem when POS is a row start after a newline and an
1479 overlay starts there with an after-string, and the overlay has an
1480 invisible property. Since we don't skip invisible text in
1481 display_line and elsewhere immediately after consuming the
1482 newline before the row start, such a POS will not be in a string,
1483 but the call to init_iterator below will move us to the
1484 after-string. */
1485 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1486 NULL, DEFAULT_FACE_ID);
1487
1488 /* If position is within an overlay string, set up IT to
1489 the right overlay string. */
1490 if (pos->overlay_string_index >= 0)
1491 {
1492 int relative_index;
1493
1494 /* We already have the first chunk of overlay strings in
1495 IT->overlay_strings. Load more until the one for
1496 pos->overlay_string_index is in IT->overlay_strings. */
1497 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1498 {
1499 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1500 it->current.overlay_string_index = 0;
1501 while (n--)
1502 {
1503 load_overlay_strings (it);
1504 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1505 }
1506 }
1507
1508 it->current.overlay_string_index = pos->overlay_string_index;
1509 relative_index = (it->current.overlay_string_index
1510 % OVERLAY_STRING_CHUNK_SIZE);
1511 it->string = it->overlay_strings[relative_index];
1512 it->current.string_pos = pos->string_pos;
1513 it->method = next_element_from_string;
1514 }
1515 else if (CHARPOS (pos->string_pos) >= 0)
1516 {
1517 /* Recorded position is not in an overlay string, but in another
1518 string. This can only be a string from a `display' property.
1519 IT should already be filled with that string. */
1520 it->current.string_pos = pos->string_pos;
1521 xassert (STRINGP (it->string));
1522 }
1523
1524 /* Restore position in display vector translations or control
1525 character translations. */
1526 if (pos->dpvec_index >= 0)
1527 {
1528 /* This fills IT->dpvec. */
1529 get_next_display_element (it);
1530 xassert (it->dpvec && it->current.dpvec_index == 0);
1531 it->current.dpvec_index = pos->dpvec_index;
1532 }
1533
1534 CHECK_IT (it);
1535}
1536
1537
1538/* Initialize IT for stepping through current_buffer in window W
1539 starting at ROW->start. */
1540
1541static void
1542init_to_row_start (it, w, row)
1543 struct it *it;
1544 struct window *w;
1545 struct glyph_row *row;
1546{
1547 init_from_display_pos (it, w, &row->start);
1548 it->continuation_lines_width = row->continuation_lines_width;
1549 CHECK_IT (it);
1550}
1551
1552
1553/* Initialize IT for stepping through current_buffer in window W
1554 starting in the line following ROW, i.e. starting at ROW->end. */
1555
1556static void
1557init_to_row_end (it, w, row)
1558 struct it *it;
1559 struct window *w;
1560 struct glyph_row *row;
1561{
1562 init_from_display_pos (it, w, &row->end);
1563
1564 if (row->continued_p)
1565 it->continuation_lines_width = (row->continuation_lines_width
1566 + row->pixel_width);
1567 CHECK_IT (it);
1568}
1569
1570
1571
1572\f
1573/***********************************************************************
1574 Text properties
1575 ***********************************************************************/
1576
1577/* Called when IT reaches IT->stop_charpos. Handle text property and
1578 overlay changes. Set IT->stop_charpos to the next position where
1579 to stop. */
1580
1581static void
1582handle_stop (it)
1583 struct it *it;
1584{
1585 enum prop_handled handled;
1586 int handle_overlay_change_p = 1;
1587 struct props *p;
1588
1589 it->dpvec = NULL;
1590 it->current.dpvec_index = -1;
1591
1592 do
1593 {
1594 handled = HANDLED_NORMALLY;
1595
1596 /* Call text property handlers. */
1597 for (p = it_props; p->handler; ++p)
1598 {
1599 handled = p->handler (it);
1600
1601 if (handled == HANDLED_RECOMPUTE_PROPS)
1602 break;
1603 else if (handled == HANDLED_RETURN)
1604 return;
1605 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1606 handle_overlay_change_p = 0;
1607 }
1608
1609 if (handled != HANDLED_RECOMPUTE_PROPS)
1610 {
1611 /* Don't check for overlay strings below when set to deliver
1612 characters from a display vector. */
1613 if (it->method == next_element_from_display_vector)
1614 handle_overlay_change_p = 0;
1615
1616 /* Handle overlay changes. */
1617 if (handle_overlay_change_p)
1618 handled = handle_overlay_change (it);
1619
1620 /* Determine where to stop next. */
1621 if (handled == HANDLED_NORMALLY)
1622 compute_stop_pos (it);
1623 }
1624 }
1625 while (handled == HANDLED_RECOMPUTE_PROPS);
1626}
1627
1628
1629/* Compute IT->stop_charpos from text property and overlay change
1630 information for IT's current position. */
1631
1632static void
1633compute_stop_pos (it)
1634 struct it *it;
1635{
1636 register INTERVAL iv, next_iv;
1637 Lisp_Object object, limit, position;
1638
1639 /* If nowhere else, stop at the end. */
1640 it->stop_charpos = it->end_charpos;
1641
1642 if (STRINGP (it->string))
1643 {
1644 /* Strings are usually short, so don't limit the search for
1645 properties. */
1646 object = it->string;
1647 limit = Qnil;
1648 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1649 }
1650 else
1651 {
1652 int charpos;
1653
1654 /* If next overlay change is in front of the current stop pos
1655 (which is IT->end_charpos), stop there. Note: value of
1656 next_overlay_change is point-max if no overlay change
1657 follows. */
1658 charpos = next_overlay_change (IT_CHARPOS (*it));
1659 if (charpos < it->stop_charpos)
1660 it->stop_charpos = charpos;
1661
1662 /* If showing the region, we have to stop at the region
1663 start or end because the face might change there. */
1664 if (it->region_beg_charpos > 0)
1665 {
1666 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1667 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1668 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1669 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1670 }
1671
1672 /* Set up variables for computing the stop position from text
1673 property changes. */
1674 XSETBUFFER (object, current_buffer);
1675 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1676 XSETFASTINT (position, IT_CHARPOS (*it));
1677
1678 }
1679
1680 /* Get the interval containing IT's position. Value is a null
1681 interval if there isn't such an interval. */
1682 iv = validate_interval_range (object, &position, &position, 0);
1683 if (!NULL_INTERVAL_P (iv))
1684 {
1685 Lisp_Object values_here[LAST_PROP_IDX];
1686 struct props *p;
1687
1688 /* Get properties here. */
1689 for (p = it_props; p->handler; ++p)
1690 values_here[p->idx] = textget (iv->plist, *p->name);
1691
1692 /* Look for an interval following iv that has different
1693 properties. */
1694 for (next_iv = next_interval (iv);
1695 (!NULL_INTERVAL_P (next_iv)
1696 && (NILP (limit)
1697 || XFASTINT (limit) > next_iv->position));
1698 next_iv = next_interval (next_iv))
1699 {
1700 for (p = it_props; p->handler; ++p)
1701 {
1702 Lisp_Object new_value;
1703
1704 new_value = textget (next_iv->plist, *p->name);
1705 if (!EQ (values_here[p->idx], new_value))
1706 break;
1707 }
1708
1709 if (p->handler)
1710 break;
1711 }
1712
1713 if (!NULL_INTERVAL_P (next_iv))
1714 {
1715 if (INTEGERP (limit)
1716 && next_iv->position >= XFASTINT (limit))
1717 /* No text property change up to limit. */
1718 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1719 else
1720 /* Text properties change in next_iv. */
1721 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1722 }
1723 }
1724
1725 xassert (STRINGP (it->string)
1726 || (it->stop_charpos >= BEGV
1727 && it->stop_charpos >= IT_CHARPOS (*it)));
1728}
1729
1730
1731/* Return the position of the next overlay change after POS in
1732 current_buffer. Value is point-max if no overlay change
1733 follows. This is like `next-overlay-change' but doesn't use
1734 xmalloc. */
1735
1736static int
1737next_overlay_change (pos)
1738 int pos;
1739{
1740 int noverlays;
1741 int endpos;
1742 Lisp_Object *overlays;
1743 int len;
1744 int i;
1745
1746 /* Get all overlays at the given position. */
1747 len = 10;
1748 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1749 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1750 if (noverlays > len)
1751 {
1752 len = noverlays;
1753 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1754 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1755 }
1756
1757 /* If any of these overlays ends before endpos,
1758 use its ending point instead. */
1759 for (i = 0; i < noverlays; ++i)
1760 {
1761 Lisp_Object oend;
1762 int oendpos;
1763
1764 oend = OVERLAY_END (overlays[i]);
1765 oendpos = OVERLAY_POSITION (oend);
1766 endpos = min (endpos, oendpos);
1767 }
1768
1769 return endpos;
1770}
1771
1772
1773\f
1774/***********************************************************************
1775 Fontification
1776 ***********************************************************************/
1777
1778/* Handle changes in the `fontified' property of the current buffer by
1779 calling hook functions from Qfontification_functions to fontify
1780 regions of text. */
1781
1782static enum prop_handled
1783handle_fontified_prop (it)
1784 struct it *it;
1785{
1786 Lisp_Object prop, pos;
1787 enum prop_handled handled = HANDLED_NORMALLY;
1788
1789 /* Get the value of the `fontified' property at IT's current buffer
1790 position. (The `fontified' property doesn't have a special
1791 meaning in strings.) If the value is nil, call functions from
1792 Qfontification_functions. */
1793 if (!STRINGP (it->string)
1794 && it->s == NULL
1795 && !NILP (Vfontification_functions)
1796 && (pos = make_number (IT_CHARPOS (*it)),
1797 prop = Fget_char_property (pos, Qfontified, Qnil),
1798 NILP (prop)))
1799 {
1800 Lisp_Object args[2];
1801
1802 /* Run the hook functions. */
1803 args[0] = Qfontification_functions;
1804 args[1] = pos;
1805 Frun_hook_with_args (make_number (2), args);
1806
1807 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1808 something. This avoids an endless loop if they failed to
1809 fontify the text for which reason ever. */
1810 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1811 handled = HANDLED_RECOMPUTE_PROPS;
1812 }
1813
1814 return handled;
1815}
1816
1817
1818\f
1819/***********************************************************************
1820 Faces
1821 ***********************************************************************/
1822
1823/* Set up iterator IT from face properties at its current position.
1824 Called from handle_stop. */
1825
1826static enum prop_handled
1827handle_face_prop (it)
1828 struct it *it;
1829{
1830 int new_face_id, next_stop;
1831
1832 if (!STRINGP (it->string))
1833 {
1834 new_face_id
1835 = face_at_buffer_position (it->w,
1836 IT_CHARPOS (*it),
1837 it->region_beg_charpos,
1838 it->region_end_charpos,
1839 &next_stop,
1840 (IT_CHARPOS (*it)
1841 + TEXT_PROP_DISTANCE_LIMIT),
1842 0);
1843
1844 /* Is this a start of a run of characters with box face?
1845 Caveat: this can be called for a freshly initialized
1846 iterator; face_id is -1 is this case. We know that the new
1847 face will not change until limit, i.e. if the new face has a
1848 box, all characters up to limit will have one. But, as
1849 usual, we don't know whether limit is really the end. */
1850 if (new_face_id != it->face_id)
1851 {
1852 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1853
1854 /* If new face has a box but old face has not, this is
1855 the start of a run of characters with box, i.e. it has
1856 a shadow on the left side. The value of face_id of the
1857 iterator will be -1 if this is the initial call that gets
1858 the face. In this case, we have to look in front of IT's
1859 position and see whether there is a face != new_face_id. */
1860 it->start_of_box_run_p
1861 = (new_face->box != FACE_NO_BOX
1862 && (it->face_id >= 0
1863 || IT_CHARPOS (*it) == BEG
1864 || new_face_id != face_before_it_pos (it)));
1865 it->face_box_p = new_face->box != FACE_NO_BOX;
1866 }
1867 }
1868 else
1869 {
1870 new_face_id
1871 = face_at_string_position (it->w,
1872 it->string,
1873 IT_STRING_CHARPOS (*it),
1874 (it->current.overlay_string_index >= 0
1875 ? IT_CHARPOS (*it)
1876 : 0),
1877 it->region_beg_charpos,
1878 it->region_end_charpos,
1879 &next_stop,
1880 it->base_face_id);
1881
1882#if 0 /* This shouldn't be neccessary. Let's check it. */
1883 /* If IT is used to display a mode line we would really like to
1884 use the mode line face instead of the frame's default face. */
1885 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1886 && new_face_id == DEFAULT_FACE_ID)
1887 new_face_id = MODE_LINE_FACE_ID;
1888#endif
1889
1890 /* Is this a start of a run of characters with box? Caveat:
1891 this can be called for a freshly allocated iterator; face_id
1892 is -1 is this case. We know that the new face will not
1893 change until the next check pos, i.e. if the new face has a
1894 box, all characters up to that position will have a
1895 box. But, as usual, we don't know whether that position
1896 is really the end. */
1897 if (new_face_id != it->face_id)
1898 {
1899 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1900 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1901
1902 /* If new face has a box but old face hasn't, this is the
1903 start of a run of characters with box, i.e. it has a
1904 shadow on the left side. */
1905 it->start_of_box_run_p
1906 = new_face->box && (old_face == NULL || !old_face->box);
1907 it->face_box_p = new_face->box != FACE_NO_BOX;
1908 }
1909 }
1910
1911 it->face_id = new_face_id;
1912 it->charset = CHARSET_ASCII;
1913 return HANDLED_NORMALLY;
1914}
1915
1916
1917/* Compute the face one character before or after the current position
1918 of IT. BEFORE_P non-zero means get the face in front of IT's
1919 position. Value is the id of the face. */
1920
1921static int
1922face_before_or_after_it_pos (it, before_p)
1923 struct it *it;
1924 int before_p;
1925{
1926 int face_id, limit;
1927 int next_check_charpos;
1928 struct text_pos pos;
1929
1930 xassert (it->s == NULL);
1931
1932 if (STRINGP (it->string))
1933 {
1934 /* No face change past the end of the string (for the case
1935 we are padding with spaces). No face change before the
1936 string start. */
1937 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1938 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1939 return it->face_id;
1940
1941 /* Set pos to the position before or after IT's current position. */
1942 if (before_p)
1943 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1944 else
1945 pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string);
1946
1947 /* Get the face for ASCII, or unibyte. */
1948 face_id
1949 = face_at_string_position (it->w,
1950 it->string,
1951 CHARPOS (pos),
1952 (it->current.overlay_string_index >= 0
1953 ? IT_CHARPOS (*it)
1954 : 0),
1955 it->region_beg_charpos,
1956 it->region_end_charpos,
1957 &next_check_charpos,
1958 it->base_face_id);
1959
1960 /* Correct the face for charsets different from ASCII. Do it
1961 for the multibyte case only. The face returned above is
1962 suitable for unibyte text if IT->string is unibyte. */
1963 if (STRING_MULTIBYTE (it->string))
1964 {
1965 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1966 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1967 int c, len, charset;
1968
4fdb80f2 1969 c = string_char_and_length (p, rest, &len);
5f5c8ee5
GM
1970 charset = CHAR_CHARSET (c);
1971 if (charset != CHARSET_ASCII)
1972 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
1973 }
1974 }
1975 else
1976 {
70851746
GM
1977 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1978 || (IT_CHARPOS (*it) <= BEGV && before_p))
1979 return it->face_id;
1980
5f5c8ee5
GM
1981 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1982 pos = it->current.pos;
1983
1984 if (before_p)
1985 DEC_TEXT_POS (pos);
1986 else
1987 INC_TEXT_POS (pos);
70851746 1988
5f5c8ee5
GM
1989 /* Determine face for CHARSET_ASCII, or unibyte. */
1990 face_id = face_at_buffer_position (it->w,
1991 CHARPOS (pos),
1992 it->region_beg_charpos,
1993 it->region_end_charpos,
1994 &next_check_charpos,
1995 limit, 0);
1996
1997 /* Correct the face for charsets different from ASCII. Do it
1998 for the multibyte case only. The face returned above is
1999 suitable for unibyte text if current_buffer is unibyte. */
2000 if (it->multibyte_p)
2001 {
2002 int charset = charset_at_position (pos);
2003 if (charset != CHARSET_ASCII)
2004 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
2005 }
2006 }
2007
2008 return face_id;
2009}
2010
2011
2012\f
2013/***********************************************************************
2014 Invisible text
2015 ***********************************************************************/
2016
2017/* Set up iterator IT from invisible properties at its current
2018 position. Called from handle_stop. */
2019
2020static enum prop_handled
2021handle_invisible_prop (it)
2022 struct it *it;
2023{
2024 enum prop_handled handled = HANDLED_NORMALLY;
2025
2026 if (STRINGP (it->string))
2027 {
2028 extern Lisp_Object Qinvisible;
2029 Lisp_Object prop, end_charpos, limit, charpos;
2030
2031 /* Get the value of the invisible text property at the
2032 current position. Value will be nil if there is no such
2033 property. */
2034 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2035 prop = Fget_text_property (charpos, Qinvisible, it->string);
2036
2037 if (!NILP (prop))
2038 {
2039 handled = HANDLED_RECOMPUTE_PROPS;
2040
2041 /* Get the position at which the next change of the
2042 invisible text property can be found in IT->string.
2043 Value will be nil if the property value is the same for
2044 all the rest of IT->string. */
2045 XSETINT (limit, XSTRING (it->string)->size);
2046 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2047 it->string, limit);
2048
2049 /* Text at current position is invisible. The next
2050 change in the property is at position end_charpos.
2051 Move IT's current position to that position. */
2052 if (INTEGERP (end_charpos)
2053 && XFASTINT (end_charpos) < XFASTINT (limit))
2054 {
2055 struct text_pos old;
2056 old = it->current.string_pos;
2057 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2058 compute_string_pos (&it->current.string_pos, old, it->string);
2059 }
2060 else
2061 {
2062 /* The rest of the string is invisible. If this is an
2063 overlay string, proceed with the next overlay string
2064 or whatever comes and return a character from there. */
2065 if (it->current.overlay_string_index >= 0)
2066 {
2067 next_overlay_string (it);
2068 /* Don't check for overlay strings when we just
2069 finished processing them. */
2070 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2071 }
2072 else
2073 {
2074 struct Lisp_String *s = XSTRING (it->string);
2075 IT_STRING_CHARPOS (*it) = s->size;
2076 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2077 }
2078 }
2079 }
2080 }
2081 else
2082 {
2083 int visible_p, newpos, next_stop;
2084 Lisp_Object pos, prop;
2085
2086 /* First of all, is there invisible text at this position? */
2087 XSETFASTINT (pos, IT_CHARPOS (*it));
2088 prop = Fget_char_property (pos, Qinvisible, it->window);
2089
2090 /* If we are on invisible text, skip over it. */
2091 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2092 {
2093 /* Record whether we have to display an ellipsis for the
2094 invisible text. */
2095 int display_ellipsis_p
2096 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2097
2098 handled = HANDLED_RECOMPUTE_PROPS;
2099
2100 /* Loop skipping over invisible text. The loop is left at
2101 ZV or with IT on the first char being visible again. */
2102 do
2103 {
2104 /* Try to skip some invisible text. Return value is the
2105 position reached which can be equal to IT's position
2106 if there is nothing invisible here. This skips both
2107 over invisible text properties and overlays with
2108 invisible property. */
2109 newpos = skip_invisible (IT_CHARPOS (*it),
2110 &next_stop, ZV, it->window);
2111
2112 /* If we skipped nothing at all we weren't at invisible
2113 text in the first place. If everything to the end of
2114 the buffer was skipped, end the loop. */
2115 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2116 visible_p = 1;
2117 else
2118 {
2119 /* We skipped some characters but not necessarily
2120 all there are. Check if we ended up on visible
2121 text. Fget_char_property returns the property of
2122 the char before the given position, i.e. if we
2123 get visible_p = 1, this means that the char at
2124 newpos is visible. */
2125 XSETFASTINT (pos, newpos);
2126 prop = Fget_char_property (pos, Qinvisible, it->window);
2127 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2128 }
2129
2130 /* If we ended up on invisible text, proceed to
2131 skip starting with next_stop. */
2132 if (!visible_p)
2133 IT_CHARPOS (*it) = next_stop;
2134 }
2135 while (!visible_p);
2136
2137 /* The position newpos is now either ZV or on visible text. */
2138 IT_CHARPOS (*it) = newpos;
2139 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2140
2141 /* Maybe return `...' next for the end of the invisible text. */
2142 if (display_ellipsis_p)
2143 {
2144 if (it->dp
2145 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2146 {
2147 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2148 it->dpvec = v->contents;
2149 it->dpend = v->contents + v->size;
2150 }
2151 else
2152 {
2153 /* Default `...'. */
2154 it->dpvec = default_invis_vector;
2155 it->dpend = default_invis_vector + 3;
2156 }
2157
2158 /* The ellipsis display does not replace the display of
2159 the character at the new position. Indicate this by
2160 setting IT->dpvec_char_len to zero. */
2161 it->dpvec_char_len = 0;
2162
2163 it->current.dpvec_index = 0;
2164 it->method = next_element_from_display_vector;
2165 }
2166 }
2167 }
2168
2169 return handled;
2170}
2171
2172
2173\f
2174/***********************************************************************
2175 'display' property
2176 ***********************************************************************/
2177
2178/* Set up iterator IT from `display' property at its current position.
2179 Called from handle_stop. */
2180
2181static enum prop_handled
2182handle_display_prop (it)
2183 struct it *it;
2184{
2185 Lisp_Object prop, object;
2186 struct text_pos *position;
2187 int space_or_image_found_p;
2188
2189 if (STRINGP (it->string))
2190 {
2191 object = it->string;
2192 position = &it->current.string_pos;
2193 }
2194 else
2195 {
2196 object = Qnil;
2197 position = &it->current.pos;
2198 }
2199
2200 /* Reset those iterator values set from display property values. */
2201 it->font_height = Qnil;
2202 it->space_width = Qnil;
2203 it->voffset = 0;
2204
2205 /* We don't support recursive `display' properties, i.e. string
2206 values that have a string `display' property, that have a string
2207 `display' property etc. */
2208 if (!it->string_from_display_prop_p)
2209 it->area = TEXT_AREA;
2210
2211 prop = Fget_char_property (make_number (position->charpos),
2212 Qdisplay, object);
2213 if (NILP (prop))
2214 return HANDLED_NORMALLY;
2215
2216 space_or_image_found_p = 0;
2217 if (CONSP (prop) && CONSP (XCAR (prop)))
2218 {
2219 while (CONSP (prop))
2220 {
2221 if (handle_single_display_prop (it, XCAR (prop), object, position))
2222 space_or_image_found_p = 1;
2223 prop = XCDR (prop);
2224 }
2225 }
2226 else if (VECTORP (prop))
2227 {
2228 int i;
2229 for (i = 0; i < XVECTOR (prop)->size; ++i)
2230 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2231 object, position))
2232 space_or_image_found_p = 1;
2233 }
2234 else
2235 {
2236 if (handle_single_display_prop (it, prop, object, position))
2237 space_or_image_found_p = 1;
2238 }
2239
2240 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2241}
2242
2243
2244/* Value is the position of the end of the `display' property stating
2245 at START_POS in OBJECT. */
2246
2247static struct text_pos
2248display_prop_end (it, object, start_pos)
2249 struct it *it;
2250 Lisp_Object object;
2251 struct text_pos start_pos;
2252{
2253 Lisp_Object end;
2254 struct text_pos end_pos;
2255
2256 /* Characters having this form of property are not displayed, so
2257 we have to find the end of the property. */
2258 end = Fnext_single_property_change (make_number (start_pos.charpos),
2259 Qdisplay, object, Qnil);
2260 if (NILP (end))
2261 {
2262 /* A nil value of `end' means there are no changes of the
2263 property to the end of the buffer or string. */
2264 if (it->current.overlay_string_index >= 0)
2265 end_pos.charpos = XSTRING (it->string)->size;
2266 else
2267 end_pos.charpos = it->end_charpos;
2268 }
2269 else
2270 end_pos.charpos = XFASTINT (end);
2271
2272 if (STRINGP (it->string))
2273 compute_string_pos (&end_pos, start_pos, it->string);
2274 else
2275 end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
2276
2277 return end_pos;
2278}
2279
2280
2281/* Set up IT from a single `display' sub-property value PROP. OBJECT
2282 is the object in which the `display' property was found. *POSITION
2283 is the position at which it was found.
2284
2285 If PROP is a `space' or `image' sub-property, set *POSITION to the
2286 end position of the `display' property.
2287
2288 Value is non-zero if a `space' or `image' property value was found. */
2289
2290static int
2291handle_single_display_prop (it, prop, object, position)
2292 struct it *it;
2293 Lisp_Object prop;
2294 Lisp_Object object;
2295 struct text_pos *position;
2296{
2297 Lisp_Object value;
2298 int space_or_image_found_p = 0;
2299
2300 Lisp_Object form;
2301
2302 /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
2303 evaluated. If the result is nil, VALUE is ignored. */
2304 form = Qt;
2305 if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
2306 {
2307 prop = XCDR (prop);
2308 if (!CONSP (prop))
2309 return 0;
2310 form = XCAR (prop);
2311 prop = XCDR (prop);
2312 if (!CONSP (prop))
2313 return 0;
2314 prop = XCAR (prop);
2315 }
2316
2317 if (!NILP (form) && !EQ (form, Qt))
2318 {
2319 struct gcpro gcpro1;
2320 struct text_pos end_pos, pt;
2321
2322 end_pos = display_prop_end (it, object, *position);
2323 GCPRO1 (form);
2324
2325 /* Temporarily set point to the end position, and then evaluate
2326 the form. This makes `(eolp)' work as FORM. */
2327 CHARPOS (pt) = PT;
2328 BYTEPOS (pt) = PT_BYTE;
2329 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2330 form = eval_form (form);
2331 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2332 UNGCPRO;
2333 }
2334
2335 if (NILP (form))
2336 return 0;
2337
2338 if (CONSP (prop)
2339 && EQ (XCAR (prop), Qheight)
2340 && CONSP (XCDR (prop)))
2341 {
2342 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2343 return 0;
2344
2345 /* `(height HEIGHT)'. */
2346 it->font_height = XCAR (XCDR (prop));
2347 if (!NILP (it->font_height))
2348 {
2349 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2350 int new_height = -1;
2351
2352 if (CONSP (it->font_height)
2353 && (EQ (XCAR (it->font_height), Qplus)
2354 || EQ (XCAR (it->font_height), Qminus))
2355 && CONSP (XCDR (it->font_height))
2356 && INTEGERP (XCAR (XCDR (it->font_height))))
2357 {
2358 /* `(+ N)' or `(- N)' where N is an integer. */
2359 int steps = XINT (XCAR (XCDR (it->font_height)));
2360 if (EQ (XCAR (it->font_height), Qplus))
2361 steps = - steps;
2362 it->face_id = smaller_face (it->f, it->face_id, steps);
2363 }
2364 else if (SYMBOLP (it->font_height))
2365 {
2366 /* Call function with current height as argument.
2367 Value is the new height. */
2368 Lisp_Object form, height;
2369 struct gcpro gcpro1;
2370
2371 height = face->lface[LFACE_HEIGHT_INDEX];
2372 form = Fcons (it->font_height, Fcons (height, Qnil));
2373 GCPRO1 (form);
2374 height = eval_form (form);
2375 if (NUMBERP (height))
2376 new_height = XFLOATINT (height);
2377 UNGCPRO;
2378 }
2379 else if (NUMBERP (it->font_height))
2380 {
2381 /* Value is a multiple of the canonical char height. */
2382 struct face *face;
2383
2384 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2385 new_height = (XFLOATINT (it->font_height)
2386 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2387 }
2388 else
2389 {
2390 /* Evaluate IT->font_height with `height' bound to the
2391 current specified height to get the new height. */
2392 Lisp_Object value;
2393 int count = specpdl_ptr - specpdl;
2394
2395 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2396 value = eval_form (it->font_height);
2397 unbind_to (count, Qnil);
2398
2399 if (NUMBERP (value))
2400 new_height = XFLOATINT (value);
2401 }
2402
2403 if (new_height > 0)
2404 it->face_id = face_with_height (it->f, it->face_id, new_height);
2405 }
2406 }
2407 else if (CONSP (prop)
2408 && EQ (XCAR (prop), Qspace_width)
2409 && CONSP (XCDR (prop)))
2410 {
2411 /* `(space_width WIDTH)'. */
2412 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2413 return 0;
2414
2415 value = XCAR (XCDR (prop));
2416 if (NUMBERP (value) && XFLOATINT (value) > 0)
2417 it->space_width = value;
2418 }
2419 else if (CONSP (prop)
2420 && EQ (XCAR (prop), Qraise)
2421 && CONSP (XCDR (prop)))
2422 {
2423#ifdef HAVE_WINDOW_SYSTEM
2424 /* `(raise FACTOR)'. */
2425 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2426 return 0;
2427
2428 value = XCAR (XCDR (prop));
2429 if (NUMBERP (value))
2430 {
2431 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2432 it->voffset = - (XFLOATINT (value)
2433 * (face->font->ascent + face->font->descent));
2434 }
2435#endif /* HAVE_WINDOW_SYSTEM */
2436 }
2437 else if (!it->string_from_display_prop_p)
2438 {
2439 /* `(left-margin VALUE)' or `(right-margin VALUE)
2440 or `(nil VALUE)' or VALUE. */
2441 Lisp_Object location, value;
2442 struct text_pos start_pos;
2443 int valid_p;
2444
2445 /* Characters having this form of property are not displayed, so
2446 we have to find the end of the property. */
2447 space_or_image_found_p = 1;
2448 start_pos = *position;
2449 *position = display_prop_end (it, object, start_pos);
2450
2451 /* Let's stop at the new position and assume that all
2452 text properties change there. */
2453 it->stop_charpos = position->charpos;
2454
2455 if (CONSP (prop)
2456 && !EQ (XCAR (prop), Qspace)
2457 && !EQ (XCAR (prop), Qimage))
2458 {
2459 location = XCAR (prop);
2460 value = XCDR (prop);
2461 }
2462 else
2463 {
2464 location = Qnil;
2465 value = prop;
2466 }
2467
2468#ifdef HAVE_WINDOW_SYSTEM
2469 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2470 valid_p = STRINGP (value);
2471 else
2472 valid_p = (STRINGP (value)
2473 || (CONSP (value) && EQ (XCAR (value), Qspace))
2474 || valid_image_p (value));
2475#else /* not HAVE_WINDOW_SYSTEM */
2476 valid_p = STRINGP (value);
2477#endif /* not HAVE_WINDOW_SYSTEM */
2478
2479 if ((EQ (location, Qleft_margin)
2480 || EQ (location, Qright_margin)
2481 || NILP (location))
2482 && valid_p)
2483 {
2484 /* Save current settings of IT so that we can restore them
2485 when we are finished with the glyph property value. */
2486 push_it (it);
2487
2488 if (NILP (location))
2489 it->area = TEXT_AREA;
2490 else if (EQ (location, Qleft_margin))
2491 it->area = LEFT_MARGIN_AREA;
2492 else
2493 it->area = RIGHT_MARGIN_AREA;
2494
2495 if (STRINGP (value))
2496 {
2497 it->string = value;
2498 it->multibyte_p = STRING_MULTIBYTE (it->string);
2499 it->current.overlay_string_index = -1;
2500 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2501 it->end_charpos = it->string_nchars
2502 = XSTRING (it->string)->size;
2503 it->method = next_element_from_string;
2504 it->stop_charpos = 0;
2505 it->string_from_display_prop_p = 1;
2506 }
2507 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2508 {
2509 it->method = next_element_from_stretch;
2510 it->object = value;
2511 it->current.pos = it->position = start_pos;
2512 }
2513#ifdef HAVE_WINDOW_SYSTEM
2514 else
2515 {
2516 it->what = IT_IMAGE;
2517 it->image_id = lookup_image (it->f, value);
2518 it->position = start_pos;
2519 it->object = NILP (object) ? it->w->buffer : object;
2520 it->method = next_element_from_image;
2521
2522 /* Say that we don't have consumed the characters with
2523 `display' property yet. The call to pop_it in
2524 set_iterator_to_next will clean this up. */
2525 *position = start_pos;
2526 }
2527#endif /* HAVE_WINDOW_SYSTEM */
2528 }
2529 }
2530
2531 return space_or_image_found_p;
2532}
2533
2534
2535\f
2536/***********************************************************************
2537 Overlay strings
2538 ***********************************************************************/
2539
2540/* The following structure is used to record overlay strings for
2541 later sorting in load_overlay_strings. */
2542
2543struct overlay_entry
2544{
2545 Lisp_Object string;
2546 int priority;
2547 int after_string_p;
2548};
2549
2550
2551/* Set up iterator IT from overlay strings at its current position.
2552 Called from handle_stop. */
2553
2554static enum prop_handled
2555handle_overlay_change (it)
2556 struct it *it;
2557{
2558 /* Overlays are handled in current_buffer only. */
2559 if (STRINGP (it->string))
2560 return HANDLED_NORMALLY;
2561 else
2562 return (get_overlay_strings (it)
2563 ? HANDLED_RECOMPUTE_PROPS
2564 : HANDLED_NORMALLY);
2565}
2566
2567
2568/* Set up the next overlay string for delivery by IT, if there is an
2569 overlay string to deliver. Called by set_iterator_to_next when the
2570 end of the current overlay string is reached. If there are more
2571 overlay strings to display, IT->string and
2572 IT->current.overlay_string_index are set appropriately here.
2573 Otherwise IT->string is set to nil. */
2574
2575static void
2576next_overlay_string (it)
2577 struct it *it;
2578{
2579 ++it->current.overlay_string_index;
2580 if (it->current.overlay_string_index == it->n_overlay_strings)
2581 {
2582 /* No more overlay strings. Restore IT's settings to what
2583 they were before overlay strings were processed, and
2584 continue to deliver from current_buffer. */
2585 pop_it (it);
2586 xassert (it->stop_charpos >= BEGV
2587 && it->stop_charpos <= it->end_charpos);
2588 it->string = Qnil;
2589 it->current.overlay_string_index = -1;
2590 SET_TEXT_POS (it->current.string_pos, -1, -1);
2591 it->n_overlay_strings = 0;
2592 it->method = next_element_from_buffer;
2593 }
2594 else
2595 {
2596 /* There are more overlay strings to process. If
2597 IT->current.overlay_string_index has advanced to a position
2598 where we must load IT->overlay_strings with more strings, do
2599 it. */
2600 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2601
2602 if (it->current.overlay_string_index && i == 0)
2603 load_overlay_strings (it);
2604
2605 /* Initialize IT to deliver display elements from the overlay
2606 string. */
2607 it->string = it->overlay_strings[i];
2608 it->multibyte_p = STRING_MULTIBYTE (it->string);
2609 SET_TEXT_POS (it->current.string_pos, 0, 0);
2610 it->method = next_element_from_string;
2611 it->stop_charpos = 0;
2612 }
2613
2614 CHECK_IT (it);
2615}
2616
2617
2618/* Compare two overlay_entry structures E1 and E2. Used as a
2619 comparison function for qsort in load_overlay_strings. Overlay
2620 strings for the same position are sorted so that
2621
2622 1. All after-strings come in front of before-strings.
2623
2624 2. Within after-strings, strings are sorted so that overlay strings
2625 from overlays with higher priorities come first.
2626
2627 2. Within before-strings, strings are sorted so that overlay
2628 strings from overlays with higher priorities come last.
2629
2630 Value is analogous to strcmp. */
2631
2632
2633static int
2634compare_overlay_entries (e1, e2)
2635 void *e1, *e2;
2636{
2637 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2638 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2639 int result;
2640
2641 if (entry1->after_string_p != entry2->after_string_p)
2642 /* Let after-strings appear in front of before-strings. */
2643 result = entry1->after_string_p ? -1 : 1;
2644 else if (entry1->after_string_p)
2645 /* After-strings sorted in order of decreasing priority. */
2646 result = entry2->priority - entry1->priority;
2647 else
2648 /* Before-strings sorted in order of increasing priority. */
2649 result = entry1->priority - entry2->priority;
2650
2651 return result;
2652}
2653
2654
2655/* Load the vector IT->overlay_strings with overlay strings from IT's
2656 current buffer position. Set IT->n_overlays to the total number of
2657 overlay strings found.
2658
2659 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2660 a time. On entry into load_overlay_strings,
2661 IT->current.overlay_string_index gives the number of overlay
2662 strings that have already been loaded by previous calls to this
2663 function.
2664
2665 Overlay strings are sorted so that after-string strings come in
2666 front of before-string strings. Within before and after-strings,
2667 strings are sorted by overlay priority. See also function
2668 compare_overlay_entries. */
2669
2670static void
2671load_overlay_strings (it)
2672 struct it *it;
2673{
2674 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2675 Lisp_Object ov, overlay, window, str;
2676 int start, end;
2677 int size = 20;
2678 int n = 0, i, j;
2679 struct overlay_entry *entries
2680 = (struct overlay_entry *) alloca (size * sizeof *entries);
2681
2682 /* Append the overlay string STRING of overlay OVERLAY to vector
2683 `entries' which has size `size' and currently contains `n'
2684 elements. AFTER_P non-zero means STRING is an after-string of
2685 OVERLAY. */
2686#define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2687 do \
2688 { \
2689 Lisp_Object priority; \
2690 \
2691 if (n == size) \
2692 { \
2693 int new_size = 2 * size; \
2694 struct overlay_entry *old = entries; \
2695 entries = \
2696 (struct overlay_entry *) alloca (new_size \
2697 * sizeof *entries); \
2698 bcopy (old, entries, size * sizeof *entries); \
2699 size = new_size; \
2700 } \
2701 \
2702 entries[n].string = (STRING); \
2703 priority = Foverlay_get ((OVERLAY), Qpriority); \
2704 entries[n].priority \
2705 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2706 entries[n].after_string_p = (AFTER_P); \
2707 ++n; \
2708 } \
2709 while (0)
2710
2711 /* Process overlay before the overlay center. */
2712 for (ov = current_buffer->overlays_before;
2713 CONSP (ov);
2714 ov = XCONS (ov)->cdr)
2715 {
2716 overlay = XCONS (ov)->car;
2717 xassert (OVERLAYP (overlay));
2718 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2719 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2720
2721 if (end < IT_CHARPOS (*it))
2722 break;
2723
2724 /* Skip this overlay if it doesn't start or end at IT's current
2725 position. */
2726 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2727 continue;
2728
2729 /* Skip this overlay if it doesn't apply to IT->w. */
2730 window = Foverlay_get (overlay, Qwindow);
2731 if (WINDOWP (window) && XWINDOW (window) != it->w)
2732 continue;
2733
2734 /* If overlay has a non-empty before-string, record it. */
2735 if (start == IT_CHARPOS (*it)
2736 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2737 && XSTRING (str)->size)
2738 RECORD_OVERLAY_STRING (overlay, str, 0);
2739
2740 /* If overlay has a non-empty after-string, record it. */
2741 if (end == IT_CHARPOS (*it)
2742 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2743 && XSTRING (str)->size)
2744 RECORD_OVERLAY_STRING (overlay, str, 1);
2745 }
2746
2747 /* Process overlays after the overlay center. */
2748 for (ov = current_buffer->overlays_after;
2749 CONSP (ov);
2750 ov = XCONS (ov)->cdr)
2751 {
2752 overlay = XCONS (ov)->car;
2753 xassert (OVERLAYP (overlay));
2754 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2755 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2756
2757 if (start > IT_CHARPOS (*it))
2758 break;
2759
2760 /* Skip this overlay if it doesn't start or end at IT's current
2761 position. */
2762 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2763 continue;
2764
2765 /* Skip this overlay if it doesn't apply to IT->w. */
2766 window = Foverlay_get (overlay, Qwindow);
2767 if (WINDOWP (window) && XWINDOW (window) != it->w)
2768 continue;
2769
2770 /* If overlay has a non-empty before-string, record it. */
2771 if (start == IT_CHARPOS (*it)
2772 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2773 && XSTRING (str)->size)
2774 RECORD_OVERLAY_STRING (overlay, str, 0);
2775
2776 /* If overlay has a non-empty after-string, record it. */
2777 if (end == IT_CHARPOS (*it)
2778 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2779 && XSTRING (str)->size)
2780 RECORD_OVERLAY_STRING (overlay, str, 1);
2781 }
2782
2783#undef RECORD_OVERLAY_STRING
2784
2785 /* Sort entries. */
2786 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2787
2788 /* Record the total number of strings to process. */
2789 it->n_overlay_strings = n;
2790
2791 /* IT->current.overlay_string_index is the number of overlay strings
2792 that have already been consumed by IT. Copy some of the
2793 remaining overlay strings to IT->overlay_strings. */
2794 i = 0;
2795 j = it->current.overlay_string_index;
2796 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2797 it->overlay_strings[i++] = entries[j++].string;
2798
2799 CHECK_IT (it);
2800}
2801
2802
2803/* Get the first chunk of overlay strings at IT's current buffer
2804 position. Value is non-zero if at least one overlay string was
2805 found. */
2806
2807static int
2808get_overlay_strings (it)
2809 struct it *it;
2810{
2811 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2812 process. This fills IT->overlay_strings with strings, and sets
2813 IT->n_overlay_strings to the total number of strings to process.
2814 IT->pos.overlay_string_index has to be set temporarily to zero
2815 because load_overlay_strings needs this; it must be set to -1
2816 when no overlay strings are found because a zero value would
2817 indicate a position in the first overlay string. */
2818 it->current.overlay_string_index = 0;
2819 load_overlay_strings (it);
2820
2821 /* If we found overlay strings, set up IT to deliver display
2822 elements from the first one. Otherwise set up IT to deliver
2823 from current_buffer. */
2824 if (it->n_overlay_strings)
2825 {
2826 /* Make sure we know settings in current_buffer, so that we can
2827 restore meaningful values when we're done with the overlay
2828 strings. */
2829 compute_stop_pos (it);
2830 xassert (it->face_id >= 0);
2831
2832 /* Save IT's settings. They are restored after all overlay
2833 strings have been processed. */
2834 xassert (it->sp == 0);
2835 push_it (it);
2836
2837 /* Set up IT to deliver display elements from the first overlay
2838 string. */
2839 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2840 it->stop_charpos = 0;
2841 it->string = it->overlay_strings[0];
2842 it->multibyte_p = STRING_MULTIBYTE (it->string);
2843 xassert (STRINGP (it->string));
2844 it->method = next_element_from_string;
2845 }
2846 else
2847 {
2848 it->string = Qnil;
2849 it->current.overlay_string_index = -1;
2850 it->method = next_element_from_buffer;
2851 }
2852
2853 CHECK_IT (it);
2854
2855 /* Value is non-zero if we found at least one overlay string. */
2856 return STRINGP (it->string);
2857}
2858
2859
2860\f
2861/***********************************************************************
2862 Saving and restoring state
2863 ***********************************************************************/
2864
2865/* Save current settings of IT on IT->stack. Called, for example,
2866 before setting up IT for an overlay string, to be able to restore
2867 IT's settings to what they were after the overlay string has been
2868 processed. */
2869
2870static void
2871push_it (it)
2872 struct it *it;
2873{
2874 struct iterator_stack_entry *p;
2875
2876 xassert (it->sp < 2);
2877 p = it->stack + it->sp;
2878
2879 p->stop_charpos = it->stop_charpos;
2880 xassert (it->face_id >= 0);
2881 p->face_id = it->face_id;
2882 p->string = it->string;
2883 p->pos = it->current;
2884 p->end_charpos = it->end_charpos;
2885 p->string_nchars = it->string_nchars;
2886 p->area = it->area;
2887 p->multibyte_p = it->multibyte_p;
2888 p->space_width = it->space_width;
2889 p->font_height = it->font_height;
2890 p->voffset = it->voffset;
2891 p->string_from_display_prop_p = it->string_from_display_prop_p;
2892 ++it->sp;
2893}
2894
2895
2896/* Restore IT's settings from IT->stack. Called, for example, when no
2897 more overlay strings must be processed, and we return to delivering
2898 display elements from a buffer, or when the end of a string from a
2899 `display' property is reached and we return to delivering display
2900 elements from an overlay string, or from a buffer. */
2901
2902static void
2903pop_it (it)
2904 struct it *it;
2905{
2906 struct iterator_stack_entry *p;
2907
2908 xassert (it->sp > 0);
2909 --it->sp;
2910 p = it->stack + it->sp;
2911 it->stop_charpos = p->stop_charpos;
2912 it->face_id = p->face_id;
2913 it->string = p->string;
2914 it->current = p->pos;
2915 it->end_charpos = p->end_charpos;
2916 it->string_nchars = p->string_nchars;
2917 it->area = p->area;
2918 it->multibyte_p = p->multibyte_p;
2919 it->space_width = p->space_width;
2920 it->font_height = p->font_height;
2921 it->voffset = p->voffset;
2922 it->string_from_display_prop_p = p->string_from_display_prop_p;
2923}
2924
2925
2926\f
2927/***********************************************************************
2928 Moving over lines
2929 ***********************************************************************/
2930
2931/* Set IT's current position to the previous line start. */
2932
2933static void
2934back_to_previous_line_start (it)
2935 struct it *it;
2936{
2937 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
2938 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2939}
2940
2941
2942/* Set IT's current position to the next line start. */
2943
2944static void
2945forward_to_next_line_start (it)
2946 struct it *it;
2947{
2948 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
2949 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2950}
2951
2952
2953/* Set IT's current position to the previous visible line start. Skip
2954 invisible text that is so either due to text properties or due to
2955 selective display. Caution: this does not change IT->current_x and
2956 IT->hpos. */
2957
2958static void
2959back_to_previous_visible_line_start (it)
2960 struct it *it;
2961{
2962 int visible_p = 0;
2963
2964 /* Go back one newline if not on BEGV already. */
2965 if (IT_CHARPOS (*it) > BEGV)
2966 back_to_previous_line_start (it);
2967
2968 /* Move over lines that are invisible because of selective display
2969 or text properties. */
2970 while (IT_CHARPOS (*it) > BEGV
2971 && !visible_p)
2972 {
2973 visible_p = 1;
2974
2975 /* If selective > 0, then lines indented more than that values
2976 are invisible. */
2977 if (it->selective > 0
2978 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
2979 it->selective))
2980 visible_p = 0;
2981#ifdef USE_TEXT_PROPERTIES
2982 else
2983 {
2984 Lisp_Object prop;
2985
2986 prop = Fget_char_property (IT_CHARPOS (*it), Qinvisible, it->window);
2987 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2988 visible_p = 0;
2989 }
2990#endif /* USE_TEXT_PROPERTIES */
2991
2992 /* Back one more newline if the current one is invisible. */
2993 if (!visible_p)
2994 back_to_previous_line_start (it);
2995 }
2996
2997 xassert (IT_CHARPOS (*it) >= BEGV);
2998 xassert (IT_CHARPOS (*it) == BEGV
2999 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3000 CHECK_IT (it);
3001}
3002
3003
3004/* Reseat iterator IT at the previous visible line start. Skip
3005 invisible text that is so either due to text properties or due to
3006 selective display. At the end, update IT's overlay information,
3007 face information etc. */
3008
3009static void
3010reseat_at_previous_visible_line_start (it)
3011 struct it *it;
3012{
3013 back_to_previous_visible_line_start (it);
3014 reseat (it, it->current.pos, 1);
3015 CHECK_IT (it);
3016}
3017
3018
3019/* Reseat iterator IT on the next visible line start in the current
312246d1
GM
3020 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3021 preceding the line start. Skip over invisible text that is so
3022 because of selective display. Compute faces, overlays etc at the
3023 new position. Note that this function does not skip over text that
3024 is invisible because of text properties. */
5f5c8ee5
GM
3025
3026static void
312246d1 3027reseat_at_next_visible_line_start (it, on_newline_p)
5f5c8ee5 3028 struct it *it;
312246d1 3029 int on_newline_p;
5f5c8ee5
GM
3030{
3031 /* Restore the buffer position when currently not delivering display
3032 elements from the current buffer. This is the case, for example,
3033 when called at the end of a truncated overlay string. */
3034 while (it->sp)
3035 pop_it (it);
3036 it->method = next_element_from_buffer;
3037
3038 /* Otherwise, scan_buffer would not work. */
3039 if (IT_CHARPOS (*it) < ZV)
3040 {
3041 /* If on a newline, advance past it. Otherwise, find the next
3042 newline which automatically gives us the position following
3043 the newline. */
3044 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3045 {
3046 ++IT_CHARPOS (*it);
3047 ++IT_BYTEPOS (*it);
3048 }
3049 else
3050 forward_to_next_line_start (it);
3051
3052 /* We must either have reached the end of the buffer or end up
3053 after a newline. */
3054 xassert (IT_CHARPOS (*it) == ZV
3055 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3056
3057 /* Skip over lines that are invisible because they are indented
3058 more than the value of IT->selective. */
3059 if (it->selective > 0)
3060 while (IT_CHARPOS (*it) < ZV
3061 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3062 it->selective))
3063 forward_to_next_line_start (it);
312246d1
GM
3064
3065 /* Position on the newline if we should. */
3066 if (on_newline_p && IT_CHARPOS (*it) > BEGV)
3067 {
3068 --IT_CHARPOS (*it);
3069 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3070 }
5f5c8ee5
GM
3071
3072 /* Set the iterator there. The 0 as the last parameter of
3073 reseat means don't force a text property lookup. The lookup
3074 is then only done if we've skipped past the iterator's
3075 check_charpos'es. This optimization is important because
3076 text property lookups tend to be expensive. */
3077 reseat (it, it->current.pos, 0);
3078 }
3079
3080 CHECK_IT (it);
3081}
3082
3083
3084\f
3085/***********************************************************************
3086 Changing an iterator's position
3087***********************************************************************/
3088
3089/* Change IT's current position to POS in current_buffer. If FORCE_P
3090 is non-zero, always check for text properties at the new position.
3091 Otherwise, text properties are only looked up if POS >=
3092 IT->check_charpos of a property. */
3093
3094static void
3095reseat (it, pos, force_p)
3096 struct it *it;
3097 struct text_pos pos;
3098 int force_p;
3099{
3100 int original_pos = IT_CHARPOS (*it);
3101
3102 reseat_1 (it, pos, 0);
3103
3104 /* Determine where to check text properties. Avoid doing it
3105 where possible because text property lookup is very expensive. */
3106 if (force_p
3107 || CHARPOS (pos) > it->stop_charpos
3108 || CHARPOS (pos) < original_pos)
3109 handle_stop (it);
3110
3111 CHECK_IT (it);
3112}
3113
3114
3115/* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3116 IT->stop_pos to POS, also. */
3117
3118static void
3119reseat_1 (it, pos, set_stop_p)
3120 struct it *it;
3121 struct text_pos pos;
3122 int set_stop_p;
3123{
3124 /* Don't call this function when scanning a C string. */
3125 xassert (it->s == NULL);
3126
3127 /* POS must be a reasonable value. */
3128 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3129
3130 it->current.pos = it->position = pos;
3131 XSETBUFFER (it->object, current_buffer);
3132 it->dpvec = NULL;
3133 it->current.dpvec_index = -1;
3134 it->current.overlay_string_index = -1;
3135 IT_STRING_CHARPOS (*it) = -1;
3136 IT_STRING_BYTEPOS (*it) = -1;
3137 it->string = Qnil;
3138 it->method = next_element_from_buffer;
3139 it->sp = 0;
3140
3141 if (set_stop_p)
3142 it->stop_charpos = CHARPOS (pos);
3143}
3144
3145
3146/* Set up IT for displaying a string, starting at CHARPOS in window W.
3147 If S is non-null, it is a C string to iterate over. Otherwise,
3148 STRING gives a Lisp string to iterate over.
3149
3150 If PRECISION > 0, don't return more then PRECISION number of
3151 characters from the string.
3152
3153 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3154 characters have been returned. FIELD_WIDTH < 0 means an infinite
3155 field width.
3156
3157 MULTIBYTE = 0 means disable processing of multibyte characters,
3158 MULTIBYTE > 0 means enable it,
3159 MULTIBYTE < 0 means use IT->multibyte_p.
3160
3161 IT must be initialized via a prior call to init_iterator before
3162 calling this function. */
3163
3164static void
3165reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3166 struct it *it;
3167 unsigned char *s;
3168 Lisp_Object string;
3169 int charpos;
3170 int precision, field_width, multibyte;
3171{
3172 /* No region in strings. */
3173 it->region_beg_charpos = it->region_end_charpos = -1;
3174
3175 /* No text property checks performed by default, but see below. */
3176 it->stop_charpos = -1;
3177
3178 /* Set iterator position and end position. */
3179 bzero (&it->current, sizeof it->current);
3180 it->current.overlay_string_index = -1;
3181 it->current.dpvec_index = -1;
3182 it->charset = CHARSET_ASCII;
3183 xassert (charpos >= 0);
3184
3185 /* Use the setting of MULTIBYTE if specified. */
3186 if (multibyte >= 0)
3187 it->multibyte_p = multibyte > 0;
3188
3189 if (s == NULL)
3190 {
3191 xassert (STRINGP (string));
3192 it->string = string;
3193 it->s = NULL;
3194 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3195 it->method = next_element_from_string;
3196 it->current.string_pos = string_pos (charpos, string);
3197 }
3198 else
3199 {
3200 it->s = s;
3201 it->string = Qnil;
3202
3203 /* Note that we use IT->current.pos, not it->current.string_pos,
3204 for displaying C strings. */
3205 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3206 if (it->multibyte_p)
3207 {
3208 it->current.pos = c_string_pos (charpos, s, 1);
3209 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3210 }
3211 else
3212 {
3213 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3214 it->end_charpos = it->string_nchars = strlen (s);
3215 }
3216
3217 it->method = next_element_from_c_string;
3218 }
3219
3220 /* PRECISION > 0 means don't return more than PRECISION characters
3221 from the string. */
3222 if (precision > 0 && it->end_charpos - charpos > precision)
3223 it->end_charpos = it->string_nchars = charpos + precision;
3224
3225 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3226 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3227 FIELD_WIDTH < 0 means infinite field width. This is useful for
3228 padding with `-' at the end of a mode line. */
3229 if (field_width < 0)
3230 field_width = INFINITY;
3231 if (field_width > it->end_charpos - charpos)
3232 it->end_charpos = charpos + field_width;
3233
3234 /* Use the standard display table for displaying strings. */
3235 if (DISP_TABLE_P (Vstandard_display_table))
3236 it->dp = XCHAR_TABLE (Vstandard_display_table);
3237
3238 it->stop_charpos = charpos;
3239 CHECK_IT (it);
3240}
3241
3242
3243\f
3244/***********************************************************************
3245 Iteration
3246 ***********************************************************************/
3247
3248/* Load IT's display element fields with information about the next
3249 display element from the current position of IT. Value is zero if
3250 end of buffer (or C string) is reached. */
3251
3252int
3253get_next_display_element (it)
3254 struct it *it;
3255{
3256 /* Non-zero means that we found an display element. Zero means that
3257 we hit the end of what we iterate over. Performance note: the
3258 function pointer `method' used here turns out to be faster than
3259 using a sequence of if-statements. */
3260 int success_p = (*it->method) (it);
3261 int charset;
3262
3263 if (it->what == IT_CHARACTER)
3264 {
3265 /* Map via display table or translate control characters.
3266 IT->c, IT->len etc. have been set to the next character by
3267 the function call above. If we have a display table, and it
3268 contains an entry for IT->c, translate it. Don't do this if
3269 IT->c itself comes from a display table, otherwise we could
3270 end up in an infinite recursion. (An alternative could be to
3271 count the recursion depth of this function and signal an
3272 error when a certain maximum depth is reached.) Is it worth
3273 it? */
3274 if (success_p && it->dpvec == NULL)
3275 {
3276 Lisp_Object dv;
3277
3278 if (it->dp
3279 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3280 VECTORP (dv)))
3281 {
3282 struct Lisp_Vector *v = XVECTOR (dv);
3283
3284 /* Return the first character from the display table
3285 entry, if not empty. If empty, don't display the
3286 current character. */
3287 if (v->size)
3288 {
3289 it->dpvec_char_len = it->len;
3290 it->dpvec = v->contents;
3291 it->dpend = v->contents + v->size;
3292 it->current.dpvec_index = 0;
3293 it->method = next_element_from_display_vector;
3294 }
3295
3296 success_p = get_next_display_element (it);
3297 }
3298
3299 /* Translate control characters into `\003' or `^C' form.
3300 Control characters coming from a display table entry are
3301 currently not translated because we use IT->dpvec to hold
3302 the translation. This could easily be changed but I
3303 don't believe that it is worth doing. */
3304 else if ((it->c < ' '
3305 && (it->area != TEXT_AREA
c6e89d6c 3306 || (it->c != '\n' && it->c != '\t')))
54c85a23 3307 || (it->c >= 127
5f5c8ee5
GM
3308 && it->len == 1))
3309 {
3310 /* IT->c is a control character which must be displayed
3311 either as '\003' or as `^C' where the '\\' and '^'
3312 can be defined in the display table. Fill
3313 IT->ctl_chars with glyphs for what we have to
3314 display. Then, set IT->dpvec to these glyphs. */
3315 GLYPH g;
3316
54c85a23 3317 if (it->c < 128 && it->ctl_arrow_p)
5f5c8ee5
GM
3318 {
3319 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3320 if (it->dp
3321 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3322 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3323 g = XINT (DISP_CTRL_GLYPH (it->dp));
3324 else
3325 g = FAST_MAKE_GLYPH ('^', 0);
3326 XSETINT (it->ctl_chars[0], g);
3327
3328 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3329 XSETINT (it->ctl_chars[1], g);
3330
3331 /* Set up IT->dpvec and return first character from it. */
3332 it->dpvec_char_len = it->len;
3333 it->dpvec = it->ctl_chars;
3334 it->dpend = it->dpvec + 2;
3335 it->current.dpvec_index = 0;
3336 it->method = next_element_from_display_vector;
3337 get_next_display_element (it);
3338 }
3339 else
3340 {
3341 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3342 if (it->dp
3343 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3344 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3345 g = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3346 else
3347 g = FAST_MAKE_GLYPH ('\\', 0);
3348 XSETINT (it->ctl_chars[0], g);
3349
3350 /* Insert three more glyphs into IT->ctl_chars for
3351 the octal display of the character. */
3352 g = FAST_MAKE_GLYPH (((it->c >> 6) & 7) + '0', 0);
3353 XSETINT (it->ctl_chars[1], g);
3354 g = FAST_MAKE_GLYPH (((it->c >> 3) & 7) + '0', 0);
3355 XSETINT (it->ctl_chars[2], g);
3356 g = FAST_MAKE_GLYPH ((it->c & 7) + '0', 0);
3357 XSETINT (it->ctl_chars[3], g);
3358
3359 /* Set up IT->dpvec and return the first character
3360 from it. */
3361 it->dpvec_char_len = it->len;
3362 it->dpvec = it->ctl_chars;
3363 it->dpend = it->dpvec + 4;
3364 it->current.dpvec_index = 0;
3365 it->method = next_element_from_display_vector;
3366 get_next_display_element (it);
3367 }
3368 }
3369 }
3370
3371 /* Adjust face id if charset changes. There are no charset
3372 changes in unibyte text because Emacs' charsets are not
3373 applicable there. */
3374 if (it->multibyte_p
3375 && success_p
3376 && (charset = CHAR_CHARSET (it->c),
3377 charset != it->charset))
3378 {
3379 it->charset = charset;
3380 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, charset);
3381 }
3382 }
3383
3384 /* Is this character the last one of a run of characters with
3385 box? If yes, set IT->end_of_box_run_p to 1. */
3386 if (it->face_box_p
3387 && it->s == NULL)
3388 {
3389 int face_id;
3390 struct face *face;
3391
3392 it->end_of_box_run_p
3393 = ((face_id = face_after_it_pos (it),
3394 face_id != it->face_id)
3395 && (face = FACE_FROM_ID (it->f, face_id),
3396 face->box == FACE_NO_BOX));
3397 }
3398
3399 /* Value is 0 if end of buffer or string reached. */
3400 return success_p;
3401}
3402
3403
3404/* Move IT to the next display element.
3405
3406 Functions get_next_display_element and set_iterator_to_next are
3407 separate because I find this arrangement easier to handle than a
3408 get_next_display_element function that also increments IT's
3409 position. The way it is we can first look at an iterator's current
3410 display element, decide whether it fits on a line, and if it does,
3411 increment the iterator position. The other way around we probably
3412 would either need a flag indicating whether the iterator has to be
3413 incremented the next time, or we would have to implement a
3414 decrement position function which would not be easy to write. */
3415
3416void
3417set_iterator_to_next (it)
3418 struct it *it;
3419{
3420 if (it->method == next_element_from_buffer)
3421 {
3422 /* The current display element of IT is a character from
3423 current_buffer. Advance in the buffer, and maybe skip over
3424 invisible lines that are so because of selective display. */
3425 if (ITERATOR_AT_END_OF_LINE_P (it))
312246d1 3426 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
3427 else
3428 {
3429 xassert (it->len != 0);
3430 IT_BYTEPOS (*it) += it->len;
3431 IT_CHARPOS (*it) += 1;
3432 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3433 }
3434 }
3435 else if (it->method == next_element_from_c_string)
3436 {
3437 /* Current display element of IT is from a C string. */
3438 IT_BYTEPOS (*it) += it->len;
3439 IT_CHARPOS (*it) += 1;
3440 }
3441 else if (it->method == next_element_from_display_vector)
3442 {
3443 /* Current display element of IT is from a display table entry.
3444 Advance in the display table definition. Reset it to null if
3445 end reached, and continue with characters from buffers/
3446 strings. */
3447 ++it->current.dpvec_index;
286bcbc9
GM
3448
3449 /* Restore face and charset of the iterator to what they were
3450 before the display vector entry (these entries may contain
3451 faces, and of course characters of different charsets). */
5f5c8ee5 3452 it->face_id = it->saved_face_id;
286bcbc9
GM
3453 it->charset = FACE_FROM_ID (it->f, it->face_id)->charset;
3454
5f5c8ee5
GM
3455 if (it->dpvec + it->current.dpvec_index == it->dpend)
3456 {
3457 if (it->s)
3458 it->method = next_element_from_c_string;
3459 else if (STRINGP (it->string))
3460 it->method = next_element_from_string;
3461 else
3462 it->method = next_element_from_buffer;
3463
3464 it->dpvec = NULL;
3465 it->current.dpvec_index = -1;
3466
312246d1
GM
3467 /* Skip over characters which were displayed via IT->dpvec. */
3468 if (it->dpvec_char_len < 0)
3469 reseat_at_next_visible_line_start (it, 1);
3470 else if (it->dpvec_char_len > 0)
5f5c8ee5
GM
3471 {
3472 it->len = it->dpvec_char_len;
3473 set_iterator_to_next (it);
3474 }
3475 }
3476 }
3477 else if (it->method == next_element_from_string)
3478 {
3479 /* Current display element is a character from a Lisp string. */
3480 xassert (it->s == NULL && STRINGP (it->string));
3481 IT_STRING_BYTEPOS (*it) += it->len;
3482 IT_STRING_CHARPOS (*it) += 1;
3483
3484 consider_string_end:
3485
3486 if (it->current.overlay_string_index >= 0)
3487 {
3488 /* IT->string is an overlay string. Advance to the
3489 next, if there is one. */
3490 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3491 next_overlay_string (it);
3492 }
3493 else
3494 {
3495 /* IT->string is not an overlay string. If we reached
3496 its end, and there is something on IT->stack, proceed
3497 with what is on the stack. This can be either another
3498 string, this time an overlay string, or a buffer. */
3499 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3500 && it->sp > 0)
3501 {
3502 pop_it (it);
3503 if (!STRINGP (it->string))
3504 it->method = next_element_from_buffer;
3505 }
3506 }
3507 }
3508 else if (it->method == next_element_from_image
3509 || it->method == next_element_from_stretch)
3510 {
3511 /* The position etc with which we have to proceed are on
3512 the stack. The position may be at the end of a string,
3513 if the `display' property takes up the whole string. */
3514 pop_it (it);
3515 it->image_id = 0;
3516 if (STRINGP (it->string))
3517 {
3518 it->method = next_element_from_string;
3519 goto consider_string_end;
3520 }
3521 else
3522 it->method = next_element_from_buffer;
3523 }
3524 else
3525 /* There are no other methods defined, so this should be a bug. */
3526 abort ();
3527
3528 /* Reset flags indicating start and end of a sequence of
3529 characters with box. */
3530 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3531
3532 xassert (it->method != next_element_from_string
3533 || (STRINGP (it->string)
3534 && IT_STRING_CHARPOS (*it) >= 0));
3535}
3536
3537
3538/* Load IT's display element fields with information about the next
3539 display element which comes from a display table entry or from the
3540 result of translating a control character to one of the forms `^C'
3541 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3542
3543static int
3544next_element_from_display_vector (it)
3545 struct it *it;
3546{
3547 /* Precondition. */
3548 xassert (it->dpvec && it->current.dpvec_index >= 0);
3549
3550 /* Remember the current face id in case glyphs specify faces.
3551 IT's face is restored in set_iterator_to_next. */
3552 it->saved_face_id = it->face_id;
3553
3554 if (INTEGERP (*it->dpvec)
3555 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3556 {
3557 int lface_id;
3558 GLYPH g;
3559
3560 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3561 it->c = FAST_GLYPH_CHAR (g);
3562 it->len = CHAR_LEN (it->c);
3563
3564 /* The entry may contain a face id to use. Such a face id is
3565 the id of a Lisp face, not a realized face. A face id of
3566 zero means no face. */
3567 lface_id = FAST_GLYPH_FACE (g);
3568 if (lface_id)
3569 {
3570 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3571 if (face_id >= 0)
3572 {
3573 it->face_id = face_id;
3574 it->charset = CHARSET_ASCII;
3575 }
3576 }
3577 }
3578 else
3579 /* Display table entry is invalid. Return a space. */
3580 it->c = ' ', it->len = 1;
3581
3582 /* Don't change position and object of the iterator here. They are
3583 still the values of the character that had this display table
3584 entry or was translated, and that's what we want. */
3585 it->what = IT_CHARACTER;
3586 return 1;
3587}
3588
3589
3590/* Load IT with the next display element from Lisp string IT->string.
3591 IT->current.string_pos is the current position within the string.
3592 If IT->current.overlay_string_index >= 0, the Lisp string is an
3593 overlay string. */
3594
3595static int
3596next_element_from_string (it)
3597 struct it *it;
3598{
3599 struct text_pos position;
3600
3601 xassert (STRINGP (it->string));
3602 xassert (IT_STRING_CHARPOS (*it) >= 0);
3603 position = it->current.string_pos;
3604
3605 /* Time to check for invisible text? */
3606 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3607 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3608 {
3609 handle_stop (it);
3610
3611 /* Since a handler may have changed IT->method, we must
3612 recurse here. */
3613 return get_next_display_element (it);
3614 }
3615
3616 if (it->current.overlay_string_index >= 0)
3617 {
3618 /* Get the next character from an overlay string. In overlay
3619 strings, There is no field width or padding with spaces to
3620 do. */
3621 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3622 {
3623 it->what = IT_EOB;
3624 return 0;
3625 }
3626 else if (STRING_MULTIBYTE (it->string))
3627 {
3628 int remaining = (STRING_BYTES (XSTRING (it->string))
3629 - IT_STRING_BYTEPOS (*it));
3630 unsigned char *s = (XSTRING (it->string)->data
3631 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3632 it->c = string_char_and_length (s, remaining, &it->len);
5f5c8ee5
GM
3633 }
3634 else
3635 {
3636 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3637 it->len = 1;
3638 }
3639 }
3640 else
3641 {
3642 /* Get the next character from a Lisp string that is not an
3643 overlay string. Such strings come from the mode line, for
3644 example. We may have to pad with spaces, or truncate the
3645 string. See also next_element_from_c_string. */
3646 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3647 {
3648 it->what = IT_EOB;
3649 return 0;
3650 }
3651 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3652 {
3653 /* Pad with spaces. */
3654 it->c = ' ', it->len = 1;
3655 CHARPOS (position) = BYTEPOS (position) = -1;
3656 }
3657 else if (STRING_MULTIBYTE (it->string))
3658 {
3659 int maxlen = (STRING_BYTES (XSTRING (it->string))
3660 - IT_STRING_BYTEPOS (*it));
3661 unsigned char *s = (XSTRING (it->string)->data
3662 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3663 it->c = string_char_and_length (s, maxlen, &it->len);
5f5c8ee5
GM
3664 }
3665 else
3666 {
3667 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3668 it->len = 1;
3669 }
3670 }
3671
3672 /* Record what we have and where it came from. Note that we store a
3673 buffer position in IT->position although it could arguably be a
3674 string position. */
3675 it->what = IT_CHARACTER;
3676 it->object = it->string;
3677 it->position = position;
3678 return 1;
3679}
3680
3681
3682/* Load IT with next display element from C string IT->s.
3683 IT->string_nchars is the maximum number of characters to return
3684 from the string. IT->end_charpos may be greater than
3685 IT->string_nchars when this function is called, in which case we
3686 may have to return padding spaces. Value is zero if end of string
3687 reached, including padding spaces. */
3688
3689static int
3690next_element_from_c_string (it)
3691 struct it *it;
3692{
3693 int success_p = 1;
3694
3695 xassert (it->s);
3696 it->what = IT_CHARACTER;
3697 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3698 it->object = Qnil;
3699
3700 /* IT's position can be greater IT->string_nchars in case a field
3701 width or precision has been specified when the iterator was
3702 initialized. */
3703 if (IT_CHARPOS (*it) >= it->end_charpos)
3704 {
3705 /* End of the game. */
3706 it->what = IT_EOB;
3707 success_p = 0;
3708 }
3709 else if (IT_CHARPOS (*it) >= it->string_nchars)
3710 {
3711 /* Pad with spaces. */
3712 it->c = ' ', it->len = 1;
3713 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3714 }
3715 else if (it->multibyte_p)
3716 {
3717 /* Implementation note: The calls to strlen apparently aren't a
3718 performance problem because there is no noticeable performance
3719 difference between Emacs running in unibyte or multibyte mode. */
3720 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
4fdb80f2
GM
3721 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3722 maxlen, &it->len);
5f5c8ee5
GM
3723 }
3724 else
3725 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3726
3727 return success_p;
3728}
3729
3730
3731/* Set up IT to return characters from an ellipsis, if appropriate.
3732 The definition of the ellipsis glyphs may come from a display table
3733 entry. This function Fills IT with the first glyph from the
3734 ellipsis if an ellipsis is to be displayed. */
3735
3736static void
3737next_element_from_ellipsis (it)
3738 struct it *it;
3739{
3740 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3741 {
3742 /* Use the display table definition for `...'. Invalid glyphs
3743 will be handled by the method returning elements from dpvec. */
3744 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3745 it->dpvec_char_len = it->len;
3746 it->dpvec = v->contents;
3747 it->dpend = v->contents + v->size;
3748 it->current.dpvec_index = 0;
3749 it->method = next_element_from_display_vector;
3750 get_next_display_element (it);
3751 }
3752 else if (it->selective_display_ellipsis_p)
3753 {
3754 /* Use default `...' which is stored in default_invis_vector. */
3755 it->dpvec_char_len = it->len;
3756 it->dpvec = default_invis_vector;
3757 it->dpend = default_invis_vector + 3;
3758 it->current.dpvec_index = 0;
3759 it->method = next_element_from_display_vector;
3760 get_next_display_element (it);
3761 }
3762}
3763
3764
3765/* Deliver an image display element. The iterator IT is already
3766 filled with image information (done in handle_display_prop). Value
3767 is always 1. */
3768
3769
3770static int
3771next_element_from_image (it)
3772 struct it *it;
3773{
3774 it->what = IT_IMAGE;
3775 return 1;
3776}
3777
3778
3779/* Fill iterator IT with next display element from a stretch glyph
3780 property. IT->object is the value of the text property. Value is
3781 always 1. */
3782
3783static int
3784next_element_from_stretch (it)
3785 struct it *it;
3786{
3787 it->what = IT_STRETCH;
3788 return 1;
3789}
3790
3791
3792/* Load IT with the next display element from current_buffer. Value
3793 is zero if end of buffer reached. IT->stop_charpos is the next
3794 position at which to stop and check for text properties or buffer
3795 end. */
3796
3797static int
3798next_element_from_buffer (it)
3799 struct it *it;
3800{
3801 int success_p = 1;
3802
3803 /* Check this assumption, otherwise, we would never enter the
3804 if-statement, below. */
3805 xassert (IT_CHARPOS (*it) >= BEGV
3806 && IT_CHARPOS (*it) <= it->stop_charpos);
3807
3808 if (IT_CHARPOS (*it) >= it->stop_charpos)
3809 {
3810 if (IT_CHARPOS (*it) >= it->end_charpos)
3811 {
3812 int overlay_strings_follow_p;
3813
3814 /* End of the game, except when overlay strings follow that
3815 haven't been returned yet. */
3816 if (it->overlay_strings_at_end_processed_p)
3817 overlay_strings_follow_p = 0;
3818 else
3819 {
3820 it->overlay_strings_at_end_processed_p = 1;
3821 overlay_strings_follow_p
3822 = get_overlay_strings (it);
3823 }
3824
3825 if (overlay_strings_follow_p)
3826 success_p = get_next_display_element (it);
3827 else
3828 {
3829 it->what = IT_EOB;
3830 it->position = it->current.pos;
3831 success_p = 0;
3832 }
3833 }
3834 else
3835 {
3836 handle_stop (it);
3837 return get_next_display_element (it);
3838 }
3839 }
3840 else
3841 {
3842 /* No face changes, overlays etc. in sight, so just return a
3843 character from current_buffer. */
3844 unsigned char *p;
3845
3846 /* Maybe run the redisplay end trigger hook. Performance note:
3847 This doesn't seem to cost measurable time. */
3848 if (it->redisplay_end_trigger_charpos
3849 && it->glyph_row
3850 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3851 run_redisplay_end_trigger_hook (it);
3852
3853 /* Get the next character, maybe multibyte. */
3854 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3855 if (it->multibyte_p)
3856 {
3857 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3858 - IT_BYTEPOS (*it));
4fdb80f2 3859 it->c = string_char_and_length (p, maxlen, &it->len);
5f5c8ee5
GM
3860 }
3861 else
3862 it->c = *p, it->len = 1;
3863
3864 /* Record what we have and where it came from. */
3865 it->what = IT_CHARACTER;;
3866 it->object = it->w->buffer;
3867 it->position = it->current.pos;
3868
3869 /* Normally we return the character found above, except when we
3870 really want to return an ellipsis for selective display. */
3871 if (it->selective)
3872 {
3873 if (it->c == '\n')
3874 {
3875 /* A value of selective > 0 means hide lines indented more
3876 than that number of columns. */
3877 if (it->selective > 0
3878 && IT_CHARPOS (*it) + 1 < ZV
3879 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3880 IT_BYTEPOS (*it) + 1,
3881 it->selective))
312246d1
GM
3882 {
3883 next_element_from_ellipsis (it);
3884 it->dpvec_char_len = -1;
3885 }
5f5c8ee5
GM
3886 }
3887 else if (it->c == '\r' && it->selective == -1)
3888 {
3889 /* A value of selective == -1 means that everything from the
3890 CR to the end of the line is invisible, with maybe an
3891 ellipsis displayed for it. */
3892 next_element_from_ellipsis (it);
312246d1 3893 it->dpvec_char_len = -1;
5f5c8ee5
GM
3894 }
3895 }
3896 }
3897
3898 /* Value is zero if end of buffer reached. */
3899 xassert (!success_p || it->len > 0);
3900 return success_p;
3901}
3902
3903
3904/* Run the redisplay end trigger hook for IT. */
3905
3906static void
3907run_redisplay_end_trigger_hook (it)
3908 struct it *it;
3909{
3910 Lisp_Object args[3];
3911
3912 /* IT->glyph_row should be non-null, i.e. we should be actually
3913 displaying something, or otherwise we should not run the hook. */
3914 xassert (it->glyph_row);
3915
3916 /* Set up hook arguments. */
3917 args[0] = Qredisplay_end_trigger_functions;
3918 args[1] = it->window;
3919 XSETINT (args[2], it->redisplay_end_trigger_charpos);
3920 it->redisplay_end_trigger_charpos = 0;
3921
3922 /* Since we are *trying* to run these functions, don't try to run
3923 them again, even if they get an error. */
3924 it->w->redisplay_end_trigger = Qnil;
3925 Frun_hook_with_args (3, args);
3926
3927 /* Notice if it changed the face of the character we are on. */
3928 handle_face_prop (it);
3929}
3930
3931
3932\f
3933/***********************************************************************
3934 Moving an iterator without producing glyphs
3935 ***********************************************************************/
3936
3937/* Move iterator IT to a specified buffer or X position within one
3938 line on the display without producing glyphs.
3939
3940 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
3941 whichever is reached first.
3942
3943 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
3944
3945 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
3946 0 <= TO_X <= IT->last_visible_x. This means in particular, that
3947 TO_X includes the amount by which a window is horizontally
3948 scrolled.
3949
3950 Value is
3951
3952 MOVE_POS_MATCH_OR_ZV
3953 - when TO_POS or ZV was reached.
3954
3955 MOVE_X_REACHED
3956 -when TO_X was reached before TO_POS or ZV were reached.
3957
3958 MOVE_LINE_CONTINUED
3959 - when we reached the end of the display area and the line must
3960 be continued.
3961
3962 MOVE_LINE_TRUNCATED
3963 - when we reached the end of the display area and the line is
3964 truncated.
3965
3966 MOVE_NEWLINE_OR_CR
3967 - when we stopped at a line end, i.e. a newline or a CR and selective
3968 display is on. */
3969
3970enum move_it_result
3971move_it_in_display_line_to (it, to_charpos, to_x, op)
3972 struct it *it;
3973 int to_charpos, to_x, op;
3974{
3975 enum move_it_result result = MOVE_UNDEFINED;
3976 struct glyph_row *saved_glyph_row;
3977
3978 /* Don't produce glyphs in produce_glyphs. */
3979 saved_glyph_row = it->glyph_row;
3980 it->glyph_row = NULL;
3981
5f5c8ee5
GM
3982 while (1)
3983 {
3984 int x, i;
3985
3986 /* Stop when ZV or TO_CHARPOS reached. */
3987 if (!get_next_display_element (it)
3988 || ((op & MOVE_TO_POS) != 0
3989 && BUFFERP (it->object)
3990 && IT_CHARPOS (*it) >= to_charpos))
3991 {
3992 result = MOVE_POS_MATCH_OR_ZV;
3993 break;
3994 }
3995
3996 /* The call to produce_glyphs will get the metrics of the
3997 display element IT is loaded with. We record in x the
3998 x-position before this display element in case it does not
3999 fit on the line. */
4000 x = it->current_x;
4001 PRODUCE_GLYPHS (it);
4002
4003 if (it->area != TEXT_AREA)
4004 {
4005 set_iterator_to_next (it);
4006 continue;
4007 }
4008
4009 /* The number of glyphs we get back in IT->nglyphs will normally
4010 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4011 character on a terminal frame, or (iii) a line end. For the
4012 second case, IT->nglyphs - 1 padding glyphs will be present
4013 (on X frames, there is only one glyph produced for a
4014 composite character.
4015
4016 The behavior implemented below means, for continuation lines,
4017 that as many spaces of a TAB as fit on the current line are
4018 displayed there. For terminal frames, as many glyphs of a
4019 multi-glyph character are displayed in the current line, too.
4020 This is what the old redisplay code did, and we keep it that
4021 way. Under X, the whole shape of a complex character must
4022 fit on the line or it will be completely displayed in the
4023 next line.
4024
4025 Note that both for tabs and padding glyphs, all glyphs have
4026 the same width. */
4027 if (it->nglyphs)
4028 {
4029 /* More than one glyph or glyph doesn't fit on line. All
4030 glyphs have the same width. */
4031 int single_glyph_width = it->pixel_width / it->nglyphs;
4032 int new_x;
4033
4034 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4035 {
4036 new_x = x + single_glyph_width;
4037
4038 /* We want to leave anything reaching TO_X to the caller. */
4039 if ((op & MOVE_TO_X) && new_x > to_x)
4040 {
4041 it->current_x = x;
4042 result = MOVE_X_REACHED;
4043 break;
4044 }
4045 else if (/* Lines are continued. */
4046 !it->truncate_lines_p
4047 && (/* And glyph doesn't fit on the line. */
4048 new_x > it->last_visible_x
4049 /* Or it fits exactly and we're on a window
4050 system frame. */
4051 || (new_x == it->last_visible_x
4052 && FRAME_WINDOW_P (it->f))))
4053 {
4054 if (/* IT->hpos == 0 means the very first glyph
4055 doesn't fit on the line, e.g. a wide image. */
4056 it->hpos == 0
4057 || (new_x == it->last_visible_x
4058 && FRAME_WINDOW_P (it->f)))
4059 {
4060 ++it->hpos;
4061 it->current_x = new_x;
4062 if (i == it->nglyphs - 1)
4063 set_iterator_to_next (it);
4064 }
4065 else
4066 it->current_x = x;
4067
4068 result = MOVE_LINE_CONTINUED;
4069 break;
4070 }
4071 else if (new_x > it->first_visible_x)
4072 {
4073 /* Glyph is visible. Increment number of glyphs that
4074 would be displayed. */
4075 ++it->hpos;
4076 }
4077 else
4078 {
4079 /* Glyph is completely off the left margin of the display
4080 area. Nothing to do. */
4081 }
4082 }
4083
4084 if (result != MOVE_UNDEFINED)
4085 break;
4086 }
4087 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4088 {
4089 /* Stop when TO_X specified and reached. This check is
4090 necessary here because of lines consisting of a line end,
4091 only. The line end will not produce any glyphs and we
4092 would never get MOVE_X_REACHED. */
4093 xassert (it->nglyphs == 0);
4094 result = MOVE_X_REACHED;
4095 break;
4096 }
4097
4098 /* Is this a line end? If yes, we're done. */
4099 if (ITERATOR_AT_END_OF_LINE_P (it))
4100 {
4101 result = MOVE_NEWLINE_OR_CR;
4102 break;
4103 }
4104
4105 /* The current display element has been consumed. Advance
4106 to the next. */
4107 set_iterator_to_next (it);
4108
4109 /* Stop if lines are truncated and IT's current x-position is
4110 past the right edge of the window now. */
4111 if (it->truncate_lines_p
4112 && it->current_x >= it->last_visible_x)
4113 {
4114 result = MOVE_LINE_TRUNCATED;
4115 break;
4116 }
4117 }
4118
4119 /* Restore the iterator settings altered at the beginning of this
4120 function. */
4121 it->glyph_row = saved_glyph_row;
4122 return result;
4123}
4124
4125
4126/* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4127 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4128 the description of enum move_operation_enum.
4129
4130 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4131 screen line, this function will set IT to the next position >
4132 TO_CHARPOS. */
4133
4134void
4135move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4136 struct it *it;
4137 int to_charpos, to_x, to_y, to_vpos;
4138 int op;
4139{
4140 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4141 int line_height;
4142
5f5c8ee5
GM
4143 while (1)
4144 {
4145 if (op & MOVE_TO_VPOS)
4146 {
4147 /* If no TO_CHARPOS and no TO_X specified, stop at the
4148 start of the line TO_VPOS. */
4149 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4150 {
4151 if (it->vpos == to_vpos)
4152 break;
4153 skip = move_it_in_display_line_to (it, -1, -1, 0);
4154 }
4155 else
4156 {
4157 /* TO_VPOS >= 0 means stop at TO_X in the line at
4158 TO_VPOS, or at TO_POS, whichever comes first. */
4159 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4160
4161 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4162 break;
4163 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4164 {
4165 /* We have reached TO_X but not in the line we want. */
4166 skip = move_it_in_display_line_to (it, to_charpos,
4167 -1, MOVE_TO_POS);
4168 if (skip == MOVE_POS_MATCH_OR_ZV)
4169 break;
4170 }
4171 }
4172 }
4173 else if (op & MOVE_TO_Y)
4174 {
4175 struct it it_backup;
4176 int done_p;
4177
4178 /* TO_Y specified means stop at TO_X in the line containing
4179 TO_Y---or at TO_CHARPOS if this is reached first. The
4180 problem is that we can't really tell whether the line
4181 contains TO_Y before we have completely scanned it, and
4182 this may skip past TO_X. What we do is to first scan to
4183 TO_X.
4184
4185 If TO_X is not specified, use a TO_X of zero. The reason
4186 is to make the outcome of this function more predictable.
4187 If we didn't use TO_X == 0, we would stop at the end of
4188 the line which is probably not what a caller would expect
4189 to happen. */
4190 skip = move_it_in_display_line_to (it, to_charpos,
4191 ((op & MOVE_TO_X)
4192 ? to_x : 0),
4193 (MOVE_TO_X
4194 | (op & MOVE_TO_POS)));
4195
4196 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4197 if (skip == MOVE_POS_MATCH_OR_ZV)
4198 break;
4199
4200 /* If TO_X was reached, we would like to know whether TO_Y
4201 is in the line. This can only be said if we know the
4202 total line height which requires us to scan the rest of
4203 the line. */
4204 done_p = 0;
4205 if (skip == MOVE_X_REACHED)
4206 {
4207 it_backup = *it;
4208 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4209 op & MOVE_TO_POS);
4210 }
4211
4212 /* Now, decide whether TO_Y is in this line. */
4213 line_height = it->max_ascent + it->max_descent;
4214
4215 if (to_y >= it->current_y
4216 && to_y < it->current_y + line_height)
4217 {
4218 if (skip == MOVE_X_REACHED)
4219 /* If TO_Y is in this line and TO_X was reached above,
4220 we scanned too far. We have to restore IT's settings
4221 to the ones before skipping. */
4222 *it = it_backup;
4223 done_p = 1;
4224 }
4225 else if (skip == MOVE_X_REACHED)
4226 {
4227 skip = skip2;
4228 if (skip == MOVE_POS_MATCH_OR_ZV)
4229 done_p = 1;
4230 }
4231
4232 if (done_p)
4233 break;
4234 }
4235 else
4236 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4237
4238 switch (skip)
4239 {
4240 case MOVE_POS_MATCH_OR_ZV:
4241 return;
4242
4243 case MOVE_NEWLINE_OR_CR:
4244 set_iterator_to_next (it);
4245 it->continuation_lines_width = 0;
4246 break;
4247
4248 case MOVE_LINE_TRUNCATED:
4249 it->continuation_lines_width = 0;
312246d1 4250 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
4251 if ((op & MOVE_TO_POS) != 0
4252 && IT_CHARPOS (*it) > to_charpos)
4253 goto out;
4254 break;
4255
4256 case MOVE_LINE_CONTINUED:
4257 it->continuation_lines_width += it->current_x;
4258 break;
4259
4260 default:
4261 abort ();
4262 }
4263
4264 /* Reset/increment for the next run. */
4265 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4266 it->current_x = it->hpos = 0;
4267 it->current_y += it->max_ascent + it->max_descent;
4268 ++it->vpos;
4269 last_height = it->max_ascent + it->max_descent;
4270 last_max_ascent = it->max_ascent;
4271 it->max_ascent = it->max_descent = 0;
4272 }
4273 out:;
4274}
4275
4276
4277/* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4278
4279 If DY > 0, move IT backward at least that many pixels. DY = 0
4280 means move IT backward to the preceding line start or BEGV. This
4281 function may move over more than DY pixels if IT->current_y - DY
4282 ends up in the middle of a line; in this case IT->current_y will be
4283 set to the top of the line moved to. */
4284
4285void
4286move_it_vertically_backward (it, dy)
4287 struct it *it;
4288 int dy;
4289{
4290 int nlines, h, line_height;
4291 struct it it2;
4292 int start_pos = IT_CHARPOS (*it);
4293
4294 xassert (dy >= 0);
4295
4296 /* Estimate how many newlines we must move back. */
4297 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4298
4299 /* Set the iterator's position that many lines back. */
4300 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4301 back_to_previous_visible_line_start (it);
4302
4303 /* Reseat the iterator here. When moving backward, we don't want
4304 reseat to skip forward over invisible text, set up the iterator
4305 to deliver from overlay strings at the new position etc. So,
4306 use reseat_1 here. */
4307 reseat_1 (it, it->current.pos, 1);
4308
4309 /* We are now surely at a line start. */
4310 it->current_x = it->hpos = 0;
4311
4312 /* Move forward and see what y-distance we moved. First move to the
4313 start of the next line so that we get its height. We need this
4314 height to be able to tell whether we reached the specified
4315 y-distance. */
4316 it2 = *it;
4317 it2.max_ascent = it2.max_descent = 0;
4318 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4319 MOVE_TO_POS | MOVE_TO_VPOS);
4320 xassert (IT_CHARPOS (*it) >= BEGV);
4321 line_height = it2.max_ascent + it2.max_descent;
4322 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4323 xassert (IT_CHARPOS (*it) >= BEGV);
4324 h = it2.current_y - it->current_y;
4325 nlines = it2.vpos - it->vpos;
4326
4327 /* Correct IT's y and vpos position. */
4328 it->vpos -= nlines;
4329 it->current_y -= h;
4330
4331 if (dy == 0)
4332 {
4333 /* DY == 0 means move to the start of the screen line. The
4334 value of nlines is > 0 if continuation lines were involved. */
4335 if (nlines > 0)
4336 move_it_by_lines (it, nlines, 1);
4337 xassert (IT_CHARPOS (*it) <= start_pos);
4338 }
4339 else if (nlines)
4340 {
4341 /* The y-position we try to reach. Note that h has been
4342 subtracted in front of the if-statement. */
4343 int target_y = it->current_y + h - dy;
4344
4345 /* If we did not reach target_y, try to move further backward if
4346 we can. If we moved too far backward, try to move forward. */
4347 if (target_y < it->current_y
4348 && IT_CHARPOS (*it) > BEGV)
4349 {
4350 move_it_vertically (it, target_y - it->current_y);
4351 xassert (IT_CHARPOS (*it) >= BEGV);
4352 }
4353 else if (target_y >= it->current_y + line_height
4354 && IT_CHARPOS (*it) < ZV)
4355 {
4356 move_it_vertically (it, target_y - (it->current_y + line_height));
4357 xassert (IT_CHARPOS (*it) >= BEGV);
4358 }
4359 }
4360}
4361
4362
4363/* Move IT by a specified amount of pixel lines DY. DY negative means
4364 move backwards. DY = 0 means move to start of screen line. At the
4365 end, IT will be on the start of a screen line. */
4366
4367void
4368move_it_vertically (it, dy)
4369 struct it *it;
4370 int dy;
4371{
4372 if (dy <= 0)
4373 move_it_vertically_backward (it, -dy);
4374 else if (dy > 0)
4375 {
4376 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4377 MOVE_TO_POS | MOVE_TO_Y);
4378
4379 /* If buffer ends in ZV without a newline, move to the start of
4380 the line to satisfy the post-condition. */
4381 if (IT_CHARPOS (*it) == ZV
4382 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4383 move_it_by_lines (it, 0, 0);
4384 }
4385}
4386
4387
4388/* Return non-zero if some text between buffer positions START_CHARPOS
4389 and END_CHARPOS is invisible. IT->window is the window for text
4390 property lookup. */
4391
4392static int
4393invisible_text_between_p (it, start_charpos, end_charpos)
4394 struct it *it;
4395 int start_charpos, end_charpos;
4396{
4397#ifdef USE_TEXT_PROPERTIES
4398 Lisp_Object prop, limit;
4399 int invisible_found_p;
4400
4401 xassert (it != NULL && start_charpos <= end_charpos);
4402
4403 /* Is text at START invisible? */
4404 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4405 it->window);
4406 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4407 invisible_found_p = 1;
4408 else
4409 {
4410 limit = Fnext_single_property_change (make_number (start_charpos),
4411 Qinvisible,
4412 Fcurrent_buffer (),
4413 make_number (end_charpos));
4414 invisible_found_p = XFASTINT (limit) < end_charpos;
4415 }
4416
4417 return invisible_found_p;
4418
4419#else /* not USE_TEXT_PROPERTIES */
4420 return 0;
4421#endif /* not USE_TEXT_PROPERTIES */
4422}
4423
4424
4425/* Move IT by a specified number DVPOS of screen lines down. DVPOS
4426 negative means move up. DVPOS == 0 means move to the start of the
4427 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4428 NEED_Y_P is zero, IT->current_y will be left unchanged.
4429
4430 Further optimization ideas: If we would know that IT->f doesn't use
4431 a face with proportional font, we could be faster for
4432 truncate-lines nil. */
4433
4434void
4435move_it_by_lines (it, dvpos, need_y_p)
4436 struct it *it;
4437 int dvpos, need_y_p;
4438{
4439 struct position pos;
4440
4441 if (!FRAME_WINDOW_P (it->f))
4442 {
4443 struct text_pos textpos;
4444
4445 /* We can use vmotion on frames without proportional fonts. */
4446 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4447 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4448 reseat (it, textpos, 1);
4449 it->vpos += pos.vpos;
4450 it->current_y += pos.vpos;
4451 }
4452 else if (dvpos == 0)
4453 {
4454 /* DVPOS == 0 means move to the start of the screen line. */
4455 move_it_vertically_backward (it, 0);
4456 xassert (it->current_x == 0 && it->hpos == 0);
4457 }
4458 else if (dvpos > 0)
4459 {
4460 /* If there are no continuation lines, and if there is no
4461 selective display, try the simple method of moving forward
4462 DVPOS newlines, then see where we are. */
4463 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4464 {
4465 int shortage = 0, charpos;
4466
4467 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4468 charpos = IT_CHARPOS (*it) + 1;
4469 else
4470 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4471 &shortage, 0);
4472
4473 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4474 {
4475 struct text_pos pos;
4476 CHARPOS (pos) = charpos;
4477 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4478 reseat (it, pos, 1);
4479 it->vpos += dvpos - shortage;
4480 it->hpos = it->current_x = 0;
4481 return;
4482 }
4483 }
4484
4485 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4486 }
4487 else
4488 {
4489 struct it it2;
4490 int start_charpos, i;
4491
4492 /* If there are no continuation lines, and if there is no
4493 selective display, try the simple method of moving backward
4494 -DVPOS newlines. */
4495 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4496 {
4497 int shortage;
4498 int charpos = IT_CHARPOS (*it);
4499 int bytepos = IT_BYTEPOS (*it);
4500
4501 /* If in the middle of a line, go to its start. */
4502 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4503 {
4504 charpos = find_next_newline_no_quit (charpos, -1);
4505 bytepos = CHAR_TO_BYTE (charpos);
4506 }
4507
4508 if (charpos == BEGV)
4509 {
4510 struct text_pos pos;
4511 CHARPOS (pos) = charpos;
4512 BYTEPOS (pos) = bytepos;
4513 reseat (it, pos, 1);
4514 it->hpos = it->current_x = 0;
4515 return;
4516 }
4517 else
4518 {
4519 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4520 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4521 {
4522 struct text_pos pos;
4523 CHARPOS (pos) = charpos;
4524 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4525 reseat (it, pos, 1);
4526 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4527 it->hpos = it->current_x = 0;
4528 return;
4529 }
4530 }
4531 }
4532
4533 /* Go back -DVPOS visible lines and reseat the iterator there. */
4534 start_charpos = IT_CHARPOS (*it);
4535 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4536 back_to_previous_visible_line_start (it);
4537 reseat (it, it->current.pos, 1);
4538 it->current_x = it->hpos = 0;
4539
4540 /* Above call may have moved too far if continuation lines
4541 are involved. Scan forward and see if it did. */
4542 it2 = *it;
4543 it2.vpos = it2.current_y = 0;
4544 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4545 it->vpos -= it2.vpos;
4546 it->current_y -= it2.current_y;
4547 it->current_x = it->hpos = 0;
4548
4549 /* If we moved too far, move IT some lines forward. */
4550 if (it2.vpos > -dvpos)
4551 {
4552 int delta = it2.vpos + dvpos;
4553 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4554 }
4555 }
4556}
4557
4558
4559\f
4560/***********************************************************************
4561 Messages
4562 ***********************************************************************/
4563
4564
4565/* Output a newline in the *Messages* buffer if "needs" one. */
4566
4567void
4568message_log_maybe_newline ()
4569{
4570 if (message_log_need_newline)
4571 message_dolog ("", 0, 1, 0);
4572}
4573
4574
4575/* Add a string M of length LEN to the message log, optionally
4576 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4577 nonzero, means interpret the contents of M as multibyte. This
4578 function calls low-level routines in order to bypass text property
4579 hooks, etc. which might not be safe to run. */
4580
4581void
4582message_dolog (m, len, nlflag, multibyte)
4583 char *m;
4584 int len, nlflag, multibyte;
4585{
4586 if (!NILP (Vmessage_log_max))
4587 {
4588 struct buffer *oldbuf;
4589 Lisp_Object oldpoint, oldbegv, oldzv;
4590 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4591 int point_at_end = 0;
4592 int zv_at_end = 0;
4593 Lisp_Object old_deactivate_mark, tem;
4594 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4595
4596 old_deactivate_mark = Vdeactivate_mark;
4597 oldbuf = current_buffer;
4598 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4599 current_buffer->undo_list = Qt;
4600
4601 oldpoint = Fpoint_marker ();
4602 oldbegv = Fpoint_min_marker ();
4603 oldzv = Fpoint_max_marker ();
4604 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4605
4606 if (PT == Z)
4607 point_at_end = 1;
4608 if (ZV == Z)
4609 zv_at_end = 1;
4610
4611 BEGV = BEG;
4612 BEGV_BYTE = BEG_BYTE;
4613 ZV = Z;
4614 ZV_BYTE = Z_BYTE;
4615 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4616
4617 /* Insert the string--maybe converting multibyte to single byte
4618 or vice versa, so that all the text fits the buffer. */
4619 if (multibyte
4620 && NILP (current_buffer->enable_multibyte_characters))
4621 {
4622 int i, c, nbytes;
4623 unsigned char work[1];
4624
4625 /* Convert a multibyte string to single-byte
4626 for the *Message* buffer. */
4627 for (i = 0; i < len; i += nbytes)
4628 {
4fdb80f2 4629 c = string_char_and_length (m + i, len - i, &nbytes);
5f5c8ee5
GM
4630 work[0] = (SINGLE_BYTE_CHAR_P (c)
4631 ? c
4632 : multibyte_char_to_unibyte (c, Qnil));
4633 insert_1_both (work, 1, 1, 1, 0, 0);
4634 }
4635 }
4636 else if (! multibyte
4637 && ! NILP (current_buffer->enable_multibyte_characters))
4638 {
4639 int i, c, nbytes;
4640 unsigned char *msg = (unsigned char *) m;
4641 unsigned char *str, work[4];
4642 /* Convert a single-byte string to multibyte
4643 for the *Message* buffer. */
4644 for (i = 0; i < len; i++)
4645 {
4646 c = unibyte_char_to_multibyte (msg[i]);
4647 nbytes = CHAR_STRING (c, work, str);
4648 insert_1_both (work, 1, nbytes, 1, 0, 0);
4649 }
4650 }
4651 else if (len)
4652 insert_1 (m, len, 1, 0, 0);
4653
4654 if (nlflag)
4655 {
4656 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4657 insert_1 ("\n", 1, 1, 0, 0);
4658
4659 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4660 this_bol = PT;
4661 this_bol_byte = PT_BYTE;
4662
4663 if (this_bol > BEG)
4664 {
4665 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4666 prev_bol = PT;
4667 prev_bol_byte = PT_BYTE;
4668
4669 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4670 this_bol, this_bol_byte);
4671 if (dup)
4672 {
4673 del_range_both (prev_bol, prev_bol_byte,
4674 this_bol, this_bol_byte, 0);
4675 if (dup > 1)
4676 {
4677 char dupstr[40];
4678 int duplen;
4679
4680 /* If you change this format, don't forget to also
4681 change message_log_check_duplicate. */
4682 sprintf (dupstr, " [%d times]", dup);
4683 duplen = strlen (dupstr);
4684 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4685 insert_1 (dupstr, duplen, 1, 0, 1);
4686 }
4687 }
4688 }
4689
4690 if (NATNUMP (Vmessage_log_max))
4691 {
4692 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4693 -XFASTINT (Vmessage_log_max) - 1, 0);
4694 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4695 }
4696 }
4697 BEGV = XMARKER (oldbegv)->charpos;
4698 BEGV_BYTE = marker_byte_position (oldbegv);
4699
4700 if (zv_at_end)
4701 {
4702 ZV = Z;
4703 ZV_BYTE = Z_BYTE;
4704 }
4705 else
4706 {
4707 ZV = XMARKER (oldzv)->charpos;
4708 ZV_BYTE = marker_byte_position (oldzv);
4709 }
4710
4711 if (point_at_end)
4712 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4713 else
4714 /* We can't do Fgoto_char (oldpoint) because it will run some
4715 Lisp code. */
4716 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4717 XMARKER (oldpoint)->bytepos);
4718
4719 UNGCPRO;
4720 free_marker (oldpoint);
4721 free_marker (oldbegv);
4722 free_marker (oldzv);
4723
4724 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4725 set_buffer_internal (oldbuf);
4726 if (NILP (tem))
4727 windows_or_buffers_changed = old_windows_or_buffers_changed;
4728 message_log_need_newline = !nlflag;
4729 Vdeactivate_mark = old_deactivate_mark;
4730 }
4731}
4732
4733
4734/* We are at the end of the buffer after just having inserted a newline.
4735 (Note: We depend on the fact we won't be crossing the gap.)
4736 Check to see if the most recent message looks a lot like the previous one.
4737 Return 0 if different, 1 if the new one should just replace it, or a
4738 value N > 1 if we should also append " [N times]". */
4739
4740static int
4741message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4742 int prev_bol, this_bol;
4743 int prev_bol_byte, this_bol_byte;
4744{
4745 int i;
4746 int len = Z_BYTE - 1 - this_bol_byte;
4747 int seen_dots = 0;
4748 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4749 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4750
4751 for (i = 0; i < len; i++)
4752 {
4753 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4754 && p1[i] != '\n')
4755 seen_dots = 1;
4756 if (p1[i] != p2[i])
4757 return seen_dots;
4758 }
4759 p1 += len;
4760 if (*p1 == '\n')
4761 return 2;
4762 if (*p1++ == ' ' && *p1++ == '[')
4763 {
4764 int n = 0;
4765 while (*p1 >= '0' && *p1 <= '9')
4766 n = n * 10 + *p1++ - '0';
4767 if (strncmp (p1, " times]\n", 8) == 0)
4768 return n+1;
4769 }
4770 return 0;
4771}
4772
4773
4774/* Display an echo area message M with a specified length of LEN
4775 chars. The string may include null characters. If M is 0, clear
4776 out any existing message, and let the mini-buffer text show through.
4777
4778 The buffer M must continue to exist until after the echo area gets
4779 cleared or some other message gets displayed there. This means do
4780 not pass text that is stored in a Lisp string; do not pass text in
4781 a buffer that was alloca'd. */
4782
4783void
4784message2 (m, len, multibyte)
4785 char *m;
4786 int len;
4787 int multibyte;
4788{
4789 /* First flush out any partial line written with print. */
4790 message_log_maybe_newline ();
4791 if (m)
4792 message_dolog (m, len, 1, multibyte);
4793 message2_nolog (m, len, multibyte);
4794}
4795
4796
4797/* The non-logging counterpart of message2. */
4798
4799void
4800message2_nolog (m, len, multibyte)
4801 char *m;
4802 int len;
4803{
4804 message_enable_multibyte = multibyte;
4805
4806 if (noninteractive)
4807 {
4808 if (noninteractive_need_newline)
4809 putc ('\n', stderr);
4810 noninteractive_need_newline = 0;
4811 if (m)
4812 fwrite (m, len, 1, stderr);
4813 if (cursor_in_echo_area == 0)
4814 fprintf (stderr, "\n");
4815 fflush (stderr);
4816 }
4817 /* A null message buffer means that the frame hasn't really been
4818 initialized yet. Error messages get reported properly by
4819 cmd_error, so this must be just an informative message; toss it. */
4820 else if (INTERACTIVE
4821 && selected_frame->glyphs_initialized_p
4822 && FRAME_MESSAGE_BUF (selected_frame))
4823 {
4824 Lisp_Object mini_window;
4825 struct frame *f;
4826
4827 /* Get the frame containing the mini-buffer
4828 that the selected frame is using. */
4829 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4830 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4831
4832 FRAME_SAMPLE_VISIBILITY (f);
4833 if (FRAME_VISIBLE_P (selected_frame)
4834 && ! FRAME_VISIBLE_P (f))
4835 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4836
4837 if (m)
4838 {
c6e89d6c 4839 set_message (m, Qnil, len, multibyte);
5f5c8ee5
GM
4840 if (minibuffer_auto_raise)
4841 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4842 }
4843 else
c6e89d6c 4844 clear_message (1, 1);
5f5c8ee5 4845
c6e89d6c 4846 do_pending_window_change (0);
5f5c8ee5 4847 echo_area_display (1);
c6e89d6c 4848 do_pending_window_change (0);
5f5c8ee5
GM
4849 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4850 (*frame_up_to_date_hook) (f);
4851 }
4852}
4853
4854
c6e89d6c
GM
4855/* Display an echo area message M with a specified length of NBYTES
4856 bytes. The string may include null characters. If M is not a
5f5c8ee5
GM
4857 string, clear out any existing message, and let the mini-buffer
4858 text show through. */
4859
4860void
c6e89d6c 4861message3 (m, nbytes, multibyte)
5f5c8ee5 4862 Lisp_Object m;
c6e89d6c 4863 int nbytes;
5f5c8ee5
GM
4864 int multibyte;
4865{
4866 struct gcpro gcpro1;
4867
4868 GCPRO1 (m);
4869
4870 /* First flush out any partial line written with print. */
4871 message_log_maybe_newline ();
4872 if (STRINGP (m))
c6e89d6c
GM
4873 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
4874 message3_nolog (m, nbytes, multibyte);
5f5c8ee5
GM
4875
4876 UNGCPRO;
4877}
4878
4879
4880/* The non-logging version of message3. */
4881
4882void
c6e89d6c 4883message3_nolog (m, nbytes, multibyte)
5f5c8ee5 4884 Lisp_Object m;
c6e89d6c 4885 int nbytes, multibyte;
5f5c8ee5
GM
4886{
4887 message_enable_multibyte = multibyte;
4888
4889 if (noninteractive)
4890 {
4891 if (noninteractive_need_newline)
4892 putc ('\n', stderr);
4893 noninteractive_need_newline = 0;
4894 if (STRINGP (m))
c6e89d6c 4895 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5f5c8ee5
GM
4896 if (cursor_in_echo_area == 0)
4897 fprintf (stderr, "\n");
4898 fflush (stderr);
4899 }
4900 /* A null message buffer means that the frame hasn't really been
4901 initialized yet. Error messages get reported properly by
4902 cmd_error, so this must be just an informative message; toss it. */
4903 else if (INTERACTIVE
4904 && selected_frame->glyphs_initialized_p
4905 && FRAME_MESSAGE_BUF (selected_frame))
4906 {
4907 Lisp_Object mini_window;
c6e89d6c 4908 Lisp_Object frame;
5f5c8ee5
GM
4909 struct frame *f;
4910
4911 /* Get the frame containing the mini-buffer
4912 that the selected frame is using. */
4913 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
c6e89d6c
GM
4914 frame = XWINDOW (mini_window)->frame;
4915 f = XFRAME (frame);
5f5c8ee5
GM
4916
4917 FRAME_SAMPLE_VISIBILITY (f);
4918 if (FRAME_VISIBLE_P (selected_frame)
c6e89d6c
GM
4919 && !FRAME_VISIBLE_P (f))
4920 Fmake_frame_visible (frame);
5f5c8ee5 4921
c6e89d6c 4922 if (STRINGP (m) && XSTRING (m)->size)
5f5c8ee5 4923 {
c6e89d6c
GM
4924 set_message (NULL, m, nbytes, multibyte);
4925 Fraise_frame (frame);
5f5c8ee5
GM
4926 }
4927 else
c6e89d6c 4928 clear_message (1, 1);
5f5c8ee5 4929
c6e89d6c 4930 do_pending_window_change (0);
5f5c8ee5 4931 echo_area_display (1);
c6e89d6c 4932 do_pending_window_change (0);
5f5c8ee5
GM
4933 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4934 (*frame_up_to_date_hook) (f);
4935 }
4936}
4937
4938
4939/* Display a null-terminated echo area message M. If M is 0, clear
4940 out any existing message, and let the mini-buffer text show through.
4941
4942 The buffer M must continue to exist until after the echo area gets
4943 cleared or some other message gets displayed there. Do not pass
4944 text that is stored in a Lisp string. Do not pass text in a buffer
4945 that was alloca'd. */
4946
4947void
4948message1 (m)
4949 char *m;
4950{
4951 message2 (m, (m ? strlen (m) : 0), 0);
4952}
4953
4954
4955/* The non-logging counterpart of message1. */
4956
4957void
4958message1_nolog (m)
4959 char *m;
4960{
4961 message2_nolog (m, (m ? strlen (m) : 0), 0);
4962}
4963
4964/* Display a message M which contains a single %s
4965 which gets replaced with STRING. */
4966
4967void
4968message_with_string (m, string, log)
4969 char *m;
4970 Lisp_Object string;
4971 int log;
4972{
4973 if (noninteractive)
4974 {
4975 if (m)
4976 {
4977 if (noninteractive_need_newline)
4978 putc ('\n', stderr);
4979 noninteractive_need_newline = 0;
4980 fprintf (stderr, m, XSTRING (string)->data);
4981 if (cursor_in_echo_area == 0)
4982 fprintf (stderr, "\n");
4983 fflush (stderr);
4984 }
4985 }
4986 else if (INTERACTIVE)
4987 {
4988 /* The frame whose minibuffer we're going to display the message on.
4989 It may be larger than the selected frame, so we need
4990 to use its buffer, not the selected frame's buffer. */
4991 Lisp_Object mini_window;
4992 FRAME_PTR f;
4993
4994 /* Get the frame containing the minibuffer
4995 that the selected frame is using. */
4996 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4997 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4998
4999 /* A null message buffer means that the frame hasn't really been
5000 initialized yet. Error messages get reported properly by
5001 cmd_error, so this must be just an informative message; toss it. */
5002 if (FRAME_MESSAGE_BUF (f))
5003 {
5004 int len;
5005 char *a[1];
5006 a[0] = (char *) XSTRING (string)->data;
5007
5008 len = doprnt (FRAME_MESSAGE_BUF (f),
5009 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5010
5011 if (log)
5012 message2 (FRAME_MESSAGE_BUF (f), len,
5013 STRING_MULTIBYTE (string));
5014 else
5015 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5016 STRING_MULTIBYTE (string));
5017
5018 /* Print should start at the beginning of the message
5019 buffer next time. */
5020 message_buf_print = 0;
5021 }
5022 }
5023}
5024
5025
5f5c8ee5
GM
5026/* Dump an informative message to the minibuf. If M is 0, clear out
5027 any existing message, and let the mini-buffer text show through. */
5028
5029/* VARARGS 1 */
5030void
5031message (m, a1, a2, a3)
5032 char *m;
5033 EMACS_INT a1, a2, a3;
5034{
5035 if (noninteractive)
5036 {
5037 if (m)
5038 {
5039 if (noninteractive_need_newline)
5040 putc ('\n', stderr);
5041 noninteractive_need_newline = 0;
5042 fprintf (stderr, m, a1, a2, a3);
5043 if (cursor_in_echo_area == 0)
5044 fprintf (stderr, "\n");
5045 fflush (stderr);
5046 }
5047 }
5048 else if (INTERACTIVE)
5049 {
5050 /* The frame whose mini-buffer we're going to display the message
5051 on. It may be larger than the selected frame, so we need to
5052 use its buffer, not the selected frame's buffer. */
5053 Lisp_Object mini_window;
5054 struct frame *f;
5055
5056 /* Get the frame containing the mini-buffer
5057 that the selected frame is using. */
5058 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5059 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5060
5061 /* A null message buffer means that the frame hasn't really been
5062 initialized yet. Error messages get reported properly by
5063 cmd_error, so this must be just an informative message; toss
5064 it. */
5065 if (FRAME_MESSAGE_BUF (f))
5066 {
5067 if (m)
5068 {
5069 int len;
5070#ifdef NO_ARG_ARRAY
5071 char *a[3];
5072 a[0] = (char *) a1;
5073 a[1] = (char *) a2;
5074 a[2] = (char *) a3;
5075
5076 len = doprnt (FRAME_MESSAGE_BUF (f),
5077 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5078#else
5079 len = doprnt (FRAME_MESSAGE_BUF (f),
5080 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5081 (char **) &a1);
5082#endif /* NO_ARG_ARRAY */
5083
5084 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5085 }
5086 else
5087 message1 (0);
5088
5089 /* Print should start at the beginning of the message
5090 buffer next time. */
5091 message_buf_print = 0;
5092 }
5093 }
5094}
5095
5096
5097/* The non-logging version of message. */
5098
5099void
5100message_nolog (m, a1, a2, a3)
5101 char *m;
5102 EMACS_INT a1, a2, a3;
5103{
5104 Lisp_Object old_log_max;
5105 old_log_max = Vmessage_log_max;
5106 Vmessage_log_max = Qnil;
5107 message (m, a1, a2, a3);
5108 Vmessage_log_max = old_log_max;
5109}
5110
5111
c6e89d6c
GM
5112/* Display the current message in the current mini-buffer. This is
5113 only called from error handlers in process.c, and is not time
5114 critical. */
5f5c8ee5
GM
5115
5116void
5117update_echo_area ()
5118{
c6e89d6c
GM
5119 if (!NILP (echo_area_buffer[0]))
5120 {
5121 Lisp_Object string;
5122 string = Fcurrent_message ();
5123 message3 (string, XSTRING (string)->size,
5124 !NILP (current_buffer->enable_multibyte_characters));
5125 }
5126}
5127
5128
5129/* Call FN with args A1..A5 with either the current or last displayed
5130 echo_area_buffer as current buffer.
5131
5132 WHICH zero means use the current message buffer
5133 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5134 from echo_buffer[] and clear it.
5135
5136 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5137 suitable buffer from echo_buffer[] and clear it.
5138
5139 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5140 that the current message becomes the last displayed one, make
5141 choose a suitable buffer for echo_area_buffer[0], and clear it.
5142
5143 Value is what FN returns. */
5144
5145static int
5146with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5)
5147 struct window *w;
5148 int which;
5149 int (*fn) ();
5150 int a1, a2, a3, a4, a5;
5151{
5152 Lisp_Object buffer;
5153 int i, this_one, the_other, clear_buffer_p, rc;
5154 int count = specpdl_ptr - specpdl;
5155
5156 /* If buffers aren't life, make new ones. */
5157 for (i = 0; i < 2; ++i)
5158 if (!BUFFERP (echo_buffer[i])
5159 || NILP (XBUFFER (echo_buffer[i])->name))
5160 {
5161 char name[30];
5162 sprintf (name, " *Echo Area %d*", i);
5163 echo_buffer[i] = Fget_buffer_create (build_string (name));
5164 }
5165
5166 clear_buffer_p = 0;
5167
5168 if (which == 0)
5169 this_one = 0, the_other = 1;
5170 else if (which > 0)
5171 this_one = 1, the_other = 0;
5f5c8ee5 5172 else
c6e89d6c
GM
5173 {
5174 this_one = 0, the_other = 1;
5175 clear_buffer_p = 1;
5176
5177 /* We need a fresh one in case the current echo buffer equals
5178 the one containing the last displayed echo area message. */
5179 if (!NILP (echo_area_buffer[this_one])
5180 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5181 echo_area_buffer[this_one] = Qnil;
5182
5183 }
5184
5185 /* Choose a suitable buffer from echo_buffer[] is we don't
5186 have one. */
5187 if (NILP (echo_area_buffer[this_one]))
5188 {
5189 echo_area_buffer[this_one]
5190 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5191 ? echo_buffer[the_other]
5192 : echo_buffer[this_one]);
5193 clear_buffer_p = 1;
5194 }
5195
5196 buffer = echo_area_buffer[this_one];
5197
5198 record_unwind_protect (unwind_with_echo_area_buffer,
5199 with_echo_area_buffer_unwind_data (w));
5200
5201 /* Make the echo area buffer current. Note that for display
5202 purposes, it is not necessary that the displayed window's buffer
5203 == current_buffer, except for text property lookup. So, let's
5204 only set that buffer temporarily here without doing a full
5205 Fset_window_buffer. We must also change w->pointm, though,
5206 because otherwise an assertions in unshow_buffer fails, and Emacs
5207 aborts. */
9142dd5b 5208 set_buffer_internal_1 (XBUFFER (buffer));
c6e89d6c
GM
5209 if (w)
5210 {
5211 w->buffer = buffer;
5212 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5213 }
5214 current_buffer->truncate_lines = Qnil;
5215 current_buffer->undo_list = Qt;
5216 current_buffer->read_only = Qnil;
5217
5218 if (clear_buffer_p && Z > BEG)
5219 del_range (BEG, Z);
5220
5221 xassert (BEGV >= BEG);
5222 xassert (ZV <= Z && ZV >= BEGV);
5223
5224 rc = fn (a1, a2, a3, a4, a5);
5225
5226 xassert (BEGV >= BEG);
5227 xassert (ZV <= Z && ZV >= BEGV);
5228
5229 unbind_to (count, Qnil);
5230 return rc;
5f5c8ee5
GM
5231}
5232
5233
c6e89d6c
GM
5234/* Save state that should be preserved around the call to the function
5235 FN called in with_echo_area_buffer. */
5f5c8ee5 5236
c6e89d6c
GM
5237static Lisp_Object
5238with_echo_area_buffer_unwind_data (w)
5239 struct window *w;
5f5c8ee5 5240{
c6e89d6c
GM
5241 int i = 0;
5242 Lisp_Object vector;
5f5c8ee5 5243
c6e89d6c
GM
5244 /* Reduce consing by keeping one vector in
5245 Vwith_echo_area_save_vector. */
5246 vector = Vwith_echo_area_save_vector;
5247 Vwith_echo_area_save_vector = Qnil;
5248
5249 if (NILP (vector))
9142dd5b 5250 vector = Fmake_vector (make_number (7), Qnil);
c6e89d6c
GM
5251
5252 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5253 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5254 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
c6e89d6c
GM
5255
5256 if (w)
5257 {
5258 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5259 XVECTOR (vector)->contents[i++] = w->buffer;
5260 XVECTOR (vector)->contents[i++]
5261 = make_number (XMARKER (w->pointm)->charpos);
5262 XVECTOR (vector)->contents[i++]
5263 = make_number (XMARKER (w->pointm)->bytepos);
5264 }
5265 else
5266 {
5267 int end = i + 4;
5268 while (i < end)
5269 XVECTOR (vector)->contents[i++] = Qnil;
5270 }
5f5c8ee5 5271
c6e89d6c
GM
5272 xassert (i == XVECTOR (vector)->size);
5273 return vector;
5274}
5f5c8ee5 5275
5f5c8ee5 5276
c6e89d6c
GM
5277/* Restore global state from VECTOR which was created by
5278 with_echo_area_buffer_unwind_data. */
5279
5280static Lisp_Object
5281unwind_with_echo_area_buffer (vector)
5282 Lisp_Object vector;
5283{
5284 int i = 0;
5285
9142dd5b 5286 set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
c6e89d6c
GM
5287 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5288 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
c6e89d6c
GM
5289
5290 if (WINDOWP (XVECTOR (vector)->contents[i]))
5291 {
5292 struct window *w;
5293 Lisp_Object buffer, charpos, bytepos;
5294
5295 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5296 buffer = XVECTOR (vector)->contents[i]; ++i;
5297 charpos = XVECTOR (vector)->contents[i]; ++i;
5298 bytepos = XVECTOR (vector)->contents[i]; ++i;
5299
5300 w->buffer = buffer;
5301 set_marker_both (w->pointm, buffer,
5302 XFASTINT (charpos), XFASTINT (bytepos));
5303 }
5304
5305 Vwith_echo_area_save_vector = vector;
5306 return Qnil;
5307}
5308
5309
5310/* Set up the echo area for use by print functions. MULTIBYTE_P
5311 non-zero means we will print multibyte. */
5312
5313void
5314setup_echo_area_for_printing (multibyte_p)
5315 int multibyte_p;
5316{
5317 if (!message_buf_print)
5318 {
5319 /* A message has been output since the last time we printed.
5320 Choose a fresh echo area buffer. */
5321 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5322 echo_area_buffer[0] = echo_buffer[1];
5323 else
5324 echo_area_buffer[0] = echo_buffer[0];
5325
5326 /* Switch to that buffer and clear it. */
5327 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5328 if (Z > BEG)
5329 del_range (BEG, Z);
5330 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5331
5332 /* Set up the buffer for the multibyteness we need. */
5333 if (multibyte_p
5334 != !NILP (current_buffer->enable_multibyte_characters))
5335 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5336
5337 /* Raise the frame containing the echo area. */
5338 if (minibuffer_auto_raise)
5339 {
5340 Lisp_Object mini_window;
5341 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5342 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5343 }
5344
5345 message_buf_print = 1;
5346 }
5347 else if (current_buffer != XBUFFER (echo_area_buffer[0]))
5348 /* Someone switched buffers between print requests. */
5349 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5350}
5351
5352
dd2eb166
GM
5353/* Display an echo area message in window W. Value is non-zero if W's
5354 height is changed. If display_last_displayed_message_p is
5355 non-zero, display the message that was last displayed, otherwise
5356 display the current message. */
c6e89d6c
GM
5357
5358static int
5359display_echo_area (w)
5360 struct window *w;
5361{
dd2eb166
GM
5362 int i, no_message_p, window_height_changed_p;
5363
5364 /* If there is no message, we must call display_echo_area_1
5365 nevertheless because it resizes the window. But we will have to
5366 reset the echo_area_buffer in question to nil at the end because
5367 with_echo_area_buffer will sets it to an empty buffer. */
5368 i = display_last_displayed_message_p ? 1 : 0;
5369 no_message_p = NILP (echo_area_buffer[i]);
5370
5371 window_height_changed_p
5372 = with_echo_area_buffer (w, display_last_displayed_message_p,
5373 (int (*) ()) display_echo_area_1, w);
5374
5375 if (no_message_p)
5376 echo_area_buffer[i] = Qnil;
5377
5378 return window_height_changed_p;
c6e89d6c
GM
5379}
5380
5381
5382/* Helper for display_echo_area. Display the current buffer which
5383 contains the current echo area message in window W, a mini-window.
5384 Change the height of W so that all of the message is displayed.
5385 Value is non-zero if height of W was changed. */
5386
5387static int
5388display_echo_area_1 (w)
5389 struct window *w;
5390{
5391 Lisp_Object window;
5392 struct frame *f = XFRAME (w->frame);
5393 struct text_pos start;
5394 int window_height_changed_p = 0;
5395
5396 /* Do this before displaying, so that we have a large enough glyph
5397 matrix for the display. */
5398 window_height_changed_p = resize_mini_window (w);
5399
5400 /* Display. */
5401 clear_glyph_matrix (w->desired_matrix);
5402 XSETWINDOW (window, w);
5403 SET_TEXT_POS (start, BEG, BEG_BYTE);
5404 try_window (window, start);
5405
c6e89d6c
GM
5406 return window_height_changed_p;
5407}
5408
5409
5410/* Resize mini-window W to fit the size of its contents. Value is
5411 non-zero if the window height has been changed. */
5412
5413static int
5414resize_mini_window (w)
5415 struct window *w;
5416{
5417 struct frame *f = XFRAME (w->frame);
5418 int window_height_changed_p = 0;
5419
5420 xassert (MINI_WINDOW_P (w));
5421
5422 if (!FRAME_MINIBUF_ONLY_P (f))
5423 {
5424 struct it it;
dd2eb166
GM
5425 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
5426 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
5427 int height, max_height;
5428 int unit = CANON_Y_UNIT (f);
5429 struct text_pos start;
9142dd5b 5430
c6e89d6c 5431 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
c6e89d6c 5432
dd2eb166
GM
5433 /* Compute the max. number of lines specified by the user. */
5434 if (FLOATP (Vmax_mini_window_height))
5435 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
5436 else if (INTEGERP (Vmax_mini_window_height))
5437 max_height = XINT (Vmax_mini_window_height);
5438
5439 /* Correct that max. height if it's bogus. */
5440 max_height = max (1, max_height);
5441 max_height = min (total_height, max_height);
5442
5443 /* Find out the height of the text in the window. */
5444 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
5445 height = (unit - 1 + it.current_y + last_height) / unit;
5446 height = max (1, height);
5447
5448 /* Compute a suitable window start. */
5449 if (height > max_height)
5450 {
5451 height = max_height;
5452 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5453 move_it_vertically_backward (&it, (height - 1) * unit);
5454 start = it.current.pos;
5455 }
5456 else
5457 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5458 SET_MARKER_FROM_TEXT_POS (w->start, start);
5459
5460 /* Change window's height, if necessary. */
9142dd5b
GM
5461 if (height > XFASTINT (w->height)
5462 || (height < XFASTINT (w->height)
5463 && NILP (Vresize_mini_config)))
dd2eb166
GM
5464 {
5465 Lisp_Object old_selected_window;
9142dd5b
GM
5466
5467 if (NILP (Vresize_mini_config))
5468 Vresize_mini_config = Fcurrent_window_configuration (Qnil);
dd2eb166
GM
5469
5470 old_selected_window = selected_window;
5471 XSETWINDOW (selected_window, w);
5472 change_window_height (height - XFASTINT (w->height), 0);
5473 selected_window = old_selected_window;
5474 window_height_changed_p = 1;
c6e89d6c 5475 }
9142dd5b
GM
5476 else if (height < XFASTINT (w->height)
5477 && !NILP (Vresize_mini_config))
5478 {
5479 Fset_window_configuration (Vresize_mini_config);
5480 Vresize_mini_config = Qnil;
5481 window_height_changed_p = 1;
5482 }
c6e89d6c
GM
5483 }
5484
5485 return window_height_changed_p;
5486}
5487
5488
5489/* Value is the current message, a string, or nil if there is no
5490 current message. */
5491
5492Lisp_Object
5493current_message ()
5494{
5495 Lisp_Object msg;
5496
5497 if (NILP (echo_area_buffer[0]))
5498 msg = Qnil;
5499 else
5500 {
5501 with_echo_area_buffer (0, 0, (int (*) ()) current_message_1, &msg);
5502 if (NILP (msg))
5503 echo_area_buffer[0] = Qnil;
5504 }
5505
5506 return msg;
5507}
5508
5509
5510static int
5511current_message_1 (msg)
5512 Lisp_Object *msg;
5513{
5514 if (Z > BEG)
5515 *msg = make_buffer_string (BEG, Z, 1);
5516 else
5517 *msg = Qnil;
5518 return 0;
5519}
5520
5521
5522/* Push the current message on Vmessage_stack for later restauration
5523 by restore_message. Value is non-zero if the current message isn't
5524 empty. This is a relatively infrequent operation, so it's not
5525 worth optimizing. */
5526
5527int
5528push_message ()
5529{
5530 Lisp_Object msg;
5531 msg = current_message ();
5532 Vmessage_stack = Fcons (msg, Vmessage_stack);
5533 return STRINGP (msg);
5534}
5535
5536
5537/* Restore message display from the top of Vmessage_stack. */
5538
5539void
5540restore_message ()
5541{
5542 Lisp_Object msg;
5543
5544 xassert (CONSP (Vmessage_stack));
5545 msg = XCAR (Vmessage_stack);
5546 if (STRINGP (msg))
5547 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
5548 else
5549 message3_nolog (msg, 0, 0);
5550}
5551
5552
5553/* Pop the top-most entry off Vmessage_stack. */
5554
5555void
5556pop_message ()
5557{
5558 xassert (CONSP (Vmessage_stack));
5559 Vmessage_stack = XCDR (Vmessage_stack);
5560}
5561
5562
5563/* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
5564 exits. If the stack is not empty, we have a missing pop_message
5565 somewhere. */
5566
5567void
5568check_message_stack ()
5569{
5570 if (!NILP (Vmessage_stack))
5571 abort ();
5572}
5573
5574
5575/* Truncate to NCHARS what will be displayed in the echo area the next
5576 time we display it---but don't redisplay it now. */
5577
5578void
5579truncate_echo_area (nchars)
5580 int nchars;
5581{
5582 if (nchars == 0)
5583 echo_area_buffer[0] = Qnil;
5584 /* A null message buffer means that the frame hasn't really been
5585 initialized yet. Error messages get reported properly by
5586 cmd_error, so this must be just an informative message; toss it. */
5587 else if (!noninteractive
5588 && INTERACTIVE
5589 && FRAME_MESSAGE_BUF (selected_frame)
5590 && !NILP (echo_area_buffer[0]))
5591 with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
5592}
5593
5594
5595/* Helper function for truncate_echo_area. Truncate the current
5596 message to at most NCHARS characters. */
5597
5598static int
5599truncate_message_1 (nchars)
5600 int nchars;
5601{
5602 if (BEG + nchars < Z)
5603 del_range (BEG + nchars, Z);
5604 if (Z == BEG)
5605 echo_area_buffer[0] = Qnil;
5606 return 0;
5607}
5608
5609
5610/* Set the current message to a substring of S or STRING.
5611
5612 If STRING is a Lisp string, set the message to the first NBYTES
5613 bytes from STRING. NBYTES zero means use the whole string. If
5614 STRING is multibyte, the message will be displayed multibyte.
5615
5616 If S is not null, set the message to the first LEN bytes of S. LEN
5617 zero means use the whole string. MULTIBYTE_P non-zero means S is
5618 multibyte. Display the message multibyte in that case. */
5619
5620void
5621set_message (s, string, nbytes, multibyte_p)
5622 char *s;
5623 Lisp_Object string;
5624 int nbytes;
5625{
5626 message_enable_multibyte
5627 = ((s && multibyte_p)
5628 || (STRINGP (string) && STRING_MULTIBYTE (string)));
5629
5630 with_echo_area_buffer (0, -1, (int (*) ()) set_message_1,
5631 s, string, nbytes, multibyte_p);
5632 message_buf_print = 0;
5633}
5634
5635
5636/* Helper function for set_message. Arguments have the same meaning
5637 as there. This function is called with the echo area buffer being
5638 current. */
5639
5640static int
5641set_message_1 (s, string, nbytes, multibyte_p)
5642 char *s;
5643 Lisp_Object string;
5644 int nbytes, multibyte_p;
5645{
5646 xassert (BEG == Z);
5647
5648 /* Change multibyteness of the echo buffer appropriately. */
5649 if (message_enable_multibyte
5650 != !NILP (current_buffer->enable_multibyte_characters))
5651 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
5652
5653 /* Insert new message at BEG. */
5654 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5655
5656 if (STRINGP (string))
5657 {
5658 int nchars;
5659
5660 if (nbytes == 0)
5661 nbytes = XSTRING (string)->size_byte;
5662 nchars = string_byte_to_char (string, nbytes);
5663
5664 /* This function takes care of single/multibyte conversion. We
5665 just have to ensure that the echo area buffer has the right
5666 setting of enable_multibyte_characters. */
5667 insert_from_string (string, 0, 0, nchars, nbytes, 1);
5668 }
5669 else if (s)
5670 {
5671 if (nbytes == 0)
5672 nbytes = strlen (s);
5673
5674 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
5675 {
5676 /* Convert from multi-byte to single-byte. */
5677 int i, c, n;
5678 unsigned char work[1];
5679
5680 /* Convert a multibyte string to single-byte. */
5681 for (i = 0; i < nbytes; i += n)
5682 {
5683 c = string_char_and_length (s + i, nbytes - i, &n);
5684 work[0] = (SINGLE_BYTE_CHAR_P (c)
5685 ? c
5686 : multibyte_char_to_unibyte (c, Qnil));
5687 insert_1_both (work, 1, 1, 1, 0, 0);
5688 }
5689 }
5690 else if (!multibyte_p
5691 && !NILP (current_buffer->enable_multibyte_characters))
5692 {
5693 /* Convert from single-byte to multi-byte. */
5694 int i, c, n;
5695 unsigned char *msg = (unsigned char *) s;
5696 unsigned char *str, work[4];
5697
5698 /* Convert a single-byte string to multibyte. */
5699 for (i = 0; i < nbytes; i++)
5700 {
5701 c = unibyte_char_to_multibyte (msg[i]);
5702 n = CHAR_STRING (c, work, str);
5703 insert_1_both (work, 1, n, 1, 0, 0);
5704 }
5705 }
5706 else
5707 insert_1 (s, nbytes, 1, 0, 0);
5708 }
5709
5710 return 0;
5711}
5712
5713
5714/* Clear messages. CURRENT_P non-zero means clear the current
5715 message. LAST_DISPLAYED_P non-zero means clear the message
5716 last displayed. */
5717
5718void
5719clear_message (current_p, last_displayed_p)
5720 int current_p, last_displayed_p;
5721{
5722 if (current_p)
5723 echo_area_buffer[0] = Qnil;
5724
5725 if (last_displayed_p)
5726 echo_area_buffer[1] = Qnil;
5727
5728 message_buf_print = 0;
5729}
5730
5731/* Clear garbaged frames.
5732
5733 This function is used where the old redisplay called
5734 redraw_garbaged_frames which in turn called redraw_frame which in
5735 turn called clear_frame. The call to clear_frame was a source of
5736 flickering. I believe a clear_frame is not necessary. It should
5737 suffice in the new redisplay to invalidate all current matrices,
5738 and ensure a complete redisplay of all windows. */
5739
5740static void
5741clear_garbaged_frames ()
5742{
5f5c8ee5
GM
5743 if (frame_garbaged)
5744 {
5f5c8ee5
GM
5745 Lisp_Object tail, frame;
5746
5747 FOR_EACH_FRAME (tail, frame)
5748 {
5749 struct frame *f = XFRAME (frame);
5750
5751 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5752 {
5753 clear_current_matrices (f);
5754 f->garbaged = 0;
5755 }
5756 }
5757
5758 frame_garbaged = 0;
5759 ++windows_or_buffers_changed;
5760 }
c6e89d6c 5761}
5f5c8ee5 5762
5f5c8ee5 5763
c6e89d6c
GM
5764/* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
5765 non-zero update selected_frame. Value is non-zero if the
5766 mini-windows height has been changed. */
5f5c8ee5 5767
c6e89d6c
GM
5768static int
5769echo_area_display (update_frame_p)
5770 int update_frame_p;
5771{
5772 Lisp_Object mini_window;
5773 struct window *w;
5774 struct frame *f;
5775 int window_height_changed_p = 0;
5776
5777 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5778 w = XWINDOW (mini_window);
5779 f = XFRAME (WINDOW_FRAME (w));
5780
5781 /* Don't display if frame is invisible or not yet initialized. */
5782 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
5783 return 0;
5f5c8ee5 5784
c6e89d6c
GM
5785 /* When Emacs starts, selected_frame may be a visible terminal
5786 frame, even if we run under a window system. If we let this
5787 through, a message would be displayed on the terminal. */
5788#ifdef HAVE_WINDOW_SYSTEM
5789 if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
5790 return 0;
5791#endif /* HAVE_WINDOW_SYSTEM */
5792
5793 /* Redraw garbaged frames. */
5794 if (frame_garbaged)
5795 clear_garbaged_frames ();
5796
5797 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
5798 {
5799 echo_area_window = mini_window;
5800 window_height_changed_p = display_echo_area (w);
5f5c8ee5 5801 w->must_be_updated_p = 1;
c6e89d6c 5802
5f5c8ee5
GM
5803 if (update_frame_p)
5804 {
5805 /* Calling update_single_window is faster when we can use
5806 window-based redisplay. */
5807 if (FRAME_WINDOW_P (f))
5808 {
5809 update_single_window (w, 1);
5810 rif->flush_display (f);
5811 }
5812 else
5813 update_frame (f, 1, 1);
5814 }
5815 }
5816 else if (!EQ (mini_window, selected_window))
5817 windows_or_buffers_changed++;
c6e89d6c 5818
dd2eb166
GM
5819 echo_area_buffer[1] = echo_area_buffer[0];
5820
5f5c8ee5
GM
5821 /* Prevent redisplay optimization in redisplay_internal by resetting
5822 this_line_start_pos. This is done because the mini-buffer now
5823 displays the message instead of its buffer text. */
5824 if (EQ (mini_window, selected_window))
5825 CHARPOS (this_line_start_pos) = 0;
c6e89d6c
GM
5826
5827 return window_height_changed_p;
5f5c8ee5
GM
5828}
5829
5830
5831\f
5832/***********************************************************************
5833 Frame Titles
5834 ***********************************************************************/
5835
5836
5837#ifdef HAVE_WINDOW_SYSTEM
5838
5839/* A buffer for constructing frame titles in it; allocated from the
5840 heap in init_xdisp and resized as needed in store_frame_title_char. */
5841
5842static char *frame_title_buf;
5843
5844/* The buffer's end, and a current output position in it. */
5845
5846static char *frame_title_buf_end;
5847static char *frame_title_ptr;
5848
5849
5850/* Store a single character C for the frame title in frame_title_buf.
5851 Re-allocate frame_title_buf if necessary. */
5852
5853static void
5854store_frame_title_char (c)
5855 char c;
5856{
5857 /* If output position has reached the end of the allocated buffer,
5858 double the buffer's size. */
5859 if (frame_title_ptr == frame_title_buf_end)
5860 {
5861 int len = frame_title_ptr - frame_title_buf;
5862 int new_size = 2 * len * sizeof *frame_title_buf;
5863 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
5864 frame_title_buf_end = frame_title_buf + new_size;
5865 frame_title_ptr = frame_title_buf + len;
5866 }
5867
5868 *frame_title_ptr++ = c;
5869}
5870
5871
5872/* Store part of a frame title in frame_title_buf, beginning at
5873 frame_title_ptr. STR is the string to store. Do not copy more
5874 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
5875 the whole string. Pad with spaces until FIELD_WIDTH number of
5876 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
5877 Called from display_mode_element when it is used to build a frame
5878 title. */
5879
5880static int
5881store_frame_title (str, field_width, precision)
5882 unsigned char *str;
5883 int field_width, precision;
5884{
5885 int n = 0;
5886
5887 /* Copy at most PRECISION chars from STR. */
5888 while ((precision <= 0 || n < precision)
5889 && *str)
5890 {
5891 store_frame_title_char (*str++);
5892 ++n;
5893 }
5894
5895 /* Fill up with spaces until FIELD_WIDTH reached. */
5896 while (field_width > 0
5897 && n < field_width)
5898 {
5899 store_frame_title_char (' ');
5900 ++n;
5901 }
5902
5903 return n;
5904}
5905
5906
5907/* Set the title of FRAME, if it has changed. The title format is
5908 Vicon_title_format if FRAME is iconified, otherwise it is
5909 frame_title_format. */
5910
5911static void
5912x_consider_frame_title (frame)
5913 Lisp_Object frame;
5914{
5915 struct frame *f = XFRAME (frame);
5916
5917 if (FRAME_WINDOW_P (f)
5918 || FRAME_MINIBUF_ONLY_P (f)
5919 || f->explicit_name)
5920 {
5921 /* Do we have more than one visible frame on this X display? */
5922 Lisp_Object tail;
5923 Lisp_Object fmt;
5924 struct buffer *obuf;
5925 int len;
5926 struct it it;
5927
5928 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
5929 {
5930 struct frame *tf = XFRAME (XCONS (tail)->car);
5931
5932 if (tf != f
5933 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
5934 && !FRAME_MINIBUF_ONLY_P (tf)
5935 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
5936 break;
5937 }
5938
5939 /* Set global variable indicating that multiple frames exist. */
5940 multiple_frames = CONSP (tail);
5941
5942 /* Switch to the buffer of selected window of the frame. Set up
5943 frame_title_ptr so that display_mode_element will output into it;
5944 then display the title. */
5945 obuf = current_buffer;
5946 Fset_buffer (XWINDOW (f->selected_window)->buffer);
5947 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
5948 frame_title_ptr = frame_title_buf;
5949 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
5950 NULL, DEFAULT_FACE_ID);
5951 len = display_mode_element (&it, 0, -1, -1, fmt);
5952 frame_title_ptr = NULL;
5953 set_buffer_internal (obuf);
5954
5955 /* Set the title only if it's changed. This avoids consing in
5956 the common case where it hasn't. (If it turns out that we've
5957 already wasted too much time by walking through the list with
5958 display_mode_element, then we might need to optimize at a
5959 higher level than this.) */
5960 if (! STRINGP (f->name)
5961 || STRING_BYTES (XSTRING (f->name)) != len
5962 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
5963 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
5964 }
5965}
5966
5967#else /* not HAVE_WINDOW_SYSTEM */
5968
5969#define frame_title_ptr ((char *)0)
5970#define store_frame_title(str, mincol, maxcol) 0
5971
5972#endif /* not HAVE_WINDOW_SYSTEM */
5973
5974
5975
5976\f
5977/***********************************************************************
5978 Menu Bars
5979 ***********************************************************************/
5980
5981
5982/* Prepare for redisplay by updating menu-bar item lists when
5983 appropriate. This can call eval. */
5984
5985void
5986prepare_menu_bars ()
5987{
5988 int all_windows;
5989 struct gcpro gcpro1, gcpro2;
5990 struct frame *f;
5991 struct frame *tooltip_frame;
5992
5993#ifdef HAVE_X_WINDOWS
5994 tooltip_frame = tip_frame;
5995#else
5996 tooltip_frame = NULL;
5997#endif
5998
5999 /* Update all frame titles based on their buffer names, etc. We do
6000 this before the menu bars so that the buffer-menu will show the
6001 up-to-date frame titles. */
6002#ifdef HAVE_WINDOW_SYSTEM
6003 if (windows_or_buffers_changed || update_mode_lines)
6004 {
6005 Lisp_Object tail, frame;
6006
6007 FOR_EACH_FRAME (tail, frame)
6008 {
6009 f = XFRAME (frame);
6010 if (f != tooltip_frame
6011 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6012 x_consider_frame_title (frame);
6013 }
6014 }
6015#endif /* HAVE_WINDOW_SYSTEM */
6016
6017 /* Update the menu bar item lists, if appropriate. This has to be
6018 done before any actual redisplay or generation of display lines. */
6019 all_windows = (update_mode_lines
6020 || buffer_shared > 1
6021 || windows_or_buffers_changed);
6022 if (all_windows)
6023 {
6024 Lisp_Object tail, frame;
6025 int count = specpdl_ptr - specpdl;
6026
6027 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6028
6029 FOR_EACH_FRAME (tail, frame)
6030 {
6031 f = XFRAME (frame);
6032
6033 /* Ignore tooltip frame. */
6034 if (f == tooltip_frame)
6035 continue;
6036
6037 /* If a window on this frame changed size, report that to
6038 the user and clear the size-change flag. */
6039 if (FRAME_WINDOW_SIZES_CHANGED (f))
6040 {
6041 Lisp_Object functions;
6042
6043 /* Clear flag first in case we get an error below. */
6044 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6045 functions = Vwindow_size_change_functions;
6046 GCPRO2 (tail, functions);
6047
6048 while (CONSP (functions))
6049 {
6050 call1 (XCAR (functions), frame);
6051 functions = XCDR (functions);
6052 }
6053 UNGCPRO;
6054 }
6055
6056 GCPRO1 (tail);
6057 update_menu_bar (f, 0);
6058#ifdef HAVE_WINDOW_SYSTEM
6059 update_toolbar (f, 0);
6060#endif
6061 UNGCPRO;
6062 }
6063
6064 unbind_to (count, Qnil);
6065 }
6066 else
6067 {
6068 update_menu_bar (selected_frame, 1);
6069#ifdef HAVE_WINDOW_SYSTEM
6070 update_toolbar (selected_frame, 1);
6071#endif
6072 }
6073
6074 /* Motif needs this. See comment in xmenu.c. Turn it off when
6075 pending_menu_activation is not defined. */
6076#ifdef USE_X_TOOLKIT
6077 pending_menu_activation = 0;
6078#endif
6079}
6080
6081
6082/* Update the menu bar item list for frame F. This has to be done
6083 before we start to fill in any display lines, because it can call
6084 eval.
6085
6086 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6087
6088static void
6089update_menu_bar (f, save_match_data)
6090 struct frame *f;
6091 int save_match_data;
6092{
6093 Lisp_Object window;
6094 register struct window *w;
6095
6096 window = FRAME_SELECTED_WINDOW (f);
6097 w = XWINDOW (window);
6098
6099 if (update_mode_lines)
6100 w->update_mode_line = Qt;
6101
6102 if (FRAME_WINDOW_P (f)
6103 ?
6104#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6105 FRAME_EXTERNAL_MENU_BAR (f)
6106#else
6107 FRAME_MENU_BAR_LINES (f) > 0
6108#endif
6109 : FRAME_MENU_BAR_LINES (f) > 0)
6110 {
6111 /* If the user has switched buffers or windows, we need to
6112 recompute to reflect the new bindings. But we'll
6113 recompute when update_mode_lines is set too; that means
6114 that people can use force-mode-line-update to request
6115 that the menu bar be recomputed. The adverse effect on
6116 the rest of the redisplay algorithm is about the same as
6117 windows_or_buffers_changed anyway. */
6118 if (windows_or_buffers_changed
6119 || !NILP (w->update_mode_line)
6120 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6121 < BUF_MODIFF (XBUFFER (w->buffer)))
6122 != !NILP (w->last_had_star))
6123 || ((!NILP (Vtransient_mark_mode)
6124 && !NILP (XBUFFER (w->buffer)->mark_active))
6125 != !NILP (w->region_showing)))
6126 {
6127 struct buffer *prev = current_buffer;
6128 int count = specpdl_ptr - specpdl;
6129
6130 set_buffer_internal_1 (XBUFFER (w->buffer));
6131 if (save_match_data)
6132 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6133 if (NILP (Voverriding_local_map_menu_flag))
6134 {
6135 specbind (Qoverriding_terminal_local_map, Qnil);
6136 specbind (Qoverriding_local_map, Qnil);
6137 }
6138
6139 /* Run the Lucid hook. */
6140 call1 (Vrun_hooks, Qactivate_menubar_hook);
6141
6142 /* If it has changed current-menubar from previous value,
6143 really recompute the menu-bar from the value. */
6144 if (! NILP (Vlucid_menu_bar_dirty_flag))
6145 call0 (Qrecompute_lucid_menubar);
6146
6147 safe_run_hooks (Qmenu_bar_update_hook);
6148 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6149
6150 /* Redisplay the menu bar in case we changed it. */
6151#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6152 if (FRAME_WINDOW_P (f))
6153 set_frame_menubar (f, 0, 0);
6154 else
6155 /* On a terminal screen, the menu bar is an ordinary screen
6156 line, and this makes it get updated. */
6157 w->update_mode_line = Qt;
6158#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6159 /* In the non-toolkit version, the menu bar is an ordinary screen
6160 line, and this makes it get updated. */
6161 w->update_mode_line = Qt;
6162#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6163
6164 unbind_to (count, Qnil);
6165 set_buffer_internal_1 (prev);
6166 }
6167 }
6168}
6169
6170
6171\f
6172/***********************************************************************
6173 Toolbars
6174 ***********************************************************************/
6175
6176#ifdef HAVE_WINDOW_SYSTEM
6177
6178/* Update the toolbar item list for frame F. This has to be done
6179 before we start to fill in any display lines. Called from
6180 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
6181 and restore it here. */
6182
6183static void
6184update_toolbar (f, save_match_data)
6185 struct frame *f;
6186 int save_match_data;
6187{
6188 if (WINDOWP (f->toolbar_window)
6189 && XFASTINT (XWINDOW (f->toolbar_window)->height) > 0)
6190 {
6191 Lisp_Object window;
6192 struct window *w;
6193
6194 window = FRAME_SELECTED_WINDOW (f);
6195 w = XWINDOW (window);
6196
6197 /* If the user has switched buffers or windows, we need to
6198 recompute to reflect the new bindings. But we'll
6199 recompute when update_mode_lines is set too; that means
6200 that people can use force-mode-line-update to request
6201 that the menu bar be recomputed. The adverse effect on
6202 the rest of the redisplay algorithm is about the same as
6203 windows_or_buffers_changed anyway. */
6204 if (windows_or_buffers_changed
6205 || !NILP (w->update_mode_line)
6206 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6207 < BUF_MODIFF (XBUFFER (w->buffer)))
6208 != !NILP (w->last_had_star))
6209 || ((!NILP (Vtransient_mark_mode)
6210 && !NILP (XBUFFER (w->buffer)->mark_active))
6211 != !NILP (w->region_showing)))
6212 {
6213 struct buffer *prev = current_buffer;
6214 int count = specpdl_ptr - specpdl;
a2889657 6215
5f5c8ee5
GM
6216 /* Set current_buffer to the buffer of the selected
6217 window of the frame, so that we get the right local
6218 keymaps. */
6219 set_buffer_internal_1 (XBUFFER (w->buffer));
1f40cad2 6220
5f5c8ee5
GM
6221 /* Save match data, if we must. */
6222 if (save_match_data)
6223 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6224
6225 /* Make sure that we don't accidentally use bogus keymaps. */
6226 if (NILP (Voverriding_local_map_menu_flag))
6227 {
6228 specbind (Qoverriding_terminal_local_map, Qnil);
6229 specbind (Qoverriding_local_map, Qnil);
1f40cad2 6230 }
1f40cad2 6231
5f5c8ee5
GM
6232 /* Build desired toolbar items from keymaps. */
6233 f->desired_toolbar_items
6234 = toolbar_items (f->desired_toolbar_items,
6235 &f->n_desired_toolbar_items);
6236
6237 /* Redisplay the toolbar in case we changed it. */
6238 w->update_mode_line = Qt;
6239
6240 unbind_to (count, Qnil);
6241 set_buffer_internal_1 (prev);
81d478f3 6242 }
a2889657
JB
6243 }
6244}
6245
6c4429a5 6246
5f5c8ee5
GM
6247/* Set F->desired_toolbar_string to a Lisp string representing frame
6248 F's desired toolbar contents. F->desired_toolbar_items must have
6249 been set up previously by calling prepare_menu_bars. */
6250
a2889657 6251static void
5f5c8ee5
GM
6252build_desired_toolbar_string (f)
6253 struct frame *f;
a2889657 6254{
5f5c8ee5
GM
6255 int i, size, size_needed, string_idx;
6256 struct gcpro gcpro1, gcpro2, gcpro3;
6257 Lisp_Object image, plist, props;
a2889657 6258
5f5c8ee5
GM
6259 image = plist = props = Qnil;
6260 GCPRO3 (image, plist, props);
a2889657 6261
5f5c8ee5
GM
6262 /* Prepare F->desired_toolbar_string. If we can reuse it, do so.
6263 Otherwise, make a new string. */
6264
6265 /* The size of the string we might be able to reuse. */
6266 size = (STRINGP (f->desired_toolbar_string)
6267 ? XSTRING (f->desired_toolbar_string)->size
6268 : 0);
6269
6270 /* Each image in the string we build is preceded by a space,
6271 and there is a space at the end. */
6272 size_needed = f->n_desired_toolbar_items + 1;
6273
6274 /* Reuse f->desired_toolbar_string, if possible. */
6275 if (size < size_needed)
6276 f->desired_toolbar_string = Fmake_string (make_number (size_needed), ' ');
6277 else
6278 {
6279 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
6280 Fremove_text_properties (make_number (0), make_number (size),
6281 props, f->desired_toolbar_string);
6282 }
a2889657 6283
5f5c8ee5
GM
6284 /* Put a `display' property on the string for the images to display,
6285 put a `menu_item' property on toolbar items with a value that
6286 is the index of the item in F's toolbar item vector. */
6287 for (i = 0, string_idx = 0;
6288 i < f->n_desired_toolbar_items;
6289 ++i, string_idx += 1)
a2889657 6290 {
5f5c8ee5
GM
6291#define PROP(IDX) \
6292 (XVECTOR (f->desired_toolbar_items) \
6293 ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
6294
6295 int enabled_p = !NILP (PROP (TOOLBAR_ITEM_ENABLED_P));
6296 int selected_p = !NILP (PROP (TOOLBAR_ITEM_SELECTED_P));
6297 int margin, relief;
6298 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
6299 extern Lisp_Object Qlaplace;
6300
6301 /* If image is a vector, choose the image according to the
6302 button state. */
6303 image = PROP (TOOLBAR_ITEM_IMAGES);
6304 if (VECTORP (image))
6305 {
6306 enum toolbar_item_image idx;
6307
6308 if (enabled_p)
6309 idx = (selected_p
6310 ? TOOLBAR_IMAGE_ENABLED_SELECTED
6311 : TOOLBAR_IMAGE_ENABLED_DESELECTED);
6312 else
6313 idx = (selected_p
6314 ? TOOLBAR_IMAGE_DISABLED_SELECTED
6315 : TOOLBAR_IMAGE_DISABLED_DESELECTED);
6316
6317 xassert (XVECTOR (image)->size >= idx);
6318 image = XVECTOR (image)->contents[idx];
6319 }
6320
6321 /* Ignore invalid image specifications. */
6322 if (!valid_image_p (image))
6323 continue;
6324
6325 /* Display the toolbar button pressed, or depressed. */
6326 plist = Fcopy_sequence (XCDR (image));
6327
6328 /* Compute margin and relief to draw. */
6329 relief = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
6330 margin = relief + max (0, toolbar_button_margin);
6331
6332 if (auto_raise_toolbar_buttons_p)
6333 {
6334 /* Add a `:relief' property to the image spec if the item is
6335 selected. */
6336 if (selected_p)
6337 {
6338 plist = Fplist_put (plist, QCrelief, make_number (-relief));
6339 margin -= relief;
6340 }
6341 }
6342 else
6343 {
6344 /* If image is selected, display it pressed, i.e. with a
6345 negative relief. If it's not selected, display it with a
6346 raised relief. */
6347 plist = Fplist_put (plist, QCrelief,
6348 (selected_p
6349 ? make_number (-relief)
6350 : make_number (relief)));
6351 margin -= relief;
6352 }
6353
6354 /* Put a margin around the image. */
6355 if (margin)
6356 plist = Fplist_put (plist, QCmargin, make_number (margin));
6357
6358 /* If button is not enabled, make the image appear disabled by
6359 applying an appropriate algorithm to it. */
6360 if (!enabled_p)
6361 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
6362
6363 /* Put a `display' text property on the string for the image to
6364 display. Put a `menu-item' property on the string that gives
6365 the start of this item's properties in the toolbar items
6366 vector. */
6367 image = Fcons (Qimage, plist);
6368 props = list4 (Qdisplay, image,
6369 Qmenu_item, make_number (i * TOOLBAR_ITEM_NSLOTS)),
6370 Fadd_text_properties (make_number (string_idx),
6371 make_number (string_idx + 1),
6372 props, f->desired_toolbar_string);
6373#undef PROP
a2889657
JB
6374 }
6375
5f5c8ee5
GM
6376 UNGCPRO;
6377}
6378
6379
6380/* Display one line of the toolbar of frame IT->f. */
6381
6382static void
6383display_toolbar_line (it)
6384 struct it *it;
6385{
6386 struct glyph_row *row = it->glyph_row;
6387 int max_x = it->last_visible_x;
6388 struct glyph *last;
6389
6390 prepare_desired_row (row);
6391 row->y = it->current_y;
6392
6393 while (it->current_x < max_x)
a2889657 6394 {
5f5c8ee5 6395 int x_before, x, n_glyphs_before, i, nglyphs;
a2f016e3 6396
5f5c8ee5
GM
6397 /* Get the next display element. */
6398 if (!get_next_display_element (it))
6399 break;
73af359d 6400
5f5c8ee5
GM
6401 /* Produce glyphs. */
6402 x_before = it->current_x;
6403 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
6404 PRODUCE_GLYPHS (it);
daa37602 6405
5f5c8ee5
GM
6406 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
6407 i = 0;
6408 x = x_before;
6409 while (i < nglyphs)
6410 {
6411 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
6412
6413 if (x + glyph->pixel_width > max_x)
6414 {
6415 /* Glyph doesn't fit on line. */
6416 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
6417 it->current_x = x;
6418 goto out;
6419 }
daa37602 6420
5f5c8ee5
GM
6421 ++it->hpos;
6422 x += glyph->pixel_width;
6423 ++i;
6424 }
6425
6426 /* Stop at line ends. */
6427 if (ITERATOR_AT_END_OF_LINE_P (it))
6428 break;
6429
6430 set_iterator_to_next (it);
a2889657 6431 }
a2889657 6432
5f5c8ee5 6433 out:;
a2889657 6434
5f5c8ee5
GM
6435 row->displays_text_p = row->used[TEXT_AREA] != 0;
6436 extend_face_to_end_of_line (it);
6437 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
6438 last->right_box_line_p = 1;
6439 compute_line_metrics (it);
6440
6441 /* If line is empty, make it occupy the rest of the toolbar. */
6442 if (!row->displays_text_p)
6443 {
312246d1
GM
6444 row->height = row->phys_height = it->last_visible_y - row->y;
6445 row->ascent = row->phys_ascent = 0;
5f5c8ee5
GM
6446 }
6447
6448 row->full_width_p = 1;
6449 row->continued_p = 0;
6450 row->truncated_on_left_p = 0;
6451 row->truncated_on_right_p = 0;
6452
6453 it->current_x = it->hpos = 0;
6454 it->current_y += row->height;
6455 ++it->vpos;
6456 ++it->glyph_row;
a2889657 6457}
96a410bc 6458
5f5c8ee5
GM
6459
6460/* Value is the number of screen lines needed to make all toolbar
6461 items of frame F visible. */
96a410bc 6462
d39b6696 6463static int
5f5c8ee5
GM
6464toolbar_lines_needed (f)
6465 struct frame *f;
d39b6696 6466{
5f5c8ee5
GM
6467 struct window *w = XWINDOW (f->toolbar_window);
6468 struct it it;
6469
6470 /* Initialize an iterator for iteration over F->desired_toolbar_string
6471 in the toolbar window of frame F. */
6472 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
6473 it.first_visible_x = 0;
6474 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6475 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
6476
6477 while (!ITERATOR_AT_END_P (&it))
6478 {
6479 it.glyph_row = w->desired_matrix->rows;
6480 clear_glyph_row (it.glyph_row);
6481 display_toolbar_line (&it);
6482 }
6483
6484 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
d39b6696 6485}
96a410bc 6486
5f5c8ee5
GM
6487
6488/* Display the toolbar of frame F. Value is non-zero if toolbar's
6489 height should be changed. */
6490
6491static int
6492redisplay_toolbar (f)
6493 struct frame *f;
96a410bc 6494{
5f5c8ee5
GM
6495 struct window *w;
6496 struct it it;
6497 struct glyph_row *row;
6498 int change_height_p = 0;
6499
6500 /* If frame hasn't a toolbar window or if it is zero-height, don't
6501 do anything. This means you must start with toolbar-lines
6502 non-zero to get the auto-sizing effect. Or in other words, you
6503 can turn off toolbars by specifying toolbar-lines zero. */
6504 if (!WINDOWP (f->toolbar_window)
6505 || (w = XWINDOW (f->toolbar_window),
6506 XFASTINT (w->height) == 0))
6507 return 0;
96a410bc 6508
5f5c8ee5
GM
6509 /* Set up an iterator for the toolbar window. */
6510 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
6511 it.first_visible_x = 0;
6512 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6513 row = it.glyph_row;
3450d04c 6514
5f5c8ee5
GM
6515 /* Build a string that represents the contents of the toolbar. */
6516 build_desired_toolbar_string (f);
6517 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
3450d04c 6518
5f5c8ee5
GM
6519 /* Display as many lines as needed to display all toolbar items. */
6520 while (it.current_y < it.last_visible_y)
6521 display_toolbar_line (&it);
3450d04c 6522
5f5c8ee5
GM
6523 /* It doesn't make much sense to try scrolling in the toolbar
6524 window, so don't do it. */
6525 w->desired_matrix->no_scrolling_p = 1;
6526 w->must_be_updated_p = 1;
3450d04c 6527
5f5c8ee5
GM
6528 if (auto_resize_toolbars_p)
6529 {
6530 int nlines;
6531
6532 /* If there are blank lines at the end, except for a partially
6533 visible blank line at the end that is smaller than
6534 CANON_Y_UNIT, change the toolbar's height. */
6535 row = it.glyph_row - 1;
6536 if (!row->displays_text_p
6537 && row->height >= CANON_Y_UNIT (f))
6538 change_height_p = 1;
6539
6540 /* If row displays toolbar items, but is partially visible,
6541 change the toolbar's height. */
6542 if (row->displays_text_p
6543 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6544 change_height_p = 1;
6545
6546 /* Resize windows as needed by changing the `toolbar-lines'
6547 frame parameter. */
6548 if (change_height_p
6549 && (nlines = toolbar_lines_needed (f),
6550 nlines != XFASTINT (w->height)))
6551 {
6552 extern Lisp_Object Qtoolbar_lines;
6553 Lisp_Object frame;
6554
6555 XSETFRAME (frame, f);
6556 clear_glyph_matrix (w->desired_matrix);
6557 Fmodify_frame_parameters (frame,
6558 Fcons (Fcons (Qtoolbar_lines,
6559 make_number (nlines)),
6560 Qnil));
6561 fonts_changed_p = 1;
6562 }
6563 }
3450d04c 6564
5f5c8ee5 6565 return change_height_p;
96a410bc 6566}
90adcf20 6567
5f5c8ee5
GM
6568
6569/* Get information about the toolbar item which is displayed in GLYPH
6570 on frame F. Return in *PROP_IDX the index where toolbar item
6571 properties start in F->current_toolbar_items. Value is zero if
6572 GLYPH doesn't display a toolbar item. */
6573
6574int
6575toolbar_item_info (f, glyph, prop_idx)
6576 struct frame *f;
6577 struct glyph *glyph;
6578 int *prop_idx;
90adcf20 6579{
5f5c8ee5
GM
6580 Lisp_Object prop;
6581 int success_p;
6582
6583 /* Get the text property `menu-item' at pos. The value of that
6584 property is the start index of this item's properties in
6585 F->current_toolbar_items. */
6586 prop = Fget_text_property (make_number (glyph->charpos),
6587 Qmenu_item, f->current_toolbar_string);
6588 if (INTEGERP (prop))
6589 {
6590 *prop_idx = XINT (prop);
6591 success_p = 1;
6592 }
6593 else
6594 success_p = 0;
90adcf20 6595
5f5c8ee5
GM
6596 return success_p;
6597}
6598
6599#endif /* HAVE_WINDOW_SYSTEM */
90adcf20 6600
feb0c42f 6601
5f5c8ee5
GM
6602\f
6603/************************************************************************
6604 Horizontal scrolling
6605 ************************************************************************/
feb0c42f 6606
5f5c8ee5
GM
6607static int hscroll_window_tree P_ ((Lisp_Object));
6608static int hscroll_windows P_ ((Lisp_Object));
feb0c42f 6609
5f5c8ee5
GM
6610/* For all leaf windows in the window tree rooted at WINDOW, set their
6611 hscroll value so that PT is (i) visible in the window, and (ii) so
6612 that it is not within a certain margin at the window's left and
6613 right border. Value is non-zero if any window's hscroll has been
6614 changed. */
6615
6616static int
6617hscroll_window_tree (window)
6618 Lisp_Object window;
6619{
6620 int hscrolled_p = 0;
6621
6622 while (WINDOWP (window))
90adcf20 6623 {
5f5c8ee5
GM
6624 struct window *w = XWINDOW (window);
6625
6626 if (WINDOWP (w->hchild))
6627 hscrolled_p |= hscroll_window_tree (w->hchild);
6628 else if (WINDOWP (w->vchild))
6629 hscrolled_p |= hscroll_window_tree (w->vchild);
6630 else if (w->cursor.vpos >= 0)
6631 {
6632 int hscroll_margin, text_area_x, text_area_y;
6633 int text_area_width, text_area_height;
6634 struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
6635 w->cursor.vpos);
a2725ab2 6636
5f5c8ee5
GM
6637 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6638 &text_area_width, &text_area_height);
90adcf20 6639
5f5c8ee5
GM
6640 /* Scroll when cursor is inside this scroll margin. */
6641 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6642
6643 if ((XFASTINT (w->hscroll)
6644 && w->cursor.x < hscroll_margin)
6645 || (cursor_row->truncated_on_right_p
6646 && (w->cursor.x > text_area_width - hscroll_margin)))
08b610e4 6647 {
5f5c8ee5
GM
6648 struct it it;
6649 int hscroll;
6650 struct buffer *saved_current_buffer;
6651 int pt;
6652
6653 /* Find point in a display of infinite width. */
6654 saved_current_buffer = current_buffer;
6655 current_buffer = XBUFFER (w->buffer);
6656
6657 if (w == XWINDOW (selected_window))
6658 pt = BUF_PT (current_buffer);
6659 else
08b610e4 6660 {
5f5c8ee5
GM
6661 pt = marker_position (w->pointm);
6662 pt = max (BEGV, pt);
6663 pt = min (ZV, pt);
6664 }
6665
6666 /* Move iterator to pt starting at cursor_row->start in
6667 a line with infinite width. */
6668 init_to_row_start (&it, w, cursor_row);
6669 it.last_visible_x = INFINITY;
6670 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6671 current_buffer = saved_current_buffer;
6672
6673 /* Center cursor in window. */
6674 hscroll = (max (0, it.current_x - text_area_width / 2)
6675 / CANON_X_UNIT (it.f));
6676
6677 /* Don't call Fset_window_hscroll if value hasn't
6678 changed because it will prevent redisplay
6679 optimizations. */
6680 if (XFASTINT (w->hscroll) != hscroll)
6681 {
6682 Fset_window_hscroll (window, make_number (hscroll));
6683 hscrolled_p = 1;
08b610e4 6684 }
08b610e4 6685 }
08b610e4 6686 }
a2725ab2 6687
5f5c8ee5 6688 window = w->next;
90adcf20 6689 }
cd6dfed6 6690
5f5c8ee5
GM
6691 /* Value is non-zero if hscroll of any leaf window has been changed. */
6692 return hscrolled_p;
6693}
6694
6695
6696/* Set hscroll so that cursor is visible and not inside horizontal
6697 scroll margins for all windows in the tree rooted at WINDOW. See
6698 also hscroll_window_tree above. Value is non-zero if any window's
6699 hscroll has been changed. If it has, desired matrices on the frame
6700 of WINDOW are cleared. */
6701
6702static int
6703hscroll_windows (window)
6704 Lisp_Object window;
6705{
6706 int hscrolled_p = hscroll_window_tree (window);
6707 if (hscrolled_p)
6708 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6709 return hscrolled_p;
90adcf20 6710}
5f5c8ee5
GM
6711
6712
90adcf20 6713\f
5f5c8ee5
GM
6714/************************************************************************
6715 Redisplay
6716 ************************************************************************/
6717
6718/* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6719 to a non-zero value. This is sometimes handy to have in a debugger
6720 session. */
6721
6722#if GLYPH_DEBUG
a2889657 6723
5f5c8ee5
GM
6724/* First and last unchanged row for try_window_id. */
6725
6726int debug_first_unchanged_at_end_vpos;
6727int debug_last_unchanged_at_beg_vpos;
6728
6729/* Delta vpos and y. */
6730
6731int debug_dvpos, debug_dy;
6732
6733/* Delta in characters and bytes for try_window_id. */
6734
6735int debug_delta, debug_delta_bytes;
6736
6737/* Values of window_end_pos and window_end_vpos at the end of
6738 try_window_id. */
6739
6740int debug_end_pos, debug_end_vpos;
6741
6742/* Append a string to W->desired_matrix->method. FMT is a printf
6743 format string. A1...A9 are a supplement for a variable-length
6744 argument list. If trace_redisplay_p is non-zero also printf the
6745 resulting string to stderr. */
6746
6747static void
6748debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
6749 struct window *w;
6750 char *fmt;
6751 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
6752{
6753 char buffer[512];
6754 char *method = w->desired_matrix->method;
6755 int len = strlen (method);
6756 int size = sizeof w->desired_matrix->method;
6757 int remaining = size - len - 1;
6758
6759 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
6760 if (len && remaining)
6761 {
6762 method[len] = '|';
6763 --remaining, ++len;
6764 }
6765
6766 strncpy (method + len, buffer, remaining);
6767
6768 if (trace_redisplay_p)
6769 fprintf (stderr, "%p (%s): %s\n",
6770 w,
6771 ((BUFFERP (w->buffer)
6772 && STRINGP (XBUFFER (w->buffer)->name))
6773 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
6774 : "no buffer"),
6775 buffer);
6776}
a2889657 6777
5f5c8ee5 6778#endif /* GLYPH_DEBUG */
90adcf20 6779
a2889657 6780
5f5c8ee5
GM
6781/* This counter is used to clear the face cache every once in a while
6782 in redisplay_internal. It is incremented for each redisplay.
6783 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
6784 cleared. */
0d231165 6785
5f5c8ee5 6786#define CLEAR_FACE_CACHE_COUNT 10000
463f6b91
RS
6787static int clear_face_cache_count;
6788
20de20dc 6789/* Record the previous terminal frame we displayed. */
5f5c8ee5
GM
6790
6791static struct frame *previous_terminal_frame;
6792
6793/* Non-zero while redisplay_internal is in progress. */
6794
6795int redisplaying_p;
6796
6797
6798/* Value is non-zero if all changes in window W, which displays
6799 current_buffer, are in the text between START and END. START is a
6800 buffer position, END is given as a distance from Z. Used in
6801 redisplay_internal for display optimization. */
6802
6803static INLINE int
6804text_outside_line_unchanged_p (w, start, end)
6805 struct window *w;
6806 int start, end;
6807{
6808 int unchanged_p = 1;
6809
6810 /* If text or overlays have changed, see where. */
6811 if (XFASTINT (w->last_modified) < MODIFF
6812 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
6813 {
6814 /* Gap in the line? */
6815 if (GPT < start || Z - GPT < end)
6816 unchanged_p = 0;
6817
6818 /* Changes start in front of the line, or end after it? */
6819 if (unchanged_p
9142dd5b
GM
6820 && (BEG_UNCHANGED < start - 1
6821 || END_UNCHANGED < end))
5f5c8ee5
GM
6822 unchanged_p = 0;
6823
6824 /* If selective display, can't optimize if changes start at the
6825 beginning of the line. */
6826 if (unchanged_p
6827 && INTEGERP (current_buffer->selective_display)
6828 && XINT (current_buffer->selective_display) > 0
9142dd5b 6829 && (BEG_UNCHANGED < start || GPT <= start))
5f5c8ee5
GM
6830 unchanged_p = 0;
6831 }
6832
6833 return unchanged_p;
6834}
6835
6836
6837/* Do a frame update, taking possible shortcuts into account. This is
6838 the main external entry point for redisplay.
6839
6840 If the last redisplay displayed an echo area message and that message
6841 is no longer requested, we clear the echo area or bring back the
6842 mini-buffer if that is in use. */
20de20dc 6843
a2889657
JB
6844void
6845redisplay ()
e9874cee
RS
6846{
6847 redisplay_internal (0);
6848}
6849
5f5c8ee5 6850
9142dd5b
GM
6851/* Reconsider the setting of B->clip_changed which is displayed
6852 in window W. */
6853
6854static INLINE void
6855reconsider_clip_changes (w, b)
6856 struct window *w;
6857 struct buffer *b;
6858{
6859 if (b->prevent_redisplay_optimizations_p)
6860 b->clip_changed = 1;
6861 else if (b->clip_changed
6862 && !NILP (w->window_end_valid)
6863 && w->current_matrix->buffer == b
6864 && w->current_matrix->zv == BUF_ZV (b)
6865 && w->current_matrix->begv == BUF_BEGV (b))
6866 b->clip_changed = 0;
6867}
6868
6869
5f5c8ee5
GM
6870/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
6871 response to any user action; therefore, we should preserve the echo
6872 area. (Actually, our caller does that job.) Perhaps in the future
6873 avoid recentering windows if it is not necessary; currently that
6874 causes some problems. */
e9874cee
RS
6875
6876static void
6877redisplay_internal (preserve_echo_area)
6878 int preserve_echo_area;
a2889657 6879{
5f5c8ee5
GM
6880 struct window *w = XWINDOW (selected_window);
6881 struct frame *f = XFRAME (w->frame);
6882 int pause;
a2889657 6883 int must_finish = 0;
5f5c8ee5 6884 struct text_pos tlbufpos, tlendpos;
89819bdd 6885 int number_of_visible_frames;
28514cd9 6886 int count;
a2889657 6887
5f5c8ee5
GM
6888 /* Non-zero means redisplay has to consider all windows on all
6889 frames. Zero means, only selected_window is considered. */
6890 int consider_all_windows_p;
6891
6892 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
6893
6894 /* No redisplay if running in batch mode or frame is not yet fully
6895 initialized, or redisplay is explicitly turned off by setting
6896 Vinhibit_redisplay. */
6897 if (noninteractive
6898 || !NILP (Vinhibit_redisplay)
6899 || !f->glyphs_initialized_p)
a2889657
JB
6900 return;
6901
5f5c8ee5
GM
6902 /* The flag redisplay_performed_directly_p is set by
6903 direct_output_for_insert when it already did the whole screen
6904 update necessary. */
6905 if (redisplay_performed_directly_p)
6906 {
6907 redisplay_performed_directly_p = 0;
6908 if (!hscroll_windows (selected_window))
6909 return;
6910 }
6911
15f0cf78
RS
6912#ifdef USE_X_TOOLKIT
6913 if (popup_activated ())
6914 return;
6915#endif
6916
28514cd9 6917 /* I don't think this happens but let's be paranoid. */
5f5c8ee5 6918 if (redisplaying_p)
735c094c
KH
6919 return;
6920
28514cd9
GM
6921 /* Record a function that resets redisplaying_p to its old value
6922 when we leave this function. */
6923 count = specpdl_ptr - specpdl;
6924 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
6925 ++redisplaying_p;
6926
8b32d885
RS
6927 retry:
6928
9142dd5b
GM
6929 reconsider_clip_changes (w, current_buffer);
6930
5f5c8ee5
GM
6931 /* If new fonts have been loaded that make a glyph matrix adjustment
6932 necessary, do it. */
6933 if (fonts_changed_p)
6934 {
6935 adjust_glyphs (NULL);
6936 ++windows_or_buffers_changed;
6937 fonts_changed_p = 0;
6938 }
6939
fd8ff63d 6940 if (! FRAME_WINDOW_P (selected_frame)
20de20dc
RS
6941 && previous_terminal_frame != selected_frame)
6942 {
5f5c8ee5
GM
6943 /* Since frames on an ASCII terminal share the same display
6944 area, displaying a different frame means redisplay the whole
6945 thing. */
20de20dc
RS
6946 windows_or_buffers_changed++;
6947 SET_FRAME_GARBAGED (selected_frame);
6948 XSETFRAME (Vterminal_frame, selected_frame);
6949 }
6950 previous_terminal_frame = selected_frame;
20de20dc 6951
5f5c8ee5
GM
6952 /* Set the visible flags for all frames. Do this before checking
6953 for resized or garbaged frames; they want to know if their frames
6954 are visible. See the comment in frame.h for
6955 FRAME_SAMPLE_VISIBILITY. */
d724d989 6956 {
35f56f96 6957 Lisp_Object tail, frame;
d724d989 6958
89819bdd
RS
6959 number_of_visible_frames = 0;
6960
35f56f96 6961 FOR_EACH_FRAME (tail, frame)
f82aff7c 6962 {
5f5c8ee5
GM
6963 struct frame *f = XFRAME (frame);
6964
6965 FRAME_SAMPLE_VISIBILITY (f);
6966 if (FRAME_VISIBLE_P (f))
6967 ++number_of_visible_frames;
6968 clear_desired_matrices (f);
f82aff7c 6969 }
d724d989
JB
6970 }
6971
44fa5b1e 6972 /* Notice any pending interrupt request to change frame size. */
c6e89d6c 6973 do_pending_window_change (1);
a2889657 6974
5f5c8ee5 6975 /* Clear frames marked as garbaged. */
44fa5b1e 6976 if (frame_garbaged)
c6e89d6c 6977 clear_garbaged_frames ();
a2889657 6978
5f5c8ee5 6979 /* Build menubar and toolbar items. */
f82aff7c
RS
6980 prepare_menu_bars ();
6981
28995e67 6982 if (windows_or_buffers_changed)
a2889657
JB
6983 update_mode_lines++;
6984
538f13d4
RS
6985 /* Detect case that we need to write or remove a star in the mode line. */
6986 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
a2889657
JB
6987 {
6988 w->update_mode_line = Qt;
6989 if (buffer_shared > 1)
6990 update_mode_lines++;
6991 }
6992
5f5c8ee5 6993 /* If %c is in the mode line, update it if needed. */
28995e67
RS
6994 if (!NILP (w->column_number_displayed)
6995 /* This alternative quickly identifies a common case
6996 where no change is needed. */
6997 && !(PT == XFASTINT (w->last_point)
8850a573
RS
6998 && XFASTINT (w->last_modified) >= MODIFF
6999 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
7000 && XFASTINT (w->column_number_displayed) != current_column ())
7001 w->update_mode_line = Qt;
7002
44fa5b1e 7003 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
a2889657 7004
5f5c8ee5
GM
7005 /* The variable buffer_shared is set in redisplay_window and
7006 indicates that we redisplay a buffer in different windows. See
7007 there. */
7008 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
a2889657
JB
7009
7010 /* If specs for an arrow have changed, do thorough redisplay
7011 to ensure we remove any arrow that should no longer exist. */
d45de95b 7012 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
ded34426 7013 || ! EQ (Voverlay_arrow_string, last_arrow_string))
5f5c8ee5 7014 consider_all_windows_p = windows_or_buffers_changed = 1;
a2889657 7015
90adcf20
RS
7016 /* Normally the message* functions will have already displayed and
7017 updated the echo area, but the frame may have been trashed, or
7018 the update may have been preempted, so display the echo area
c6e89d6c
GM
7019 again here. Checking both message buffers captures the case that
7020 the echo area should be cleared. */
7021 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
90adcf20 7022 {
c6e89d6c 7023 int window_height_changed_p = echo_area_display (0);
90adcf20 7024 must_finish = 1;
dd2eb166 7025
c6e89d6c
GM
7026 if (fonts_changed_p)
7027 goto retry;
7028 else if (window_height_changed_p)
7029 {
7030 consider_all_windows_p = 1;
7031 ++update_mode_lines;
7032 ++windows_or_buffers_changed;
9142dd5b
GM
7033
7034 /* If window configuration was changed, frames may have been
7035 marked garbaged. Clear them or we will experience
7036 surprises wrt scrolling. */
7037 if (frame_garbaged)
7038 clear_garbaged_frames ();
c6e89d6c 7039 }
90adcf20 7040 }
dd2eb166
GM
7041 else if (w == XWINDOW (minibuf_window)
7042 && (current_buffer->clip_changed
7043 || XFASTINT (w->last_modified) < MODIFF
7044 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7045 && resize_mini_window (w))
c6e89d6c
GM
7046 {
7047 /* Resized active mini-window to fit the size of what it is
dd2eb166
GM
7048 showing if its contents might have changed. */
7049 must_finish = 1;
7050 consider_all_windows_p = 1;
c6e89d6c 7051 ++windows_or_buffers_changed;
dd2eb166 7052 ++update_mode_lines;
9142dd5b
GM
7053
7054 /* If window configuration was changed, frames may have been
7055 marked garbaged. Clear them or we will experience
7056 surprises wrt scrolling. */
7057 if (frame_garbaged)
7058 clear_garbaged_frames ();
c6e89d6c
GM
7059 }
7060
90adcf20 7061
5f5c8ee5
GM
7062 /* If showing the region, and mark has changed, we must redisplay
7063 the whole window. The assignment to this_line_start_pos prevents
7064 the optimization directly below this if-statement. */
bd66d1ba
RS
7065 if (((!NILP (Vtransient_mark_mode)
7066 && !NILP (XBUFFER (w->buffer)->mark_active))
7067 != !NILP (w->region_showing))
82d04750
JB
7068 || (!NILP (w->region_showing)
7069 && !EQ (w->region_showing,
7070 Fmarker_position (XBUFFER (w->buffer)->mark))))
5f5c8ee5
GM
7071 CHARPOS (this_line_start_pos) = 0;
7072
7073 /* Optimize the case that only the line containing the cursor in the
7074 selected window has changed. Variables starting with this_ are
7075 set in display_line and record information about the line
7076 containing the cursor. */
7077 tlbufpos = this_line_start_pos;
7078 tlendpos = this_line_end_pos;
7079 if (!consider_all_windows_p
7080 && CHARPOS (tlbufpos) > 0
7081 && NILP (w->update_mode_line)
73af359d 7082 && !current_buffer->clip_changed
44fa5b1e 7083 && FRAME_VISIBLE_P (XFRAME (w->frame))
f21ef775 7084 && !FRAME_OBSCURED_P (XFRAME (w->frame))
5f5c8ee5 7085 /* Make sure recorded data applies to current buffer, etc. */
a2889657
JB
7086 && this_line_buffer == current_buffer
7087 && current_buffer == XBUFFER (w->buffer)
265a9e55 7088 && NILP (w->force_start)
5f5c8ee5
GM
7089 /* Point must be on the line that we have info recorded about. */
7090 && PT >= CHARPOS (tlbufpos)
7091 && PT <= Z - CHARPOS (tlendpos)
a2889657
JB
7092 /* All text outside that line, including its final newline,
7093 must be unchanged */
5f5c8ee5
GM
7094 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7095 CHARPOS (tlendpos)))
7096 {
7097 if (CHARPOS (tlbufpos) > BEGV
7098 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
7099 && (CHARPOS (tlbufpos) == ZV
7100 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
a2889657
JB
7101 /* Former continuation line has disappeared by becoming empty */
7102 goto cancel;
7103 else if (XFASTINT (w->last_modified) < MODIFF
8850a573 7104 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
a2889657
JB
7105 || MINI_WINDOW_P (w))
7106 {
1c9241f5
KH
7107 /* We have to handle the case of continuation around a
7108 wide-column character (See the comment in indent.c around
7109 line 885).
7110
7111 For instance, in the following case:
7112
7113 -------- Insert --------
7114 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
7115 J_I_ ==> J_I_ `^^' are cursors.
7116 ^^ ^^
7117 -------- --------
7118
7119 As we have to redraw the line above, we should goto cancel. */
7120
5f5c8ee5
GM
7121 struct it it;
7122 int line_height_before = this_line_pixel_height;
7123
7124 /* Note that start_display will handle the case that the
7125 line starting at tlbufpos is a continuation lines. */
7126 start_display (&it, w, tlbufpos);
7127
7128 /* Implementation note: It this still necessary? */
7129 if (it.current_x != this_line_start_x)
1c9241f5
KH
7130 goto cancel;
7131
5f5c8ee5
GM
7132 TRACE ((stderr, "trying display optimization 1\n"));
7133 w->cursor.vpos = -1;
a2889657 7134 overlay_arrow_seen = 0;
5f5c8ee5
GM
7135 it.vpos = this_line_vpos;
7136 it.current_y = this_line_y;
7137 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
7138 display_line (&it);
7139
a2889657 7140 /* If line contains point, is not continued,
5f5c8ee5
GM
7141 and ends at same distance from eob as before, we win */
7142 if (w->cursor.vpos >= 0
7143 /* Line is not continued, otherwise this_line_start_pos
7144 would have been set to 0 in display_line. */
7145 && CHARPOS (this_line_start_pos)
7146 /* Line ends as before. */
7147 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
7148 /* Line has same height as before. Otherwise other lines
7149 would have to be shifted up or down. */
7150 && this_line_pixel_height == line_height_before)
a2889657 7151 {
5f5c8ee5
GM
7152 /* If this is not the window's last line, we must adjust
7153 the charstarts of the lines below. */
7154 if (it.current_y < it.last_visible_y)
7155 {
7156 struct glyph_row *row
7157 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
7158 int delta, delta_bytes;
7159
7160 if (Z - CHARPOS (tlendpos) == ZV)
7161 {
7162 /* This line ends at end of (accessible part of)
7163 buffer. There is no newline to count. */
7164 delta = (Z
7165 - CHARPOS (tlendpos)
7166 - MATRIX_ROW_START_CHARPOS (row));
7167 delta_bytes = (Z_BYTE
7168 - BYTEPOS (tlendpos)
7169 - MATRIX_ROW_START_BYTEPOS (row));
7170 }
7171 else
7172 {
7173 /* This line ends in a newline. Must take
7174 account of the newline and the rest of the
7175 text that follows. */
7176 delta = (Z
7177 - CHARPOS (tlendpos)
7178 - MATRIX_ROW_START_CHARPOS (row));
7179 delta_bytes = (Z_BYTE
7180 - BYTEPOS (tlendpos)
7181 - MATRIX_ROW_START_BYTEPOS (row));
7182 }
7183
7184 increment_glyph_matrix_buffer_positions (w->current_matrix,
7185 this_line_vpos + 1,
7186 w->current_matrix->nrows,
7187 delta, delta_bytes);
85bcef6c 7188 }
46db8486 7189
5f5c8ee5
GM
7190 /* If this row displays text now but previously didn't,
7191 or vice versa, w->window_end_vpos may have to be
7192 adjusted. */
7193 if ((it.glyph_row - 1)->displays_text_p)
7194 {
7195 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
7196 XSETINT (w->window_end_vpos, this_line_vpos);
7197 }
7198 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
7199 && this_line_vpos > 0)
7200 XSETINT (w->window_end_vpos, this_line_vpos - 1);
7201 w->window_end_valid = Qnil;
7202
7203 /* Update hint: No need to try to scroll in update_window. */
7204 w->desired_matrix->no_scrolling_p = 1;
7205
7206#if GLYPH_DEBUG
7207 *w->desired_matrix->method = 0;
7208 debug_method_add (w, "optimization 1");
7209#endif
a2889657
JB
7210 goto update;
7211 }
7212 else
7213 goto cancel;
7214 }
5f5c8ee5
GM
7215 else if (/* Cursor position hasn't changed. */
7216 PT == XFASTINT (w->last_point)
b6f0fe04
RS
7217 /* Make sure the cursor was last displayed
7218 in this window. Otherwise we have to reposition it. */
5f5c8ee5
GM
7219 && 0 <= w->cursor.vpos
7220 && XINT (w->height) > w->cursor.vpos)
a2889657
JB
7221 {
7222 if (!must_finish)
7223 {
c6e89d6c 7224 do_pending_window_change (1);
5f5c8ee5
GM
7225
7226 /* We used to always goto end_of_redisplay here, but this
7227 isn't enough if we have a blinking cursor. */
7228 if (w->cursor_off_p == w->last_cursor_off_p)
7229 goto end_of_redisplay;
a2889657
JB
7230 }
7231 goto update;
7232 }
8b51f1e3
KH
7233 /* If highlighting the region, or if the cursor is in the echo area,
7234 then we can't just move the cursor. */
bd66d1ba
RS
7235 else if (! (!NILP (Vtransient_mark_mode)
7236 && !NILP (current_buffer->mark_active))
293a54ce
RS
7237 && (w == XWINDOW (current_buffer->last_selected_window)
7238 || highlight_nonselected_windows)
8b51f1e3 7239 && NILP (w->region_showing)
8f897821 7240 && NILP (Vshow_trailing_whitespace)
8b51f1e3 7241 && !cursor_in_echo_area)
a2889657 7242 {
5f5c8ee5
GM
7243 struct it it;
7244 struct glyph_row *row;
7245
7246 /* Skip from tlbufpos to PT and see where it is. Note that
7247 PT may be in invisible text. If so, we will end at the
7248 next visible position. */
7249 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
7250 NULL, DEFAULT_FACE_ID);
7251 it.current_x = this_line_start_x;
7252 it.current_y = this_line_y;
7253 it.vpos = this_line_vpos;
7254
7255 /* The call to move_it_to stops in front of PT, but
7256 moves over before-strings. */
7257 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
7258
7259 if (it.vpos == this_line_vpos
7260 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
7261 row->enabled_p))
a2889657 7262 {
5f5c8ee5
GM
7263 xassert (this_line_vpos == it.vpos);
7264 xassert (this_line_y == it.current_y);
7265 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
a2889657
JB
7266 goto update;
7267 }
7268 else
7269 goto cancel;
7270 }
5f5c8ee5 7271
a2889657 7272 cancel:
5f5c8ee5
GM
7273 /* Text changed drastically or point moved off of line. */
7274 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
a2889657
JB
7275 }
7276
5f5c8ee5
GM
7277 CHARPOS (this_line_start_pos) = 0;
7278 consider_all_windows_p |= buffer_shared > 1;
7279 ++clear_face_cache_count;
a2889657 7280
5f5c8ee5
GM
7281
7282 /* Build desired matrices. If consider_all_windows_p is non-zero,
7283 do it for all windows on all frames. Otherwise do it for
7284 selected_window, only. */
463f6b91 7285
5f5c8ee5 7286 if (consider_all_windows_p)
a2889657 7287 {
35f56f96 7288 Lisp_Object tail, frame;
a2889657 7289
5f5c8ee5
GM
7290 /* Clear the face cache eventually. */
7291 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
463f6b91 7292 {
5f5c8ee5 7293 clear_face_cache (0);
463f6b91
RS
7294 clear_face_cache_count = 0;
7295 }
31b24551 7296
5f5c8ee5
GM
7297 /* Recompute # windows showing selected buffer. This will be
7298 incremented each time such a window is displayed. */
a2889657
JB
7299 buffer_shared = 0;
7300
35f56f96 7301 FOR_EACH_FRAME (tail, frame)
30c566e4 7302 {
5f5c8ee5 7303 struct frame *f = XFRAME (frame);
fd8ff63d 7304 if (FRAME_WINDOW_P (f) || f == selected_frame)
9769686d 7305 {
5f5c8ee5
GM
7306 /* Mark all the scroll bars to be removed; we'll redeem
7307 the ones we want when we redisplay their windows. */
9769686d
RS
7308 if (condemn_scroll_bars_hook)
7309 (*condemn_scroll_bars_hook) (f);
30c566e4 7310
f21ef775 7311 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
5f5c8ee5 7312 redisplay_windows (FRAME_ROOT_WINDOW (f));
30c566e4 7313
5f5c8ee5
GM
7314 /* Any scroll bars which redisplay_windows should have
7315 nuked should now go away. */
9769686d
RS
7316 if (judge_scroll_bars_hook)
7317 (*judge_scroll_bars_hook) (f);
7318 }
30c566e4 7319 }
a2889657 7320 }
5f5c8ee5
GM
7321 else if (FRAME_VISIBLE_P (selected_frame)
7322 && !FRAME_OBSCURED_P (selected_frame))
7323 redisplay_window (selected_window, 1);
7324
7325
7326 /* Compare desired and current matrices, perform output. */
7327
7328update:
7329
7330 /* If fonts changed, display again. */
7331 if (fonts_changed_p)
7332 goto retry;
a2889657 7333
a2889657
JB
7334 /* Prevent various kinds of signals during display update.
7335 stdio is not robust about handling signals,
7336 which can cause an apparent I/O error. */
7337 if (interrupt_input)
7338 unrequest_sigio ();
7339 stop_polling ();
7340
5f5c8ee5 7341 if (consider_all_windows_p)
a2889657
JB
7342 {
7343 Lisp_Object tail;
7344
7345 pause = 0;
7346
44fa5b1e 7347 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
a2889657 7348 {
5f5c8ee5 7349 struct frame *f;
a2889657 7350
e24c997d 7351 if (!FRAMEP (XCONS (tail)->car))
a2889657
JB
7352 continue;
7353
44fa5b1e 7354 f = XFRAME (XCONS (tail)->car);
1af9f229 7355
fd8ff63d 7356 if ((FRAME_WINDOW_P (f) || f == selected_frame)
f21ef775 7357 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
a2889657 7358 {
5f5c8ee5
GM
7359 /* Mark all windows as to be updated. */
7360 set_window_update_flags (XWINDOW (f->root_window), 1);
44fa5b1e 7361 pause |= update_frame (f, 0, 0);
a2889657 7362 if (!pause)
efc63ef0 7363 {
5f5c8ee5
GM
7364 if (hscroll_windows (f->root_window))
7365 goto retry;
7366
efc63ef0
RS
7367 mark_window_display_accurate (f->root_window, 1);
7368 if (frame_up_to_date_hook != 0)
7369 (*frame_up_to_date_hook) (f);
7370 }
a2889657
JB
7371 }
7372 }
7373 }
7374 else
6e8290aa 7375 {
5f5c8ee5
GM
7376 if (FRAME_VISIBLE_P (selected_frame)
7377 && !FRAME_OBSCURED_P (selected_frame))
7378 {
7379 XWINDOW (selected_window)->must_be_updated_p = 1;
7380 pause = update_frame (selected_frame, 0, 0);
7381 if (!pause && hscroll_windows (selected_window))
7382 goto retry;
7383 }
4d641a15
KH
7384 else
7385 pause = 0;
d724d989 7386
8de2d90b 7387 /* We may have called echo_area_display at the top of this
44fa5b1e
JB
7388 function. If the echo area is on another frame, that may
7389 have put text on a frame other than the selected one, so the
7390 above call to update_frame would not have caught it. Catch
8de2d90b
JB
7391 it here. */
7392 {
84faf44c 7393 Lisp_Object mini_window;
5f5c8ee5 7394 struct frame *mini_frame;
84faf44c
RS
7395
7396 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
7397 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8de2d90b 7398
fd8ff63d 7399 if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
5f5c8ee5
GM
7400 {
7401 XWINDOW (mini_window)->must_be_updated_p = 1;
7402 pause |= update_frame (mini_frame, 0, 0);
7403 if (!pause && hscroll_windows (mini_window))
7404 goto retry;
7405 }
8de2d90b 7406 }
6e8290aa 7407 }
a2889657 7408
5f5c8ee5
GM
7409 /* If display was paused because of pending input, make sure we do a
7410 thorough update the next time. */
a2889657
JB
7411 if (pause)
7412 {
5f5c8ee5
GM
7413 /* Prevent the optimization at the beginning of
7414 redisplay_internal that tries a single-line update of the
7415 line containing the cursor in the selected window. */
7416 CHARPOS (this_line_start_pos) = 0;
7417
7418 /* Let the overlay arrow be updated the next time. */
265a9e55 7419 if (!NILP (last_arrow_position))
a2889657
JB
7420 {
7421 last_arrow_position = Qt;
7422 last_arrow_string = Qt;
7423 }
5f5c8ee5
GM
7424
7425 /* If we pause after scrolling, some rows in the current
7426 matrices of some windows are not valid. */
7427 if (!WINDOW_FULL_WIDTH_P (w)
7428 && !FRAME_WINDOW_P (XFRAME (w->frame)))
a2889657
JB
7429 update_mode_lines = 1;
7430 }
7431
5f5c8ee5
GM
7432 /* Now text on frame agrees with windows, so put info into the
7433 windows for partial redisplay to follow. */
a2889657
JB
7434 if (!pause)
7435 {
7436 register struct buffer *b = XBUFFER (w->buffer);
7437
9142dd5b
GM
7438 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
7439 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
7440 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
7441 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
a2889657 7442
5f5c8ee5 7443 if (consider_all_windows_p)
11e82b76 7444 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
a2889657
JB
7445 else
7446 {
5f5c8ee5
GM
7447 XSETFASTINT (w->last_point, BUF_PT (b));
7448 w->last_cursor = w->cursor;
7449 w->last_cursor_off_p = w->cursor_off_p;
7450
28995e67 7451 b->clip_changed = 0;
9142dd5b 7452 b->prevent_redisplay_optimizations_p = 0;
a2889657 7453 w->update_mode_line = Qnil;
c2213350 7454 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
8850a573 7455 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
538f13d4
RS
7456 w->last_had_star
7457 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7458 ? Qt : Qnil);
3ee4159a
RS
7459
7460 /* Record if we are showing a region, so can make sure to
7461 update it fully at next redisplay. */
7462 w->region_showing = (!NILP (Vtransient_mark_mode)
293a54ce
RS
7463 && (w == XWINDOW (current_buffer->last_selected_window)
7464 || highlight_nonselected_windows)
3ee4159a
RS
7465 && !NILP (XBUFFER (w->buffer)->mark_active)
7466 ? Fmarker_position (XBUFFER (w->buffer)->mark)
7467 : Qnil);
7468
d2f84654 7469 w->window_end_valid = w->buffer;
d45de95b 7470 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657 7471 last_arrow_string = Voverlay_arrow_string;
efc63ef0
RS
7472 if (frame_up_to_date_hook != 0)
7473 (*frame_up_to_date_hook) (selected_frame);
9142dd5b
GM
7474
7475 w->current_matrix->buffer = b;
7476 w->current_matrix->begv = BUF_BEGV (b);
7477 w->current_matrix->zv = BUF_ZV (b);
a2889657 7478 }
5f5c8ee5 7479
a2889657
JB
7480 update_mode_lines = 0;
7481 windows_or_buffers_changed = 0;
7482 }
7483
5f5c8ee5
GM
7484 /* Start SIGIO interrupts coming again. Having them off during the
7485 code above makes it less likely one will discard output, but not
7486 impossible, since there might be stuff in the system buffer here.
a2889657 7487 But it is much hairier to try to do anything about that. */
a2889657
JB
7488 if (interrupt_input)
7489 request_sigio ();
7490 start_polling ();
7491
5f5c8ee5
GM
7492 /* If a frame has become visible which was not before, redisplay
7493 again, so that we display it. Expose events for such a frame
7494 (which it gets when becoming visible) don't call the parts of
7495 redisplay constructing glyphs, so simply exposing a frame won't
7496 display anything in this case. So, we have to display these
7497 frames here explicitly. */
11c52c4f
RS
7498 if (!pause)
7499 {
7500 Lisp_Object tail, frame;
7501 int new_count = 0;
7502
7503 FOR_EACH_FRAME (tail, frame)
7504 {
7505 int this_is_visible = 0;
8e83f802
RS
7506
7507 if (XFRAME (frame)->visible)
7508 this_is_visible = 1;
7509 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
7510 if (XFRAME (frame)->visible)
7511 this_is_visible = 1;
11c52c4f
RS
7512
7513 if (this_is_visible)
7514 new_count++;
7515 }
7516
89819bdd 7517 if (new_count != number_of_visible_frames)
11c52c4f
RS
7518 windows_or_buffers_changed++;
7519 }
7520
44fa5b1e 7521 /* Change frame size now if a change is pending. */
c6e89d6c 7522 do_pending_window_change (1);
d8e242fd 7523
8b32d885
RS
7524 /* If we just did a pending size change, or have additional
7525 visible frames, redisplay again. */
3c8c72e0 7526 if (windows_or_buffers_changed && !pause)
8b32d885 7527 goto retry;
5f5c8ee5
GM
7528
7529 end_of_redisplay:;
c6e89d6c 7530
28514cd9 7531 unbind_to (count, Qnil);
a2889657
JB
7532}
7533
5f5c8ee5
GM
7534
7535/* Redisplay, but leave alone any recent echo area message unless
7536 another message has been requested in its place.
a2889657
JB
7537
7538 This is useful in situations where you need to redisplay but no
7539 user action has occurred, making it inappropriate for the message
7540 area to be cleared. See tracking_off and
7541 wait_reading_process_input for examples of these situations. */
7542
8991bb31 7543void
a2889657
JB
7544redisplay_preserve_echo_area ()
7545{
c6e89d6c 7546 if (!NILP (echo_area_buffer[1]))
a2889657 7547 {
c6e89d6c
GM
7548 /* We have a previously displayed message, but no current
7549 message. Redisplay the previous message. */
7550 display_last_displayed_message_p = 1;
e9874cee 7551 redisplay_internal (1);
c6e89d6c 7552 display_last_displayed_message_p = 0;
a2889657
JB
7553 }
7554 else
e9874cee 7555 redisplay_internal (1);
a2889657
JB
7556}
7557
5f5c8ee5 7558
28514cd9
GM
7559/* Function registered with record_unwind_protect in
7560 redisplay_internal. Clears the flag indicating that a redisplay is
7561 in progress. */
7562
7563static Lisp_Object
7564unwind_redisplay (old_redisplaying_p)
7565 Lisp_Object old_redisplaying_p;
7566{
7567 redisplaying_p = XFASTINT (old_redisplaying_p);
c6e89d6c 7568 return Qnil;
28514cd9
GM
7569}
7570
7571
5f5c8ee5
GM
7572/* Mark the display of windows in the window tree rooted at WINDOW as
7573 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7574 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7575 the next time redisplay_internal is called. */
7576
a2889657 7577void
5f5c8ee5 7578mark_window_display_accurate (window, accurate_p)
a2889657 7579 Lisp_Object window;
5f5c8ee5 7580 int accurate_p;
a2889657 7581{
5f5c8ee5
GM
7582 struct window *w;
7583
7584 for (; !NILP (window); window = w->next)
a2889657
JB
7585 {
7586 w = XWINDOW (window);
7587
5f5c8ee5 7588 if (BUFFERP (w->buffer))
bd66d1ba 7589 {
5f5c8ee5
GM
7590 struct buffer *b = XBUFFER (w->buffer);
7591
c2213350 7592 XSETFASTINT (w->last_modified,
5f5c8ee5 7593 accurate_p ? BUF_MODIFF (b) : 0);
8850a573 7594 XSETFASTINT (w->last_overlay_modified,
5f5c8ee5
GM
7595 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7596 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7597 ? Qt : Qnil);
bd66d1ba 7598
5f5c8ee5
GM
7599#if 0 /* I don't think this is necessary because display_line does it.
7600 Let's check it. */
bd66d1ba
RS
7601 /* Record if we are showing a region, so can make sure to
7602 update it fully at next redisplay. */
5f5c8ee5
GM
7603 w->region_showing
7604 = (!NILP (Vtransient_mark_mode)
7605 && (w == XWINDOW (current_buffer->last_selected_window)
7606 || highlight_nonselected_windows)
7607 && (!NILP (b->mark_active)
7608 ? Fmarker_position (b->mark)
7609 : Qnil));
7610#endif
7611
7612 if (accurate_p)
7613 {
7614 b->clip_changed = 0;
9142dd5b
GM
7615 b->prevent_redisplay_optimizations_p = 0;
7616 w->current_matrix->buffer = b;
7617 w->current_matrix->begv = BUF_BEGV (b);
7618 w->current_matrix->zv = BUF_ZV (b);
5f5c8ee5
GM
7619 w->last_cursor = w->cursor;
7620 w->last_cursor_off_p = w->cursor_off_p;
7621 if (w == XWINDOW (selected_window))
7622 w->last_point = BUF_PT (b);
7623 else
7624 w->last_point = XMARKER (w->pointm)->charpos;
7625 }
bd66d1ba
RS
7626 }
7627
d2f84654 7628 w->window_end_valid = w->buffer;
a2889657
JB
7629 w->update_mode_line = Qnil;
7630
265a9e55 7631 if (!NILP (w->vchild))
5f5c8ee5 7632 mark_window_display_accurate (w->vchild, accurate_p);
265a9e55 7633 if (!NILP (w->hchild))
5f5c8ee5 7634 mark_window_display_accurate (w->hchild, accurate_p);
a2889657
JB
7635 }
7636
5f5c8ee5 7637 if (accurate_p)
a2889657 7638 {
d45de95b 7639 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657
JB
7640 last_arrow_string = Voverlay_arrow_string;
7641 }
7642 else
7643 {
5f5c8ee5
GM
7644 /* Force a thorough redisplay the next time by setting
7645 last_arrow_position and last_arrow_string to t, which is
7646 unequal to any useful value of Voverlay_arrow_... */
a2889657
JB
7647 last_arrow_position = Qt;
7648 last_arrow_string = Qt;
7649 }
7650}
5f5c8ee5
GM
7651
7652
7653/* Return value in display table DP (Lisp_Char_Table *) for character
7654 C. Since a display table doesn't have any parent, we don't have to
7655 follow parent. Do not call this function directly but use the
7656 macro DISP_CHAR_VECTOR. */
7657
7658Lisp_Object
7659disp_char_vector (dp, c)
7660 struct Lisp_Char_Table *dp;
7661 int c;
7662{
7663 int code[4], i;
7664 Lisp_Object val;
7665
7666 if (SINGLE_BYTE_CHAR_P (c))
7667 return (dp->contents[c]);
7668
7669 SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
7670 if (code[0] != CHARSET_COMPOSITION)
7671 {
7672 if (code[1] < 32)
7673 code[1] = -1;
7674 else if (code[2] < 32)
7675 code[2] = -1;
7676 }
7677
7678 /* Here, the possible range of code[0] (== charset ID) is
7679 128..max_charset. Since the top level char table contains data
7680 for multibyte characters after 256th element, we must increment
7681 code[0] by 128 to get a correct index. */
7682 code[0] += 128;
7683 code[3] = -1; /* anchor */
7684
7685 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
7686 {
7687 val = dp->contents[code[i]];
7688 if (!SUB_CHAR_TABLE_P (val))
7689 return (NILP (val) ? dp->defalt : val);
7690 }
7691
7692 /* Here, val is a sub char table. We return the default value of
7693 it. */
7694 return (dp->defalt);
7695}
7696
7697
a2889657 7698\f
5f5c8ee5
GM
7699/***********************************************************************
7700 Window Redisplay
7701 ***********************************************************************/
a2725ab2 7702
5f5c8ee5 7703/* Redisplay all leaf windows in the window tree rooted at WINDOW. */
90adcf20
RS
7704
7705static void
5f5c8ee5
GM
7706redisplay_windows (window)
7707 Lisp_Object window;
90adcf20 7708{
5f5c8ee5
GM
7709 while (!NILP (window))
7710 {
7711 struct window *w = XWINDOW (window);
7712
7713 if (!NILP (w->hchild))
7714 redisplay_windows (w->hchild);
7715 else if (!NILP (w->vchild))
7716 redisplay_windows (w->vchild);
7717 else
7718 redisplay_window (window, 0);
a2725ab2 7719
5f5c8ee5
GM
7720 window = w->next;
7721 }
7722}
7723
7724
7725/* Set cursor position of W. PT is assumed to be displayed in ROW.
7726 DELTA is the number of bytes by which positions recorded in ROW
7727 differ from current buffer positions. */
7728
7729void
7730set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
7731 struct window *w;
7732 struct glyph_row *row;
7733 struct glyph_matrix *matrix;
7734 int delta, delta_bytes, dy, dvpos;
7735{
7736 struct glyph *glyph = row->glyphs[TEXT_AREA];
7737 struct glyph *end = glyph + row->used[TEXT_AREA];
7738 int x = row->x;
7739 int pt_old = PT - delta;
7740
7741 /* Skip over glyphs not having an object at the start of the row.
7742 These are special glyphs like truncation marks on terminal
7743 frames. */
7744 if (row->displays_text_p)
7745 while (glyph < end
7746 && !glyph->object
7747 && glyph->charpos < 0)
7748 {
7749 x += glyph->pixel_width;
7750 ++glyph;
7751 }
7752
7753 while (glyph < end
7754 && glyph->object
7755 && (!BUFFERP (glyph->object)
7756 || glyph->charpos < pt_old))
7757 {
7758 x += glyph->pixel_width;
7759 ++glyph;
7760 }
7761
7762 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
7763 w->cursor.x = x;
7764 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
7765 w->cursor.y = row->y + dy;
7766
7767 if (w == XWINDOW (selected_window))
7768 {
7769 if (!row->continued_p
7770 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
7771 && row->x == 0)
7772 {
7773 this_line_buffer = XBUFFER (w->buffer);
7774
7775 CHARPOS (this_line_start_pos)
7776 = MATRIX_ROW_START_CHARPOS (row) + delta;
7777 BYTEPOS (this_line_start_pos)
7778 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
7779
7780 CHARPOS (this_line_end_pos)
7781 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
7782 BYTEPOS (this_line_end_pos)
7783 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
7784
7785 this_line_y = w->cursor.y;
7786 this_line_pixel_height = row->height;
7787 this_line_vpos = w->cursor.vpos;
7788 this_line_start_x = row->x;
7789 }
7790 else
7791 CHARPOS (this_line_start_pos) = 0;
7792 }
7793}
7794
7795
7796/* Run window scroll functions, if any, for WINDOW with new window
7797 start STARTP. Sets the window start of WINDOW to that position. */
7798
7799static INLINE struct text_pos
7800run_window_scroll_functions (window, startp)
7801 Lisp_Object window;
7802 struct text_pos startp;
7803{
7804 struct window *w = XWINDOW (window);
7805 SET_MARKER_FROM_TEXT_POS (w->start, startp);
90adcf20 7806
5f5c8ee5
GM
7807 if (!NILP (Vwindow_scroll_functions))
7808 {
7809 run_hook_with_args_2 (Qwindow_scroll_functions, window,
7810 make_number (CHARPOS (startp)));
7811 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7812 }
90adcf20 7813
5f5c8ee5
GM
7814 return startp;
7815}
7816
7817
7818/* Modify the desired matrix of window W and W->vscroll so that the
7819 line containing the cursor is fully visible. */
7820
7821static void
7822make_cursor_line_fully_visible (w)
7823 struct window *w;
7824{
7825 struct glyph_matrix *matrix;
7826 struct glyph_row *row;
7827 int top_line_height;
7828
7829 /* It's not always possible to find the cursor, e.g, when a window
7830 is full of overlay strings. Don't do anything in that case. */
7831 if (w->cursor.vpos < 0)
7832 return;
7833
7834 matrix = w->desired_matrix;
7835 row = MATRIX_ROW (matrix, w->cursor.vpos);
7836
7837 /* If row->y == top y of window display area, the window isn't tall
7838 enough to display a single line. There is nothing we can do
7839 about it. */
7840 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
7841 if (row->y == top_line_height)
7842 return;
7843
7844 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
7845 {
7846 int dy = row->height - row->visible_height;
7847 w->vscroll = 0;
7848 w->cursor.y += dy;
7849 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7850 }
7851 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
7852 {
7853 int dy = - (row->height - row->visible_height);
7854 w->vscroll = dy;
7855 w->cursor.y += dy;
7856 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7857 }
7858
7859 /* When we change the cursor y-position of the selected window,
7860 change this_line_y as well so that the display optimization for
7861 the cursor line of the selected window in redisplay_internal uses
7862 the correct y-position. */
7863 if (w == XWINDOW (selected_window))
7864 this_line_y = w->cursor.y;
7865}
7866
7867
7868/* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
7869 non-zero means only WINDOW is redisplayed in redisplay_internal.
7870 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
7871 in redisplay_window to bring a partially visible line into view in
7872 the case that only the cursor has moved.
7873
7874 Value is
7875
7876 1 if scrolling succeeded
7877
7878 0 if scrolling didn't find point.
7879
7880 -1 if new fonts have been loaded so that we must interrupt
7881 redisplay, adjust glyph matrices, and try again. */
7882
7883static int
7884try_scrolling (window, just_this_one_p, scroll_conservatively,
7885 scroll_step, temp_scroll_step)
7886 Lisp_Object window;
7887 int just_this_one_p;
7888 int scroll_conservatively, scroll_step;
7889 int temp_scroll_step;
7890{
7891 struct window *w = XWINDOW (window);
7892 struct frame *f = XFRAME (w->frame);
7893 struct text_pos scroll_margin_pos;
7894 struct text_pos pos;
7895 struct text_pos startp;
7896 struct it it;
7897 Lisp_Object window_end;
7898 int this_scroll_margin;
7899 int dy = 0;
7900 int scroll_max;
7901 int line_height, rc;
7902 int amount_to_scroll = 0;
7903 Lisp_Object aggressive;
7904 int height;
7905
7906#if GLYPH_DEBUG
7907 debug_method_add (w, "try_scrolling");
78614721 7908#endif
5f5c8ee5
GM
7909
7910 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7911
7912 /* Compute scroll margin height in pixels. We scroll when point is
7913 within this distance from the top or bottom of the window. */
7914 if (scroll_margin > 0)
90adcf20 7915 {
5f5c8ee5
GM
7916 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
7917 this_scroll_margin *= CANON_Y_UNIT (f);
7918 }
7919 else
7920 this_scroll_margin = 0;
7921
7922 /* Compute how much we should try to scroll maximally to bring point
7923 into view. */
7924 if (scroll_step)
7925 scroll_max = scroll_step;
7926 else if (scroll_conservatively)
7927 scroll_max = scroll_conservatively;
7928 else if (temp_scroll_step)
7929 scroll_max = temp_scroll_step;
7930 else if (NUMBERP (current_buffer->scroll_down_aggressively)
7931 || NUMBERP (current_buffer->scroll_up_aggressively))
7932 /* We're trying to scroll because of aggressive scrolling
7933 but no scroll_step is set. Choose an arbitrary one. Maybe
7934 there should be a variable for this. */
7935 scroll_max = 10;
7936 else
7937 scroll_max = 0;
7938 scroll_max *= CANON_Y_UNIT (f);
7939
7940 /* Decide whether we have to scroll down. Start at the window end
7941 and move this_scroll_margin up to find the position of the scroll
7942 margin. */
7943 window_end = Fwindow_end (window, Qt);
7944 CHARPOS (scroll_margin_pos) = XINT (window_end);
7945 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
7946 if (this_scroll_margin)
7947 {
7948 start_display (&it, w, scroll_margin_pos);
7949 move_it_vertically (&it, - this_scroll_margin);
7950 scroll_margin_pos = it.current.pos;
7951 }
7952
7953 if (PT >= CHARPOS (scroll_margin_pos))
7954 {
7955 int y0;
7956
7957 /* Point is in the scroll margin at the bottom of the window, or
7958 below. Compute a new window start that makes point visible. */
7959
7960 /* Compute the distance from the scroll margin to PT.
7961 Give up if the distance is greater than scroll_max. */
7962 start_display (&it, w, scroll_margin_pos);
7963 y0 = it.current_y;
7964 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7965 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7966 line_height = (it.max_ascent + it.max_descent
7967 ? it.max_ascent + it.max_descent
7968 : last_height);
7969 dy = it.current_y + line_height - y0;
7970 if (dy > scroll_max)
7971 return 0;
7972
7973 /* Move the window start down. If scrolling conservatively,
7974 move it just enough down to make point visible. If
7975 scroll_step is set, move it down by scroll_step. */
7976 start_display (&it, w, startp);
7977
7978 if (scroll_conservatively)
7979 amount_to_scroll = dy;
7980 else if (scroll_step || temp_scroll_step)
7981 amount_to_scroll = scroll_max;
7982 else
90adcf20 7983 {
5f5c8ee5
GM
7984 aggressive = current_buffer->scroll_down_aggressively;
7985 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7986 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7987 if (NUMBERP (aggressive))
7988 amount_to_scroll = XFLOATINT (aggressive) * height;
7989 }
a2725ab2 7990
5f5c8ee5
GM
7991 if (amount_to_scroll <= 0)
7992 return 0;
a2725ab2 7993
5f5c8ee5
GM
7994 move_it_vertically (&it, amount_to_scroll);
7995 startp = it.current.pos;
7996 }
7997 else
7998 {
7999 /* See if point is inside the scroll margin at the top of the
8000 window. */
8001 scroll_margin_pos = startp;
8002 if (this_scroll_margin)
8003 {
8004 start_display (&it, w, startp);
8005 move_it_vertically (&it, this_scroll_margin);
8006 scroll_margin_pos = it.current.pos;
8007 }
8008
8009 if (PT < CHARPOS (scroll_margin_pos))
8010 {
8011 /* Point is in the scroll margin at the top of the window or
8012 above what is displayed in the window. */
8013 int y0;
8014
8015 /* Compute the vertical distance from PT to the scroll
8016 margin position. Give up if distance is greater than
8017 scroll_max. */
8018 SET_TEXT_POS (pos, PT, PT_BYTE);
8019 start_display (&it, w, pos);
8020 y0 = it.current_y;
8021 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
8022 it.last_visible_y, -1,
8023 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8024 dy = it.current_y - y0;
8025 if (dy > scroll_max)
8026 return 0;
8027
8028 /* Compute new window start. */
8029 start_display (&it, w, startp);
8030
8031 if (scroll_conservatively)
8032 amount_to_scroll = dy;
8033 else if (scroll_step || temp_scroll_step)
8034 amount_to_scroll = scroll_max;
538f13d4 8035 else
5f5c8ee5
GM
8036 {
8037 aggressive = current_buffer->scroll_up_aggressively;
8038 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8039 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
8040 if (NUMBERP (aggressive))
8041 amount_to_scroll = XFLOATINT (aggressive) * height;
8042 }
a2725ab2 8043
5f5c8ee5
GM
8044 if (amount_to_scroll <= 0)
8045 return 0;
8046
8047 move_it_vertically (&it, - amount_to_scroll);
8048 startp = it.current.pos;
90adcf20
RS
8049 }
8050 }
a2889657 8051
5f5c8ee5
GM
8052 /* Run window scroll functions. */
8053 startp = run_window_scroll_functions (window, startp);
90adcf20 8054
5f5c8ee5
GM
8055 /* Display the window. Give up if new fonts are loaded, or if point
8056 doesn't appear. */
8057 if (!try_window (window, startp))
8058 rc = -1;
8059 else if (w->cursor.vpos < 0)
8060 {
8061 clear_glyph_matrix (w->desired_matrix);
8062 rc = 0;
8063 }
8064 else
8065 {
8066 /* Maybe forget recorded base line for line number display. */
8067 if (!just_this_one_p
8068 || current_buffer->clip_changed
9142dd5b 8069 || BEG_UNCHANGED < CHARPOS (startp))
5f5c8ee5
GM
8070 w->base_line_number = Qnil;
8071
8072 /* If cursor ends up on a partially visible line, shift display
8073 lines up or down. */
8074 make_cursor_line_fully_visible (w);
8075 rc = 1;
8076 }
8077
8078 return rc;
a2889657
JB
8079}
8080
5f5c8ee5
GM
8081
8082/* Compute a suitable window start for window W if display of W starts
8083 on a continuation line. Value is non-zero if a new window start
8084 was computed.
8085
8086 The new window start will be computed, based on W's width, starting
8087 from the start of the continued line. It is the start of the
8088 screen line with the minimum distance from the old start W->start. */
8089
8090static int
8091compute_window_start_on_continuation_line (w)
8092 struct window *w;
1f1ff51d 8093{
5f5c8ee5
GM
8094 struct text_pos pos, start_pos;
8095 int window_start_changed_p = 0;
1f1ff51d 8096
5f5c8ee5 8097 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
1f1ff51d 8098
5f5c8ee5
GM
8099 /* If window start is on a continuation line... Window start may be
8100 < BEGV in case there's invisible text at the start of the
8101 buffer (M-x rmail, for example). */
8102 if (CHARPOS (start_pos) > BEGV
8103 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
1f1ff51d 8104 {
5f5c8ee5
GM
8105 struct it it;
8106 struct glyph_row *row;
8107
8108 /* Find the start of the continued line. This should be fast
8109 because scan_buffer is fast (newline cache). */
8110 row = w->desired_matrix->rows + (WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0);
8111 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
8112 row, DEFAULT_FACE_ID);
8113 reseat_at_previous_visible_line_start (&it);
8114
8115 /* If the line start is "too far" away from the window start,
8116 say it takes too much time to compute a new window start. */
8117 if (CHARPOS (start_pos) - IT_CHARPOS (it)
8118 < XFASTINT (w->height) * XFASTINT (w->width))
8119 {
8120 int min_distance, distance;
8121
8122 /* Move forward by display lines to find the new window
8123 start. If window width was enlarged, the new start can
8124 be expected to be > the old start. If window width was
8125 decreased, the new window start will be < the old start.
8126 So, we're looking for the display line start with the
8127 minimum distance from the old window start. */
8128 pos = it.current.pos;
8129 min_distance = INFINITY;
8130 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
8131 distance < min_distance)
8132 {
8133 min_distance = distance;
8134 pos = it.current.pos;
8135 move_it_by_lines (&it, 1, 0);
8136 }
8137
8138 /* Set the window start there. */
8139 SET_MARKER_FROM_TEXT_POS (w->start, pos);
8140 window_start_changed_p = 1;
8141 }
1f1ff51d 8142 }
5f5c8ee5
GM
8143
8144 return window_start_changed_p;
1f1ff51d
KH
8145}
8146
5f5c8ee5
GM
8147
8148/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
8149 selected_window is redisplayed. */
90adcf20 8150
a2889657 8151static void
5f5c8ee5 8152redisplay_window (window, just_this_one_p)
a2889657 8153 Lisp_Object window;
5f5c8ee5 8154 int just_this_one_p;
a2889657 8155{
5f5c8ee5
GM
8156 struct window *w = XWINDOW (window);
8157 struct frame *f = XFRAME (w->frame);
8158 struct buffer *buffer = XBUFFER (w->buffer);
a2889657 8159 struct buffer *old = current_buffer;
5f5c8ee5 8160 struct text_pos lpoint, opoint, startp;
e481f960 8161 int update_mode_line;
5f5c8ee5
GM
8162 int tem;
8163 struct it it;
8164 /* Record it now because it's overwritten. */
8165 int current_matrix_up_to_date_p = 0;
5ba50c51 8166 int really_switched_buffer = 0;
5f5c8ee5 8167 int temp_scroll_step = 0;
2e54982e 8168 int count = specpdl_ptr - specpdl;
a2889657 8169
5f5c8ee5
GM
8170 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8171 opoint = lpoint;
a2889657 8172
5f5c8ee5
GM
8173 /* W must be a leaf window here. */
8174 xassert (!NILP (w->buffer));
8175#if GLYPH_DEBUG
8176 *w->desired_matrix->method = 0;
8177#endif
2e54982e
RS
8178
8179 specbind (Qinhibit_point_motion_hooks, Qt);
9142dd5b
GM
8180
8181 reconsider_clip_changes (w, buffer);
8182
5f5c8ee5
GM
8183 /* Has the mode line to be updated? */
8184 update_mode_line = (!NILP (w->update_mode_line)
8185 || update_mode_lines
8186 || buffer->clip_changed);
8de2d90b
JB
8187
8188 if (MINI_WINDOW_P (w))
8189 {
5f5c8ee5 8190 if (w == XWINDOW (echo_area_window)
c6e89d6c 8191 && !NILP (echo_area_buffer[0]))
5f5c8ee5
GM
8192 {
8193 if (update_mode_line)
8194 /* We may have to update a tty frame's menu bar or a
8195 toolbar. Example `M-x C-h C-h C-g'. */
8196 goto finish_menu_bars;
8197 else
8198 /* We've already displayed the echo area glyphs in this window. */
8199 goto finish_scroll_bars;
8200 }
73af359d 8201 else if (w != XWINDOW (minibuf_window))
8de2d90b 8202 {
5f5c8ee5
GM
8203 /* W is a mini-buffer window, but it's not the currently
8204 active one, so clear it. */
8205 int yb = window_text_bottom_y (w);
8206 struct glyph_row *row;
8207 int y;
8208
8209 for (y = 0, row = w->desired_matrix->rows;
8210 y < yb;
8211 y += row->height, ++row)
8212 blank_row (w, row, y);
88f22aff 8213 goto finish_scroll_bars;
8de2d90b
JB
8214 }
8215 }
a2889657 8216
5f5c8ee5
GM
8217 /* Otherwise set up data on this window; select its buffer and point
8218 value. */
e481f960 8219 if (update_mode_line)
5ba50c51 8220 {
5f5c8ee5
GM
8221 /* Really select the buffer, for the sake of buffer-local
8222 variables. */
5ba50c51
RS
8223 set_buffer_internal_1 (XBUFFER (w->buffer));
8224 really_switched_buffer = 1;
8225 }
e481f960
RS
8226 else
8227 set_buffer_temp (XBUFFER (w->buffer));
5f5c8ee5
GM
8228 SET_TEXT_POS (opoint, PT, PT_BYTE);
8229
8230 current_matrix_up_to_date_p
8231 = (!NILP (w->window_end_valid)
8232 && !current_buffer->clip_changed
8233 && XFASTINT (w->last_modified) >= MODIFF
8234 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
e481f960 8235
5f5c8ee5
GM
8236 /* When windows_or_buffers_changed is non-zero, we can't rely on
8237 the window end being valid, so set it to nil there. */
8238 if (windows_or_buffers_changed)
8239 {
8240 /* If window starts on a continuation line, maybe adjust the
8241 window start in case the window's width changed. */
8242 if (XMARKER (w->start)->buffer == current_buffer)
8243 compute_window_start_on_continuation_line (w);
8244
8245 w->window_end_valid = Qnil;
8246 }
12adba34 8247
5f5c8ee5
GM
8248 /* Some sanity checks. */
8249 CHECK_WINDOW_END (w);
8250 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12adba34 8251 abort ();
5f5c8ee5 8252 if (BYTEPOS (opoint) < CHARPOS (opoint))
12adba34 8253 abort ();
a2889657 8254
28995e67
RS
8255 /* If %c is in mode line, update it if needed. */
8256 if (!NILP (w->column_number_displayed)
8257 /* This alternative quickly identifies a common case
8258 where no change is needed. */
8259 && !(PT == XFASTINT (w->last_point)
8850a573
RS
8260 && XFASTINT (w->last_modified) >= MODIFF
8261 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
8262 && XFASTINT (w->column_number_displayed) != current_column ())
8263 update_mode_line = 1;
8264
5f5c8ee5
GM
8265 /* Count number of windows showing the selected buffer. An indirect
8266 buffer counts as its base buffer. */
8267 if (!just_this_one_p)
42640f83
RS
8268 {
8269 struct buffer *current_base, *window_base;
8270 current_base = current_buffer;
8271 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
8272 if (current_base->base_buffer)
8273 current_base = current_base->base_buffer;
8274 if (window_base->base_buffer)
8275 window_base = window_base->base_buffer;
8276 if (current_base == window_base)
8277 buffer_shared++;
8278 }
a2889657 8279
5f5c8ee5
GM
8280 /* Point refers normally to the selected window. For any other
8281 window, set up appropriate value. */
a2889657
JB
8282 if (!EQ (window, selected_window))
8283 {
12adba34
RS
8284 int new_pt = XMARKER (w->pointm)->charpos;
8285 int new_pt_byte = marker_byte_position (w->pointm);
f67a0f51 8286 if (new_pt < BEGV)
a2889657 8287 {
f67a0f51 8288 new_pt = BEGV;
12adba34
RS
8289 new_pt_byte = BEGV_BYTE;
8290 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
a2889657 8291 }
f67a0f51 8292 else if (new_pt > (ZV - 1))
a2889657 8293 {
f67a0f51 8294 new_pt = ZV;
12adba34
RS
8295 new_pt_byte = ZV_BYTE;
8296 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
a2889657 8297 }
5f5c8ee5 8298
f67a0f51 8299 /* We don't use SET_PT so that the point-motion hooks don't run. */
12adba34 8300 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
a2889657
JB
8301 }
8302
f4faa47c 8303 /* If any of the character widths specified in the display table
5f5c8ee5
GM
8304 have changed, invalidate the width run cache. It's true that
8305 this may be a bit late to catch such changes, but the rest of
f4faa47c
JB
8306 redisplay goes (non-fatally) haywire when the display table is
8307 changed, so why should we worry about doing any better? */
8308 if (current_buffer->width_run_cache)
8309 {
f908610f 8310 struct Lisp_Char_Table *disptab = buffer_display_table ();
f4faa47c
JB
8311
8312 if (! disptab_matches_widthtab (disptab,
8313 XVECTOR (current_buffer->width_table)))
8314 {
8315 invalidate_region_cache (current_buffer,
8316 current_buffer->width_run_cache,
8317 BEG, Z);
8318 recompute_width_table (current_buffer, disptab);
8319 }
8320 }
8321
a2889657 8322 /* If window-start is screwed up, choose a new one. */
a2889657
JB
8323 if (XMARKER (w->start)->buffer != current_buffer)
8324 goto recenter;
8325
5f5c8ee5 8326 SET_TEXT_POS_FROM_MARKER (startp, w->start);
a2889657 8327
cf0df6ab
RS
8328 /* If someone specified a new starting point but did not insist,
8329 check whether it can be used. */
5f5c8ee5 8330 if (!NILP (w->optional_new_start))
cf0df6ab
RS
8331 {
8332 w->optional_new_start = Qnil;
5f5c8ee5
GM
8333 /* This takes a mini-buffer prompt into account. */
8334 start_display (&it, w, startp);
8335 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8336 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8337 if (IT_CHARPOS (it) == PT)
cf0df6ab
RS
8338 w->force_start = Qt;
8339 }
8340
8de2d90b 8341 /* Handle case where place to start displaying has been specified,
aa6d10fa 8342 unless the specified location is outside the accessible range. */
265a9e55 8343 if (!NILP (w->force_start))
a2889657 8344 {
e63574d7 8345 w->force_start = Qnil;
5f5c8ee5 8346 w->vscroll = 0;
b5174a51 8347 w->window_end_valid = Qnil;
5f5c8ee5
GM
8348
8349 /* Forget any recorded base line for line number display. */
8350 if (!current_matrix_up_to_date_p
8351 || current_buffer->clip_changed)
8352 w->base_line_number = Qnil;
8353
75c43375
RS
8354 /* Redisplay the mode line. Select the buffer properly for that.
8355 Also, run the hook window-scroll-functions
8356 because we have scrolled. */
e63574d7
RS
8357 /* Note, we do this after clearing force_start because
8358 if there's an error, it is better to forget about force_start
8359 than to get into an infinite loop calling the hook functions
8360 and having them get more errors. */
75c43375
RS
8361 if (!update_mode_line
8362 || ! NILP (Vwindow_scroll_functions))
e481f960 8363 {
5ba50c51
RS
8364 if (!really_switched_buffer)
8365 {
8366 set_buffer_temp (old);
8367 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 8368 really_switched_buffer = 1;
5ba50c51 8369 }
5f5c8ee5 8370
e481f960
RS
8371 update_mode_line = 1;
8372 w->update_mode_line = Qt;
5f5c8ee5 8373 startp = run_window_scroll_functions (window, startp);
e481f960 8374 }
5f5c8ee5 8375
c2213350 8376 XSETFASTINT (w->last_modified, 0);
8850a573 8377 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5
GM
8378 if (CHARPOS (startp) < BEGV)
8379 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
8380 else if (CHARPOS (startp) > ZV)
8381 SET_TEXT_POS (startp, ZV, ZV_BYTE);
8382
8383 /* Redisplay, then check if cursor has been set during the
8384 redisplay. Give up if new fonts were loaded. */
8385 if (!try_window (window, startp))
8386 {
8387 w->force_start = Qt;
8388 clear_glyph_matrix (w->desired_matrix);
8389 goto restore_buffers;
8390 }
8391
8392 if (w->cursor.vpos < 0)
8393 {
8394 /* If point does not appear, or on a line that is not fully
8395 visible, move point so it does appear. The desired
8396 matrix has been built above, so we can use it. */
8397 int height = window_box_height (w) / 2;
8398 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
8399
8400 while (row->y < height)
8401 ++row;
8402
8403 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
8404 MATRIX_ROW_START_BYTEPOS (row));
8405
90adcf20 8406 if (w != XWINDOW (selected_window))
12adba34 8407 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5f5c8ee5
GM
8408 else if (current_buffer == old)
8409 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8410
8411 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
8412
8413 /* If we are highlighting the region, then we just changed
8414 the region, so redisplay to show it. */
df0b5ea1
RS
8415 if (!NILP (Vtransient_mark_mode)
8416 && !NILP (current_buffer->mark_active))
6f27fa9b 8417 {
5f5c8ee5
GM
8418 clear_glyph_matrix (w->desired_matrix);
8419 if (!try_window (window, startp))
8420 goto restore_buffers;
6f27fa9b 8421 }
a2889657 8422 }
5f5c8ee5
GM
8423
8424 make_cursor_line_fully_visible (w);
8425#if GLYPH_DEBUG
8426 debug_method_add (w, "forced window start");
8427#endif
a2889657
JB
8428 goto done;
8429 }
8430
5f5c8ee5
GM
8431 /* Handle case where text has not changed, only point, and it has
8432 not moved off the frame. */
8433 if (current_matrix_up_to_date_p
8434 /* Point may be in this window. */
8435 && PT >= CHARPOS (startp)
8436 /* If we don't check this, we are called to move the cursor in a
8437 horizontally split window with a current matrix that doesn't
8438 fit the display. */
8439 && !windows_or_buffers_changed
8440 /* Selective display hasn't changed. */
8441 && !current_buffer->clip_changed
b1aa6cb3
RS
8442 /* If force-mode-line-update was called, really redisplay;
8443 that's how redisplay is forced after e.g. changing
8444 buffer-invisibility-spec. */
632ab665 8445 && NILP (w->update_mode_line)
5f5c8ee5
GM
8446 /* Can't use this case if highlighting a region. When a
8447 region exists, cursor movement has to do more than just
8448 set the cursor. */
8449 && !(!NILP (Vtransient_mark_mode)
8450 && !NILP (current_buffer->mark_active))
bd66d1ba 8451 && NILP (w->region_showing)
8f897821 8452 && NILP (Vshow_trailing_whitespace)
5f5c8ee5
GM
8453 /* Right after splitting windows, last_point may be nil. */
8454 && INTEGERP (w->last_point)
8455 /* This code is not used for mini-buffer for the sake of the case
8456 of redisplaying to replace an echo area message; since in
8457 that case the mini-buffer contents per se are usually
8458 unchanged. This code is of no real use in the mini-buffer
8459 since the handling of this_line_start_pos, etc., in redisplay
8460 handles the same cases. */
d45de95b 8461 && !EQ (window, minibuf_window)
5f5c8ee5
GM
8462 /* When splitting windows or for new windows, it happens that
8463 redisplay is called with a nil window_end_vpos or one being
8464 larger than the window. This should really be fixed in
8465 window.c. I don't have this on my list, now, so we do
8466 approximately the same as the old redisplay code. --gerd. */
8467 && INTEGERP (w->window_end_vpos)
8468 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
8469 && (FRAME_WINDOW_P (f)
8470 || !MARKERP (Voverlay_arrow_position)
377dbd97 8471 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
a2889657 8472 {
5f5c8ee5
GM
8473 int this_scroll_margin;
8474 struct glyph_row *row;
8475 int scroll_p;
a2889657 8476
5f5c8ee5
GM
8477#if GLYPH_DEBUG
8478 debug_method_add (w, "cursor movement");
8479#endif
9afd2168 8480
5f5c8ee5
GM
8481 /* Scroll if point within this distance from the top or bottom
8482 of the window. This is a pixel value. */
8483 this_scroll_margin = max (0, scroll_margin);
8484 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
8485 this_scroll_margin *= CANON_Y_UNIT (f);
8486
8487 /* Start with the row the cursor was displayed during the last
8488 not paused redisplay. Give up if that row is not valid. */
8489 if (w->last_cursor.vpos >= w->current_matrix->nrows)
8490 goto try_to_scroll;
8491 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
8492 if (row->mode_line_p)
8493 ++row;
8494 if (!row->enabled_p)
8495 goto try_to_scroll;
8496
8497 scroll_p = 0;
8498 if (PT > XFASTINT (w->last_point))
8499 {
8500 /* Point has moved forward. */
8501 int last_y = window_text_bottom_y (w) - this_scroll_margin;
8502
8503 while ((MATRIX_ROW_END_CHARPOS (row) < PT
8504 /* The end position of a row equals the start
8505 position of the next row. If PT is there, we
8506 would rather display it in the next line, except
8507 when this line ends in ZV. */
8508 || (MATRIX_ROW_END_CHARPOS (row) == PT
8509 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
8510 || !row->ends_at_zv_p)))
8511 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
8512 {
8513 xassert (row->enabled_p);
8514 ++row;
8515 }
9afd2168 8516
5f5c8ee5
GM
8517 /* If within the scroll margin, scroll. Note that
8518 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
8519 next line would be drawn, and that this_scroll_margin can
8520 be zero. */
8521 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
8522 || PT > MATRIX_ROW_END_CHARPOS (row)
8523 /* Line is completely visible last line in window and PT
8524 is to be set in the next line. */
8525 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
8526 && PT == MATRIX_ROW_END_CHARPOS (row)
8527 && !row->ends_at_zv_p
8528 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
8529 scroll_p = 1;
8530 }
8531 else if (PT < XFASTINT (w->last_point))
a2889657 8532 {
5f5c8ee5
GM
8533 /* Cursor has to be moved backward. Note that PT >=
8534 CHARPOS (startp) because of the outer if-statement. */
8535 while (!row->mode_line_p
8536 && (MATRIX_ROW_START_CHARPOS (row) > PT
8537 || (MATRIX_ROW_START_CHARPOS (row) == PT
8538 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
8539 && (row->y > this_scroll_margin
8540 || CHARPOS (startp) == BEGV))
a2889657 8541 {
5f5c8ee5
GM
8542 xassert (row->enabled_p);
8543 --row;
a2889657 8544 }
abb4c08f 8545
5f5c8ee5
GM
8546 /* Consider the following case: Window starts at BEGV, there
8547 is invisible, intangible text at BEGV, so that display
8548 starts at some point START > BEGV. It can happen that
8549 we are called with PT somewhere between BEGV and START.
8550 Try to handle that case. */
8551 if (row < w->current_matrix->rows
8552 || row->mode_line_p)
8553 {
8554 row = w->current_matrix->rows;
8555 if (row->mode_line_p)
8556 ++row;
8557 }
8558
8559 /* Due to newlines in overlay strings, we may have to skip
8560 forward over overlay strings. */
8561 while (MATRIX_ROW_END_CHARPOS (row) == PT
8562 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8563 && !row->ends_at_zv_p)
8564 ++row;
8565
8566 /* If within the scroll margin, scroll. */
8567 if (row->y < this_scroll_margin
8568 && CHARPOS (startp) != BEGV)
8569 scroll_p = 1;
8570 }
8571
8572 /* if PT is not in the glyph row, give up. */
8573 if (PT < MATRIX_ROW_START_CHARPOS (row)
8574 || PT > MATRIX_ROW_END_CHARPOS (row))
8575 goto try_to_scroll;
8576
8577 /* If we end up in a partially visible line, let's make it fully
8578 visible. This can be done most easily by using the existing
8579 scrolling code. */
8580 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8581 {
8582 temp_scroll_step = 1;
8583 goto try_to_scroll;
a2889657 8584 }
5f5c8ee5
GM
8585 else if (scroll_p)
8586 goto try_to_scroll;
8587
8588 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8589 goto done;
a2889657 8590 }
5f5c8ee5 8591
a2889657
JB
8592 /* If current starting point was originally the beginning of a line
8593 but no longer is, find a new starting point. */
265a9e55 8594 else if (!NILP (w->start_at_line_beg)
5f5c8ee5
GM
8595 && !(CHARPOS (startp) <= BEGV
8596 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
a2889657 8597 {
5f5c8ee5
GM
8598#if GLYPH_DEBUG
8599 debug_method_add (w, "recenter 1");
8600#endif
a2889657
JB
8601 goto recenter;
8602 }
5f5c8ee5
GM
8603
8604 /* Try scrolling with try_window_id. */
9142dd5b
GM
8605 else if (/* Windows and buffers haven't changed. */
8606 !windows_or_buffers_changed
5f5c8ee5
GM
8607 /* Window must be either use window-based redisplay or
8608 be full width. */
8609 && (FRAME_WINDOW_P (f)
8610 || ((line_ins_del_ok && WINDOW_FULL_WIDTH_P (w))
8611 && just_this_one_p))
8612 && !MINI_WINDOW_P (w)
8613 /* Point is not known NOT to appear in window. */
8614 && PT >= CHARPOS (startp)
a2889657 8615 && XFASTINT (w->last_modified)
5f5c8ee5
GM
8616 /* Window is not hscrolled. */
8617 && XFASTINT (w->hscroll) == 0
8618 /* Selective display has not changed. */
8619 && !current_buffer->clip_changed
8620 /* Current matrix is up to date. */
8621 && !NILP (w->window_end_valid)
8622 /* Can't use this case if highlighting a region because
8623 a cursor movement will do more than just set the cursor. */
bd66d1ba
RS
8624 && !(!NILP (Vtransient_mark_mode)
8625 && !NILP (current_buffer->mark_active))
8626 && NILP (w->region_showing)
8f897821 8627 && NILP (Vshow_trailing_whitespace)
5f5c8ee5 8628 /* Overlay arrow position and string not changed. */
d45de95b 8629 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
a2889657 8630 && EQ (last_arrow_string, Voverlay_arrow_string)
5f5c8ee5
GM
8631 /* Value is > 0 if update has been done, it is -1 if we
8632 know that the same window start will not work. It is 0
8633 if unsuccessful for some other reason. */
8634 && (tem = try_window_id (w)) != 0)
a2889657 8635 {
5f5c8ee5
GM
8636#if GLYPH_DEBUG
8637 debug_method_add (w, "try_window_id");
8638#endif
8639
8640 if (fonts_changed_p)
8641 goto restore_buffers;
a2889657
JB
8642 if (tem > 0)
8643 goto done;
5f5c8ee5
GM
8644 /* Otherwise try_window_id has returned -1 which means that we
8645 don't want the alternative below this comment to execute. */
a2889657 8646 }
5f5c8ee5
GM
8647 else if (CHARPOS (startp) >= BEGV
8648 && CHARPOS (startp) <= ZV
8649 && PT >= CHARPOS (startp)
8650 && (CHARPOS (startp) < ZV
e9874cee 8651 /* Avoid starting at end of buffer. */
5f5c8ee5 8652 || CHARPOS (startp) == BEGV
8850a573
RS
8653 || (XFASTINT (w->last_modified) >= MODIFF
8654 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
a2889657 8655 {
5f5c8ee5
GM
8656#if GLYPH_DEBUG
8657 debug_method_add (w, "same window start");
8658#endif
8659
8660 /* Try to redisplay starting at same place as before.
8661 If point has not moved off frame, accept the results. */
8662 if (!current_matrix_up_to_date_p
8663 /* Don't use try_window_reusing_current_matrix in this case
8664 because it can have changed the buffer. */
8665 || !NILP (Vwindow_scroll_functions)
8666 || MINI_WINDOW_P (w)
8667 || !try_window_reusing_current_matrix (w))
8668 {
8669 IF_DEBUG (debug_method_add (w, "1"));
8670 try_window (window, startp);
8671 }
8672
8673 if (fonts_changed_p)
8674 goto restore_buffers;
8675
8676 if (w->cursor.vpos >= 0)
aa6d10fa 8677 {
5f5c8ee5
GM
8678 if (!just_this_one_p
8679 || current_buffer->clip_changed
9142dd5b 8680 || BEG_UNCHANGED < CHARPOS (startp))
aa6d10fa
RS
8681 /* Forget any recorded base line for line number display. */
8682 w->base_line_number = Qnil;
5f5c8ee5
GM
8683
8684 make_cursor_line_fully_visible (w);
aa6d10fa
RS
8685 goto done;
8686 }
a2889657 8687 else
5f5c8ee5 8688 clear_glyph_matrix (w->desired_matrix);
a2889657
JB
8689 }
8690
5f5c8ee5
GM
8691 try_to_scroll:
8692
c2213350 8693 XSETFASTINT (w->last_modified, 0);
8850a573 8694 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5 8695
e481f960
RS
8696 /* Redisplay the mode line. Select the buffer properly for that. */
8697 if (!update_mode_line)
8698 {
5ba50c51
RS
8699 if (!really_switched_buffer)
8700 {
8701 set_buffer_temp (old);
8702 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 8703 really_switched_buffer = 1;
5ba50c51 8704 }
e481f960
RS
8705 update_mode_line = 1;
8706 w->update_mode_line = Qt;
8707 }
a2889657 8708
5f5c8ee5
GM
8709 /* Try to scroll by specified few lines. */
8710 if ((scroll_conservatively
8711 || scroll_step
8712 || temp_scroll_step
8713 || NUMBERP (current_buffer->scroll_up_aggressively)
8714 || NUMBERP (current_buffer->scroll_down_aggressively))
09cacf9c 8715 && !current_buffer->clip_changed
5f5c8ee5
GM
8716 && CHARPOS (startp) >= BEGV
8717 && CHARPOS (startp) <= ZV)
0789adb2 8718 {
5f5c8ee5
GM
8719 /* The function returns -1 if new fonts were loaded, 1 if
8720 successful, 0 if not successful. */
8721 int rc = try_scrolling (window, just_this_one_p,
8722 scroll_conservatively,
8723 scroll_step,
8724 temp_scroll_step);
8725 if (rc > 0)
8726 goto done;
8727 else if (rc < 0)
8728 goto restore_buffers;
8729 }
f9c8af06 8730
5f5c8ee5 8731 /* Finally, just choose place to start which centers point */
5936754e 8732
5f5c8ee5 8733 recenter:
44173109 8734
5f5c8ee5
GM
8735#if GLYPH_DEBUG
8736 debug_method_add (w, "recenter");
8737#endif
0789adb2 8738
5f5c8ee5 8739 /* w->vscroll = 0; */
0789adb2 8740
5f5c8ee5
GM
8741 /* Forget any previously recorded base line for line number display. */
8742 if (!current_matrix_up_to_date_p
8743 || current_buffer->clip_changed)
8744 w->base_line_number = Qnil;
8745
8746 /* Move backward half the height of the window. */
8747 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8748 it.current_y = it.last_visible_y;
8749 move_it_vertically_backward (&it, it.last_visible_y / 2);
8750 xassert (IT_CHARPOS (it) >= BEGV);
8751
8752 /* The function move_it_vertically_backward may move over more
8753 than the specified y-distance. If it->w is small, e.g. a
8754 mini-buffer window, we may end up in front of the window's
8755 display area. Start displaying at the start of the line
8756 containing PT in this case. */
8757 if (it.current_y <= 0)
8758 {
8759 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8760 move_it_vertically (&it, 0);
8761 xassert (IT_CHARPOS (it) <= PT);
8762 it.current_y = 0;
0789adb2
RS
8763 }
8764
5f5c8ee5
GM
8765 it.current_x = it.hpos = 0;
8766
8767 /* Set startp here explicitly in case that helps avoid an infinite loop
8768 in case the window-scroll-functions functions get errors. */
8769 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
8770
8771 /* Run scroll hooks. */
8772 startp = run_window_scroll_functions (window, it.current.pos);
8773
8774 /* Redisplay the window. */
8775 if (!current_matrix_up_to_date_p
8776 || windows_or_buffers_changed
8777 /* Don't use try_window_reusing_current_matrix in this case
8778 because it can have changed the buffer. */
8779 || !NILP (Vwindow_scroll_functions)
8780 || !just_this_one_p
8781 || MINI_WINDOW_P (w)
8782 || !try_window_reusing_current_matrix (w))
8783 try_window (window, startp);
8784
8785 /* If new fonts have been loaded (due to fontsets), give up. We
8786 have to start a new redisplay since we need to re-adjust glyph
8787 matrices. */
8788 if (fonts_changed_p)
8789 goto restore_buffers;
8790
8791 /* If cursor did not appear assume that the middle of the window is
8792 in the first line of the window. Do it again with the next line.
8793 (Imagine a window of height 100, displaying two lines of height
8794 60. Moving back 50 from it->last_visible_y will end in the first
8795 line.) */
8796 if (w->cursor.vpos < 0)
a2889657 8797 {
5f5c8ee5
GM
8798 if (!NILP (w->window_end_valid)
8799 && PT >= Z - XFASTINT (w->window_end_pos))
a2889657 8800 {
5f5c8ee5
GM
8801 clear_glyph_matrix (w->desired_matrix);
8802 move_it_by_lines (&it, 1, 0);
8803 try_window (window, it.current.pos);
a2889657 8804 }
5f5c8ee5 8805 else if (PT < IT_CHARPOS (it))
a2889657 8806 {
5f5c8ee5
GM
8807 clear_glyph_matrix (w->desired_matrix);
8808 move_it_by_lines (&it, -1, 0);
8809 try_window (window, it.current.pos);
8810 }
8811 else
8812 {
8813 /* Not much we can do about it. */
a2889657 8814 }
a2889657 8815 }
010494d0 8816
5f5c8ee5
GM
8817 /* Consider the following case: Window starts at BEGV, there is
8818 invisible, intangible text at BEGV, so that display starts at
8819 some point START > BEGV. It can happen that we are called with
8820 PT somewhere between BEGV and START. Try to handle that case. */
8821 if (w->cursor.vpos < 0)
835766b6 8822 {
5f5c8ee5
GM
8823 struct glyph_row *row = w->current_matrix->rows;
8824 if (row->mode_line_p)
8825 ++row;
8826 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
835766b6 8827 }
5f5c8ee5
GM
8828
8829 make_cursor_line_fully_visible (w);
b5174a51 8830
5f5c8ee5
GM
8831 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8832 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
8833 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
8834 ? Qt : Qnil);
a2889657 8835
5f5c8ee5 8836 done:
a2889657 8837
5f5c8ee5 8838 /* Display the mode line, if we must. */
e481f960 8839 if ((update_mode_line
aa6d10fa 8840 /* If window not full width, must redo its mode line
5f5c8ee5
GM
8841 if (a) the window to its side is being redone and
8842 (b) we do a frame-based redisplay. This is a consequence
8843 of how inverted lines are drawn in frame-based redisplay. */
8844 || (!just_this_one_p
8845 && !FRAME_WINDOW_P (f)
8846 && !WINDOW_FULL_WIDTH_P (w))
8847 /* Line number to display. */
155ef550 8848 || INTEGERP (w->base_line_pos)
5f5c8ee5 8849 /* Column number is displayed and different from the one displayed. */
155ef550
KH
8850 || (!NILP (w->column_number_displayed)
8851 && XFASTINT (w->column_number_displayed) != current_column ()))
5f5c8ee5
GM
8852 /* This means that the window has a mode line. */
8853 && (WINDOW_WANTS_MODELINE_P (w)
8854 || WINDOW_WANTS_TOP_LINE_P (w)))
5ba50c51 8855 {
5f5c8ee5
GM
8856 display_mode_lines (w);
8857
8858 /* If mode line height has changed, arrange for a thorough
8859 immediate redisplay using the correct mode line height. */
8860 if (WINDOW_WANTS_MODELINE_P (w)
8861 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
5ba50c51 8862 {
5f5c8ee5
GM
8863 fonts_changed_p = 1;
8864 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
8865 = DESIRED_MODE_LINE_HEIGHT (w);
5ba50c51 8866 }
5f5c8ee5
GM
8867
8868 /* If top line height has changed, arrange for a thorough
8869 immediate redisplay using the correct mode line height. */
8870 if (WINDOW_WANTS_TOP_LINE_P (w)
8871 && CURRENT_TOP_LINE_HEIGHT (w) != DESIRED_TOP_LINE_HEIGHT (w))
8872 {
8873 fonts_changed_p = 1;
8874 MATRIX_TOP_LINE_ROW (w->current_matrix)->height
8875 = DESIRED_TOP_LINE_HEIGHT (w);
8876 }
8877
8878 if (fonts_changed_p)
8879 goto restore_buffers;
5ba50c51 8880 }
5f5c8ee5
GM
8881
8882 if (!line_number_displayed
8883 && !BUFFERP (w->base_line_pos))
aa6d10fa
RS
8884 {
8885 w->base_line_pos = Qnil;
8886 w->base_line_number = Qnil;
8887 }
a2889657 8888
5f5c8ee5
GM
8889 finish_menu_bars:
8890
7ce2c095 8891 /* When we reach a frame's selected window, redo the frame's menu bar. */
e481f960 8892 if (update_mode_line
5f5c8ee5
GM
8893 && EQ (FRAME_SELECTED_WINDOW (f), window))
8894 {
8895 int redisplay_menu_p = 0;
8896
8897 if (FRAME_WINDOW_P (f))
8898 {
dc937613 8899#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5f5c8ee5 8900 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
76412d64 8901#else
5f5c8ee5 8902 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
76412d64 8903#endif
5f5c8ee5
GM
8904 }
8905 else
8906 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
8907
8908 if (redisplay_menu_p)
8909 display_menu_bar (w);
8910
8911#ifdef HAVE_WINDOW_SYSTEM
8912 if (WINDOWP (f->toolbar_window)
8913 && (FRAME_TOOLBAR_LINES (f) > 0
8914 || auto_resize_toolbars_p))
8915 redisplay_toolbar (f);
8916#endif
8917 }
7ce2c095 8918
88f22aff 8919 finish_scroll_bars:
5f5c8ee5 8920
88f22aff 8921 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
30c566e4 8922 {
b1d1124b 8923 int start, end, whole;
30c566e4 8924
b1d1124b 8925 /* Calculate the start and end positions for the current window.
3505ea70
JB
8926 At some point, it would be nice to choose between scrollbars
8927 which reflect the whole buffer size, with special markers
8928 indicating narrowing, and scrollbars which reflect only the
8929 visible region.
8930
5f5c8ee5 8931 Note that mini-buffers sometimes aren't displaying any text. */
c6e89d6c 8932 if (!MINI_WINDOW_P (w)
5f5c8ee5 8933 || (w == XWINDOW (minibuf_window)
c6e89d6c 8934 && NILP (echo_area_buffer[0])))
b1d1124b 8935 {
8a9311d7 8936 whole = ZV - BEGV;
4d641a15 8937 start = marker_position (w->start) - BEGV;
b1d1124b
JB
8938 /* I don't think this is guaranteed to be right. For the
8939 moment, we'll pretend it is. */
5f5c8ee5 8940 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
3505ea70 8941
5f5c8ee5
GM
8942 if (end < start)
8943 end = start;
8944 if (whole < (end - start))
8945 whole = end - start;
b1d1124b
JB
8946 }
8947 else
8948 start = end = whole = 0;
30c566e4 8949
88f22aff 8950 /* Indicate what this scroll bar ought to be displaying now. */
7eb9ba41 8951 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
30c566e4 8952
5f5c8ee5
GM
8953 /* Note that we actually used the scroll bar attached to this
8954 window, so it shouldn't be deleted at the end of redisplay. */
88f22aff 8955 (*redeem_scroll_bar_hook) (w);
30c566e4 8956 }
b1d1124b 8957
5f5c8ee5
GM
8958 restore_buffers:
8959
8960 /* Restore current_buffer and value of point in it. */
8961 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
5ba50c51 8962 if (really_switched_buffer)
f72df6ac 8963 set_buffer_internal_1 (old);
e481f960
RS
8964 else
8965 set_buffer_temp (old);
5f5c8ee5 8966 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
2e54982e
RS
8967
8968 unbind_to (count, Qnil);
a2889657 8969}
a2889657 8970
5f5c8ee5
GM
8971
8972/* Build the complete desired matrix of WINDOW with a window start
8973 buffer position POS. Value is non-zero if successful. It is zero
8974 if fonts were loaded during redisplay which makes re-adjusting
8975 glyph matrices necessary. */
8976
8977int
a2889657
JB
8978try_window (window, pos)
8979 Lisp_Object window;
5f5c8ee5
GM
8980 struct text_pos pos;
8981{
8982 struct window *w = XWINDOW (window);
8983 struct it it;
8984 struct glyph_row *last_text_row = NULL;
9cbab4ff 8985
5f5c8ee5
GM
8986 /* Make POS the new window start. */
8987 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12adba34 8988
5f5c8ee5
GM
8989 /* Mark cursor position as unknown. No overlay arrow seen. */
8990 w->cursor.vpos = -1;
a2889657 8991 overlay_arrow_seen = 0;
642eefc6 8992
5f5c8ee5
GM
8993 /* Initialize iterator and info to start at POS. */
8994 start_display (&it, w, pos);
a2889657 8995
5f5c8ee5
GM
8996 /* Display all lines of W. */
8997 while (it.current_y < it.last_visible_y)
8998 {
8999 if (display_line (&it))
9000 last_text_row = it.glyph_row - 1;
9001 if (fonts_changed_p)
9002 return 0;
9003 }
a2889657 9004
5f5c8ee5
GM
9005 /* If bottom moved off end of frame, change mode line percentage. */
9006 if (XFASTINT (w->window_end_pos) <= 0
9007 && Z != IT_CHARPOS (it))
a2889657
JB
9008 w->update_mode_line = Qt;
9009
5f5c8ee5
GM
9010 /* Set window_end_pos to the offset of the last character displayed
9011 on the window from the end of current_buffer. Set
9012 window_end_vpos to its row number. */
9013 if (last_text_row)
9014 {
9015 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
9016 w->window_end_bytepos
9017 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9018 XSETFASTINT (w->window_end_pos,
9019 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9020 XSETFASTINT (w->window_end_vpos,
9021 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9022 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
9023 ->displays_text_p);
9024 }
9025 else
9026 {
9027 w->window_end_bytepos = 0;
9028 XSETFASTINT (w->window_end_pos, 0);
9029 XSETFASTINT (w->window_end_vpos, 0);
9030 }
9031
a2889657
JB
9032 /* But that is not valid info until redisplay finishes. */
9033 w->window_end_valid = Qnil;
5f5c8ee5 9034 return 1;
a2889657 9035}
5f5c8ee5
GM
9036
9037
a2889657 9038\f
5f5c8ee5
GM
9039/************************************************************************
9040 Window redisplay reusing current matrix when buffer has not changed
9041 ************************************************************************/
9042
9043/* Try redisplay of window W showing an unchanged buffer with a
9044 different window start than the last time it was displayed by
9045 reusing its current matrix. Value is non-zero if successful.
9046 W->start is the new window start. */
a2889657
JB
9047
9048static int
5f5c8ee5
GM
9049try_window_reusing_current_matrix (w)
9050 struct window *w;
a2889657 9051{
5f5c8ee5
GM
9052 struct frame *f = XFRAME (w->frame);
9053 struct glyph_row *row, *bottom_row;
9054 struct it it;
9055 struct run run;
9056 struct text_pos start, new_start;
9057 int nrows_scrolled, i;
9058 struct glyph_row *last_text_row;
9059 struct glyph_row *last_reused_text_row;
9060 struct glyph_row *start_row;
9061 int start_vpos, min_y, max_y;
9062
9063 /* Right now this function doesn't handle terminal frames. */
9064 if (!FRAME_WINDOW_P (f))
9065 return 0;
a2889657 9066
5f5c8ee5
GM
9067 /* Can't do this if region may have changed. */
9068 if ((!NILP (Vtransient_mark_mode)
9069 && !NILP (current_buffer->mark_active))
8f897821
GM
9070 || !NILP (w->region_showing)
9071 || !NILP (Vshow_trailing_whitespace))
5f5c8ee5 9072 return 0;
a2889657 9073
5f5c8ee5
GM
9074 /* If top-line visibility has changed, give up. */
9075 if (WINDOW_WANTS_TOP_LINE_P (w)
9076 != MATRIX_TOP_LINE_ROW (w->current_matrix)->mode_line_p)
9077 return 0;
9078
9079 /* Give up if old or new display is scrolled vertically. We could
9080 make this function handle this, but right now it doesn't. */
9081 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9082 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
9083 return 0;
9084
9085 /* The variable new_start now holds the new window start. The old
9086 start `start' can be determined from the current matrix. */
9087 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
9088 start = start_row->start.pos;
9089 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
a2889657 9090
5f5c8ee5
GM
9091 /* Clear the desired matrix for the display below. */
9092 clear_glyph_matrix (w->desired_matrix);
9093
9094 if (CHARPOS (new_start) <= CHARPOS (start))
9095 {
9096 int first_row_y;
9097
9098 IF_DEBUG (debug_method_add (w, "twu1"));
9099
9100 /* Display up to a row that can be reused. The variable
9101 last_text_row is set to the last row displayed that displays
9102 text. */
9103 start_display (&it, w, new_start);
9104 first_row_y = it.current_y;
9105 w->cursor.vpos = -1;
9106 last_text_row = last_reused_text_row = NULL;
9107 while (it.current_y < it.last_visible_y
9108 && IT_CHARPOS (it) < CHARPOS (start)
9109 && !fonts_changed_p)
9110 if (display_line (&it))
9111 last_text_row = it.glyph_row - 1;
9112
9113 /* A value of current_y < last_visible_y means that we stopped
9114 at the previous window start, which in turn means that we
9115 have at least one reusable row. */
9116 if (it.current_y < it.last_visible_y)
a2889657 9117 {
5f5c8ee5
GM
9118 nrows_scrolled = it.vpos;
9119
9120 /* Find PT if not already found in the lines displayed. */
9121 if (w->cursor.vpos < 0)
a2889657 9122 {
5f5c8ee5
GM
9123 int dy = it.current_y - first_row_y;
9124
9125 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9126 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9127 {
9128 if (PT >= MATRIX_ROW_START_CHARPOS (row)
9129 && PT < MATRIX_ROW_END_CHARPOS (row))
9130 {
9131 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
9132 dy, nrows_scrolled);
9133 break;
9134 }
9135
9136 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
9137 break;
9138
9139 ++row;
9140 }
9141
9142 /* Give up if point was not found. This shouldn't
9143 happen often; not more often than with try_window
9144 itself. */
9145 if (w->cursor.vpos < 0)
9146 {
9147 clear_glyph_matrix (w->desired_matrix);
9148 return 0;
9149 }
a2889657 9150 }
5f5c8ee5
GM
9151
9152 /* Scroll the display. Do it before the current matrix is
9153 changed. The problem here is that update has not yet
9154 run, i.e. part of the current matrix is not up to date.
9155 scroll_run_hook will clear the cursor, and use the
9156 current matrix to get the height of the row the cursor is
9157 in. */
9158 run.current_y = first_row_y;
9159 run.desired_y = it.current_y;
9160 run.height = it.last_visible_y - it.current_y;
9161 if (run.height > 0)
a2889657 9162 {
5f5c8ee5
GM
9163 update_begin (f);
9164 rif->update_window_begin_hook (w);
9165 rif->scroll_run_hook (w, &run);
9166 rif->update_window_end_hook (w, 0);
9167 update_end (f);
a2889657 9168 }
5f5c8ee5
GM
9169
9170 /* Shift current matrix down by nrows_scrolled lines. */
9171 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9172 rotate_matrix (w->current_matrix,
9173 start_vpos,
9174 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9175 nrows_scrolled);
9176
9177 /* Disable lines not reused. */
9178 for (i = 0; i < it.vpos; ++i)
9179 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
9180
9181 /* Re-compute Y positions. */
9182 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
9183 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
9184 max_y = it.last_visible_y;
9185 while (row < bottom_row)
d2f84654 9186 {
5f5c8ee5
GM
9187 row->y = it.current_y;
9188
9189 if (row->y < min_y)
9190 row->visible_height = row->height - (min_y - row->y);
9191 else if (row->y + row->height > max_y)
9192 row->visible_height
9193 = row->height - (row->y + row->height - max_y);
9194 else
9195 row->visible_height = row->height;
9196
9197 it.current_y += row->height;
9198 ++it.vpos;
9199
9200 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9201 last_reused_text_row = row;
9202 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
9203 break;
9204 ++row;
d2f84654 9205 }
a2889657 9206 }
5f5c8ee5
GM
9207
9208 /* Update window_end_pos etc.; last_reused_text_row is the last
9209 reused row from the current matrix containing text, if any.
9210 The value of last_text_row is the last displayed line
9211 containing text. */
9212 if (last_reused_text_row)
a2889657 9213 {
5f5c8ee5
GM
9214 w->window_end_bytepos
9215 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
9216 XSETFASTINT (w->window_end_pos,
9217 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
9218 XSETFASTINT (w->window_end_vpos,
9219 MATRIX_ROW_VPOS (last_reused_text_row,
9220 w->current_matrix));
a2889657 9221 }
5f5c8ee5
GM
9222 else if (last_text_row)
9223 {
9224 w->window_end_bytepos
9225 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9226 XSETFASTINT (w->window_end_pos,
9227 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9228 XSETFASTINT (w->window_end_vpos,
9229 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9230 }
9231 else
9232 {
9233 /* This window must be completely empty. */
9234 w->window_end_bytepos = 0;
9235 XSETFASTINT (w->window_end_pos, 0);
9236 XSETFASTINT (w->window_end_vpos, 0);
9237 }
9238 w->window_end_valid = Qnil;
a2889657 9239
5f5c8ee5
GM
9240 /* Update hint: don't try scrolling again in update_window. */
9241 w->desired_matrix->no_scrolling_p = 1;
9242
9243#if GLYPH_DEBUG
9244 debug_method_add (w, "try_window_reusing_current_matrix 1");
9245#endif
9246 return 1;
a2889657 9247 }
5f5c8ee5
GM
9248 else if (CHARPOS (new_start) > CHARPOS (start))
9249 {
9250 struct glyph_row *pt_row, *row;
9251 struct glyph_row *first_reusable_row;
9252 struct glyph_row *first_row_to_display;
9253 int dy;
9254 int yb = window_text_bottom_y (w);
9255
9256 IF_DEBUG (debug_method_add (w, "twu2"));
9257
9258 /* Find the row starting at new_start, if there is one. Don't
9259 reuse a partially visible line at the end. */
9260 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9261 while (first_reusable_row->enabled_p
9262 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
9263 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9264 < CHARPOS (new_start)))
9265 ++first_reusable_row;
9266
9267 /* Give up if there is no row to reuse. */
9268 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
28514cd9
GM
9269 || !first_reusable_row->enabled_p
9270 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9271 != CHARPOS (new_start)))
5f5c8ee5
GM
9272 return 0;
9273
5f5c8ee5
GM
9274 /* We can reuse fully visible rows beginning with
9275 first_reusable_row to the end of the window. Set
9276 first_row_to_display to the first row that cannot be reused.
9277 Set pt_row to the row containing point, if there is any. */
9278 first_row_to_display = first_reusable_row;
9279 pt_row = NULL;
9280 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
9281 {
9282 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
9283 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
9284 pt_row = first_row_to_display;
a2889657 9285
5f5c8ee5
GM
9286 ++first_row_to_display;
9287 }
a2889657 9288
5f5c8ee5
GM
9289 /* Start displaying at the start of first_row_to_display. */
9290 xassert (first_row_to_display->y < yb);
9291 init_to_row_start (&it, w, first_row_to_display);
9292 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
9293 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
9294 - nrows_scrolled);
9295 it.current_y = first_row_to_display->y - first_reusable_row->y;
9296
9297 /* Display lines beginning with first_row_to_display in the
9298 desired matrix. Set last_text_row to the last row displayed
9299 that displays text. */
9300 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
9301 if (pt_row == NULL)
9302 w->cursor.vpos = -1;
9303 last_text_row = NULL;
9304 while (it.current_y < it.last_visible_y && !fonts_changed_p)
9305 if (display_line (&it))
9306 last_text_row = it.glyph_row - 1;
9307
9308 /* Give up If point isn't in a row displayed or reused. */
9309 if (w->cursor.vpos < 0)
9310 {
9311 clear_glyph_matrix (w->desired_matrix);
9312 return 0;
9313 }
12adba34 9314
5f5c8ee5
GM
9315 /* If point is in a reused row, adjust y and vpos of the cursor
9316 position. */
9317 if (pt_row)
9318 {
9319 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
9320 w->current_matrix);
9321 w->cursor.y -= first_reusable_row->y;
a2889657
JB
9322 }
9323
5f5c8ee5
GM
9324 /* Scroll the display. */
9325 run.current_y = first_reusable_row->y;
9326 run.desired_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
9327 run.height = it.last_visible_y - run.current_y;
9328 if (run.height)
9329 {
9330 struct frame *f = XFRAME (WINDOW_FRAME (w));
9331 update_begin (f);
9332 rif->update_window_begin_hook (w);
9333 rif->scroll_run_hook (w, &run);
9334 rif->update_window_end_hook (w, 0);
9335 update_end (f);
9336 }
a2889657 9337
5f5c8ee5
GM
9338 /* Adjust Y positions of reused rows. */
9339 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9340 row = first_reusable_row;
9341 dy = first_reusable_row->y;
9342 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
9343 max_y = it.last_visible_y;
9344 while (row < first_row_to_display)
9345 {
9346 row->y -= dy;
9347 if (row->y < min_y)
9348 row->visible_height = row->height - (min_y - row->y);
9349 else if (row->y + row->height > max_y)
9350 row->visible_height
9351 = row->height - (row->y + row->height - max_y);
9352 else
9353 row->visible_height = row->height;
9354 ++row;
9355 }
a2889657 9356
5f5c8ee5
GM
9357 /* Disable rows not reused. */
9358 while (row < bottom_row)
9359 {
9360 row->enabled_p = 0;
9361 ++row;
9362 }
9363
9364 /* Scroll the current matrix. */
9365 xassert (nrows_scrolled > 0);
9366 rotate_matrix (w->current_matrix,
9367 start_vpos,
9368 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9369 -nrows_scrolled);
9370
9371 /* Adjust window end. A null value of last_text_row means that
9372 the window end is in reused rows which in turn means that
9373 only its vpos can have changed. */
9374 if (last_text_row)
9375 {
9376 w->window_end_bytepos
9377 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9378 XSETFASTINT (w->window_end_pos,
9379 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9380 XSETFASTINT (w->window_end_vpos,
9381 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9382 }
9383 else
a2889657 9384 {
e8e536a9 9385 XSETFASTINT (w->window_end_vpos,
5f5c8ee5 9386 XFASTINT (w->window_end_vpos) - nrows_scrolled);
a2889657 9387 }
5f5c8ee5
GM
9388
9389 w->window_end_valid = Qnil;
9390 w->desired_matrix->no_scrolling_p = 1;
9391
9392#if GLYPH_DEBUG
9393 debug_method_add (w, "try_window_reusing_current_matrix 2");
9394#endif
9395 return 1;
a2889657 9396 }
5f5c8ee5
GM
9397
9398 return 0;
9399}
a2889657 9400
a2889657 9401
5f5c8ee5
GM
9402\f
9403/************************************************************************
9404 Window redisplay reusing current matrix when buffer has changed
9405 ************************************************************************/
9406
9407static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
9408static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
9409 int *, int *));
9410static struct glyph_row *
9411find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
9412 struct glyph_row *));
9413
9414
9415/* Return the last row in MATRIX displaying text. If row START is
9416 non-null, start searching with that row. IT gives the dimensions
9417 of the display. Value is null if matrix is empty; otherwise it is
9418 a pointer to the row found. */
9419
9420static struct glyph_row *
9421find_last_row_displaying_text (matrix, it, start)
9422 struct glyph_matrix *matrix;
9423 struct it *it;
9424 struct glyph_row *start;
9425{
9426 struct glyph_row *row, *row_found;
9427
9428 /* Set row_found to the last row in IT->w's current matrix
9429 displaying text. The loop looks funny but think of partially
9430 visible lines. */
9431 row_found = NULL;
9432 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
9433 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9434 {
9435 xassert (row->enabled_p);
9436 row_found = row;
9437 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
9438 break;
9439 ++row;
a2889657 9440 }
5f5c8ee5
GM
9441
9442 return row_found;
9443}
9444
a2889657 9445
5f5c8ee5
GM
9446/* Return the last row in the current matrix of W that is not affected
9447 by changes at the start of current_buffer that occurred since the
9448 last time W was redisplayed. Value is null if no such row exists.
a2889657 9449
5f5c8ee5
GM
9450 The global variable beg_unchanged has to contain the number of
9451 bytes unchanged at the start of current_buffer. BEG +
9452 beg_unchanged is the buffer position of the first changed byte in
9453 current_buffer. Characters at positions < BEG + beg_unchanged are
9454 at the same buffer positions as they were when the current matrix
9455 was built. */
9456
9457static struct glyph_row *
9458get_last_unchanged_at_beg_row (w)
9459 struct window *w;
9460{
9142dd5b 9461 int first_changed_pos = BEG + BEG_UNCHANGED;
5f5c8ee5
GM
9462 struct glyph_row *row;
9463 struct glyph_row *row_found = NULL;
9464 int yb = window_text_bottom_y (w);
9465
9466 /* Find the last row displaying unchanged text. */
9467 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9468 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
9469 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
a2889657 9470 {
5f5c8ee5
GM
9471 if (/* If row ends before first_changed_pos, it is unchanged,
9472 except in some case. */
9473 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
9474 /* When row ends in ZV and we write at ZV it is not
9475 unchanged. */
9476 && !row->ends_at_zv_p
9477 /* When first_changed_pos is the end of a continued line,
9478 row is not unchanged because it may be no longer
9479 continued. */
9480 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
9481 && row->continued_p))
9482 row_found = row;
9483
9484 /* Stop if last visible row. */
9485 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
9486 break;
9487
9488 ++row;
a2889657
JB
9489 }
9490
5f5c8ee5 9491 return row_found;
a2889657 9492}
5f5c8ee5
GM
9493
9494
9495/* Find the first glyph row in the current matrix of W that is not
9496 affected by changes at the end of current_buffer since the last
9497 time the window was redisplayed. Return in *DELTA the number of
9498 bytes by which buffer positions in unchanged text at the end of
9499 current_buffer must be adjusted. Value is null if no such row
9500 exists, i.e. all rows are affected by changes.
9501
9502 The global variable end_unchanged is assumed to contain the number
9503 of unchanged bytes at the end of current_buffer. The buffer
9504 position of the last changed byte in current_buffer is then Z -
9505 end_unchanged. */
9506
9507static struct glyph_row *
9508get_first_unchanged_at_end_row (w, delta, delta_bytes)
9509 struct window *w;
9510 int *delta, *delta_bytes;
a2889657 9511{
5f5c8ee5
GM
9512 struct glyph_row *row;
9513 struct glyph_row *row_found = NULL;
c581d710 9514
5f5c8ee5 9515 *delta = *delta_bytes = 0;
b2a76982 9516
5f5c8ee5
GM
9517 /* A value of window_end_pos >= end_unchanged means that the window
9518 end is in the range of changed text. If so, there is no
9519 unchanged row at the end of W's current matrix. */
9520 xassert (!NILP (w->window_end_valid));
9142dd5b 9521 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
5f5c8ee5
GM
9522 return NULL;
9523
9524 /* Set row to the last row in W's current matrix displaying text. */
9525 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9526
5f5c8ee5
GM
9527 /* If matrix is entirely empty, no unchanged row exists. */
9528 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9529 {
9530 /* The value of row is the last glyph row in the matrix having a
9531 meaningful buffer position in it. The end position of row
9532 corresponds to window_end_pos. This allows us to translate
9533 buffer positions in the current matrix to current buffer
9534 positions for characters not in changed text. */
9535 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
9536 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
9537 int last_unchanged_pos, last_unchanged_pos_old;
9538 struct glyph_row *first_text_row
9539 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9540
9541 *delta = Z - Z_old;
9542 *delta_bytes = Z_BYTE - Z_BYTE_old;
9543
9544 /* Set last_unchanged_pos to the buffer position of the last
9545 character in the buffer that has not been changed. Z is the
9546 index + 1 of the last byte in current_buffer, i.e. by
9547 subtracting end_unchanged we get the index of the last
9548 unchanged character, and we have to add BEG to get its buffer
9549 position. */
9142dd5b 9550 last_unchanged_pos = Z - END_UNCHANGED + BEG;
5f5c8ee5
GM
9551 last_unchanged_pos_old = last_unchanged_pos - *delta;
9552
9553 /* Search backward from ROW for a row displaying a line that
9554 starts at a minimum position >= last_unchanged_pos_old. */
9555 while (row >= first_text_row)
9556 {
9557 xassert (row->enabled_p);
9558 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9559
9560 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9561 row_found = row;
9562 --row;
9563 }
9564 }
9565
9566 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9567 return row_found;
c581d710
RS
9568}
9569
c581d710 9570
5f5c8ee5
GM
9571/* Make sure that glyph rows in the current matrix of window W
9572 reference the same glyph memory as corresponding rows in the
9573 frame's frame matrix. This function is called after scrolling W's
9574 current matrix on a terminal frame in try_window_id and
9575 try_window_reusing_current_matrix. */
9576
9577static void
9578sync_frame_with_window_matrix_rows (w)
9579 struct window *w;
c581d710 9580{
5f5c8ee5
GM
9581 struct frame *f = XFRAME (w->frame);
9582 struct glyph_row *window_row, *window_row_end, *frame_row;
9583
9584 /* Preconditions: W must be a leaf window and full-width. Its frame
9585 must have a frame matrix. */
9586 xassert (NILP (w->hchild) && NILP (w->vchild));
9587 xassert (WINDOW_FULL_WIDTH_P (w));
9588 xassert (!FRAME_WINDOW_P (f));
9589
9590 /* If W is a full-width window, glyph pointers in W's current matrix
9591 have, by definition, to be the same as glyph pointers in the
9592 corresponding frame matrix. */
9593 window_row = w->current_matrix->rows;
9594 window_row_end = window_row + w->current_matrix->nrows;
9595 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9596 while (window_row < window_row_end)
659a218f 9597 {
5f5c8ee5
GM
9598 int area;
9599 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9600 frame_row->glyphs[area] = window_row->glyphs[area];
9601 ++window_row, ++frame_row;
659a218f 9602 }
a2889657 9603}
5f5c8ee5
GM
9604
9605
9606/* Try to redisplay window W by reusing its existing display. W's
9607 current matrix must be up to date when this function is called,
9608 i.e. window_end_valid must not be nil.
9609
9610 Value is
9611
9612 1 if display has been updated
9613 0 if otherwise unsuccessful
9614 -1 if redisplay with same window start is known not to succeed
9615
9616 The following steps are performed:
9617
9618 1. Find the last row in the current matrix of W that is not
9619 affected by changes at the start of current_buffer. If no such row
9620 is found, give up.
9621
9622 2. Find the first row in W's current matrix that is not affected by
9623 changes at the end of current_buffer. Maybe there is no such row.
9624
9625 3. Display lines beginning with the row + 1 found in step 1 to the
9626 row found in step 2 or, if step 2 didn't find a row, to the end of
9627 the window.
9628
9629 4. If cursor is not known to appear on the window, give up.
9630
9631 5. If display stopped at the row found in step 2, scroll the
9632 display and current matrix as needed.
9633
9634 6. Maybe display some lines at the end of W, if we must. This can
9635 happen under various circumstances, like a partially visible line
9636 becoming fully visible, or because newly displayed lines are displayed
9637 in smaller font sizes.
9638
9639 7. Update W's window end information. */
9640
9641 /* Check that window end is what we expect it to be. */
12adba34
RS
9642
9643static int
5f5c8ee5 9644try_window_id (w)
12adba34 9645 struct window *w;
12adba34 9646{
5f5c8ee5
GM
9647 struct frame *f = XFRAME (w->frame);
9648 struct glyph_matrix *current_matrix = w->current_matrix;
9649 struct glyph_matrix *desired_matrix = w->desired_matrix;
9650 struct glyph_row *last_unchanged_at_beg_row;
9651 struct glyph_row *first_unchanged_at_end_row;
9652 struct glyph_row *row;
9653 struct glyph_row *bottom_row;
9654 int bottom_vpos;
9655 struct it it;
9656 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
9657 struct text_pos start_pos;
9658 struct run run;
9659 int first_unchanged_at_end_vpos = 0;
9660 struct glyph_row *last_text_row, *last_text_row_at_end;
9661 struct text_pos start;
9662
9663 SET_TEXT_POS_FROM_MARKER (start, w->start);
9664
9665 /* Check pre-conditions. Window end must be valid, otherwise
9666 the current matrix would not be up to date. */
9667 xassert (!NILP (w->window_end_valid));
9668 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
9669 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
9670
9671 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
9672 only if buffer has really changed. The reason is that the gap is
9673 initially at Z for freshly visited files. The code below would
9674 set end_unchanged to 0 in that case. */
9675 if (MODIFF > SAVE_MODIFF)
9676 {
9142dd5b
GM
9677 if (GPT - BEG < BEG_UNCHANGED)
9678 BEG_UNCHANGED = GPT - BEG;
9679 if (Z - GPT < END_UNCHANGED)
9680 END_UNCHANGED = Z - GPT;
5f5c8ee5
GM
9681 }
9682
9683 /* If window starts after a line end, and the last change is in
9684 front of that newline, then changes don't affect the display.
9685 This case happens with stealth-fontification. */
9686 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9687 if (CHARPOS (start) > BEGV
9142dd5b 9688 && Z - END_UNCHANGED < CHARPOS (start) - 1
5f5c8ee5
GM
9689 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
9690 && PT < MATRIX_ROW_END_CHARPOS (row))
9691 {
9692 /* We have to update window end positions because the buffer's
9693 size has changed. */
9694 w->window_end_pos
9695 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9696 w->window_end_bytepos
9697 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9698 return 1;
9699 }
9700
9701 /* Return quickly if changes are all below what is displayed in the
9702 window, and if PT is in the window. */
9142dd5b 9703 if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
5f5c8ee5
GM
9704 && PT < MATRIX_ROW_END_CHARPOS (row))
9705 {
9706 /* We have to update window end positions because the buffer's
9707 size has changed. */
9708 w->window_end_pos
9709 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9710 w->window_end_bytepos
9711 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9712 return 1;
9713 }
9714
9715 /* Check that window start agrees with the start of the first glyph
9716 row in its current matrix. Check this after we know the window
9717 start is not in changed text, otherwise positions would not be
9718 comparable. */
9719 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9720 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
9721 return 0;
9722
5f5c8ee5
GM
9723 /* Compute the position at which we have to start displaying new
9724 lines. Some of the lines at the top of the window might be
9725 reusable because they are not displaying changed text. Find the
9726 last row in W's current matrix not affected by changes at the
9727 start of current_buffer. Value is null if changes start in the
9728 first line of window. */
9729 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
9730 if (last_unchanged_at_beg_row)
9731 {
9732 init_to_row_end (&it, w, last_unchanged_at_beg_row);
9733 start_pos = it.current.pos;
9734
9735 /* Start displaying new lines in the desired matrix at the same
9736 vpos we would use in the current matrix, i.e. below
9737 last_unchanged_at_beg_row. */
9738 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
9739 current_matrix);
9740 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9741 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
9742
9743 xassert (it.hpos == 0 && it.current_x == 0);
9744 }
9745 else
9746 {
9747 /* There are no reusable lines at the start of the window.
9748 Start displaying in the first line. */
9749 start_display (&it, w, start);
9750 start_pos = it.current.pos;
9751 }
9752
9753 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
9754 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
9755
9756 /* Find the first row that is not affected by changes at the end of
9757 the buffer. Value will be null if there is no unchanged row, in
9758 which case we must redisplay to the end of the window. delta
9759 will be set to the value by which buffer positions beginning with
9760 first_unchanged_at_end_row have to be adjusted due to text
9761 changes. */
9762 first_unchanged_at_end_row
9763 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
9764 IF_DEBUG (debug_delta = delta);
9765 IF_DEBUG (debug_delta_bytes = delta_bytes);
9766
9767 /* Set stop_pos to the buffer position up to which we will have to
9768 display new lines. If first_unchanged_at_end_row != NULL, this
9769 is the buffer position of the start of the line displayed in that
9770 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
9771 that we don't stop at a buffer position. */
9772 stop_pos = 0;
9773 if (first_unchanged_at_end_row)
9774 {
9775 xassert (last_unchanged_at_beg_row == NULL
9776 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
9777
9778 /* If this is a continuation line, move forward to the next one
9779 that isn't. Changes in lines above affect this line.
9780 Caution: this may move first_unchanged_at_end_row to a row
9781 not displaying text. */
9782 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
9783 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9784 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9785 < it.last_visible_y))
9786 ++first_unchanged_at_end_row;
9787
9788 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9789 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9790 >= it.last_visible_y))
9791 first_unchanged_at_end_row = NULL;
9792 else
9793 {
9794 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
9795 + delta);
9796 first_unchanged_at_end_vpos
9797 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
9142dd5b 9798 xassert (stop_pos >= Z - END_UNCHANGED);
5f5c8ee5
GM
9799 }
9800 }
9801 else if (last_unchanged_at_beg_row == NULL)
9802 return 0;
9803
9804
9805#if GLYPH_DEBUG
9806
9807 /* Either there is no unchanged row at the end, or the one we have
9808 now displays text. This is a necessary condition for the window
9809 end pos calculation at the end of this function. */
9810 xassert (first_unchanged_at_end_row == NULL
9811 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
9812
9813 debug_last_unchanged_at_beg_vpos
9814 = (last_unchanged_at_beg_row
9815 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
9816 : -1);
9817 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
9818
9819#endif /* GLYPH_DEBUG != 0 */
9820
9821
9822 /* Display new lines. Set last_text_row to the last new line
9823 displayed which has text on it, i.e. might end up as being the
9824 line where the window_end_vpos is. */
9825 w->cursor.vpos = -1;
9826 last_text_row = NULL;
9827 overlay_arrow_seen = 0;
9828 while (it.current_y < it.last_visible_y
9829 && !fonts_changed_p
9830 && (first_unchanged_at_end_row == NULL
9831 || IT_CHARPOS (it) < stop_pos))
9832 {
9833 if (display_line (&it))
9834 last_text_row = it.glyph_row - 1;
9835 }
9836
9837 if (fonts_changed_p)
9838 return -1;
9839
9840
9841 /* Compute differences in buffer positions, y-positions etc. for
9842 lines reused at the bottom of the window. Compute what we can
9843 scroll. */
9844 if (first_unchanged_at_end_row)
9845 {
9846 dvpos = (it.vpos
9847 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
9848 current_matrix));
9849 dy = it.current_y - first_unchanged_at_end_row->y;
9850 run.current_y = first_unchanged_at_end_row->y;
9851 run.desired_y = run.current_y + dy;
9852 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
9853 }
9854 else
9855 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
9856 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
9857
9858
9859 /* Find the cursor if not already found. We have to decide whether
9860 PT will appear on this window (it sometimes doesn't, but this is
9861 not a very frequent case.) This decision has to be made before
9862 the current matrix is altered. A value of cursor.vpos < 0 means
9863 that PT is either in one of the lines beginning at
9864 first_unchanged_at_end_row or below the window. Don't care for
9865 lines that might be displayed later at the window end; as
9866 mentioned, this is not a frequent case. */
9867 if (w->cursor.vpos < 0)
9868 {
9869 int last_y = min (it.last_visible_y, it.last_visible_y + dy);
9870
9871 /* Cursor in unchanged rows at the top? */
9872 if (PT < CHARPOS (start_pos)
9873 && last_unchanged_at_beg_row)
9874 {
9875 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9876 while (row <= last_unchanged_at_beg_row
9877 && MATRIX_ROW_END_CHARPOS (row) <= PT)
9878 ++row;
9879 xassert (row <= last_unchanged_at_beg_row);
9880 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9881 }
9882
9883 /* Start from first_unchanged_at_end_row looking for PT. */
9884 else if (first_unchanged_at_end_row)
9885 {
9886 row = first_unchanged_at_end_row;
9887 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9888 {
9889 if (PT - delta >= MATRIX_ROW_START_CHARPOS (row)
9890 && PT - delta < MATRIX_ROW_END_CHARPOS (row))
9891 {
9892 set_cursor_from_row (w, row, w->current_matrix, delta,
9893 delta_bytes, dy, dvpos);
9894 break;
9895 }
9896 else if (MATRIX_ROW_BOTTOM_Y (row) >= last_y)
9897 break;
9898 ++row;
9899 }
9900 }
9901
9902 /* Give up if cursor was not found. */
9903 if (w->cursor.vpos < 0)
9904 {
9905 clear_glyph_matrix (w->desired_matrix);
9906 return -1;
9907 }
9908 }
9909
9910 /* Don't let the cursor end in the scroll margins. */
9911 {
9912 int this_scroll_margin, cursor_height;
9913
9914 this_scroll_margin = max (0, scroll_margin);
9915 this_scroll_margin = min (this_scroll_margin,
9916 XFASTINT (w->height) / 4);
9917 this_scroll_margin *= CANON_Y_UNIT (it.f);
9918 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
9919
9920 if ((w->cursor.y < this_scroll_margin
9921 && CHARPOS (start) > BEGV)
9922 /* Don't take scroll margin into account at the bottom because
9923 old redisplay didn't do it either. */
9924 || w->cursor.y + cursor_height > it.last_visible_y)
9925 {
9926 w->cursor.vpos = -1;
9927 clear_glyph_matrix (w->desired_matrix);
9928 return -1;
9929 }
9930 }
9931
9932 /* Scroll the display. Do it before changing the current matrix so
9933 that xterm.c doesn't get confused about where the cursor glyph is
9934 found. */
9935 if (dy)
9936 {
9937 update_begin (f);
9938
9939 if (FRAME_WINDOW_P (f))
9940 {
9941 rif->update_window_begin_hook (w);
9942 rif->scroll_run_hook (w, &run);
9943 rif->update_window_end_hook (w, 0);
9944 }
9945 else
9946 {
9947 /* Terminal frame. In this case, dvpos gives the number of
9948 lines to scroll by; dvpos < 0 means scroll up. */
9949 int first_unchanged_at_end_vpos
9950 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
9951 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
9952 int end = XFASTINT (w->top) + window_internal_height (w);
9953
9954 /* Perform the operation on the screen. */
9955 if (dvpos > 0)
9956 {
9957 /* Scroll last_unchanged_at_beg_row to the end of the
9958 window down dvpos lines. */
9959 set_terminal_window (end);
9960
9961 /* On dumb terminals delete dvpos lines at the end
9962 before inserting dvpos empty lines. */
9963 if (!scroll_region_ok)
9964 ins_del_lines (end - dvpos, -dvpos);
9965
9966 /* Insert dvpos empty lines in front of
9967 last_unchanged_at_beg_row. */
9968 ins_del_lines (from, dvpos);
9969 }
9970 else if (dvpos < 0)
9971 {
9972 /* Scroll up last_unchanged_at_beg_vpos to the end of
9973 the window to last_unchanged_at_beg_vpos - |dvpos|. */
9974 set_terminal_window (end);
9975
9976 /* Delete dvpos lines in front of
9977 last_unchanged_at_beg_vpos. ins_del_lines will set
9978 the cursor to the given vpos and emit |dvpos| delete
9979 line sequences. */
9980 ins_del_lines (from + dvpos, dvpos);
9981
9982 /* On a dumb terminal insert dvpos empty lines at the
9983 end. */
9984 if (!scroll_region_ok)
9985 ins_del_lines (end + dvpos, -dvpos);
9986 }
9987
9988 set_terminal_window (0);
9989 }
9990
9991 update_end (f);
9992 }
9993
9994 /* Shift reused rows of the current matrix to the right position. */
9995 if (dvpos < 0)
9996 {
9997 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
9998 bottom_vpos, dvpos);
9999 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
10000 bottom_vpos, 0);
10001 }
10002 else if (dvpos > 0)
10003 {
10004 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
10005 bottom_vpos, dvpos);
10006 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
10007 first_unchanged_at_end_vpos + dvpos, 0);
10008 }
10009
10010 /* For frame-based redisplay, make sure that current frame and window
10011 matrix are in sync with respect to glyph memory. */
10012 if (!FRAME_WINDOW_P (f))
10013 sync_frame_with_window_matrix_rows (w);
10014
10015 /* Adjust buffer positions in reused rows. */
10016 if (delta)
10017 increment_glyph_matrix_buffer_positions (current_matrix,
10018 first_unchanged_at_end_vpos + dvpos,
10019 bottom_vpos, delta, delta_bytes);
10020
10021 /* Adjust Y positions. */
10022 if (dy)
10023 shift_glyph_matrix (w, current_matrix,
10024 first_unchanged_at_end_vpos + dvpos,
10025 bottom_vpos, dy);
10026
10027 if (first_unchanged_at_end_row)
10028 first_unchanged_at_end_row += dvpos;
10029
10030 /* If scrolling up, there may be some lines to display at the end of
10031 the window. */
10032 last_text_row_at_end = NULL;
10033 if (dy < 0)
10034 {
10035 /* Set last_row to the glyph row in the current matrix where the
10036 window end line is found. It has been moved up or down in
10037 the matrix by dvpos. */
10038 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
10039 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
10040
10041 /* If last_row is the window end line, it should display text. */
10042 xassert (last_row->displays_text_p);
10043
10044 /* If window end line was partially visible before, begin
10045 displaying at that line. Otherwise begin displaying with the
10046 line following it. */
10047 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
10048 {
10049 init_to_row_start (&it, w, last_row);
10050 it.vpos = last_vpos;
10051 it.current_y = last_row->y;
10052 }
10053 else
10054 {
10055 init_to_row_end (&it, w, last_row);
10056 it.vpos = 1 + last_vpos;
10057 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
10058 ++last_row;
10059 }
12adba34 10060
5f5c8ee5
GM
10061 /* We may start in a continuation line. If so, we have to get
10062 the right continuation_lines_width and current_x. */
10063 it.continuation_lines_width = last_row->continuation_lines_width;
10064 it.hpos = it.current_x = 0;
10065
10066 /* Display the rest of the lines at the window end. */
10067 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10068 while (it.current_y < it.last_visible_y
10069 && !fonts_changed_p)
10070 {
10071 /* Is it always sure that the display agrees with lines in
10072 the current matrix? I don't think so, so we mark rows
10073 displayed invalid in the current matrix by setting their
10074 enabled_p flag to zero. */
10075 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
10076 if (display_line (&it))
10077 last_text_row_at_end = it.glyph_row - 1;
10078 }
10079 }
12adba34 10080
5f5c8ee5
GM
10081 /* Update window_end_pos and window_end_vpos. */
10082 if (first_unchanged_at_end_row
10083 && first_unchanged_at_end_row->y < it.last_visible_y
10084 && !last_text_row_at_end)
10085 {
10086 /* Window end line if one of the preserved rows from the current
10087 matrix. Set row to the last row displaying text in current
10088 matrix starting at first_unchanged_at_end_row, after
10089 scrolling. */
10090 xassert (first_unchanged_at_end_row->displays_text_p);
10091 row = find_last_row_displaying_text (w->current_matrix, &it,
10092 first_unchanged_at_end_row);
10093 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
10094
10095 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
10096 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10097 XSETFASTINT (w->window_end_vpos,
10098 MATRIX_ROW_VPOS (row, w->current_matrix));
10099 }
10100 else if (last_text_row_at_end)
10101 {
10102 XSETFASTINT (w->window_end_pos,
10103 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
10104 w->window_end_bytepos
10105 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
10106 XSETFASTINT (w->window_end_vpos,
10107 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
10108 }
10109 else if (last_text_row)
10110 {
10111 /* We have displayed either to the end of the window or at the
10112 end of the window, i.e. the last row with text is to be found
10113 in the desired matrix. */
10114 XSETFASTINT (w->window_end_pos,
10115 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10116 w->window_end_bytepos
10117 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10118 XSETFASTINT (w->window_end_vpos,
10119 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
10120 }
10121 else if (first_unchanged_at_end_row == NULL
10122 && last_text_row == NULL
10123 && last_text_row_at_end == NULL)
10124 {
10125 /* Displayed to end of window, but no line containing text was
10126 displayed. Lines were deleted at the end of the window. */
10127 int vpos;
10128 int top_line_p = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
10129
10130 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
10131 if ((w->desired_matrix->rows[vpos + top_line_p].enabled_p
10132 && w->desired_matrix->rows[vpos + top_line_p].displays_text_p)
10133 || (!w->desired_matrix->rows[vpos + top_line_p].enabled_p
10134 && w->current_matrix->rows[vpos + top_line_p].displays_text_p))
10135 break;
12adba34 10136
5f5c8ee5
GM
10137 w->window_end_vpos = make_number (vpos);
10138 }
10139 else
10140 abort ();
10141
10142 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
10143 debug_end_vpos = XFASTINT (w->window_end_vpos));
12adba34 10144
5f5c8ee5
GM
10145 /* Record that display has not been completed. */
10146 w->window_end_valid = Qnil;
10147 w->desired_matrix->no_scrolling_p = 1;
10148 return 1;
12adba34 10149}
0f9c0ff0 10150
a2889657 10151
5f5c8ee5
GM
10152\f
10153/***********************************************************************
10154 More debugging support
10155 ***********************************************************************/
a2889657 10156
5f5c8ee5 10157#if GLYPH_DEBUG
a2889657 10158
5f5c8ee5
GM
10159 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
10160static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
1c9241f5 10161
31b24551 10162
5f5c8ee5
GM
10163/* Dump the contents of glyph matrix MATRIX on stderr. If
10164 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
ca26e1c8 10165
5f5c8ee5
GM
10166void
10167dump_glyph_matrix (matrix, with_glyphs_p)
10168 struct glyph_matrix *matrix;
10169 int with_glyphs_p;
10170{
efc63ef0 10171 int i;
5f5c8ee5
GM
10172 for (i = 0; i < matrix->nrows; ++i)
10173 dump_glyph_row (matrix, i, with_glyphs_p);
10174}
31b24551 10175
68a37fa8 10176
5f5c8ee5
GM
10177/* Dump the contents of glyph row at VPOS in MATRIX to stderr.
10178 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
a2889657 10179
5f5c8ee5
GM
10180void
10181dump_glyph_row (matrix, vpos, with_glyphs_p)
10182 struct glyph_matrix *matrix;
10183 int vpos, with_glyphs_p;
10184{
10185 struct glyph_row *row;
10186
10187 if (vpos < 0 || vpos >= matrix->nrows)
10188 return;
10189
10190 row = MATRIX_ROW (matrix, vpos);
10191
10192 fprintf (stderr, "Row Start End Used oEI><O\\CTZF X Y W\n");
10193 fprintf (stderr, "=============================================\n");
10194
10195 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",
10196 row - matrix->rows,
10197 MATRIX_ROW_START_CHARPOS (row),
10198 MATRIX_ROW_END_CHARPOS (row),
10199 row->used[TEXT_AREA],
10200 row->contains_overlapping_glyphs_p,
10201 row->enabled_p,
10202 row->inverse_p,
10203 row->truncated_on_left_p,
10204 row->truncated_on_right_p,
10205 row->overlay_arrow_p,
10206 row->continued_p,
10207 MATRIX_ROW_CONTINUATION_LINE_P (row),
10208 row->displays_text_p,
10209 row->ends_at_zv_p,
10210 row->fill_line_p,
10211 row->x,
10212 row->y,
10213 row->pixel_width);
10214 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
10215 row->end.overlay_string_index);
10216 fprintf (stderr, "%9d %5d\n",
10217 CHARPOS (row->start.string_pos),
10218 CHARPOS (row->end.string_pos));
10219 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
10220 row->end.dpvec_index);
10221
10222 if (with_glyphs_p)
bd66d1ba 10223 {
5f5c8ee5
GM
10224 struct glyph *glyph, *glyph_end;
10225 int prev_had_glyphs_p;
10226
10227 glyph = row->glyphs[TEXT_AREA];
10228 glyph_end = glyph + row->used[TEXT_AREA];
10229
10230 /* Glyph for a line end in text. */
10231 if (glyph == glyph_end && glyph->charpos > 0)
10232 ++glyph_end;
10233
10234 if (glyph < glyph_end)
bd66d1ba 10235 {
5f5c8ee5
GM
10236 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
10237 prev_had_glyphs_p = 1;
bd66d1ba
RS
10238 }
10239 else
5f5c8ee5
GM
10240 prev_had_glyphs_p = 0;
10241
10242 while (glyph < glyph_end)
f7b4b63a 10243 {
5f5c8ee5
GM
10244 if (glyph->type == CHAR_GLYPH)
10245 {
10246 fprintf (stderr,
10247 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10248 glyph - row->glyphs[TEXT_AREA],
10249 'C',
10250 glyph->charpos,
10251 glyph->pixel_width,
10252 glyph->u.ch.code,
10253 (glyph->u.ch.code < 0x80 && glyph->u.ch.code >= ' '
10254 ? glyph->u.ch.code
10255 : '.'),
10256 glyph->u.ch.face_id,
10257 glyph->left_box_line_p,
10258 glyph->right_box_line_p);
10259 }
10260 else if (glyph->type == STRETCH_GLYPH)
10261 {
10262 fprintf (stderr,
10263 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10264 glyph - row->glyphs[TEXT_AREA],
10265 'S',
10266 glyph->charpos,
10267 glyph->pixel_width,
10268 0,
10269 '.',
10270 glyph->u.stretch.face_id,
10271 glyph->left_box_line_p,
10272 glyph->right_box_line_p);
10273 }
10274 else if (glyph->type == IMAGE_GLYPH)
10275 {
10276 fprintf (stderr,
10277 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10278 glyph - row->glyphs[TEXT_AREA],
10279 'I',
10280 glyph->charpos,
10281 glyph->pixel_width,
10282 glyph->u.img.id,
10283 '.',
10284 glyph->u.img.face_id,
10285 glyph->left_box_line_p,
10286 glyph->right_box_line_p);
10287 }
10288 ++glyph;
f7b4b63a 10289 }
f4faa47c 10290 }
5f5c8ee5 10291}
f4faa47c 10292
a2889657 10293
5f5c8ee5
GM
10294DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
10295 Sdump_glyph_matrix, 0, 1, "p",
10296 "Dump the current matrix of the selected window to stderr.\n\
10297Shows contents of glyph row structures. With non-nil optional\n\
10298parameter WITH-GLYPHS-P, dump glyphs as well.")
10299 (with_glyphs_p)
10300{
10301 struct window *w = XWINDOW (selected_window);
10302 struct buffer *buffer = XBUFFER (w->buffer);
10303
10304 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
10305 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
10306 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
10307 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
10308 fprintf (stderr, "=============================================\n");
10309 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
10310 return Qnil;
10311}
1c2250c2 10312
1fca3fae 10313
5f5c8ee5
GM
10314DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
10315 "Dump glyph row ROW to stderr.")
10316 (row)
10317 Lisp_Object row;
10318{
10319 CHECK_NUMBER (row, 0);
10320 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
10321 return Qnil;
10322}
1fca3fae 10323
67481ae5 10324
5f5c8ee5
GM
10325DEFUN ("dump-toolbar-row", Fdump_toolbar_row, Sdump_toolbar_row,
10326 0, 0, "", "")
10327 ()
10328{
10329 struct glyph_matrix *m = (XWINDOW (selected_frame->toolbar_window)
10330 ->current_matrix);
10331 dump_glyph_row (m, 0, 1);
10332 return Qnil;
10333}
ca26e1c8 10334
0f9c0ff0 10335
5f5c8ee5
GM
10336DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
10337 Strace_redisplay_toggle, 0, 0, "",
10338 "Toggle tracing of redisplay.")
10339 ()
10340{
10341 trace_redisplay_p = !trace_redisplay_p;
10342 return Qnil;
10343}
10344
10345
10346#endif /* GLYPH_DEBUG */
ca26e1c8 10347
ca26e1c8 10348
5f5c8ee5
GM
10349\f
10350/***********************************************************************
10351 Building Desired Matrix Rows
10352 ***********************************************************************/
a2889657 10353
5f5c8ee5
GM
10354/* Return a temporary glyph row holding the glyphs of an overlay
10355 arrow. Only used for non-window-redisplay windows. */
ca26e1c8 10356
5f5c8ee5
GM
10357static struct glyph_row *
10358get_overlay_arrow_glyph_row (w)
10359 struct window *w;
10360{
10361 struct frame *f = XFRAME (WINDOW_FRAME (w));
10362 struct buffer *buffer = XBUFFER (w->buffer);
10363 struct buffer *old = current_buffer;
10364 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
10365 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
10366 unsigned char *arrow_end = arrow_string + arrow_len;
10367 unsigned char *p;
10368 struct it it;
10369 int multibyte_p;
10370 int n_glyphs_before;
10371
10372 set_buffer_temp (buffer);
10373 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
10374 it.glyph_row->used[TEXT_AREA] = 0;
10375 SET_TEXT_POS (it.position, 0, 0);
10376
10377 multibyte_p = !NILP (buffer->enable_multibyte_characters);
10378 p = arrow_string;
10379 while (p < arrow_end)
10380 {
10381 Lisp_Object face, ilisp;
10382
10383 /* Get the next character. */
10384 if (multibyte_p)
4fdb80f2 10385 it.c = string_char_and_length (p, arrow_len, &it.len);
5f5c8ee5
GM
10386 else
10387 it.c = *p, it.len = 1;
10388 p += it.len;
10389
10390 /* Get its face. */
10391 XSETFASTINT (ilisp, p - arrow_string);
10392 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
10393 it.face_id = compute_char_face (f, it.c, face);
10394
10395 /* Compute its width, get its glyphs. */
10396 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
337042a9 10397 SET_TEXT_POS (it.position, -1, -1);
5f5c8ee5
GM
10398 PRODUCE_GLYPHS (&it);
10399
10400 /* If this character doesn't fit any more in the line, we have
10401 to remove some glyphs. */
10402 if (it.current_x > it.last_visible_x)
10403 {
10404 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
10405 break;
10406 }
10407 }
10408
10409 set_buffer_temp (old);
10410 return it.glyph_row;
10411}
ca26e1c8 10412
b0a0fbda 10413
5f5c8ee5
GM
10414/* Insert truncation glyphs at the start of IT->glyph_row. Truncation
10415 glyphs are only inserted for terminal frames since we can't really
10416 win with truncation glyphs when partially visible glyphs are
10417 involved. Which glyphs to insert is determined by
10418 produce_special_glyphs. */
67481ae5 10419
5f5c8ee5
GM
10420static void
10421insert_left_trunc_glyphs (it)
10422 struct it *it;
10423{
10424 struct it truncate_it;
10425 struct glyph *from, *end, *to, *toend;
10426
10427 xassert (!FRAME_WINDOW_P (it->f));
10428
10429 /* Get the truncation glyphs. */
10430 truncate_it = *it;
10431 truncate_it.charset = -1;
10432 truncate_it.current_x = 0;
10433 truncate_it.face_id = DEFAULT_FACE_ID;
10434 truncate_it.glyph_row = &scratch_glyph_row;
10435 truncate_it.glyph_row->used[TEXT_AREA] = 0;
10436 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
10437 truncate_it.object = 0;
10438 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
10439
10440 /* Overwrite glyphs from IT with truncation glyphs. */
10441 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
10442 end = from + truncate_it.glyph_row->used[TEXT_AREA];
10443 to = it->glyph_row->glyphs[TEXT_AREA];
10444 toend = to + it->glyph_row->used[TEXT_AREA];
10445
10446 while (from < end)
10447 *to++ = *from++;
10448
10449 /* There may be padding glyphs left over. Remove them. */
10450 from = to;
10451 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
10452 ++from;
10453 while (from < toend)
10454 *to++ = *from++;
10455
10456 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
10457}
e0bfbde6 10458
e0bfbde6 10459
5f5c8ee5 10460/* Compute the pixel height and width of IT->glyph_row.
9c49d3d7 10461
5f5c8ee5
GM
10462 Most of the time, ascent and height of a display line will be equal
10463 to the max_ascent and max_height values of the display iterator
10464 structure. This is not the case if
67481ae5 10465
5f5c8ee5
GM
10466 1. We hit ZV without displaying anything. In this case, max_ascent
10467 and max_height will be zero.
1c9241f5 10468
5f5c8ee5
GM
10469 2. We have some glyphs that don't contribute to the line height.
10470 (The glyph row flag contributes_to_line_height_p is for future
10471 pixmap extensions).
f6fd109b 10472
5f5c8ee5
GM
10473 The first case is easily covered by using default values because in
10474 these cases, the line height does not really matter, except that it
10475 must not be zero. */
67481ae5 10476
5f5c8ee5
GM
10477static void
10478compute_line_metrics (it)
10479 struct it *it;
10480{
10481 struct glyph_row *row = it->glyph_row;
10482 int area, i;
1c2250c2 10483
5f5c8ee5
GM
10484 if (FRAME_WINDOW_P (it->f))
10485 {
10486 int i, top_line_height;
1c2250c2 10487
5f5c8ee5
GM
10488 /* The line may consist of one space only, that was added to
10489 place the cursor on it. If so, the row's height hasn't been
10490 computed yet. */
10491 if (row->height == 0)
10492 {
10493 if (it->max_ascent + it->max_descent == 0)
312246d1 10494 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
5f5c8ee5
GM
10495 row->ascent = it->max_ascent;
10496 row->height = it->max_ascent + it->max_descent;
312246d1
GM
10497 row->phys_ascent = it->max_phys_ascent;
10498 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
10499 }
10500
10501 /* Compute the width of this line. */
10502 row->pixel_width = row->x;
10503 for (i = 0; i < row->used[TEXT_AREA]; ++i)
10504 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
10505
10506 xassert (row->pixel_width >= 0);
10507 xassert (row->ascent >= 0 && row->height > 0);
10508
312246d1
GM
10509 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
10510 || MATRIX_ROW_OVERLAPS_PRED_P (row));
10511
10512 /* If first line's physical ascent is larger than its logical
10513 ascent, use the physical ascent, and make the row taller.
10514 This makes accented characters fully visible. */
10515 if (row == it->w->desired_matrix->rows
10516 && row->phys_ascent > row->ascent)
10517 {
10518 row->height += row->phys_ascent - row->ascent;
10519 row->ascent = row->phys_ascent;
10520 }
10521
5f5c8ee5
GM
10522 /* Compute how much of the line is visible. */
10523 row->visible_height = row->height;
10524
10525 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w);
10526 if (row->y < top_line_height)
10527 row->visible_height -= top_line_height - row->y;
10528 else
10529 {
10530 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
10531 if (row->y + row->height > max_y)
10532 row->visible_height -= row->y + row->height - max_y;
10533 }
10534 }
10535 else
10536 {
10537 row->pixel_width = row->used[TEXT_AREA];
312246d1
GM
10538 row->ascent = row->phys_ascent = 0;
10539 row->height = row->phys_height = row->visible_height = 1;
5f5c8ee5 10540 }
67481ae5 10541
5f5c8ee5
GM
10542 /* Compute a hash code for this row. */
10543 row->hash = 0;
10544 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
10545 for (i = 0; i < row->used[area]; ++i)
10546 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
10547 + row->glyphs[area][i].u.val
10548 + (row->glyphs[area][i].type << 2));
a2889657 10549
5f5c8ee5 10550 it->max_ascent = it->max_descent = 0;
312246d1 10551 it->max_phys_ascent = it->max_phys_descent = 0;
5f5c8ee5 10552}
12adba34 10553
ca26e1c8 10554
5f5c8ee5
GM
10555/* Append one space to the glyph row of iterator IT if doing a
10556 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10557 space have the default face, otherwise let it have the same face as
c6e89d6c
GM
10558 IT->face_id.
10559
10560 This function is called to make sure that there is always one glyph
10561 at the end of a glyph row that the cursor can be set on under
10562 window-systems. (If there weren't such a glyph we would not know
10563 how wide and tall a box cursor should be displayed).
10564
10565 At the same time this space let's a nicely handle clearing to the
10566 end of the line if the row ends in italic text. */
ca26e1c8 10567
5f5c8ee5
GM
10568static void
10569append_space (it, default_face_p)
10570 struct it *it;
10571 int default_face_p;
10572{
10573 if (FRAME_WINDOW_P (it->f))
10574 {
10575 int n = it->glyph_row->used[TEXT_AREA];
ca26e1c8 10576
5f5c8ee5
GM
10577 if (it->glyph_row->glyphs[TEXT_AREA] + n
10578 < it->glyph_row->glyphs[1 + TEXT_AREA])
a2889657 10579 {
5f5c8ee5
GM
10580 /* Save some values that must not be changed. */
10581 int saved_x = it->current_x;
10582 struct text_pos saved_pos;
10583 int saved_what = it->what;
10584 int saved_face_id = it->face_id;
10585 int saved_charset = it->charset;
10586 Lisp_Object saved_object;
10587
10588 saved_object = it->object;
10589 saved_pos = it->position;
10590
10591 it->what = IT_CHARACTER;
10592 bzero (&it->position, sizeof it->position);
10593 it->object = 0;
10594 it->c = ' ';
10595 it->len = 1;
10596 it->charset = CHARSET_ASCII;
10597
10598 if (default_face_p)
10599 it->face_id = DEFAULT_FACE_ID;
10600 if (it->multibyte_p)
10601 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, CHARSET_ASCII);
10602 else
10603 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, -1);
1842fc1a 10604
5f5c8ee5
GM
10605 PRODUCE_GLYPHS (it);
10606
10607 it->current_x = saved_x;
10608 it->object = saved_object;
10609 it->position = saved_pos;
10610 it->what = saved_what;
10611 it->face_id = saved_face_id;
10612 it->charset = saved_charset;
10613 }
10614 }
10615}
12adba34 10616
1842fc1a 10617
5f5c8ee5
GM
10618/* Extend the face of the last glyph in the text area of IT->glyph_row
10619 to the end of the display line. Called from display_line.
10620 If the glyph row is empty, add a space glyph to it so that we
10621 know the face to draw. Set the glyph row flag fill_line_p. */
10622
10623static void
10624extend_face_to_end_of_line (it)
10625 struct it *it;
10626{
10627 struct face *face;
10628 struct frame *f = it->f;
1842fc1a 10629
5f5c8ee5
GM
10630 /* If line is already filled, do nothing. */
10631 if (it->current_x >= it->last_visible_x)
10632 return;
10633
10634 /* Face extension extends the background and box of IT->face_id
10635 to the end of the line. If the background equals the background
10636 of the frame, we haven't to do anything. */
10637 face = FACE_FROM_ID (f, it->face_id);
10638 if (FRAME_WINDOW_P (f)
10639 && face->box == FACE_NO_BOX
10640 && face->background == FRAME_BACKGROUND_PIXEL (f)
10641 && !face->stipple)
10642 return;
1842fc1a 10643
5f5c8ee5
GM
10644 /* Set the glyph row flag indicating that the face of the last glyph
10645 in the text area has to be drawn to the end of the text area. */
10646 it->glyph_row->fill_line_p = 1;
545e04f6 10647
5f5c8ee5
GM
10648 /* If current charset of IT is not ASCII, make sure we have the
10649 ASCII face. This will be automatically undone the next time
10650 get_next_display_element returns a character from a different
10651 charset. Note that the charset will always be ASCII in unibyte
10652 text. */
10653 if (it->charset != CHARSET_ASCII)
10654 {
10655 it->charset = CHARSET_ASCII;
10656 it->face_id = FACE_FOR_CHARSET (f, it->face_id, CHARSET_ASCII);
10657 }
545e04f6 10658
5f5c8ee5
GM
10659 if (FRAME_WINDOW_P (f))
10660 {
10661 /* If the row is empty, add a space with the current face of IT,
10662 so that we know which face to draw. */
10663 if (it->glyph_row->used[TEXT_AREA] == 0)
a2889657 10664 {
5f5c8ee5
GM
10665 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
10666 it->glyph_row->glyphs[TEXT_AREA][0].u.ch.face_id = it->face_id;
10667 it->glyph_row->used[TEXT_AREA] = 1;
a2889657 10668 }
5f5c8ee5
GM
10669 }
10670 else
10671 {
10672 /* Save some values that must not be changed. */
10673 int saved_x = it->current_x;
10674 struct text_pos saved_pos;
10675 Lisp_Object saved_object;
10676 int saved_what = it->what;
10677
10678 saved_object = it->object;
10679 saved_pos = it->position;
10680
10681 it->what = IT_CHARACTER;
10682 bzero (&it->position, sizeof it->position);
10683 it->object = 0;
10684 it->c = ' ';
10685 it->len = 1;
10686
10687 PRODUCE_GLYPHS (it);
10688
10689 while (it->current_x <= it->last_visible_x)
10690 PRODUCE_GLYPHS (it);
10691
10692 /* Don't count these blanks really. It would let us insert a left
10693 truncation glyph below and make us set the cursor on them, maybe. */
10694 it->current_x = saved_x;
10695 it->object = saved_object;
10696 it->position = saved_pos;
10697 it->what = saved_what;
10698 }
10699}
12adba34 10700
545e04f6 10701
5f5c8ee5
GM
10702/* Value is non-zero if text starting at CHARPOS in current_buffer is
10703 trailing whitespace. */
1c9241f5 10704
5f5c8ee5
GM
10705static int
10706trailing_whitespace_p (charpos)
10707 int charpos;
10708{
10709 int bytepos = CHAR_TO_BYTE (charpos);
10710 int c = 0;
7bbe686f 10711
5f5c8ee5
GM
10712 while (bytepos < ZV_BYTE
10713 && (c = FETCH_CHAR (bytepos),
10714 c == ' ' || c == '\t'))
10715 ++bytepos;
0d09d1e6 10716
8f897821
GM
10717 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
10718 {
10719 if (bytepos != PT_BYTE)
10720 return 1;
10721 }
10722 return 0;
5f5c8ee5 10723}
31b24551 10724
545e04f6 10725
5f5c8ee5 10726/* Highlight trailing whitespace, if any, in ROW. */
545e04f6 10727
5f5c8ee5
GM
10728void
10729highlight_trailing_whitespace (f, row)
10730 struct frame *f;
10731 struct glyph_row *row;
10732{
10733 int used = row->used[TEXT_AREA];
10734
10735 if (used)
10736 {
10737 struct glyph *start = row->glyphs[TEXT_AREA];
10738 struct glyph *glyph = start + used - 1;
10739
10740 /* Skip over the space glyph inserted to display the
10741 cursor at the end of a line. */
10742 if (glyph->type == CHAR_GLYPH
10743 && glyph->u.ch.code == ' '
10744 && glyph->object == 0)
10745 --glyph;
10746
10747 /* If last glyph is a space or stretch, and it's trailing
10748 whitespace, set the face of all trailing whitespace glyphs in
10749 IT->glyph_row to `trailing-whitespace'. */
10750 if (glyph >= start
10751 && BUFFERP (glyph->object)
10752 && (glyph->type == STRETCH_GLYPH
10753 || (glyph->type == CHAR_GLYPH
10754 && glyph->u.ch.code == ' '))
10755 && trailing_whitespace_p (glyph->charpos))
545e04f6 10756 {
5f5c8ee5
GM
10757 int face_id = lookup_named_face (f, Qtrailing_whitespace,
10758 CHARSET_ASCII);
10759
10760 while (glyph >= start
10761 && BUFFERP (glyph->object)
10762 && (glyph->type == STRETCH_GLYPH
10763 || (glyph->type == CHAR_GLYPH
10764 && glyph->u.ch.code == ' ')))
545e04f6 10765 {
5f5c8ee5
GM
10766 if (glyph->type == STRETCH_GLYPH)
10767 glyph->u.stretch.face_id = face_id;
10768 else
10769 glyph->u.ch.face_id = face_id;
10770 --glyph;
545e04f6
KH
10771 }
10772 }
a2889657 10773 }
5f5c8ee5 10774}
a2889657 10775
5fcbb24d 10776
5f5c8ee5
GM
10777/* Construct the glyph row IT->glyph_row in the desired matrix of
10778 IT->w from text at the current position of IT. See dispextern.h
10779 for an overview of struct it. Value is non-zero if
10780 IT->glyph_row displays text, as opposed to a line displaying ZV
10781 only. */
10782
10783static int
10784display_line (it)
10785 struct it *it;
10786{
10787 struct glyph_row *row = it->glyph_row;
10788
10789 /* We always start displaying at hpos zero even if hscrolled. */
10790 xassert (it->hpos == 0 && it->current_x == 0);
a2889657 10791
5f5c8ee5
GM
10792 /* We must not display in a row that's not a text row. */
10793 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
10794 < it->w->desired_matrix->nrows);
12adba34 10795
5f5c8ee5
GM
10796 /* Is IT->w showing the region? */
10797 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
12adba34 10798
5f5c8ee5
GM
10799 /* Clear the result glyph row and enable it. */
10800 prepare_desired_row (row);
12adba34 10801
5f5c8ee5
GM
10802 row->y = it->current_y;
10803 row->start = it->current;
10804 row->continuation_lines_width = it->continuation_lines_width;
10805 row->displays_text_p = 1;
10806
10807 /* Arrange the overlays nicely for our purposes. Usually, we call
10808 display_line on only one line at a time, in which case this
10809 can't really hurt too much, or we call it on lines which appear
10810 one after another in the buffer, in which case all calls to
10811 recenter_overlay_lists but the first will be pretty cheap. */
10812 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
10813
5f5c8ee5
GM
10814 /* Move over display elements that are not visible because we are
10815 hscrolled. This may stop at an x-position < IT->first_visible_x
10816 if the first glyph is partially visible or if we hit a line end. */
10817 if (it->current_x < it->first_visible_x)
10818 move_it_in_display_line_to (it, ZV, it->first_visible_x,
10819 MOVE_TO_POS | MOVE_TO_X);
10820
10821 /* Get the initial row height. This is either the height of the
10822 text hscrolled, if there is any, or zero. */
10823 row->ascent = it->max_ascent;
10824 row->height = it->max_ascent + it->max_descent;
312246d1
GM
10825 row->phys_ascent = it->max_phys_ascent;
10826 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
10827
10828 /* Loop generating characters. The loop is left with IT on the next
10829 character to display. */
10830 while (1)
10831 {
10832 int n_glyphs_before, hpos_before, x_before;
10833 int x, i, nglyphs;
10834
10835 /* Retrieve the next thing to display. Value is zero if end of
10836 buffer reached. */
10837 if (!get_next_display_element (it))
10838 {
10839 /* Maybe add a space at the end of this line that is used to
10840 display the cursor there under X. */
10841 append_space (it, 1);
10842
10843 /* The position -1 below indicates a blank line not
10844 corresponding to any text, as opposed to an empty line
10845 corresponding to a line end. */
10846 if (row->used[TEXT_AREA] <= 1)
a2889657 10847 {
5f5c8ee5
GM
10848 row->glyphs[TEXT_AREA]->charpos = -1;
10849 row->displays_text_p = 0;
10850
10851 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
10852 row->indicate_empty_line_p = 1;
a2889657 10853 }
5f5c8ee5
GM
10854
10855 it->continuation_lines_width = 0;
10856 row->ends_at_zv_p = 1;
10857 break;
a2889657 10858 }
a2889657 10859
5f5c8ee5
GM
10860 /* Now, get the metrics of what we want to display. This also
10861 generates glyphs in `row' (which is IT->glyph_row). */
10862 n_glyphs_before = row->used[TEXT_AREA];
10863 x = it->current_x;
10864 PRODUCE_GLYPHS (it);
a2889657 10865
5f5c8ee5
GM
10866 /* If this display element was in marginal areas, continue with
10867 the next one. */
10868 if (it->area != TEXT_AREA)
a2889657 10869 {
5f5c8ee5
GM
10870 row->ascent = max (row->ascent, it->max_ascent);
10871 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10872 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10873 row->phys_height = max (row->phys_height,
10874 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10875 set_iterator_to_next (it);
10876 continue;
10877 }
5936754e 10878
5f5c8ee5
GM
10879 /* Does the display element fit on the line? If we truncate
10880 lines, we should draw past the right edge of the window. If
10881 we don't truncate, we want to stop so that we can display the
10882 continuation glyph before the right margin. If lines are
10883 continued, there are two possible strategies for characters
10884 resulting in more than 1 glyph (e.g. tabs): Display as many
10885 glyphs as possible in this line and leave the rest for the
10886 continuation line, or display the whole element in the next
10887 line. Original redisplay did the former, so we do it also. */
10888 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10889 hpos_before = it->hpos;
10890 x_before = x;
10891
10892 if (nglyphs == 1
10893 && it->current_x < it->last_visible_x)
10894 {
10895 ++it->hpos;
10896 row->ascent = max (row->ascent, it->max_ascent);
10897 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10898 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10899 row->phys_height = max (row->phys_height,
10900 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10901 if (it->current_x - it->pixel_width < it->first_visible_x)
10902 row->x = x - it->first_visible_x;
10903 }
10904 else
10905 {
10906 int new_x;
10907 struct glyph *glyph;
10908
10909 for (i = 0; i < nglyphs; ++i, x = new_x)
b5bbc9a5 10910 {
5f5c8ee5
GM
10911 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10912 new_x = x + glyph->pixel_width;
10913
10914 if (/* Lines are continued. */
10915 !it->truncate_lines_p
10916 && (/* Glyph doesn't fit on the line. */
10917 new_x > it->last_visible_x
10918 /* Or it fits exactly on a window system frame. */
10919 || (new_x == it->last_visible_x
10920 && FRAME_WINDOW_P (it->f))))
a2889657 10921 {
5f5c8ee5
GM
10922 /* End of a continued line. */
10923
10924 if (it->hpos == 0
10925 || (new_x == it->last_visible_x
10926 && FRAME_WINDOW_P (it->f)))
10927 {
10928 /* Current glyph fits exactly on the line. We
10929 must continue the line because we can't draw
10930 the cursor after the glyph. */
10931 row->continued_p = 1;
10932 it->current_x = new_x;
10933 it->continuation_lines_width += new_x;
10934 ++it->hpos;
10935 if (i == nglyphs - 1)
10936 set_iterator_to_next (it);
10937 }
10938 else
5936754e 10939 {
5f5c8ee5
GM
10940 /* Display element draws past the right edge of
10941 the window. Restore positions to values
10942 before the element. The next line starts
10943 with current_x before the glyph that could
10944 not be displayed, so that TAB works right. */
10945 row->used[TEXT_AREA] = n_glyphs_before + i;
10946
10947 /* Display continuation glyphs. */
10948 if (!FRAME_WINDOW_P (it->f))
10949 produce_special_glyphs (it, IT_CONTINUATION);
10950 row->continued_p = 1;
10951
10952 it->current_x = x;
10953 it->continuation_lines_width += x;
5936754e 10954 }
5f5c8ee5
GM
10955 break;
10956 }
10957 else if (new_x > it->first_visible_x)
10958 {
10959 /* Increment number of glyphs actually displayed. */
10960 ++it->hpos;
10961
10962 if (x < it->first_visible_x)
10963 /* Glyph is partially visible, i.e. row starts at
10964 negative X position. */
10965 row->x = x - it->first_visible_x;
10966 }
10967 else
10968 {
10969 /* Glyph is completely off the left margin of the
10970 window. This should not happen because of the
10971 move_it_in_display_line at the start of
10972 this function. */
10973 abort ();
a2889657 10974 }
a2889657 10975 }
5f5c8ee5
GM
10976
10977 row->ascent = max (row->ascent, it->max_ascent);
10978 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10979 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10980 row->phys_height = max (row->phys_height,
10981 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10982
10983 /* End of this display line if row is continued. */
10984 if (row->continued_p)
10985 break;
a2889657 10986 }
a2889657 10987
5f5c8ee5
GM
10988 /* Is this a line end? If yes, we're also done, after making
10989 sure that a non-default face is extended up to the right
10990 margin of the window. */
10991 if (ITERATOR_AT_END_OF_LINE_P (it))
1c9241f5 10992 {
5f5c8ee5
GM
10993 int used_before = row->used[TEXT_AREA];
10994
10995 /* Add a space at the end of the line that is used to
10996 display the cursor there. */
10997 append_space (it, 0);
10998
10999 /* Extend the face to the end of the line. */
11000 extend_face_to_end_of_line (it);
11001
11002 /* Make sure we have the position. */
11003 if (used_before == 0)
11004 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
11005
11006 /* Consume the line end. This skips over invisible lines. */
11007 set_iterator_to_next (it);
11008 it->continuation_lines_width = 0;
11009 break;
1c9241f5 11010 }
a2889657 11011
5f5c8ee5
GM
11012 /* Proceed with next display element. Note that this skips
11013 over lines invisible because of selective display. */
11014 set_iterator_to_next (it);
b1d1124b 11015
5f5c8ee5
GM
11016 /* If we truncate lines, we are done when the last displayed
11017 glyphs reach past the right margin of the window. */
11018 if (it->truncate_lines_p
11019 && (FRAME_WINDOW_P (it->f)
11020 ? (it->current_x >= it->last_visible_x)
11021 : (it->current_x > it->last_visible_x)))
75d13c64 11022 {
5f5c8ee5
GM
11023 /* Maybe add truncation glyphs. */
11024 if (!FRAME_WINDOW_P (it->f))
11025 {
11026 --it->glyph_row->used[TEXT_AREA];
11027 produce_special_glyphs (it, IT_TRUNCATION);
11028 }
11029
11030 row->truncated_on_right_p = 1;
11031 it->continuation_lines_width = 0;
312246d1 11032 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
11033 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
11034 it->hpos = hpos_before;
11035 it->current_x = x_before;
11036 break;
75d13c64 11037 }
a2889657 11038 }
a2889657 11039
5f5c8ee5
GM
11040 /* If line is not empty and hscrolled, maybe insert truncation glyphs
11041 at the left window margin. */
11042 if (it->first_visible_x
11043 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
11044 {
11045 if (!FRAME_WINDOW_P (it->f))
11046 insert_left_trunc_glyphs (it);
11047 row->truncated_on_left_p = 1;
11048 }
a2889657 11049
5f5c8ee5
GM
11050 /* If the start of this line is the overlay arrow-position, then
11051 mark this glyph row as the one containing the overlay arrow.
11052 This is clearly a mess with variable size fonts. It would be
11053 better to let it be displayed like cursors under X. */
e24c997d 11054 if (MARKERP (Voverlay_arrow_position)
a2889657 11055 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
5f5c8ee5
GM
11056 && (MATRIX_ROW_START_CHARPOS (row)
11057 == marker_position (Voverlay_arrow_position))
e24c997d 11058 && STRINGP (Voverlay_arrow_string)
a2889657
JB
11059 && ! overlay_arrow_seen)
11060 {
5f5c8ee5
GM
11061 /* Overlay arrow in window redisplay is a bitmap. */
11062 if (!FRAME_WINDOW_P (it->f))
c4628384 11063 {
5f5c8ee5
GM
11064 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
11065 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
11066 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
11067 struct glyph *p = row->glyphs[TEXT_AREA];
11068 struct glyph *p2, *end;
11069
11070 /* Copy the arrow glyphs. */
11071 while (glyph < arrow_end)
11072 *p++ = *glyph++;
11073
11074 /* Throw away padding glyphs. */
11075 p2 = p;
11076 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
11077 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
11078 ++p2;
11079 if (p2 > p)
212e4f87 11080 {
5f5c8ee5
GM
11081 while (p2 < end)
11082 *p++ = *p2++;
11083 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
c4628384 11084 }
c4628384 11085 }
5f5c8ee5 11086
a2889657 11087 overlay_arrow_seen = 1;
5f5c8ee5 11088 row->overlay_arrow_p = 1;
a2889657
JB
11089 }
11090
5f5c8ee5
GM
11091 /* Compute pixel dimensions of this line. */
11092 compute_line_metrics (it);
11093
11094 /* Remember the position at which this line ends. */
11095 row->end = it->current;
11096
11097 /* Maybe set the cursor. If you change this, it's probably a good
11098 idea to also change the code in redisplay_window for cursor
11099 movement in an unchanged window. */
11100 if (it->w->cursor.vpos < 0
11101 && PT >= MATRIX_ROW_START_CHARPOS (row)
11102 && MATRIX_ROW_END_CHARPOS (row) >= PT
11103 && !(MATRIX_ROW_END_CHARPOS (row) == PT
11104 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
11105 || !row->ends_at_zv_p)))
11106 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
11107
11108 /* Highlight trailing whitespace. */
8f897821 11109 if (!NILP (Vshow_trailing_whitespace))
5f5c8ee5
GM
11110 highlight_trailing_whitespace (it->f, it->glyph_row);
11111
11112 /* Prepare for the next line. This line starts horizontally at (X
11113 HPOS) = (0 0). Vertical positions are incremented. As a
11114 convenience for the caller, IT->glyph_row is set to the next
11115 row to be used. */
11116 it->current_x = it->hpos = 0;
11117 it->current_y += row->height;
11118 ++it->vpos;
11119 ++it->glyph_row;
11120 return row->displays_text_p;
a2889657 11121}
5f5c8ee5
GM
11122
11123
a2889657 11124\f
5f5c8ee5
GM
11125/***********************************************************************
11126 Menu Bar
11127 ***********************************************************************/
11128
11129/* Redisplay the menu bar in the frame for window W.
11130
11131 The menu bar of X frames that don't have X toolkit support is
11132 displayed in a special window W->frame->menu_bar_window.
11133
11134 The menu bar of terminal frames is treated specially as far as
11135 glyph matrices are concerned. Menu bar lines are not part of
11136 windows, so the update is done directly on the frame matrix rows
11137 for the menu bar. */
7ce2c095
RS
11138
11139static void
11140display_menu_bar (w)
11141 struct window *w;
11142{
5f5c8ee5
GM
11143 struct frame *f = XFRAME (WINDOW_FRAME (w));
11144 struct it it;
11145 Lisp_Object items;
8351baf2 11146 int i;
7ce2c095 11147
5f5c8ee5 11148 /* Don't do all this for graphical frames. */
dc937613 11149#ifdef HAVE_NTGUI
d129c4c2
KH
11150 if (!NILP (Vwindow_system))
11151 return;
dc937613 11152#endif
dc937613 11153#ifdef USE_X_TOOLKIT
d3413a53 11154 if (FRAME_X_P (f))
7ce2c095 11155 return;
5f5c8ee5
GM
11156#endif
11157
11158#ifdef USE_X_TOOLKIT
11159 xassert (!FRAME_WINDOW_P (f));
11160 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
11161 it.first_visible_x = 0;
11162 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11163#else /* not USE_X_TOOLKIT */
11164 if (FRAME_WINDOW_P (f))
11165 {
11166 /* Menu bar lines are displayed in the desired matrix of the
11167 dummy window menu_bar_window. */
11168 struct window *menu_w;
11169 xassert (WINDOWP (f->menu_bar_window));
11170 menu_w = XWINDOW (f->menu_bar_window);
11171 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
11172 MODE_LINE_FACE_ID);
11173 it.first_visible_x = 0;
11174 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11175 }
11176 else
11177 {
11178 /* This is a TTY frame, i.e. character hpos/vpos are used as
11179 pixel x/y. */
11180 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
11181 MODE_LINE_FACE_ID);
11182 it.first_visible_x = 0;
11183 it.last_visible_x = FRAME_WIDTH (f);
11184 }
11185#endif /* not USE_X_TOOLKIT */
11186
11187 /* Clear all rows of the menu bar. */
11188 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
11189 {
11190 struct glyph_row *row = it.glyph_row + i;
11191 clear_glyph_row (row);
11192 row->enabled_p = 1;
11193 row->full_width_p = 1;
11194 }
7ce2c095 11195
5f5c8ee5
GM
11196 /* Make the first line of the menu bar appear in reverse video. */
11197 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
7ce2c095 11198
5f5c8ee5
GM
11199 /* Display all items of the menu bar. */
11200 items = FRAME_MENU_BAR_ITEMS (it.f);
469937ac 11201 for (i = 0; i < XVECTOR (items)->size; i += 4)
7ce2c095 11202 {
5f5c8ee5
GM
11203 Lisp_Object string;
11204
11205 /* Stop at nil string. */
8351baf2
RS
11206 string = XVECTOR (items)->contents[i + 1];
11207 if (NILP (string))
11208 break;
2d66ad19 11209
5f5c8ee5
GM
11210 /* Remember where item was displayed. */
11211 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
7ce2c095 11212
5f5c8ee5
GM
11213 /* Display the item, pad with one space. */
11214 if (it.current_x < it.last_visible_x)
11215 display_string (NULL, string, Qnil, 0, 0, &it,
11216 XSTRING (string)->size + 1, 0, 0, -1);
7ce2c095
RS
11217 }
11218
2d66ad19 11219 /* Fill out the line with spaces. */
5f5c8ee5
GM
11220 if (it.current_x < it.last_visible_x)
11221 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
db6f348c 11222
5f5c8ee5
GM
11223 /* Compute the total height of the lines. */
11224 compute_line_metrics (&it);
7ce2c095 11225}
5f5c8ee5
GM
11226
11227
7ce2c095 11228\f
5f5c8ee5
GM
11229/***********************************************************************
11230 Mode Line
11231 ***********************************************************************/
11232
11233/* Display the mode and/or top line of window W. */
a2889657
JB
11234
11235static void
5f5c8ee5 11236display_mode_lines (w)
a2889657
JB
11237 struct window *w;
11238{
5f5c8ee5 11239 /* These will be set while the mode line specs are processed. */
aa6d10fa 11240 line_number_displayed = 0;
155ef550 11241 w->column_number_displayed = Qnil;
aa6d10fa 11242
5f5c8ee5
GM
11243 if (WINDOW_WANTS_MODELINE_P (w))
11244 display_mode_line (w, MODE_LINE_FACE_ID, current_buffer->mode_line_format);
11245
11246 if (WINDOW_WANTS_TOP_LINE_P (w))
11247 display_mode_line (w, TOP_LINE_FACE_ID, current_buffer->top_line_format);
11248}
03b294dc 11249
03b294dc 11250
5f5c8ee5
GM
11251/* Display mode or top line of window W. FACE_ID specifies which line
11252 to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
11253 FORMAT is the mode line format to display. */
03b294dc 11254
5f5c8ee5
GM
11255static void
11256display_mode_line (w, face_id, format)
11257 struct window *w;
11258 enum face_id face_id;
11259 Lisp_Object format;
11260{
11261 struct it it;
11262 struct face *face;
03b294dc 11263
5f5c8ee5
GM
11264 init_iterator (&it, w, -1, -1, NULL, face_id);
11265 prepare_desired_row (it.glyph_row);
11266
11267 /* Temporarily make frame's keyboard the current kboard so that
11268 kboard-local variables in the mode_line_format will get the right
11269 values. */
11270 push_frame_kboard (it.f);
11271 display_mode_element (&it, 0, 0, 0, format);
11272 pop_frame_kboard ();
a2889657 11273
5f5c8ee5
GM
11274 /* Fill up with spaces. */
11275 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
11276
11277 compute_line_metrics (&it);
11278 it.glyph_row->full_width_p = 1;
11279 it.glyph_row->mode_line_p = 1;
11280 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11281 it.glyph_row->continued_p = 0;
11282 it.glyph_row->truncated_on_left_p = 0;
11283 it.glyph_row->truncated_on_right_p = 0;
11284
11285 /* Make a 3D mode-line have a shadow at its right end. */
11286 face = FACE_FROM_ID (it.f, face_id);
11287 extend_face_to_end_of_line (&it);
11288 if (face->box != FACE_NO_BOX)
d7eb09a0 11289 {
5f5c8ee5
GM
11290 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
11291 + it.glyph_row->used[TEXT_AREA] - 1);
11292 last->right_box_line_p = 1;
d7eb09a0 11293 }
a2889657
JB
11294}
11295
a2889657 11296
5f5c8ee5
GM
11297/* Contribute ELT to the mode line for window IT->w. How it
11298 translates into text depends on its data type.
a2889657 11299
5f5c8ee5 11300 IT describes the display environment in which we display, as usual.
a2889657
JB
11301
11302 DEPTH is the depth in recursion. It is used to prevent
11303 infinite recursion here.
11304
5f5c8ee5
GM
11305 FIELD_WIDTH is the number of characters the display of ELT should
11306 occupy in the mode line, and PRECISION is the maximum number of
11307 characters to display from ELT's representation. See
11308 display_string for details. *
a2889657 11309
5f5c8ee5 11310 Returns the hpos of the end of the text generated by ELT. */
a2889657
JB
11311
11312static int
5f5c8ee5
GM
11313display_mode_element (it, depth, field_width, precision, elt)
11314 struct it *it;
a2889657 11315 int depth;
5f5c8ee5
GM
11316 int field_width, precision;
11317 Lisp_Object elt;
a2889657 11318{
5f5c8ee5
GM
11319 int n = 0, field, prec;
11320
a2889657
JB
11321 tail_recurse:
11322 if (depth > 10)
11323 goto invalid;
11324
11325 depth++;
11326
0220c518 11327 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
a2889657
JB
11328 {
11329 case Lisp_String:
11330 {
11331 /* A string: output it and check for %-constructs within it. */
5f5c8ee5
GM
11332 unsigned char c;
11333 unsigned char *this = XSTRING (elt)->data;
11334 unsigned char *lisp_string = this;
11335
11336 while ((precision <= 0 || n < precision)
11337 && *this
11338 && (frame_title_ptr
11339 || it->current_x < it->last_visible_x))
a2889657
JB
11340 {
11341 unsigned char *last = this;
5f5c8ee5
GM
11342
11343 /* Advance to end of string or next format specifier. */
a2889657
JB
11344 while ((c = *this++) != '\0' && c != '%')
11345 ;
5f5c8ee5 11346
a2889657
JB
11347 if (this - 1 != last)
11348 {
5f5c8ee5
GM
11349 /* Output to end of string or up to '%'. Field width
11350 is length of string. Don't output more than
11351 PRECISION allows us. */
11352 prec = --this - last;
11353 if (precision > 0 && prec > precision - n)
11354 prec = precision - n;
11355
d39b6696 11356 if (frame_title_ptr)
5f5c8ee5 11357 n += store_frame_title (last, prec, prec);
d39b6696 11358 else
5f5c8ee5
GM
11359 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
11360 it, 0, prec, 0, -1);
a2889657
JB
11361 }
11362 else /* c == '%' */
11363 {
5f5c8ee5
GM
11364 unsigned char *percent_position = this;
11365
11366 /* Get the specified minimum width. Zero means
11367 don't pad. */
11368 field = 0;
a2889657 11369 while ((c = *this++) >= '0' && c <= '9')
5f5c8ee5 11370 field = field * 10 + c - '0';
a2889657 11371
5f5c8ee5
GM
11372 /* Don't pad beyond the total padding allowed. */
11373 if (field_width - n > 0 && field > field_width - n)
11374 field = field_width - n;
a2889657 11375
5f5c8ee5
GM
11376 /* Note that either PRECISION <= 0 or N < PRECISION. */
11377 prec = precision - n;
11378
a2889657 11379 if (c == 'M')
5f5c8ee5
GM
11380 n += display_mode_element (it, depth, field, prec,
11381 Vglobal_mode_string);
a2889657 11382 else if (c != 0)
d39b6696 11383 {
5f5c8ee5
GM
11384 unsigned char *spec
11385 = decode_mode_spec (it->w, c, field, prec);
11386
d39b6696 11387 if (frame_title_ptr)
5f5c8ee5 11388 n += store_frame_title (spec, field, prec);
d39b6696 11389 else
5f5c8ee5
GM
11390 {
11391 int nglyphs_before
11392 = it->glyph_row->used[TEXT_AREA];
11393 int charpos
11394 = percent_position - XSTRING (elt)->data;
11395 int nwritten
11396 = display_string (spec, Qnil, elt, charpos, 0, it,
11397 field, prec, 0, -1);
11398
11399 /* Assign to the glyphs written above the
11400 string where the `%x' came from, position
11401 of the `%'. */
11402 if (nwritten > 0)
11403 {
11404 struct glyph *glyph
11405 = (it->glyph_row->glyphs[TEXT_AREA]
11406 + nglyphs_before);
11407 int i;
11408
11409 for (i = 0; i < nwritten; ++i)
11410 {
11411 glyph[i].object = elt;
11412 glyph[i].charpos = charpos;
11413 }
11414
11415 n += nwritten;
11416 }
11417 }
d39b6696 11418 }
a2889657
JB
11419 }
11420 }
11421 }
11422 break;
11423
11424 case Lisp_Symbol:
11425 /* A symbol: process the value of the symbol recursively
11426 as if it appeared here directly. Avoid error if symbol void.
11427 Special case: if value of symbol is a string, output the string
11428 literally. */
11429 {
11430 register Lisp_Object tem;
11431 tem = Fboundp (elt);
265a9e55 11432 if (!NILP (tem))
a2889657
JB
11433 {
11434 tem = Fsymbol_value (elt);
11435 /* If value is a string, output that string literally:
11436 don't check for % within it. */
e24c997d 11437 if (STRINGP (tem))
d39b6696 11438 {
5f5c8ee5
GM
11439 prec = XSTRING (tem)->size;
11440 if (precision > 0 && prec > precision - n)
11441 prec = precision - n;
d39b6696 11442 if (frame_title_ptr)
5f5c8ee5 11443 n += store_frame_title (XSTRING (tem)->data, -1, prec);
d39b6696 11444 else
5f5c8ee5
GM
11445 n += display_string (NULL, tem, Qnil, 0, 0, it,
11446 0, prec, 0, -1);
d39b6696 11447 }
a2889657 11448 else if (!EQ (tem, elt))
5f5c8ee5
GM
11449 {
11450 /* Give up right away for nil or t. */
11451 elt = tem;
11452 goto tail_recurse;
11453 }
a2889657
JB
11454 }
11455 }
11456 break;
11457
11458 case Lisp_Cons:
11459 {
11460 register Lisp_Object car, tem;
11461
11462 /* A cons cell: three distinct cases.
11463 If first element is a string or a cons, process all the elements
11464 and effectively concatenate them.
11465 If first element is a negative number, truncate displaying cdr to
11466 at most that many characters. If positive, pad (with spaces)
11467 to at least that many characters.
11468 If first element is a symbol, process the cadr or caddr recursively
11469 according to whether the symbol's value is non-nil or nil. */
11470 car = XCONS (elt)->car;
5f5c8ee5
GM
11471 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
11472 {
11473 /* An element of the form (:eval FORM) means evaluate FORM
11474 and use the result as mode line elements. */
11475 struct gcpro gcpro1;
11476 Lisp_Object spec;
11477
11478 spec = eval_form (XCAR (XCDR (elt)));
11479 GCPRO1 (spec);
11480 n += display_mode_element (it, depth, field_width - n,
11481 precision - n, spec);
11482 UNGCPRO;
11483 }
11484 else if (SYMBOLP (car))
a2889657
JB
11485 {
11486 tem = Fboundp (car);
11487 elt = XCONS (elt)->cdr;
e24c997d 11488 if (!CONSP (elt))
a2889657
JB
11489 goto invalid;
11490 /* elt is now the cdr, and we know it is a cons cell.
11491 Use its car if CAR has a non-nil value. */
265a9e55 11492 if (!NILP (tem))
a2889657
JB
11493 {
11494 tem = Fsymbol_value (car);
265a9e55 11495 if (!NILP (tem))
a2889657
JB
11496 { elt = XCONS (elt)->car; goto tail_recurse; }
11497 }
11498 /* Symbol's value is nil (or symbol is unbound)
11499 Get the cddr of the original list
11500 and if possible find the caddr and use that. */
11501 elt = XCONS (elt)->cdr;
265a9e55 11502 if (NILP (elt))
a2889657 11503 break;
e24c997d 11504 else if (!CONSP (elt))
a2889657
JB
11505 goto invalid;
11506 elt = XCONS (elt)->car;
11507 goto tail_recurse;
11508 }
e24c997d 11509 else if (INTEGERP (car))
a2889657
JB
11510 {
11511 register int lim = XINT (car);
11512 elt = XCONS (elt)->cdr;
11513 if (lim < 0)
5f5c8ee5
GM
11514 {
11515 /* Negative int means reduce maximum width. */
11516 if (precision <= 0)
11517 precision = -lim;
11518 else
11519 precision = min (precision, -lim);
11520 }
a2889657
JB
11521 else if (lim > 0)
11522 {
11523 /* Padding specified. Don't let it be more than
11524 current maximum. */
5f5c8ee5
GM
11525 if (precision > 0)
11526 lim = min (precision, lim);
11527
a2889657
JB
11528 /* If that's more padding than already wanted, queue it.
11529 But don't reduce padding already specified even if
11530 that is beyond the current truncation point. */
5f5c8ee5 11531 field_width = max (lim, field_width);
a2889657
JB
11532 }
11533 goto tail_recurse;
11534 }
e24c997d 11535 else if (STRINGP (car) || CONSP (car))
a2889657
JB
11536 {
11537 register int limit = 50;
5f5c8ee5
GM
11538 /* Limit is to protect against circular lists. */
11539 while (CONSP (elt)
11540 && --limit > 0
11541 && (precision <= 0 || n < precision))
a2889657 11542 {
5f5c8ee5
GM
11543 n += display_mode_element (it, depth, field_width - n,
11544 precision - n, XCONS (elt)->car);
a2889657
JB
11545 elt = XCONS (elt)->cdr;
11546 }
11547 }
11548 }
11549 break;
11550
11551 default:
11552 invalid:
d39b6696 11553 if (frame_title_ptr)
5f5c8ee5 11554 n += store_frame_title ("*invalid*", 0, precision - n);
d39b6696 11555 else
5f5c8ee5
GM
11556 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
11557 precision - n, 0, 0);
11558 return n;
a2889657
JB
11559 }
11560
5f5c8ee5
GM
11561 /* Pad to FIELD_WIDTH. */
11562 if (field_width > 0 && n < field_width)
11563 {
11564 if (frame_title_ptr)
11565 n += store_frame_title ("", field_width - n, 0);
11566 else
11567 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
11568 0, 0, 0);
11569 }
11570
11571 return n;
a2889657 11572}
5f5c8ee5
GM
11573
11574
766525bc
RS
11575/* Write a null-terminated, right justified decimal representation of
11576 the positive integer D to BUF using a minimal field width WIDTH. */
11577
11578static void
11579pint2str (buf, width, d)
11580 register char *buf;
11581 register int width;
11582 register int d;
11583{
11584 register char *p = buf;
11585
11586 if (d <= 0)
5f5c8ee5 11587 *p++ = '0';
766525bc 11588 else
5f5c8ee5 11589 {
766525bc 11590 while (d > 0)
5f5c8ee5 11591 {
766525bc
RS
11592 *p++ = d % 10 + '0';
11593 d /= 10;
5f5c8ee5
GM
11594 }
11595 }
11596
11597 for (width -= (int) (p - buf); width > 0; --width)
11598 *p++ = ' ';
766525bc
RS
11599 *p-- = '\0';
11600 while (p > buf)
5f5c8ee5 11601 {
766525bc
RS
11602 d = *buf;
11603 *buf++ = *p;
11604 *p-- = d;
5f5c8ee5 11605 }
766525bc
RS
11606}
11607
5f5c8ee5 11608/* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
1c9241f5
KH
11609 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
11610 type of CODING_SYSTEM. Return updated pointer into BUF. */
11611
6693a99a 11612static unsigned char invalid_eol_type[] = "(*invalid*)";
d24715e8 11613
1c9241f5
KH
11614static char *
11615decode_mode_spec_coding (coding_system, buf, eol_flag)
11616 Lisp_Object coding_system;
11617 register char *buf;
11618 int eol_flag;
11619{
1e1078d6 11620 Lisp_Object val;
916848d8 11621 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
302f2b38
EZ
11622 unsigned char *eol_str;
11623 int eol_str_len;
11624 /* The EOL conversion we are using. */
11625 Lisp_Object eoltype;
1e1078d6
RS
11626
11627 val = coding_system;
1c9241f5
KH
11628
11629 if (NILP (val)) /* Not yet decided. */
11630 {
916848d8
RS
11631 if (multibyte)
11632 *buf++ = '-';
21e989e3 11633 if (eol_flag)
302f2b38 11634 eoltype = eol_mnemonic_undecided;
1e1078d6 11635 /* Don't mention EOL conversion if it isn't decided. */
1c9241f5
KH
11636 }
11637 else
11638 {
1e1078d6
RS
11639 Lisp_Object eolvalue;
11640
11641 eolvalue = Fget (coding_system, Qeol_type);
11642
1c9241f5 11643 while (!NILP (val) && SYMBOLP (val))
1e1078d6
RS
11644 {
11645 val = Fget (val, Qcoding_system);
11646 if (NILP (eolvalue))
b070c1d7 11647 eolvalue = Fget (val, Qeol_type);
1e1078d6
RS
11648 }
11649
916848d8
RS
11650 if (multibyte)
11651 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
11652
1c9241f5
KH
11653 if (eol_flag)
11654 {
1e1078d6
RS
11655 /* The EOL conversion that is normal on this system. */
11656
11657 if (NILP (eolvalue)) /* Not yet decided. */
11658 eoltype = eol_mnemonic_undecided;
11659 else if (VECTORP (eolvalue)) /* Not yet decided. */
11660 eoltype = eol_mnemonic_undecided;
11661 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
11662 eoltype = (XFASTINT (eolvalue) == 0
11663 ? eol_mnemonic_unix
11664 : (XFASTINT (eolvalue) == 1
11665 ? eol_mnemonic_dos : eol_mnemonic_mac));
302f2b38
EZ
11666 }
11667 }
5f5c8ee5 11668
302f2b38
EZ
11669 if (eol_flag)
11670 {
11671 /* Mention the EOL conversion if it is not the usual one. */
11672 if (STRINGP (eoltype))
11673 {
11674 eol_str = XSTRING (eoltype)->data;
11675 eol_str_len = XSTRING (eoltype)->size;
11676 }
f30b3499
KH
11677 else if (INTEGERP (eoltype)
11678 && CHAR_VALID_P (XINT (eoltype), 0))
11679 {
f30b3499
KH
11680 unsigned char work[4];
11681
11682 eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
11683 }
302f2b38
EZ
11684 else
11685 {
11686 eol_str = invalid_eol_type;
11687 eol_str_len = sizeof (invalid_eol_type) - 1;
1c9241f5 11688 }
f30b3499 11689 bcopy (eol_str, buf, eol_str_len);
302f2b38 11690 buf += eol_str_len;
1c9241f5 11691 }
302f2b38 11692
1c9241f5
KH
11693 return buf;
11694}
11695
a2889657 11696/* Return a string for the output of a mode line %-spec for window W,
5f5c8ee5
GM
11697 generated by character C. PRECISION >= 0 means don't return a
11698 string longer than that value. FIELD_WIDTH > 0 means pad the
11699 string returned with spaces to that value. */
a2889657 11700
11e82b76
JB
11701static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
11702
a2889657 11703static char *
5f5c8ee5 11704decode_mode_spec (w, c, field_width, precision)
a2889657
JB
11705 struct window *w;
11706 register char c;
5f5c8ee5 11707 int field_width, precision;
a2889657 11708{
0b67772d 11709 Lisp_Object obj;
5f5c8ee5
GM
11710 struct frame *f = XFRAME (WINDOW_FRAME (w));
11711 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
d39b6696 11712 struct buffer *b = XBUFFER (w->buffer);
a2889657 11713
0b67772d 11714 obj = Qnil;
a2889657
JB
11715
11716 switch (c)
11717 {
1af9f229
RS
11718 case '*':
11719 if (!NILP (b->read_only))
11720 return "%";
11721 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11722 return "*";
11723 return "-";
11724
11725 case '+':
11726 /* This differs from %* only for a modified read-only buffer. */
11727 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11728 return "*";
11729 if (!NILP (b->read_only))
11730 return "%";
11731 return "-";
11732
11733 case '&':
11734 /* This differs from %* in ignoring read-only-ness. */
11735 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11736 return "*";
11737 return "-";
11738
11739 case '%':
11740 return "%";
11741
11742 case '[':
11743 {
11744 int i;
11745 char *p;
11746
11747 if (command_loop_level > 5)
11748 return "[[[... ";
11749 p = decode_mode_spec_buf;
11750 for (i = 0; i < command_loop_level; i++)
11751 *p++ = '[';
11752 *p = 0;
11753 return decode_mode_spec_buf;
11754 }
11755
11756 case ']':
11757 {
11758 int i;
11759 char *p;
11760
11761 if (command_loop_level > 5)
11762 return " ...]]]";
11763 p = decode_mode_spec_buf;
11764 for (i = 0; i < command_loop_level; i++)
11765 *p++ = ']';
11766 *p = 0;
11767 return decode_mode_spec_buf;
11768 }
11769
11770 case '-':
11771 {
1af9f229 11772 register int i;
5f5c8ee5
GM
11773
11774 /* Let lots_of_dashes be a string of infinite length. */
11775 if (field_width <= 0
11776 || field_width > sizeof (lots_of_dashes))
1af9f229 11777 {
5f5c8ee5
GM
11778 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
11779 decode_mode_spec_buf[i] = '-';
11780 decode_mode_spec_buf[i] = '\0';
11781 return decode_mode_spec_buf;
1af9f229 11782 }
5f5c8ee5
GM
11783 else
11784 return lots_of_dashes;
1af9f229
RS
11785 }
11786
a2889657 11787 case 'b':
d39b6696 11788 obj = b->name;
a2889657
JB
11789 break;
11790
1af9f229
RS
11791 case 'c':
11792 {
11793 int col = current_column ();
11794 XSETFASTINT (w->column_number_displayed, col);
5f5c8ee5 11795 pint2str (decode_mode_spec_buf, field_width, col);
1af9f229
RS
11796 return decode_mode_spec_buf;
11797 }
11798
11799 case 'F':
11800 /* %F displays the frame name. */
5f5c8ee5 11801 if (!NILP (f->title))
95184b48 11802 return (char *) XSTRING (f->title)->data;
fd8ff63d 11803 if (f->explicit_name || ! FRAME_WINDOW_P (f))
95184b48 11804 return (char *) XSTRING (f->name)->data;
9c6da96f 11805 return "Emacs";
1af9f229 11806
a2889657 11807 case 'f':
d39b6696 11808 obj = b->filename;
a2889657
JB
11809 break;
11810
aa6d10fa
RS
11811 case 'l':
11812 {
12adba34
RS
11813 int startpos = XMARKER (w->start)->charpos;
11814 int startpos_byte = marker_byte_position (w->start);
11815 int line, linepos, linepos_byte, topline;
aa6d10fa 11816 int nlines, junk;
aa6d10fa
RS
11817 int height = XFASTINT (w->height);
11818
11819 /* If we decided that this buffer isn't suitable for line numbers,
11820 don't forget that too fast. */
11821 if (EQ (w->base_line_pos, w->buffer))
766525bc 11822 goto no_value;
5300fd39
RS
11823 /* But do forget it, if the window shows a different buffer now. */
11824 else if (BUFFERP (w->base_line_pos))
11825 w->base_line_pos = Qnil;
aa6d10fa
RS
11826
11827 /* If the buffer is very big, don't waste time. */
d39b6696 11828 if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit)
aa6d10fa
RS
11829 {
11830 w->base_line_pos = Qnil;
11831 w->base_line_number = Qnil;
766525bc 11832 goto no_value;
aa6d10fa
RS
11833 }
11834
11835 if (!NILP (w->base_line_number)
11836 && !NILP (w->base_line_pos)
12adba34 11837 && XFASTINT (w->base_line_pos) <= startpos)
aa6d10fa
RS
11838 {
11839 line = XFASTINT (w->base_line_number);
11840 linepos = XFASTINT (w->base_line_pos);
12adba34 11841 linepos_byte = buf_charpos_to_bytepos (b, linepos);
aa6d10fa
RS
11842 }
11843 else
11844 {
11845 line = 1;
d39b6696 11846 linepos = BUF_BEGV (b);
12adba34 11847 linepos_byte = BUF_BEGV_BYTE (b);
aa6d10fa
RS
11848 }
11849
11850 /* Count lines from base line to window start position. */
12adba34
RS
11851 nlines = display_count_lines (linepos, linepos_byte,
11852 startpos_byte,
11853 startpos, &junk);
aa6d10fa
RS
11854
11855 topline = nlines + line;
11856
11857 /* Determine a new base line, if the old one is too close
11858 or too far away, or if we did not have one.
11859 "Too close" means it's plausible a scroll-down would
11860 go back past it. */
d39b6696 11861 if (startpos == BUF_BEGV (b))
aa6d10fa 11862 {
c2213350
KH
11863 XSETFASTINT (w->base_line_number, topline);
11864 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
aa6d10fa
RS
11865 }
11866 else if (nlines < height + 25 || nlines > height * 3 + 50
d39b6696 11867 || linepos == BUF_BEGV (b))
aa6d10fa 11868 {
d39b6696 11869 int limit = BUF_BEGV (b);
12adba34 11870 int limit_byte = BUF_BEGV_BYTE (b);
aa6d10fa 11871 int position;
5d121aec 11872 int distance = (height * 2 + 30) * line_number_display_limit_width;
aa6d10fa
RS
11873
11874 if (startpos - distance > limit)
12adba34
RS
11875 {
11876 limit = startpos - distance;
11877 limit_byte = CHAR_TO_BYTE (limit);
11878 }
aa6d10fa 11879
12adba34
RS
11880 nlines = display_count_lines (startpos, startpos_byte,
11881 limit_byte,
11882 - (height * 2 + 30),
aa6d10fa
RS
11883 &position);
11884 /* If we couldn't find the lines we wanted within
5d121aec 11885 line_number_display_limit_width chars per line,
aa6d10fa 11886 give up on line numbers for this window. */
12adba34 11887 if (position == limit_byte && limit == startpos - distance)
aa6d10fa
RS
11888 {
11889 w->base_line_pos = w->buffer;
11890 w->base_line_number = Qnil;
766525bc 11891 goto no_value;
aa6d10fa
RS
11892 }
11893
c2213350 11894 XSETFASTINT (w->base_line_number, topline - nlines);
12adba34 11895 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
aa6d10fa
RS
11896 }
11897
11898 /* Now count lines from the start pos to point. */
12adba34
RS
11899 nlines = display_count_lines (startpos, startpos_byte,
11900 PT_BYTE, PT, &junk);
aa6d10fa
RS
11901
11902 /* Record that we did display the line number. */
11903 line_number_displayed = 1;
11904
11905 /* Make the string to show. */
5f5c8ee5 11906 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
aa6d10fa 11907 return decode_mode_spec_buf;
766525bc
RS
11908 no_value:
11909 {
11910 char* p = decode_mode_spec_buf;
5f5c8ee5
GM
11911 int pad = field_width - 2;
11912 while (pad-- > 0)
11913 *p++ = ' ';
11914 *p++ = '?';
11915 *p = '?';
766525bc
RS
11916 return decode_mode_spec_buf;
11917 }
aa6d10fa
RS
11918 }
11919 break;
11920
a2889657 11921 case 'm':
d39b6696 11922 obj = b->mode_name;
a2889657
JB
11923 break;
11924
11925 case 'n':
d39b6696 11926 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
a2889657
JB
11927 return " Narrow";
11928 break;
11929
a2889657
JB
11930 case 'p':
11931 {
11932 int pos = marker_position (w->start);
d39b6696 11933 int total = BUF_ZV (b) - BUF_BEGV (b);
a2889657 11934
d39b6696 11935 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
a2889657 11936 {
d39b6696 11937 if (pos <= BUF_BEGV (b))
a2889657
JB
11938 return "All";
11939 else
11940 return "Bottom";
11941 }
d39b6696 11942 else if (pos <= BUF_BEGV (b))
a2889657
JB
11943 return "Top";
11944 else
11945 {
3c7d31b9
RS
11946 if (total > 1000000)
11947 /* Do it differently for a large value, to avoid overflow. */
11948 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11949 else
11950 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
a2889657
JB
11951 /* We can't normally display a 3-digit number,
11952 so get us a 2-digit number that is close. */
11953 if (total == 100)
11954 total = 99;
11955 sprintf (decode_mode_spec_buf, "%2d%%", total);
11956 return decode_mode_spec_buf;
11957 }
11958 }
11959
8ffcb79f
RS
11960 /* Display percentage of size above the bottom of the screen. */
11961 case 'P':
11962 {
11963 int toppos = marker_position (w->start);
d39b6696
KH
11964 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
11965 int total = BUF_ZV (b) - BUF_BEGV (b);
8ffcb79f 11966
d39b6696 11967 if (botpos >= BUF_ZV (b))
8ffcb79f 11968 {
d39b6696 11969 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11970 return "All";
11971 else
11972 return "Bottom";
11973 }
11974 else
11975 {
3c7d31b9
RS
11976 if (total > 1000000)
11977 /* Do it differently for a large value, to avoid overflow. */
11978 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11979 else
11980 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
8ffcb79f
RS
11981 /* We can't normally display a 3-digit number,
11982 so get us a 2-digit number that is close. */
11983 if (total == 100)
11984 total = 99;
d39b6696 11985 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11986 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
11987 else
11988 sprintf (decode_mode_spec_buf, "%2d%%", total);
11989 return decode_mode_spec_buf;
11990 }
11991 }
11992
1af9f229
RS
11993 case 's':
11994 /* status of process */
11995 obj = Fget_buffer_process (w->buffer);
11996 if (NILP (obj))
11997 return "no process";
11998#ifdef subprocesses
11999 obj = Fsymbol_name (Fprocess_status (obj));
12000#endif
12001 break;
d39b6696 12002
1af9f229
RS
12003 case 't': /* indicate TEXT or BINARY */
12004#ifdef MODE_LINE_BINARY_TEXT
12005 return MODE_LINE_BINARY_TEXT (b);
12006#else
12007 return "T";
12008#endif
1c9241f5
KH
12009
12010 case 'z':
12011 /* coding-system (not including end-of-line format) */
12012 case 'Z':
12013 /* coding-system (including end-of-line type) */
12014 {
12015 int eol_flag = (c == 'Z');
539b4d41 12016 char *p = decode_mode_spec_buf;
1c9241f5 12017
d30e754b 12018 if (! FRAME_WINDOW_P (f))
1c9241f5 12019 {
11c52c4f
RS
12020 /* No need to mention EOL here--the terminal never needs
12021 to do EOL conversion. */
12022 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
12023 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
1c9241f5 12024 }
f13c925f 12025 p = decode_mode_spec_coding (b->buffer_file_coding_system,
539b4d41 12026 p, eol_flag);
f13c925f 12027
11c52c4f 12028#if 0 /* This proves to be annoying; I think we can do without. -- rms. */
1c9241f5
KH
12029#ifdef subprocesses
12030 obj = Fget_buffer_process (Fcurrent_buffer ());
12031 if (PROCESSP (obj))
12032 {
12033 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
12034 p, eol_flag);
12035 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
12036 p, eol_flag);
12037 }
12038#endif /* subprocesses */
11c52c4f 12039#endif /* 0 */
1c9241f5
KH
12040 *p = 0;
12041 return decode_mode_spec_buf;
12042 }
a2889657 12043 }
d39b6696 12044
e24c997d 12045 if (STRINGP (obj))
a2889657
JB
12046 return (char *) XSTRING (obj)->data;
12047 else
12048 return "";
12049}
5f5c8ee5
GM
12050
12051
12adba34
RS
12052/* Count up to COUNT lines starting from START / START_BYTE.
12053 But don't go beyond LIMIT_BYTE.
12054 Return the number of lines thus found (always nonnegative).
59b49f63 12055
12adba34 12056 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
59b49f63
RS
12057
12058static int
12adba34
RS
12059display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
12060 int start, start_byte, limit_byte, count;
12061 int *byte_pos_ptr;
59b49f63 12062{
59b49f63
RS
12063 register unsigned char *cursor;
12064 unsigned char *base;
12065
12066 register int ceiling;
12067 register unsigned char *ceiling_addr;
12adba34 12068 int orig_count = count;
59b49f63
RS
12069
12070 /* If we are not in selective display mode,
12071 check only for newlines. */
12adba34
RS
12072 int selective_display = (!NILP (current_buffer->selective_display)
12073 && !INTEGERP (current_buffer->selective_display));
59b49f63
RS
12074
12075 if (count > 0)
12adba34
RS
12076 {
12077 while (start_byte < limit_byte)
12078 {
12079 ceiling = BUFFER_CEILING_OF (start_byte);
12080 ceiling = min (limit_byte - 1, ceiling);
12081 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
12082 base = (cursor = BYTE_POS_ADDR (start_byte));
12083 while (1)
12084 {
12085 if (selective_display)
12086 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
12087 ;
12088 else
12089 while (*cursor != '\n' && ++cursor != ceiling_addr)
12090 ;
12091
12092 if (cursor != ceiling_addr)
12093 {
12094 if (--count == 0)
12095 {
12096 start_byte += cursor - base + 1;
12097 *byte_pos_ptr = start_byte;
12098 return orig_count;
12099 }
12100 else
12101 if (++cursor == ceiling_addr)
12102 break;
12103 }
12104 else
12105 break;
12106 }
12107 start_byte += cursor - base;
12108 }
12109 }
59b49f63
RS
12110 else
12111 {
12adba34
RS
12112 while (start_byte > limit_byte)
12113 {
12114 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
12115 ceiling = max (limit_byte, ceiling);
12116 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
12117 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
59b49f63
RS
12118 while (1)
12119 {
12adba34
RS
12120 if (selective_display)
12121 while (--cursor != ceiling_addr
12122 && *cursor != '\n' && *cursor != 015)
12123 ;
12124 else
12125 while (--cursor != ceiling_addr && *cursor != '\n')
12126 ;
12127
59b49f63
RS
12128 if (cursor != ceiling_addr)
12129 {
12130 if (++count == 0)
12131 {
12adba34
RS
12132 start_byte += cursor - base + 1;
12133 *byte_pos_ptr = start_byte;
12134 /* When scanning backwards, we should
12135 not count the newline posterior to which we stop. */
12136 return - orig_count - 1;
59b49f63
RS
12137 }
12138 }
12139 else
12140 break;
12141 }
12adba34
RS
12142 /* Here we add 1 to compensate for the last decrement
12143 of CURSOR, which took it past the valid range. */
12144 start_byte += cursor - base + 1;
59b49f63
RS
12145 }
12146 }
12147
12adba34 12148 *byte_pos_ptr = limit_byte;
aa6d10fa 12149
12adba34
RS
12150 if (count < 0)
12151 return - orig_count + count;
12152 return orig_count - count;
aa6d10fa 12153
12adba34 12154}
a2889657 12155
a2889657 12156
5f5c8ee5
GM
12157\f
12158/***********************************************************************
12159 Displaying strings
12160 ***********************************************************************/
278feba9 12161
5f5c8ee5 12162/* Display a NUL-terminated string, starting with index START.
a3788d53 12163
5f5c8ee5
GM
12164 If STRING is non-null, display that C string. Otherwise, the Lisp
12165 string LISP_STRING is displayed.
a2889657 12166
5f5c8ee5
GM
12167 If FACE_STRING is not nil, FACE_STRING_POS is a position in
12168 FACE_STRING. Display STRING or LISP_STRING with the face at
12169 FACE_STRING_POS in FACE_STRING:
a2889657 12170
5f5c8ee5
GM
12171 Display the string in the environment given by IT, but use the
12172 standard display table, temporarily.
a3788d53 12173
5f5c8ee5
GM
12174 FIELD_WIDTH is the minimum number of output glyphs to produce.
12175 If STRING has fewer characters than FIELD_WIDTH, pad to the right
12176 with spaces. If STRING has more characters, more than FIELD_WIDTH
12177 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
12178
12179 PRECISION is the maximum number of characters to output from
12180 STRING. PRECISION < 0 means don't truncate the string.
a2889657 12181
5f5c8ee5 12182 This is roughly equivalent to printf format specifiers:
a2889657 12183
5f5c8ee5
GM
12184 FIELD_WIDTH PRECISION PRINTF
12185 ----------------------------------------
12186 -1 -1 %s
12187 -1 10 %.10s
12188 10 -1 %10s
12189 20 10 %20.10s
a2889657 12190
5f5c8ee5
GM
12191 MULTIBYTE zero means do not display multibyte chars, > 0 means do
12192 display them, and < 0 means obey the current buffer's value of
12193 enable_multibyte_characters.
278feba9 12194
5f5c8ee5 12195 Value is the number of glyphs produced. */
b1d1124b 12196
5f5c8ee5
GM
12197static int
12198display_string (string, lisp_string, face_string, face_string_pos,
12199 start, it, field_width, precision, max_x, multibyte)
12200 unsigned char *string;
12201 Lisp_Object lisp_string;
12202 int start;
12203 struct it *it;
12204 int field_width, precision, max_x;
12205 int multibyte;
12206{
12207 int hpos_at_start = it->hpos;
12208 int saved_face_id = it->face_id;
12209 struct glyph_row *row = it->glyph_row;
12210
12211 /* Initialize the iterator IT for iteration over STRING beginning
12212 with index START. We assume that IT may be modified here (which
12213 means that display_line has to do something when displaying a
12214 mini-buffer prompt, which it does). */
12215 reseat_to_string (it, string, lisp_string, start,
12216 precision, field_width, multibyte);
12217
12218 /* If displaying STRING, set up the face of the iterator
12219 from LISP_STRING, if that's given. */
12220 if (STRINGP (face_string))
12221 {
12222 int endptr;
12223 struct face *face;
12224
12225 it->face_id
12226 = face_at_string_position (it->w, face_string, face_string_pos,
12227 0, it->region_beg_charpos,
12228 it->region_end_charpos,
12229 &endptr, it->base_face_id);
12230 face = FACE_FROM_ID (it->f, it->face_id);
12231 it->face_box_p = face->box != FACE_NO_BOX;
b1d1124b 12232 }
a2889657 12233
5f5c8ee5
GM
12234 /* Set max_x to the maximum allowed X position. Don't let it go
12235 beyond the right edge of the window. */
12236 if (max_x <= 0)
12237 max_x = it->last_visible_x;
12238 else
12239 max_x = min (max_x, it->last_visible_x);
efc63ef0 12240
5f5c8ee5
GM
12241 /* Skip over display elements that are not visible. because IT->w is
12242 hscrolled. */
12243 if (it->current_x < it->first_visible_x)
12244 move_it_in_display_line_to (it, 100000, it->first_visible_x,
12245 MOVE_TO_POS | MOVE_TO_X);
a2889657 12246
5f5c8ee5
GM
12247 row->ascent = it->max_ascent;
12248 row->height = it->max_ascent + it->max_descent;
312246d1
GM
12249 row->phys_ascent = it->max_phys_ascent;
12250 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
1c9241f5 12251
5f5c8ee5
GM
12252 /* This condition is for the case that we are called with current_x
12253 past last_visible_x. */
12254 while (it->current_x < max_x)
a2889657 12255 {
5f5c8ee5 12256 int x_before, x, n_glyphs_before, i, nglyphs;
1c9241f5 12257
5f5c8ee5
GM
12258 /* Get the next display element. */
12259 if (!get_next_display_element (it))
90adcf20 12260 break;
1c9241f5 12261
5f5c8ee5
GM
12262 /* Produce glyphs. */
12263 x_before = it->current_x;
12264 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
12265 PRODUCE_GLYPHS (it);
90adcf20 12266
5f5c8ee5
GM
12267 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
12268 i = 0;
12269 x = x_before;
12270 while (i < nglyphs)
a2889657 12271 {
5f5c8ee5
GM
12272 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12273
12274 if (!it->truncate_lines_p
12275 && x + glyph->pixel_width > max_x)
12276 {
12277 /* End of continued line or max_x reached. */
12278 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
12279 it->current_x = x;
12280 break;
12281 }
12282 else if (x + glyph->pixel_width > it->first_visible_x)
12283 {
12284 /* Glyph is at least partially visible. */
12285 ++it->hpos;
12286 if (x < it->first_visible_x)
12287 it->glyph_row->x = x - it->first_visible_x;
12288 }
12289 else
a2889657 12290 {
5f5c8ee5
GM
12291 /* Glyph is off the left margin of the display area.
12292 Should not happen. */
12293 abort ();
a2889657 12294 }
5f5c8ee5
GM
12295
12296 row->ascent = max (row->ascent, it->max_ascent);
12297 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
12298 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12299 row->phys_height = max (row->phys_height,
12300 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
12301 x += glyph->pixel_width;
12302 ++i;
a2889657 12303 }
5f5c8ee5
GM
12304
12305 /* Stop if max_x reached. */
12306 if (i < nglyphs)
12307 break;
12308
12309 /* Stop at line ends. */
12310 if (ITERATOR_AT_END_OF_LINE_P (it))
a2889657 12311 {
5f5c8ee5
GM
12312 it->continuation_lines_width = 0;
12313 break;
a2889657 12314 }
1c9241f5 12315
5f5c8ee5 12316 set_iterator_to_next (it);
a688bb24 12317
5f5c8ee5
GM
12318 /* Stop if truncating at the right edge. */
12319 if (it->truncate_lines_p
12320 && it->current_x >= it->last_visible_x)
12321 {
12322 /* Add truncation mark, but don't do it if the line is
12323 truncated at a padding space. */
12324 if (IT_CHARPOS (*it) < it->string_nchars)
1c9241f5 12325 {
5f5c8ee5
GM
12326 if (!FRAME_WINDOW_P (it->f))
12327 produce_special_glyphs (it, IT_TRUNCATION);
12328 it->glyph_row->truncated_on_right_p = 1;
1c9241f5 12329 }
5f5c8ee5 12330 break;
1c9241f5 12331 }
a2889657
JB
12332 }
12333
5f5c8ee5
GM
12334 /* Maybe insert a truncation at the left. */
12335 if (it->first_visible_x
12336 && IT_CHARPOS (*it) > 0)
a2889657 12337 {
5f5c8ee5
GM
12338 if (!FRAME_WINDOW_P (it->f))
12339 insert_left_trunc_glyphs (it);
12340 it->glyph_row->truncated_on_left_p = 1;
a2889657
JB
12341 }
12342
5f5c8ee5
GM
12343 it->face_id = saved_face_id;
12344
12345 /* Value is number of columns displayed. */
12346 return it->hpos - hpos_at_start;
12347}
a2889657 12348
a2889657 12349
a2889657 12350\f
5f5c8ee5
GM
12351/* This is like a combination of memq and assq. Return 1 if PROPVAL
12352 appears as an element of LIST or as the car of an element of LIST.
12353 If PROPVAL is a list, compare each element against LIST in that
12354 way, and return 1 if any element of PROPVAL is found in LIST.
12355 Otherwise return 0. This function cannot quit. */
642eefc6
RS
12356
12357int
12358invisible_p (propval, list)
12359 register Lisp_Object propval;
12360 Lisp_Object list;
12361{
af460d46
RS
12362 register Lisp_Object tail, proptail;
12363 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
12364 {
12365 register Lisp_Object tem;
af460d46 12366 tem = XCONS (tail)->car;
642eefc6
RS
12367 if (EQ (propval, tem))
12368 return 1;
12369 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
12370 return 1;
12371 }
af460d46
RS
12372 if (CONSP (propval))
12373 for (proptail = propval; CONSP (proptail);
12374 proptail = XCONS (proptail)->cdr)
12375 {
12376 Lisp_Object propelt;
12377 propelt = XCONS (proptail)->car;
12378 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
12379 {
12380 register Lisp_Object tem;
12381 tem = XCONS (tail)->car;
12382 if (EQ (propelt, tem))
12383 return 1;
12384 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
12385 return 1;
12386 }
12387 }
642eefc6
RS
12388 return 0;
12389}
12390
5f5c8ee5
GM
12391
12392/* Return 1 if PROPVAL appears as the car of an element of LIST and
12393 the cdr of that element is non-nil. If PROPVAL is a list, check
12394 each element of PROPVAL in that way, and the first time some
12395 element is found, return 1 if the cdr of that element is non-nil.
12396 Otherwise return 0. This function cannot quit. */
642eefc6
RS
12397
12398int
12399invisible_ellipsis_p (propval, list)
12400 register Lisp_Object propval;
12401 Lisp_Object list;
12402{
af460d46
RS
12403 register Lisp_Object tail, proptail;
12404 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
12405 {
12406 register Lisp_Object tem;
af460d46 12407 tem = XCONS (tail)->car;
642eefc6
RS
12408 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
12409 return ! NILP (XCONS (tem)->cdr);
12410 }
af460d46
RS
12411 if (CONSP (propval))
12412 for (proptail = propval; CONSP (proptail);
12413 proptail = XCONS (proptail)->cdr)
12414 {
12415 Lisp_Object propelt;
12416 propelt = XCONS (proptail)->car;
12417 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
12418 {
12419 register Lisp_Object tem;
12420 tem = XCONS (tail)->car;
12421 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
12422 return ! NILP (XCONS (tem)->cdr);
12423 }
12424 }
642eefc6
RS
12425 return 0;
12426}
5f5c8ee5
GM
12427
12428
642eefc6 12429\f
5f5c8ee5
GM
12430/***********************************************************************
12431 Initialization
12432 ***********************************************************************/
12433
a2889657
JB
12434void
12435syms_of_xdisp ()
12436{
9142dd5b
GM
12437 Vresize_mini_config = Qnil;
12438 staticpro (&Vresize_mini_config);
12439
c6e89d6c
GM
12440 Vwith_echo_area_save_vector = Qnil;
12441 staticpro (&Vwith_echo_area_save_vector);
5f5c8ee5 12442
c6e89d6c
GM
12443 Vmessage_stack = Qnil;
12444 staticpro (&Vmessage_stack);
12445
735c094c 12446 Qinhibit_redisplay = intern ("inhibit-redisplay");
c6e89d6c 12447 staticpro (&Qinhibit_redisplay);
735c094c 12448
5f5c8ee5
GM
12449#if GLYPH_DEBUG
12450 defsubr (&Sdump_glyph_matrix);
12451 defsubr (&Sdump_glyph_row);
12452 defsubr (&Sdump_toolbar_row);
12453 defsubr (&Strace_redisplay_toggle);
12454#endif
12455
cf074754
RS
12456 staticpro (&Qmenu_bar_update_hook);
12457 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
12458
d46fb96a 12459 staticpro (&Qoverriding_terminal_local_map);
7079aefa 12460 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
d46fb96a 12461
399164b4
KH
12462 staticpro (&Qoverriding_local_map);
12463 Qoverriding_local_map = intern ("overriding-local-map");
12464
75c43375
RS
12465 staticpro (&Qwindow_scroll_functions);
12466 Qwindow_scroll_functions = intern ("window-scroll-functions");
12467
e0bfbde6
RS
12468 staticpro (&Qredisplay_end_trigger_functions);
12469 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
5f5c8ee5 12470
2e54982e
RS
12471 staticpro (&Qinhibit_point_motion_hooks);
12472 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
12473
5f5c8ee5
GM
12474 staticpro (&Qdisplay);
12475 Qdisplay = intern ("display");
12476 staticpro (&Qleft_margin);
12477 Qspace_width = intern ("space-width");
12478 staticpro (&Qspace_width);
12479 Qheight = intern ("height");
12480 staticpro (&Qheight);
12481 Qraise = intern ("raise");
12482 staticpro (&Qraise);
12483 Qspace = intern ("space");
12484 staticpro (&Qspace);
12485 Qleft_margin = intern ("left-margin");
12486 staticpro (&Qright_margin);
12487 Qright_margin = intern ("right-margin");
12488 Qalign_to = intern ("align-to");
12489 staticpro (&Qalign_to);
12490 QCalign_to = intern (":align-to");
12491 staticpro (&QCalign_to);
12492 Qwidth = intern ("width");
12493 staticpro (&Qwidth);
12494 Qrelative_width = intern ("relative-width");
12495 staticpro (&Qrelative_width);
12496 QCrelative_width = intern (":relative-width");
12497 staticpro (&QCrelative_width);
12498 QCrelative_height = intern (":relative-height");
12499 staticpro (&QCrelative_height);
12500 QCeval = intern (":eval");
12501 staticpro (&QCeval);
12502 QCwhen = intern (":when");
12503 staticpro (&QCwhen);
12504 Qfontified = intern ("fontified");
12505 staticpro (&Qfontified);
12506 Qfontification_functions = intern ("fontification-functions");
12507 staticpro (&Qfontification_functions);
5f5c8ee5
GM
12508 Qtrailing_whitespace = intern ("trailing-whitespace");
12509 staticpro (&Qtrailing_whitespace);
12510 Qimage = intern ("image");
12511 staticpro (&Qimage);
12512
a2889657
JB
12513 staticpro (&last_arrow_position);
12514 staticpro (&last_arrow_string);
12515 last_arrow_position = Qnil;
12516 last_arrow_string = Qnil;
c6e89d6c
GM
12517
12518 echo_buffer[0] = echo_buffer[1] = Qnil;
12519 staticpro (&echo_buffer[0]);
12520 staticpro (&echo_buffer[1]);
12521
12522 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
12523 staticpro (&echo_area_buffer[0]);
12524 staticpro (&echo_area_buffer[1]);
a2889657 12525
8f897821
GM
12526 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
12527 "Non-nil means highlight trailing whitespace.\n\
12528The face used for trailing whitespace is `trailing-whitespace'.");
12529 Vshow_trailing_whitespace = Qnil;
12530
735c094c
KH
12531 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
12532 "Non-nil means don't actually do any redisplay.\n\
12533This is used for internal purposes.");
12534 Vinhibit_redisplay = Qnil;
12535
a2889657 12536 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
8c45d522 12537 "String (or mode line construct) included (normally) in `mode-line-format'.");
a2889657
JB
12538 Vglobal_mode_string = Qnil;
12539
12540 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
12541 "Marker for where to display an arrow on top of the buffer text.\n\
12542This must be the beginning of a line in order to work.\n\
12543See also `overlay-arrow-string'.");
12544 Voverlay_arrow_position = Qnil;
12545
12546 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
12547 "String to display as an arrow. See also `overlay-arrow-position'.");
12548 Voverlay_arrow_string = Qnil;
12549
12550 DEFVAR_INT ("scroll-step", &scroll_step,
12551 "*The number of lines to try scrolling a window by when point moves out.\n\
44fa5b1e
JB
12552If that fails to bring point back on frame, point is centered instead.\n\
12553If this is zero, point is always centered after it moves off frame.");
a2889657 12554
0789adb2
RS
12555 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
12556 "*Scroll up to this many lines, to bring point back on screen.");
12557 scroll_conservatively = 0;
12558
9afd2168
RS
12559 DEFVAR_INT ("scroll-margin", &scroll_margin,
12560 "*Number of lines of margin at the top and bottom of a window.\n\
12561Recenter the window whenever point gets within this many lines\n\
12562of the top or bottom of the window.");
12563 scroll_margin = 0;
12564
5f5c8ee5 12565#if GLYPH_DEBUG
a2889657 12566 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
5f5c8ee5 12567#endif
a2889657
JB
12568
12569 DEFVAR_BOOL ("truncate-partial-width-windows",
12570 &truncate_partial_width_windows,
44fa5b1e 12571 "*Non-nil means truncate lines in all windows less than full frame wide.");
a2889657
JB
12572 truncate_partial_width_windows = 1;
12573
12574 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
12575 "*Non-nil means use inverse video for the mode line.");
12576 mode_line_inverse_video = 1;
aa6d10fa
RS
12577
12578 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
5f5c8ee5 12579 "*Maximum buffer size for which line number should be displayed.\n\
db4f2bfa 12580If the buffer is bigger than this, the line number does not appear\n\
9f027393 12581in the mode line.");
aa6d10fa 12582 line_number_display_limit = 1000000;
fba9ce76 12583
5d121aec
KH
12584 DEFVAR_INT ("line-number-display-limit-width", &line_number_display_limit_width,
12585 "*Maximum line width (in characters) for line number display.\n\
12586If the average length of the lines near point is bigger than this, then the\n\
12587line number may be omitted from the mode line.");
12588 line_number_display_limit_width = 200;
12589
fba9ce76
RS
12590 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
12591 "*Non-nil means highlight region even in nonselected windows.");
293a54ce 12592 highlight_nonselected_windows = 0;
d39b6696
KH
12593
12594 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
3450d04c
KH
12595 "Non-nil if more than one frame is visible on this display.\n\
12596Minibuffer-only frames don't count, but iconified frames do.\n\
4c2eb242
RS
12597This variable is not guaranteed to be accurate except while processing\n\
12598`frame-title-format' and `icon-title-format'.");
d39b6696
KH
12599
12600 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
5f5c8ee5 12601 "Template for displaying the title bar of visible frames.\n\
d39b6696
KH
12602\(Assuming the window manager supports this feature.)\n\
12603This variable has the same structure as `mode-line-format' (which see),\n\
12604and is used only on frames for which no explicit name has been set\n\
12605\(see `modify-frame-parameters').");
12606 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
5f5c8ee5 12607 "Template for displaying the title bar of an iconified frame.\n\
d39b6696
KH
12608\(Assuming the window manager supports this feature.)\n\
12609This variable has the same structure as `mode-line-format' (which see),\n\
12610and is used only on frames for which no explicit name has been set\n\
12611\(see `modify-frame-parameters').");
12612 Vicon_title_format
12613 = Vframe_title_format
12614 = Fcons (intern ("multiple-frames"),
12615 Fcons (build_string ("%b"),
12616 Fcons (Fcons (build_string (""),
12617 Fcons (intern ("invocation-name"),
12618 Fcons (build_string ("@"),
12619 Fcons (intern ("system-name"),
12620 Qnil)))),
12621 Qnil)));
5992c4f7
KH
12622
12623 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
12624 "Maximum number of lines to keep in the message log buffer.\n\
12625If nil, disable message logging. If t, log messages but don't truncate\n\
12626the buffer when it becomes large.");
12627 XSETFASTINT (Vmessage_log_max, 50);
08b610e4
RS
12628
12629 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
12630 "Functions called before redisplay, if window sizes have changed.\n\
12631The value should be a list of functions that take one argument.\n\
12632Just before redisplay, for each frame, if any of its windows have changed\n\
12633size since the last redisplay, or have been split or deleted,\n\
12634all the functions in the list are called, with the frame as argument.");
12635 Vwindow_size_change_functions = Qnil;
75c43375
RS
12636
12637 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
5f5c8ee5 12638 "List of Functions to call before redisplaying a window with scrolling.\n\
75c43375 12639Each function is called with two arguments, the window\n\
8d9583b0
RS
12640and its new display-start position. Note that the value of `window-end'\n\
12641is not valid when these functions are called.");
75c43375 12642 Vwindow_scroll_functions = Qnil;
5f5c8ee5
GM
12643
12644 DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p,
12645 "*Non-nil means automatically resize toolbars.\n\
12646This increases a toolbar's height if not all toolbar items are visible.\n\
12647It decreases a toolbar's height when it would display blank lines\n\
12648otherwise.");
12649 auto_resize_toolbars_p = 1;
12650
12651 DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p,
12652 "*Non-nil means raise toolbar buttons when the mouse moves over them.");
12653 auto_raise_toolbar_buttons_p = 1;
12654
12655 DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin,
12656 "*Margin around toolbar buttons in pixels.");
12657 toolbar_button_margin = 1;
12658
12659 DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief,
12660 "Relief thickness of toolbar buttons.");
12661 toolbar_button_relief = 3;
12662
12663 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
12664 "List of functions to call to fontify regions of text.\n\
12665Each function is called with one argument POS. Functions must\n\
12666fontify a region starting at POS in the current buffer, and give\n\
12667fontified regions the property `fontified'.\n\
12668This variable automatically becomes buffer-local when set.");
12669 Vfontification_functions = Qnil;
12670 Fmake_local_variable (Qfontification_functions);
7bbe686f
AI
12671
12672 DEFVAR_BOOL ("unibyte-display-via-language-environment",
5f5c8ee5
GM
12673 &unibyte_display_via_language_environment,
12674 "*Non-nil means display unibyte text according to language environment.\n\
7bbe686f
AI
12675Specifically this means that unibyte non-ASCII characters\n\
12676are displayed by converting them to the equivalent multibyte characters\n\
12677according to the current language environment. As a result, they are\n\
12678displayed according to the current fontset.");
12679 unibyte_display_via_language_environment = 0;
c6e89d6c
GM
12680
12681 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
12682 "*Maximum height for resizing mini-windows.\n\
12683If a float, it specifies a fraction of the mini-window frame's height.\n\
12684If an integer, it specifies a number of lines.");
12685 Vmax_mini_window_height = make_float (0.25);
a2889657
JB
12686}
12687
5f5c8ee5
GM
12688
12689/* Initialize this module when Emacs starts. */
12690
dfcf069d 12691void
a2889657
JB
12692init_xdisp ()
12693{
12694 Lisp_Object root_window;
5f5c8ee5 12695 struct window *mini_w;
a2889657 12696
5f5c8ee5 12697 CHARPOS (this_line_start_pos) = 0;
a2889657
JB
12698
12699 mini_w = XWINDOW (minibuf_window);
11e82b76 12700 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
a2889657 12701
a2889657
JB
12702 if (!noninteractive)
12703 {
5f5c8ee5
GM
12704 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
12705 int i;
12706
12707 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
12c226c5 12708 set_window_height (root_window,
5f5c8ee5 12709 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
12c226c5 12710 0);
c2213350 12711 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
a2889657
JB
12712 set_window_height (minibuf_window, 1, 0);
12713
c2213350
KH
12714 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
12715 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
5f5c8ee5
GM
12716
12717 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
12718 scratch_glyph_row.glyphs[TEXT_AREA + 1]
12719 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
12720
12721 /* The default ellipsis glyphs `...'. */
12722 for (i = 0; i < 3; ++i)
12723 XSETFASTINT (default_invis_vector[i], '.');
a2889657 12724 }
5f5c8ee5
GM
12725
12726#ifdef HAVE_WINDOW_SYSTEM
12727 {
12728 /* Allocate the buffer for frame titles. */
12729 int size = 100;
12730 frame_title_buf = (char *) xmalloc (size);
12731 frame_title_buf_end = frame_title_buf + size;
12732 frame_title_ptr = NULL;
12733 }
12734#endif /* HAVE_WINDOW_SYSTEM */
a2889657 12735}
5f5c8ee5
GM
12736
12737