(direct_output_for_insert): Use
[bpt/emacs.git] / src / xdisp.c
CommitLineData
a2889657 1/* Display generation from window structure and buffer text.
5f5c8ee5
GM
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99
3 Free Software Foundation, Inc.
a2889657
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
b1d1124b 9the Free Software Foundation; either version 2, or (at your option)
a2889657
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a2889657 21
5f5c8ee5
GM
22/* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the the description of direct update
37 operations, below.).
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay() +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking a iterator structure (struct it)
124 argument.
125
126 Iteration over things to be be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator
128 (or init_string_iterator for that matter). Calls to
129 get_next_display_element fill the iterator structure with relevant
130 information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
132
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
138 see in dispextern.h.
139
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
147
148
149 Frame matrices.
150
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
157
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
a2889657 169
18160b98 170#include <config.h>
a2889657 171#include <stdio.h>
5f5c8ee5
GM
172#ifdef STDC_HEADERS
173#include <stdlib.h>
174#endif
a2889657 175#include "lisp.h"
44fa5b1e 176#include "frame.h"
a2889657
JB
177#include "window.h"
178#include "termchar.h"
179#include "dispextern.h"
180#include "buffer.h"
1c9241f5 181#include "charset.h"
a2889657
JB
182#include "indent.h"
183#include "commands.h"
184#include "macros.h"
185#include "disptab.h"
30c566e4 186#include "termhooks.h"
b0a0fbda 187#include "intervals.h"
fe8b0cf8 188#include "keyboard.h"
1c9241f5
KH
189#include "coding.h"
190#include "process.h"
dfcf069d
AS
191#include "region-cache.h"
192
6d55d620 193#ifdef HAVE_X_WINDOWS
dfcf069d
AS
194#include "xterm.h"
195#endif
a2889657 196
5f5c8ee5
GM
197#define min(a, b) ((a) < (b) ? (a) : (b))
198#define max(a, b) ((a) > (b) ? (a) : (b))
199
200#define INFINITY 10000000
201
8f3343d0 202#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
76412d64 203extern void set_frame_menubar ();
cd6dfed6 204extern int pending_menu_activation;
76412d64
RS
205#endif
206
a2889657
JB
207extern int interrupt_input;
208extern int command_loop_level;
209
b6436d4e
RS
210extern int minibuffer_auto_raise;
211
c4628384
RS
212extern Lisp_Object Qface;
213
399164b4
KH
214extern Lisp_Object Voverriding_local_map;
215extern Lisp_Object Voverriding_local_map_menu_flag;
5f5c8ee5 216extern Lisp_Object Qmenu_item;
399164b4 217
d46fb96a 218Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
75c43375 219Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
e0bfbde6 220Lisp_Object Qredisplay_end_trigger_functions;
2e54982e 221Lisp_Object Qinhibit_point_motion_hooks;
5f5c8ee5
GM
222Lisp_Object QCeval, QCwhen;
223Lisp_Object Qfontified;
224
225/* Functions called to fontify regions of text. */
226
227Lisp_Object Vfontification_functions;
228Lisp_Object Qfontification_functions;
229
230/* Non-zero means draw toolbar buttons raised when the mouse moves
231 over them. */
232
233int auto_raise_toolbar_buttons_p;
234
235/* Margin around toolbar buttons in pixels. */
236
237int toolbar_button_margin;
238
239/* Thickness of shadow to draw around toolbar buttons. */
240
241int toolbar_button_relief;
242
243/* Non-zero means automatically resize toolbars so that all toolbar
244 items are visible, and no blank lines remain. */
245
246int auto_resize_toolbars_p;
399164b4 247
735c094c
KH
248/* Non-nil means don't actually do any redisplay. */
249
250Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
251
5f5c8ee5
GM
252/* Names of text properties relevant for redisplay. */
253
254Lisp_Object Qdisplay, Qrelative_width, Qwidth, Qalign_to;
255extern Lisp_Object Qface, Qinvisible, Qimage;
256
257/* Symbols used in text property values. */
258
259Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
260Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qheight, Qraise;
261
262/* Name of the variable controlling the highlighting of trailing
263 whitespace. The implementation uses find_symbol_value to get its
264 value. */
265
266Lisp_Object Qshow_trailing_whitespace;
267
268/* Name of the face used to highlight trailing whitespace. */
269
270Lisp_Object Qtrailing_whitespace;
271
272/* The symbol `image' which is the car of the lists used to represent
273 images in Lisp. */
274
275Lisp_Object Qimage;
276
277/* Non-zero means print newline to stdout before next mini-buffer
278 message. */
a2889657
JB
279
280int noninteractive_need_newline;
281
5f5c8ee5 282/* Non-zero means print newline to message log before next message. */
f88eb0b6 283
3c6595e0 284static int message_log_need_newline;
f88eb0b6 285
5f5c8ee5
GM
286\f
287/* The buffer position of the first character appearing entirely or
288 partially on the line of the selected window which contains the
289 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
290 redisplay optimization in redisplay_internal. */
a2889657 291
5f5c8ee5 292static struct text_pos this_line_start_pos;
a2889657 293
5f5c8ee5
GM
294/* Number of characters past the end of the line above, including the
295 terminating newline. */
296
297static struct text_pos this_line_end_pos;
298
299/* The vertical positions and the height of this line. */
a2889657 300
a2889657 301static int this_line_vpos;
5f5c8ee5
GM
302static int this_line_y;
303static int this_line_pixel_height;
304
305/* X position at which this display line starts. Usually zero;
306 negative if first character is partially visible. */
307
308static int this_line_start_x;
a2889657 309
5f5c8ee5 310/* Buffer that this_line_.* variables are referring to. */
a2889657 311
a2889657
JB
312static struct buffer *this_line_buffer;
313
5f5c8ee5
GM
314/* Nonzero means truncate lines in all windows less wide than the
315 frame. */
a2889657 316
a2889657
JB
317int truncate_partial_width_windows;
318
7bbe686f 319/* A flag to control how to display unibyte 8-bit character. */
5f5c8ee5 320
7bbe686f 321int unibyte_display_via_language_environment;
5f5c8ee5
GM
322
323/* Nonzero means we have more than one non-mini-buffer-only frame.
324 Not guaranteed to be accurate except while parsing
325 frame-title-format. */
7bbe686f 326
d39b6696
KH
327int multiple_frames;
328
a2889657
JB
329Lisp_Object Vglobal_mode_string;
330
331/* Marker for where to display an arrow on top of the buffer text. */
5f5c8ee5 332
a2889657
JB
333Lisp_Object Voverlay_arrow_position;
334
5f5c8ee5
GM
335/* String to display for the arrow. Only used on terminal frames. */
336
a2889657
JB
337Lisp_Object Voverlay_arrow_string;
338
5f5c8ee5
GM
339/* Values of those variables at last redisplay. However, if
340 Voverlay_arrow_position is a marker, last_arrow_position is its
341 numerical position. */
342
d45de95b
RS
343static Lisp_Object last_arrow_position, last_arrow_string;
344
5f5c8ee5
GM
345/* Like mode-line-format, but for the title bar on a visible frame. */
346
d39b6696
KH
347Lisp_Object Vframe_title_format;
348
5f5c8ee5
GM
349/* Like mode-line-format, but for the title bar on an iconified frame. */
350
d39b6696
KH
351Lisp_Object Vicon_title_format;
352
08b610e4
RS
353/* List of functions to call when a window's size changes. These
354 functions get one arg, a frame on which one or more windows' sizes
355 have changed. */
5f5c8ee5 356
08b610e4
RS
357static Lisp_Object Vwindow_size_change_functions;
358
cf074754
RS
359Lisp_Object Qmenu_bar_update_hook;
360
a2889657 361/* Nonzero if overlay arrow has been displayed once in this window. */
a2889657 362
5f5c8ee5 363static int overlay_arrow_seen;
ca26e1c8 364
fba9ce76 365/* Nonzero means highlight the region even in nonselected windows. */
fba9ce76 366
5f5c8ee5
GM
367int highlight_nonselected_windows;
368
369/* If cursor motion alone moves point off frame, try scrolling this
370 many lines up or down if that will bring it back. */
371
14510fee 372static int scroll_step;
a2889657 373
5f5c8ee5
GM
374/* Non-0 means scroll just far enough to bring point back on the
375 screen, when appropriate. */
376
0789adb2
RS
377static int scroll_conservatively;
378
5f5c8ee5
GM
379/* Recenter the window whenever point gets within this many lines of
380 the top or bottom of the window. This value is translated into a
381 pixel value by multiplying it with CANON_Y_UNIT, which means that
382 there is really a fixed pixel height scroll margin. */
383
9afd2168
RS
384int scroll_margin;
385
5f5c8ee5
GM
386/* Number of characters of overlap to show, when scrolling a one-line
387 window such as a minibuffer. */
388
010494d0
KH
389static int minibuffer_scroll_overlap;
390
5f5c8ee5
GM
391/* Number of windows showing the buffer of the selected window (or
392 another buffer with the same base buffer). keyboard.c refers to
393 this. */
a2889657 394
a2889657
JB
395int buffer_shared;
396
5f5c8ee5 397/* Vector containing glyphs for an ellipsis `...'. */
a2889657 398
5f5c8ee5 399static Lisp_Object default_invis_vector[3];
a2889657 400
5f5c8ee5 401/* Nonzero means display mode line highlighted. */
a2889657 402
a2889657
JB
403int mode_line_inverse_video;
404
5f5c8ee5
GM
405/* Prompt to display in front of the mini-buffer contents. */
406
8c5b6a0a 407Lisp_Object minibuf_prompt;
a2889657 408
5f5c8ee5
GM
409/* Width of current mini-buffer prompt. Only set after display_line
410 of the line that contains the prompt. */
411
a2889657 412int minibuf_prompt_width;
5f5c8ee5
GM
413int minibuf_prompt_pixel_width;
414
415/* Message to display instead of mini-buffer contents. This is what
416 the functions error and message make, and command echoing uses it
417 as well. It overrides the minibuf_prompt as well as the buffer. */
a2889657 418
a2889657
JB
419char *echo_area_glyphs;
420
5f5c8ee5
GM
421/* A Lisp string to display instead of mini-buffer contents, analogous
422 to echo_area_glyphs. If this is a string, display that string.
423 Otherwise, if echo_area_glyphs is non-null, display that. */
424
425Lisp_Object echo_area_message;
426
427/* This is the length of the message in echo_area_glyphs or
428 echo_area_message. */
429
90adcf20
RS
430int echo_area_glyphs_length;
431
5f5c8ee5
GM
432/* Value of echo_area_glyphs when it was last acted on. If this is
433 nonzero, there is a message on the frame in the mini-buffer and it
434 should be erased as soon as it is no longer requested to appear. */
435
436char *previous_echo_glyphs;
437Lisp_Object previous_echo_area_message;
438static int previous_echo_glyphs_length;
439
440/* This is the window where the echo area message was displayed. It
441 is always a mini-buffer window, but it may not be the same window
442 currently active as a mini-buffer. */
443
73af359d
RS
444Lisp_Object echo_area_window;
445
a3788d53
RS
446/* Nonzero means multibyte characters were enabled when the echo area
447 message was specified. */
5f5c8ee5 448
a3788d53
RS
449int message_enable_multibyte;
450
5f5c8ee5
GM
451/* True if we should redraw the mode lines on the next redisplay. */
452
a2889657
JB
453int update_mode_lines;
454
5f5c8ee5
GM
455/* Smallest number of characters before the gap at any time since last
456 redisplay that finished. Valid for current buffer when
457 try_window_id can be called. */
458
a2889657
JB
459int beg_unchanged;
460
5f5c8ee5
GM
461/* Smallest number of characters after the gap at any time since last
462 redisplay that finished. Valid for current buffer when
463 try_window_id can be called. */
464
a2889657
JB
465int end_unchanged;
466
5f5c8ee5
GM
467/* MODIFF as of last redisplay that finished; if it matches MODIFF,
468 and overlay_unchanged_modified matches OVERLAY_MODIFF, that means
469 beg_unchanged and end_unchanged contain no useful information. */
470
a2889657
JB
471int unchanged_modified;
472
8850a573 473/* OVERLAY_MODIFF as of last redisplay that finished. */
5f5c8ee5 474
8850a573
RS
475int overlay_unchanged_modified;
476
5f5c8ee5
GM
477/* Nonzero if window sizes or contents have changed since last
478 redisplay that finished */
479
a2889657
JB
480int windows_or_buffers_changed;
481
5f5c8ee5
GM
482/* Nonzero after display_mode_line if %l was used and it displayed a
483 line number. */
484
aa6d10fa
RS
485int line_number_displayed;
486
487/* Maximum buffer size for which to display line numbers. */
5f5c8ee5 488
14510fee 489static int line_number_display_limit;
5992c4f7 490
5d121aec
KH
491/* line width to consider when repostioning for line number display */
492
493static int line_number_display_limit_width;
494
5f5c8ee5
GM
495/* Number of lines to keep in the message log buffer. t means
496 infinite. nil means don't log at all. */
497
5992c4f7 498Lisp_Object Vmessage_log_max;
d45de95b 499
5f5c8ee5
GM
500/* A scratch glyph row with contents used for generating truncation
501 glyphs. Also used in direct_output_for_insert. */
12adba34 502
5f5c8ee5
GM
503#define MAX_SCRATCH_GLYPHS 100
504struct glyph_row scratch_glyph_row;
505static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
1adc55de 506
5f5c8ee5
GM
507/* Ascent and height of the last line processed by move_it_to. */
508
509static int last_max_ascent, last_height;
510
511/* The maximum distance to look ahead for text properties. Values
512 that are too small let us call compute_char_face and similar
513 functions too often which is expensive. Values that are too large
514 let us call compute_char_face and alike too often because we
515 might not be interested in text properties that far away. */
516
517#define TEXT_PROP_DISTANCE_LIMIT 100
518
519/* Non-zero means print traces of redisplay if compiled with
520 GLYPH_DEBUG != 0. */
521
522#if GLYPH_DEBUG
523int trace_redisplay_p;
524#endif
525
526/* Value returned from text property handlers (see below). */
527
528enum prop_handled
3c6595e0 529{
5f5c8ee5
GM
530 HANDLED_NORMALLY,
531 HANDLED_RECOMPUTE_PROPS,
532 HANDLED_OVERLAY_STRING_CONSUMED,
533 HANDLED_RETURN
534};
3c6595e0 535
5f5c8ee5
GM
536/* A description of text properties that redisplay is interested
537 in. */
3c6595e0 538
5f5c8ee5
GM
539struct props
540{
541 /* The name of the property. */
542 Lisp_Object *name;
90adcf20 543
5f5c8ee5
GM
544 /* A unique index for the property. */
545 enum prop_idx idx;
546
547 /* A handler function called to set up iterator IT from the property
548 at IT's current position. Value is used to steer handle_stop. */
549 enum prop_handled (*handler) P_ ((struct it *it));
550};
551
552static enum prop_handled handle_face_prop P_ ((struct it *));
553static enum prop_handled handle_invisible_prop P_ ((struct it *));
554static enum prop_handled handle_display_prop P_ ((struct it *));
555static enum prop_handled handle_overlay_change P_ ((struct it *));
556static enum prop_handled handle_fontified_prop P_ ((struct it *));
557
558/* Properties handled by iterators. */
559
560static struct props it_props[] =
5992c4f7 561{
5f5c8ee5
GM
562 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
563 /* Handle `face' before `display' because some sub-properties of
564 `display' need to know the face. */
565 {&Qface, FACE_PROP_IDX, handle_face_prop},
566 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
567 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
568 {NULL, 0, NULL}
569};
5992c4f7 570
5f5c8ee5
GM
571/* Value is the position described by X. If X is a marker, value is
572 the marker_position of X. Otherwise, value is X. */
12adba34 573
5f5c8ee5 574#define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
12adba34 575
5f5c8ee5 576/* Enumeration returned by some move_it_.* functions internally. */
12adba34 577
5f5c8ee5
GM
578enum move_it_result
579{
580 /* Not used. Undefined value. */
581 MOVE_UNDEFINED,
bab29e15 582
5f5c8ee5
GM
583 /* Move ended at the requested buffer position or ZV. */
584 MOVE_POS_MATCH_OR_ZV,
bab29e15 585
5f5c8ee5
GM
586 /* Move ended at the requested X pixel position. */
587 MOVE_X_REACHED,
12adba34 588
5f5c8ee5
GM
589 /* Move within a line ended at the end of a line that must be
590 continued. */
591 MOVE_LINE_CONTINUED,
592
593 /* Move within a line ended at the end of a line that would
594 be displayed truncated. */
595 MOVE_LINE_TRUNCATED,
ff6c30e5 596
5f5c8ee5
GM
597 /* Move within a line ended at a line end. */
598 MOVE_NEWLINE_OR_CR
599};
12adba34 600
ff6c30e5 601
5f5c8ee5
GM
602\f
603/* Function prototypes. */
604
4fdb80f2 605static int string_char_and_length P_ ((unsigned char *, int, int *));
5f5c8ee5
GM
606static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
607 struct text_pos));
608static int compute_window_start_on_continuation_line P_ ((struct window *));
609static Lisp_Object eval_handler P_ ((Lisp_Object));
610static Lisp_Object eval_form P_ ((Lisp_Object));
611static void insert_left_trunc_glyphs P_ ((struct it *));
612static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
613static void extend_face_to_end_of_line P_ ((struct it *));
614static void append_space P_ ((struct it *, int));
615static void make_cursor_line_fully_visible P_ ((struct window *));
616static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
617static int trailing_whitespace_p P_ ((int));
618static int message_log_check_duplicate P_ ((int, int, int, int));
619int invisible_p P_ ((Lisp_Object, Lisp_Object));
620int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
621static void push_it P_ ((struct it *));
622static void pop_it P_ ((struct it *));
623static void sync_frame_with_window_matrix_rows P_ ((struct window *));
624static void redisplay_internal P_ ((int));
625static void echo_area_display P_ ((int));
626static void redisplay_windows P_ ((Lisp_Object));
627static void redisplay_window P_ ((Lisp_Object, int));
628static void update_menu_bar P_ ((struct frame *, int));
629static int try_window_reusing_current_matrix P_ ((struct window *));
630static int try_window_id P_ ((struct window *));
631static int display_line P_ ((struct it *));
632static void display_mode_lines P_ ((struct window *));
633static void display_mode_line P_ ((struct window *, enum face_id,
634 Lisp_Object));
635static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
636static char *decode_mode_spec P_ ((struct window *, char, int, int));
637static void display_menu_bar P_ ((struct window *));
638static int display_count_lines P_ ((int, int, int, int, int *));
639static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
640 int, int, struct it *, int, int, int, int));
641static void compute_line_metrics P_ ((struct it *));
642static void run_redisplay_end_trigger_hook P_ ((struct it *));
643static int get_overlay_strings P_ ((struct it *));
644static void next_overlay_string P_ ((struct it *));
645void set_iterator_to_next P_ ((struct it *));
646static void reseat P_ ((struct it *, struct text_pos, int));
647static void reseat_1 P_ ((struct it *, struct text_pos, int));
648static void back_to_previous_visible_line_start P_ ((struct it *));
649static void reseat_at_previous_visible_line_start P_ ((struct it *));
312246d1 650static void reseat_at_next_visible_line_start P_ ((struct it *, int));
5f5c8ee5
GM
651static int next_element_from_display_vector P_ ((struct it *));
652static int next_element_from_string P_ ((struct it *));
653static int next_element_from_c_string P_ ((struct it *));
654static int next_element_from_buffer P_ ((struct it *));
655static int next_element_from_image P_ ((struct it *));
656static int next_element_from_stretch P_ ((struct it *));
657static void load_overlay_strings P_ ((struct it *));
658static void init_from_display_pos P_ ((struct it *, struct window *,
659 struct display_pos *));
660static void reseat_to_string P_ ((struct it *, unsigned char *,
661 Lisp_Object, int, int, int, int));
662static int charset_at_position P_ ((struct text_pos));
663static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
664 int, int, int));
665void move_it_vertically_backward P_ ((struct it *, int));
666static void init_to_row_start P_ ((struct it *, struct window *,
667 struct glyph_row *));
668static void init_to_row_end P_ ((struct it *, struct window *,
669 struct glyph_row *));
670static void back_to_previous_line_start P_ ((struct it *));
671static void forward_to_next_line_start P_ ((struct it *));
672static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
673 Lisp_Object, int));
674static struct text_pos string_pos P_ ((int, Lisp_Object));
675static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
676static int number_of_chars P_ ((unsigned char *, int));
677static void compute_stop_pos P_ ((struct it *));
678static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
679 Lisp_Object));
680static int face_before_or_after_it_pos P_ ((struct it *, int));
681static int next_overlay_change P_ ((int));
682static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
683 Lisp_Object, struct text_pos *));
684
685#define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
686#define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
ff6c30e5 687
5f5c8ee5 688#ifdef HAVE_WINDOW_SYSTEM
12adba34 689
5f5c8ee5
GM
690static void update_toolbar P_ ((struct frame *, int));
691static void build_desired_toolbar_string P_ ((struct frame *f));
692static int redisplay_toolbar P_ ((struct frame *));
693static void display_toolbar_line P_ ((struct it *));
12adba34 694
5f5c8ee5 695#endif /* HAVE_WINDOW_SYSTEM */
12adba34 696
5f5c8ee5
GM
697\f
698/***********************************************************************
699 Window display dimensions
700 ***********************************************************************/
12adba34 701
5f5c8ee5
GM
702/* Return the window-relative maximum y + 1 for glyph rows displaying
703 text in window W. This is the height of W minus the height of a
704 mode line, if any. */
705
706INLINE int
707window_text_bottom_y (w)
708 struct window *w;
709{
710 struct frame *f = XFRAME (w->frame);
711 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
712
713 if (WINDOW_WANTS_MODELINE_P (w))
714 height -= CURRENT_MODE_LINE_HEIGHT (w);
715 return height;
f88eb0b6
KH
716}
717
f82aff7c 718
5f5c8ee5
GM
719/* Return the pixel width of display area AREA of window W. AREA < 0
720 means return the total width of W, not including bitmap areas to
721 the left and right of the window. */
ff6c30e5 722
5f5c8ee5
GM
723INLINE int
724window_box_width (w, area)
725 struct window *w;
726 int area;
727{
728 struct frame *f = XFRAME (w->frame);
729 int width = XFASTINT (w->width);
730
731 if (!w->pseudo_window_p)
ff6c30e5 732 {
5f5c8ee5
GM
733 width -= FRAME_SCROLL_BAR_WIDTH (f) + 2 * FRAME_FLAGS_AREA_COLS (f);
734
735 if (area == TEXT_AREA)
736 {
737 if (INTEGERP (w->left_margin_width))
738 width -= XFASTINT (w->left_margin_width);
739 if (INTEGERP (w->right_margin_width))
740 width -= XFASTINT (w->right_margin_width);
741 }
742 else if (area == LEFT_MARGIN_AREA)
743 width = (INTEGERP (w->left_margin_width)
744 ? XFASTINT (w->left_margin_width) : 0);
745 else if (area == RIGHT_MARGIN_AREA)
746 width = (INTEGERP (w->right_margin_width)
747 ? XFASTINT (w->right_margin_width) : 0);
ff6c30e5 748 }
5f5c8ee5
GM
749
750 return width * CANON_X_UNIT (f);
ff6c30e5 751}
1adc55de 752
1adc55de 753
5f5c8ee5
GM
754/* Return the pixel height of the display area of window W, not
755 including mode lines of W, if any.. */
f88eb0b6 756
5f5c8ee5
GM
757INLINE int
758window_box_height (w)
759 struct window *w;
f88eb0b6 760{
5f5c8ee5
GM
761 struct frame *f = XFRAME (w->frame);
762 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
763
764 if (WINDOW_WANTS_MODELINE_P (w))
765 height -= CURRENT_MODE_LINE_HEIGHT (w);
766
767 if (WINDOW_WANTS_TOP_LINE_P (w))
768 height -= CURRENT_TOP_LINE_HEIGHT (w);
769
770 return height;
5992c4f7
KH
771}
772
773
5f5c8ee5
GM
774/* Return the frame-relative coordinate of the left edge of display
775 area AREA of window W. AREA < 0 means return the left edge of the
776 whole window, to the right of any bitmap area at the left side of
777 W. */
5992c4f7 778
5f5c8ee5
GM
779INLINE int
780window_box_left (w, area)
781 struct window *w;
782 int area;
90adcf20 783{
5f5c8ee5
GM
784 struct frame *f = XFRAME (w->frame);
785 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
a3788d53 786
5f5c8ee5 787 if (!w->pseudo_window_p)
90adcf20 788 {
5f5c8ee5
GM
789 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
790 + FRAME_FLAGS_AREA_WIDTH (f));
791
792 if (area == TEXT_AREA)
793 x += window_box_width (w, LEFT_MARGIN_AREA);
794 else if (area == RIGHT_MARGIN_AREA)
795 x += (window_box_width (w, LEFT_MARGIN_AREA)
796 + window_box_width (w, TEXT_AREA));
90adcf20 797 }
73af359d 798
5f5c8ee5
GM
799 return x;
800}
90adcf20 801
b6436d4e 802
5f5c8ee5
GM
803/* Return the frame-relative coordinate of the right edge of display
804 area AREA of window W. AREA < 0 means return the left edge of the
805 whole window, to the left of any bitmap area at the right side of
806 W. */
ded34426 807
5f5c8ee5
GM
808INLINE int
809window_box_right (w, area)
810 struct window *w;
811 int area;
812{
813 return window_box_left (w, area) + window_box_width (w, area);
814}
815
816
817/* Get the bounding box of the display area AREA of window W, without
818 mode lines, in frame-relative coordinates. AREA < 0 means the
819 whole window, not including bitmap areas to the left and right of
820 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
821 coordinates of the upper-left corner of the box. Return in
822 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
823
824INLINE void
825window_box (w, area, box_x, box_y, box_width, box_height)
826 struct window *w;
827 int area;
828 int *box_x, *box_y, *box_width, *box_height;
829{
830 struct frame *f = XFRAME (w->frame);
831
832 *box_width = window_box_width (w, area);
833 *box_height = window_box_height (w);
834 *box_x = window_box_left (w, area);
835 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
836 + XFASTINT (w->top) * CANON_Y_UNIT (f));
837 if (WINDOW_WANTS_TOP_LINE_P (w))
838 *box_y += CURRENT_TOP_LINE_HEIGHT (w);
ded34426 839}
1adc55de 840
1adc55de 841
5f5c8ee5
GM
842/* Get the bounding box of the display area AREA of window W, without
843 mode lines. AREA < 0 means the whole window, not including bitmap
844 areas to the left and right of the window. Return in *TOP_LEFT_X
845 and TOP_LEFT_Y the frame-relative pixel coordinates of the
846 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
847 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
848 box. */
ded34426 849
5f5c8ee5
GM
850INLINE void
851window_box_edges (w, area, top_left_x, top_left_y,
852 bottom_right_x, bottom_right_y)
853 struct window *w;
854 int area;
855 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
48ae5f0a 856{
5f5c8ee5
GM
857 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
858 bottom_right_y);
859 *bottom_right_x += *top_left_x;
860 *bottom_right_y += *top_left_y;
48ae5f0a
KH
861}
862
5f5c8ee5
GM
863
864\f
865/***********************************************************************
866 Utilities
867 ***********************************************************************/
868
4fdb80f2
GM
869/* Return the next character from STR which is MAXLEN bytes long.
870 Return in *LEN the length of the character. This is like
871 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
872 we find one, we return a `?', but with the length of the illegal
873 character. */
874
875static INLINE int
7a5b8a93 876string_char_and_length (str, maxlen, len)
4fdb80f2 877 unsigned char *str;
7a5b8a93 878 int maxlen, *len;
4fdb80f2
GM
879{
880 int c;
881
882 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
883 if (!CHAR_VALID_P (c, 1))
884 /* We may not change the length here because other places in Emacs
885 don't use this function, i.e. they silently accept illegal
886 characters. */
887 c = '?';
888
889 return c;
890}
891
892
893
5f5c8ee5
GM
894/* Given a position POS containing a valid character and byte position
895 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
896
897static struct text_pos
898string_pos_nchars_ahead (pos, string, nchars)
899 struct text_pos pos;
900 Lisp_Object string;
901 int nchars;
0b1005ef 902{
5f5c8ee5
GM
903 xassert (STRINGP (string) && nchars >= 0);
904
905 if (STRING_MULTIBYTE (string))
906 {
907 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
908 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
909 int len;
910
911 while (nchars--)
912 {
4fdb80f2 913 string_char_and_length (p, rest, &len);
5f5c8ee5
GM
914 p += len, rest -= len;
915 xassert (rest >= 0);
916 CHARPOS (pos) += 1;
917 BYTEPOS (pos) += len;
918 }
919 }
920 else
921 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
922
923 return pos;
0a9dc68b
RS
924}
925
0a9dc68b 926
5f5c8ee5
GM
927/* Value is the text position, i.e. character and byte position,
928 for character position CHARPOS in STRING. */
929
930static INLINE struct text_pos
931string_pos (charpos, string)
932 int charpos;
0a9dc68b 933 Lisp_Object string;
0a9dc68b 934{
5f5c8ee5
GM
935 struct text_pos pos;
936 xassert (STRINGP (string));
937 xassert (charpos >= 0);
938 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
939 return pos;
940}
941
942
943/* Value is a text position, i.e. character and byte position, for
944 character position CHARPOS in C string S. MULTIBYTE_P non-zero
945 means recognize multibyte characters. */
946
947static struct text_pos
948c_string_pos (charpos, s, multibyte_p)
949 int charpos;
950 unsigned char *s;
951 int multibyte_p;
952{
953 struct text_pos pos;
954
955 xassert (s != NULL);
956 xassert (charpos >= 0);
957
958 if (multibyte_p)
0a9dc68b 959 {
5f5c8ee5
GM
960 int rest = strlen (s), len;
961
962 SET_TEXT_POS (pos, 0, 0);
963 while (charpos--)
0a9dc68b 964 {
4fdb80f2 965 string_char_and_length (s, rest, &len);
5f5c8ee5
GM
966 s += len, rest -= len;
967 xassert (rest >= 0);
968 CHARPOS (pos) += 1;
969 BYTEPOS (pos) += len;
0a9dc68b
RS
970 }
971 }
5f5c8ee5
GM
972 else
973 SET_TEXT_POS (pos, charpos, charpos);
0a9dc68b 974
5f5c8ee5
GM
975 return pos;
976}
0a9dc68b 977
0a9dc68b 978
5f5c8ee5
GM
979/* Value is the number of characters in C string S. MULTIBYTE_P
980 non-zero means recognize multibyte characters. */
0a9dc68b 981
5f5c8ee5
GM
982static int
983number_of_chars (s, multibyte_p)
984 unsigned char *s;
985 int multibyte_p;
986{
987 int nchars;
988
989 if (multibyte_p)
990 {
991 int rest = strlen (s), len;
992 unsigned char *p = (unsigned char *) s;
0a9dc68b 993
5f5c8ee5
GM
994 for (nchars = 0; rest > 0; ++nchars)
995 {
4fdb80f2 996 string_char_and_length (p, rest, &len);
5f5c8ee5 997 rest -= len, p += len;
0a9dc68b
RS
998 }
999 }
5f5c8ee5
GM
1000 else
1001 nchars = strlen (s);
1002
1003 return nchars;
0b1005ef
KH
1004}
1005
5f5c8ee5
GM
1006
1007/* Compute byte position NEWPOS->bytepos corresponding to
1008 NEWPOS->charpos. POS is a known position in string STRING.
1009 NEWPOS->charpos must be >= POS.charpos. */
76412d64 1010
5f5c8ee5
GM
1011static void
1012compute_string_pos (newpos, pos, string)
1013 struct text_pos *newpos, pos;
1014 Lisp_Object string;
76412d64 1015{
5f5c8ee5
GM
1016 xassert (STRINGP (string));
1017 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1018
1019 if (STRING_MULTIBYTE (string))
1020 *newpos = string_pos_nchars_ahead (pos, CHARPOS (*newpos) - CHARPOS (pos),
1021 string);
1022 else
1023 BYTEPOS (*newpos) = CHARPOS (*newpos);
76412d64
RS
1024}
1025
9c74a0dd 1026
5f5c8ee5
GM
1027/* Return the charset of the character at position POS in
1028 current_buffer. */
1adc55de 1029
5f5c8ee5
GM
1030static int
1031charset_at_position (pos)
1032 struct text_pos pos;
a2889657 1033{
5f5c8ee5
GM
1034 int c, multibyte_p;
1035 unsigned char *p = BYTE_POS_ADDR (BYTEPOS (pos));
1036
1037 multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1038 if (multibyte_p)
a2889657 1039 {
5f5c8ee5
GM
1040 int maxlen = ((BYTEPOS (pos) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
1041 - BYTEPOS (pos));
1042 int len;
4fdb80f2 1043 c = string_char_and_length (p, maxlen, &len);
a2889657 1044 }
5f5c8ee5
GM
1045 else
1046 c = *p;
1047
1048 return CHAR_CHARSET (c);
1049}
1050
1051
1052\f
1053/***********************************************************************
1054 Lisp form evaluation
1055 ***********************************************************************/
1056
1057/* Error handler for eval_form. */
1058
1059static Lisp_Object
1060eval_handler (arg)
1061 Lisp_Object arg;
1062{
1063 return Qnil;
1064}
1065
1066
1067/* Evaluate SEXPR and return the result, or nil if something went
1068 wrong. */
1069
1070static Lisp_Object
1071eval_form (sexpr)
1072 Lisp_Object sexpr;
1073{
1074 int count = specpdl_ptr - specpdl;
1075 Lisp_Object val;
1076 specbind (Qinhibit_redisplay, Qt);
1077 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1078 return unbind_to (count, val);
1079}
1080
1081
1082\f
1083/***********************************************************************
1084 Debugging
1085 ***********************************************************************/
1086
1087#if 0
1088
1089/* Define CHECK_IT to perform sanity checks on iterators.
1090 This is for debugging. It is too slow to do unconditionally. */
1091
1092static void
1093check_it (it)
1094 struct it *it;
1095{
1096 if (it->method == next_element_from_string)
a2889657 1097 {
5f5c8ee5
GM
1098 xassert (STRINGP (it->string));
1099 xassert (IT_STRING_CHARPOS (*it) >= 0);
1100 }
1101 else if (it->method == next_element_from_buffer)
1102 {
1103 /* Check that character and byte positions agree. */
1104 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1105 }
73af359d 1106
5f5c8ee5
GM
1107 if (it->dpvec)
1108 xassert (it->current.dpvec_index >= 0);
1109 else
1110 xassert (it->current.dpvec_index < 0);
1111}
1f40cad2 1112
5f5c8ee5
GM
1113#define CHECK_IT(IT) check_it ((IT))
1114
1115#else /* not 0 */
1116
1117#define CHECK_IT(IT) (void) 0
1118
1119#endif /* not 0 */
1120
1121
1122#if GLYPH_DEBUG
1123
1124/* Check that the window end of window W is what we expect it
1125 to be---the last row in the current matrix displaying text. */
1126
1127static void
1128check_window_end (w)
1129 struct window *w;
1130{
1131 if (!MINI_WINDOW_P (w)
1132 && !NILP (w->window_end_valid))
1133 {
1134 struct glyph_row *row;
1135 xassert ((row = MATRIX_ROW (w->current_matrix,
1136 XFASTINT (w->window_end_vpos)),
1137 !row->enabled_p
1138 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1139 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1140 }
1141}
1142
1143#define CHECK_WINDOW_END(W) check_window_end ((W))
1144
1145#else /* not GLYPH_DEBUG */
1146
1147#define CHECK_WINDOW_END(W) (void) 0
1148
1149#endif /* not GLYPH_DEBUG */
1150
1151
1152\f
1153/***********************************************************************
1154 Iterator initialization
1155 ***********************************************************************/
1156
1157/* Initialize IT for displaying current_buffer in window W, starting
1158 at character position CHARPOS. CHARPOS < 0 means that no buffer
1159 position is specified which is useful when the iterator is assigned
1160 a position later. BYTEPOS is the byte position corresponding to
1161 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1162
1163 If ROW is not null, calls to produce_glyphs with IT as parameter
1164 will produce glyphs in that row.
1165
1166 BASE_FACE_ID is the id of a base face to use. It must be one of
1167 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1168 TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
1169 displaying the toolbar.
1170
1171 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1172 TOP_LINE_FACE_ID, the iterator will be initialized to use the
1173 corresponding mode line glyph row of the desired matrix of W. */
1174
1175void
1176init_iterator (it, w, charpos, bytepos, row, base_face_id)
1177 struct it *it;
1178 struct window *w;
1179 int charpos, bytepos;
1180 struct glyph_row *row;
1181 enum face_id base_face_id;
1182{
1183 int highlight_region_p;
1184 Lisp_Object value;
1185
1186 /* Some precondition checks. */
1187 xassert (w != NULL && it != NULL);
1188 xassert (charpos < 0 || current_buffer == XBUFFER (w->buffer));
1189 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1190
1191 /* If face attributes have been changed since the last redisplay,
1192 free realized faces now because they depend on face definitions
1193 that might have changed. */
1194 if (face_change_count)
1195 {
1196 face_change_count = 0;
1197 free_all_realized_faces (Qnil);
1198 }
1199
1200 /* Use one of the mode line rows of W's desired matrix if
1201 appropriate. */
1202 if (row == NULL)
1203 {
1204 if (base_face_id == MODE_LINE_FACE_ID)
1205 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1206 else if (base_face_id == TOP_LINE_FACE_ID)
1207 row = MATRIX_TOP_LINE_ROW (w->desired_matrix);
1208 }
1209
1210 /* Clear IT. */
1211 bzero (it, sizeof *it);
1212 it->current.overlay_string_index = -1;
1213 it->current.dpvec_index = -1;
1214 it->charset = CHARSET_ASCII;
1215 it->base_face_id = base_face_id;
1216
1217 /* The window in which we iterate over current_buffer: */
1218 XSETWINDOW (it->window, w);
1219 it->w = w;
1220 it->f = XFRAME (w->frame);
1221
1222 /* If realized faces have been removed, e.g. because of face
1223 attribute changes of named faces, recompute them. */
1224 if (FRAME_FACE_CACHE (it->f)->used == 0)
1225 recompute_basic_faces (it->f);
1226
1227 /* Should we highlight trailing whitespace? */
1228 value = find_symbol_value (Qshow_trailing_whitespace);
1229 it->show_trailing_whitespace_p
1230 = EQ (value, Qunbound) ? 0 : !NILP (value);
1231
1232 /* Current value of the `space-width', and 'height' properties. */
1233 it->space_width = Qnil;
1234 it->font_height = Qnil;
1235
1236 /* Are control characters displayed as `^C'? */
1237 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1238
1239 /* -1 means everything between a CR and the following line end
1240 is invisible. >0 means lines indented more than this value are
1241 invisible. */
1242 it->selective = (INTEGERP (current_buffer->selective_display)
1243 ? XFASTINT (current_buffer->selective_display)
1244 : (!NILP (current_buffer->selective_display)
1245 ? -1 : 0));
1246 it->selective_display_ellipsis_p
1247 = !NILP (current_buffer->selective_display_ellipses);
1248
1249 /* Display table to use. */
1250 it->dp = window_display_table (w);
1251
1252 /* Are multibyte characters enabled in current_buffer? */
1253 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1254
1255 /* Non-zero if we should highlight the region. */
1256 highlight_region_p
1257 = (!NILP (Vtransient_mark_mode)
1258 && !NILP (current_buffer->mark_active)
1259 && XMARKER (current_buffer->mark)->buffer != 0);
1260
1261 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1262 start and end of a visible region in window IT->w. Set both to
1263 -1 to indicate no region. */
1264 if (highlight_region_p
1265 /* Maybe highlight only in selected window. */
1266 && (/* Either show region everywhere. */
1267 highlight_nonselected_windows
1268 /* Or show region in the selected window. */
1269 || w == XWINDOW (selected_window)
1270 /* Or show the region if we are in the mini-buffer and W is
1271 the window the mini-buffer refers to. */
1272 || (MINI_WINDOW_P (XWINDOW (selected_window))
1273 && w == XWINDOW (Vminibuf_scroll_window))))
1274 {
1275 int charpos = marker_position (current_buffer->mark);
1276 it->region_beg_charpos = min (PT, charpos);
1277 it->region_end_charpos = max (PT, charpos);
1278 }
1279 else
1280 it->region_beg_charpos = it->region_end_charpos = -1;
1281
1282 /* Get the position at which the redisplay_end_trigger hook should
1283 be run, if it is to be run at all. */
1284 if (MARKERP (w->redisplay_end_trigger)
1285 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1286 it->redisplay_end_trigger_charpos
1287 = marker_position (w->redisplay_end_trigger);
1288 else if (INTEGERP (w->redisplay_end_trigger))
1289 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1290
1291 /* Correct bogus values of tab_width. */
1292 it->tab_width = XINT (current_buffer->tab_width);
1293 if (it->tab_width <= 0 || it->tab_width > 1000)
1294 it->tab_width = 8;
1295
1296 /* Are lines in the display truncated? */
1297 it->truncate_lines_p
1298 = (base_face_id != DEFAULT_FACE_ID
1299 || XINT (it->w->hscroll)
1300 || (truncate_partial_width_windows
1301 && !WINDOW_FULL_WIDTH_P (it->w))
1302 || !NILP (current_buffer->truncate_lines));
1303
1304 /* Get dimensions of truncation and continuation glyphs. These are
1305 displayed as bitmaps under X, so we don't need them for such
1306 frames. */
1307 if (!FRAME_WINDOW_P (it->f))
1308 {
1309 if (it->truncate_lines_p)
1310 {
1311 /* We will need the truncation glyph. */
1312 xassert (it->glyph_row == NULL);
1313 produce_special_glyphs (it, IT_TRUNCATION);
1314 it->truncation_pixel_width = it->pixel_width;
1315 }
1316 else
1317 {
1318 /* We will need the continuation glyph. */
1319 xassert (it->glyph_row == NULL);
1320 produce_special_glyphs (it, IT_CONTINUATION);
1321 it->continuation_pixel_width = it->pixel_width;
1322 }
1323
1324 /* Reset these values to zero becaue the produce_special_glyphs
1325 above has changed them. */
1326 it->pixel_width = it->ascent = it->descent = 0;
312246d1 1327 it->phys_ascent = it->phys_descent = 0;
5f5c8ee5
GM
1328 }
1329
1330 /* Set this after getting the dimensions of truncation and
1331 continuation glyphs, so that we don't produce glyphs when calling
1332 produce_special_glyphs, above. */
1333 it->glyph_row = row;
1334 it->area = TEXT_AREA;
1335
1336 /* Get the dimensions of the display area. The display area
1337 consists of the visible window area plus a horizontally scrolled
1338 part to the left of the window. All x-values are relative to the
1339 start of this total display area. */
1340 if (base_face_id != DEFAULT_FACE_ID)
1341 {
1342 /* Mode lines, menu bar in terminal frames. */
1343 it->first_visible_x = 0;
1344 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1345 }
1346 else
1347 {
1348 it->first_visible_x
1349 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1350 it->last_visible_x = (it->first_visible_x
1351 + window_box_width (w, TEXT_AREA));
1352
1353 /* If we truncate lines, leave room for the truncator glyph(s) at
1354 the right margin. Otherwise, leave room for the continuation
1355 glyph(s). Truncation and continuation glyphs are not inserted
1356 for window-based redisplay. */
1357 if (!FRAME_WINDOW_P (it->f))
1358 {
1359 if (it->truncate_lines_p)
1360 it->last_visible_x -= it->truncation_pixel_width;
1361 else
1362 it->last_visible_x -= it->continuation_pixel_width;
1363 }
1364
1365 it->top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
1366 it->current_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w) + w->vscroll;
1367 }
1368
1369 /* Leave room for a border glyph. */
1370 if (!FRAME_WINDOW_P (it->f)
1371 && !WINDOW_RIGHTMOST_P (it->w))
1372 it->last_visible_x -= 1;
1373
1374 it->last_visible_y = window_text_bottom_y (w);
1375
1376 /* For mode lines and alike, arrange for the first glyph having a
1377 left box line if the face specifies a box. */
1378 if (base_face_id != DEFAULT_FACE_ID)
1379 {
1380 struct face *face;
1381
1382 it->face_id = base_face_id;
1383
1384 /* If we have a boxed mode line, make the first character appear
1385 with a left box line. */
1386 face = FACE_FROM_ID (it->f, base_face_id);
1387 if (face->box != FACE_NO_BOX)
1388 it->start_of_box_run_p = 1;
1389 }
1390
1391 /* If a buffer position was specified, set the iterator there,
1392 getting overlays and face properties from that position. */
1393 if (charpos > 0)
1394 {
1395 it->end_charpos = ZV;
1396 it->face_id = -1;
1397 IT_CHARPOS (*it) = charpos;
1398
1399 /* Compute byte position if not specified. */
1400 if (bytepos <= 0)
1401 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1402 else
1403 IT_BYTEPOS (*it) = bytepos;
1404
1405 /* Compute faces etc. */
1406 reseat (it, it->current.pos, 1);
1407 }
1408
1409 CHECK_IT (it);
1410}
1411
1412
1413/* Initialize IT for the display of window W with window start POS. */
1414
1415void
1416start_display (it, w, pos)
1417 struct it *it;
1418 struct window *w;
1419 struct text_pos pos;
1420{
1421 int start_at_line_beg_p;
1422 struct glyph_row *row;
1423 int first_vpos = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
1424 int first_y;
1425
1426 row = w->desired_matrix->rows + first_vpos;
1427 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1428 first_y = it->current_y;
1429
1430 /* If window start is not at a line start, move back to the line
1431 start. This makes sure that we take continuation lines into
1432 account. */
1433 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1434 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1435 if (!start_at_line_beg_p)
1436 reseat_at_previous_visible_line_start (it);
1437
1438#if NO_PROMPT_IN_BUFFER
1439 /* Take the mini-buffer prompt width into account for tab
1440 calculations. */
1441 if (MINI_WINDOW_P (w) && IT_CHARPOS (*it) == BEGV)
1442 {
1443 /* Why is mini-buffer_prompt_width guaranteed to be set here? */
1444 it->prompt_width = minibuf_prompt_pixel_width;
1445 }
1446#endif /* NO_PROMPT_IN_BUFFER */
1447
1448 /* If window start is not at a line start, skip forward to POS to
1449 get the correct continuation_lines_width and current_x. */
1450 if (!start_at_line_beg_p)
1451 {
1452 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1453
1454 /* If lines are continued, this line may end in the middle of a
1455 multi-glyph character (e.g. a control character displayed as
1456 \003, or in the middle of an overlay string). In this case
1457 move_it_to above will not have taken us to the start of
1458 the continuation line but to the end of the continued line. */
1459 if (!it->truncate_lines_p && it->current_x > 0)
1460 {
1461 if (it->current.dpvec_index >= 0
1462 || it->current.overlay_string_index >= 0)
1463 {
1464 set_iterator_to_next (it);
1465 move_it_in_display_line_to (it, -1, -1, 0);
1466 }
1467 it->continuation_lines_width += it->current_x;
1468 }
1469
1470 it->current_y = first_y;
1471 it->vpos = 0;
1472 it->current_x = it->hpos = 0;
1473 }
1474
1475#if 0 /* Don't assert the following because start_display is sometimes
1476 called intentionally with a window start that is not at a
1477 line start. Please leave this code in as a comment. */
1478
1479 /* Window start should be on a line start, now. */
1480 xassert (it->continuation_lines_width
1481 || IT_CHARPOS (it) == BEGV
1482 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1483#endif /* 0 */
1484}
1485
1486
1487/* Initialize IT for stepping through current_buffer in window W,
1488 starting at position POS that includes overlay string and display
1489 vector/ control character translation position information. */
1490
1491static void
1492init_from_display_pos (it, w, pos)
1493 struct it *it;
1494 struct window *w;
1495 struct display_pos *pos;
1496{
1497 /* Keep in mind: the call to reseat in init_iterator skips invisible
1498 text, so we might end up at a position different from POS. This
1499 is only a problem when POS is a row start after a newline and an
1500 overlay starts there with an after-string, and the overlay has an
1501 invisible property. Since we don't skip invisible text in
1502 display_line and elsewhere immediately after consuming the
1503 newline before the row start, such a POS will not be in a string,
1504 but the call to init_iterator below will move us to the
1505 after-string. */
1506 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1507 NULL, DEFAULT_FACE_ID);
1508
1509 /* If position is within an overlay string, set up IT to
1510 the right overlay string. */
1511 if (pos->overlay_string_index >= 0)
1512 {
1513 int relative_index;
1514
1515 /* We already have the first chunk of overlay strings in
1516 IT->overlay_strings. Load more until the one for
1517 pos->overlay_string_index is in IT->overlay_strings. */
1518 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1519 {
1520 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1521 it->current.overlay_string_index = 0;
1522 while (n--)
1523 {
1524 load_overlay_strings (it);
1525 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1526 }
1527 }
1528
1529 it->current.overlay_string_index = pos->overlay_string_index;
1530 relative_index = (it->current.overlay_string_index
1531 % OVERLAY_STRING_CHUNK_SIZE);
1532 it->string = it->overlay_strings[relative_index];
1533 it->current.string_pos = pos->string_pos;
1534 it->method = next_element_from_string;
1535 }
1536 else if (CHARPOS (pos->string_pos) >= 0)
1537 {
1538 /* Recorded position is not in an overlay string, but in another
1539 string. This can only be a string from a `display' property.
1540 IT should already be filled with that string. */
1541 it->current.string_pos = pos->string_pos;
1542 xassert (STRINGP (it->string));
1543 }
1544
1545 /* Restore position in display vector translations or control
1546 character translations. */
1547 if (pos->dpvec_index >= 0)
1548 {
1549 /* This fills IT->dpvec. */
1550 get_next_display_element (it);
1551 xassert (it->dpvec && it->current.dpvec_index == 0);
1552 it->current.dpvec_index = pos->dpvec_index;
1553 }
1554
1555 CHECK_IT (it);
1556}
1557
1558
1559/* Initialize IT for stepping through current_buffer in window W
1560 starting at ROW->start. */
1561
1562static void
1563init_to_row_start (it, w, row)
1564 struct it *it;
1565 struct window *w;
1566 struct glyph_row *row;
1567{
1568 init_from_display_pos (it, w, &row->start);
1569 it->continuation_lines_width = row->continuation_lines_width;
1570 CHECK_IT (it);
1571}
1572
1573
1574/* Initialize IT for stepping through current_buffer in window W
1575 starting in the line following ROW, i.e. starting at ROW->end. */
1576
1577static void
1578init_to_row_end (it, w, row)
1579 struct it *it;
1580 struct window *w;
1581 struct glyph_row *row;
1582{
1583 init_from_display_pos (it, w, &row->end);
1584
1585 if (row->continued_p)
1586 it->continuation_lines_width = (row->continuation_lines_width
1587 + row->pixel_width);
1588 CHECK_IT (it);
1589}
1590
1591
1592
1593\f
1594/***********************************************************************
1595 Text properties
1596 ***********************************************************************/
1597
1598/* Called when IT reaches IT->stop_charpos. Handle text property and
1599 overlay changes. Set IT->stop_charpos to the next position where
1600 to stop. */
1601
1602static void
1603handle_stop (it)
1604 struct it *it;
1605{
1606 enum prop_handled handled;
1607 int handle_overlay_change_p = 1;
1608 struct props *p;
1609
1610 it->dpvec = NULL;
1611 it->current.dpvec_index = -1;
1612
1613 do
1614 {
1615 handled = HANDLED_NORMALLY;
1616
1617 /* Call text property handlers. */
1618 for (p = it_props; p->handler; ++p)
1619 {
1620 handled = p->handler (it);
1621
1622 if (handled == HANDLED_RECOMPUTE_PROPS)
1623 break;
1624 else if (handled == HANDLED_RETURN)
1625 return;
1626 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1627 handle_overlay_change_p = 0;
1628 }
1629
1630 if (handled != HANDLED_RECOMPUTE_PROPS)
1631 {
1632 /* Don't check for overlay strings below when set to deliver
1633 characters from a display vector. */
1634 if (it->method == next_element_from_display_vector)
1635 handle_overlay_change_p = 0;
1636
1637 /* Handle overlay changes. */
1638 if (handle_overlay_change_p)
1639 handled = handle_overlay_change (it);
1640
1641 /* Determine where to stop next. */
1642 if (handled == HANDLED_NORMALLY)
1643 compute_stop_pos (it);
1644 }
1645 }
1646 while (handled == HANDLED_RECOMPUTE_PROPS);
1647}
1648
1649
1650/* Compute IT->stop_charpos from text property and overlay change
1651 information for IT's current position. */
1652
1653static void
1654compute_stop_pos (it)
1655 struct it *it;
1656{
1657 register INTERVAL iv, next_iv;
1658 Lisp_Object object, limit, position;
1659
1660 /* If nowhere else, stop at the end. */
1661 it->stop_charpos = it->end_charpos;
1662
1663 if (STRINGP (it->string))
1664 {
1665 /* Strings are usually short, so don't limit the search for
1666 properties. */
1667 object = it->string;
1668 limit = Qnil;
1669 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1670 }
1671 else
1672 {
1673 int charpos;
1674
1675 /* If next overlay change is in front of the current stop pos
1676 (which is IT->end_charpos), stop there. Note: value of
1677 next_overlay_change is point-max if no overlay change
1678 follows. */
1679 charpos = next_overlay_change (IT_CHARPOS (*it));
1680 if (charpos < it->stop_charpos)
1681 it->stop_charpos = charpos;
1682
1683 /* If showing the region, we have to stop at the region
1684 start or end because the face might change there. */
1685 if (it->region_beg_charpos > 0)
1686 {
1687 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1688 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1689 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1690 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1691 }
1692
1693 /* Set up variables for computing the stop position from text
1694 property changes. */
1695 XSETBUFFER (object, current_buffer);
1696 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1697 XSETFASTINT (position, IT_CHARPOS (*it));
1698
1699 }
1700
1701 /* Get the interval containing IT's position. Value is a null
1702 interval if there isn't such an interval. */
1703 iv = validate_interval_range (object, &position, &position, 0);
1704 if (!NULL_INTERVAL_P (iv))
1705 {
1706 Lisp_Object values_here[LAST_PROP_IDX];
1707 struct props *p;
1708
1709 /* Get properties here. */
1710 for (p = it_props; p->handler; ++p)
1711 values_here[p->idx] = textget (iv->plist, *p->name);
1712
1713 /* Look for an interval following iv that has different
1714 properties. */
1715 for (next_iv = next_interval (iv);
1716 (!NULL_INTERVAL_P (next_iv)
1717 && (NILP (limit)
1718 || XFASTINT (limit) > next_iv->position));
1719 next_iv = next_interval (next_iv))
1720 {
1721 for (p = it_props; p->handler; ++p)
1722 {
1723 Lisp_Object new_value;
1724
1725 new_value = textget (next_iv->plist, *p->name);
1726 if (!EQ (values_here[p->idx], new_value))
1727 break;
1728 }
1729
1730 if (p->handler)
1731 break;
1732 }
1733
1734 if (!NULL_INTERVAL_P (next_iv))
1735 {
1736 if (INTEGERP (limit)
1737 && next_iv->position >= XFASTINT (limit))
1738 /* No text property change up to limit. */
1739 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1740 else
1741 /* Text properties change in next_iv. */
1742 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1743 }
1744 }
1745
1746 xassert (STRINGP (it->string)
1747 || (it->stop_charpos >= BEGV
1748 && it->stop_charpos >= IT_CHARPOS (*it)));
1749}
1750
1751
1752/* Return the position of the next overlay change after POS in
1753 current_buffer. Value is point-max if no overlay change
1754 follows. This is like `next-overlay-change' but doesn't use
1755 xmalloc. */
1756
1757static int
1758next_overlay_change (pos)
1759 int pos;
1760{
1761 int noverlays;
1762 int endpos;
1763 Lisp_Object *overlays;
1764 int len;
1765 int i;
1766
1767 /* Get all overlays at the given position. */
1768 len = 10;
1769 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1770 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1771 if (noverlays > len)
1772 {
1773 len = noverlays;
1774 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1775 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1776 }
1777
1778 /* If any of these overlays ends before endpos,
1779 use its ending point instead. */
1780 for (i = 0; i < noverlays; ++i)
1781 {
1782 Lisp_Object oend;
1783 int oendpos;
1784
1785 oend = OVERLAY_END (overlays[i]);
1786 oendpos = OVERLAY_POSITION (oend);
1787 endpos = min (endpos, oendpos);
1788 }
1789
1790 return endpos;
1791}
1792
1793
1794\f
1795/***********************************************************************
1796 Fontification
1797 ***********************************************************************/
1798
1799/* Handle changes in the `fontified' property of the current buffer by
1800 calling hook functions from Qfontification_functions to fontify
1801 regions of text. */
1802
1803static enum prop_handled
1804handle_fontified_prop (it)
1805 struct it *it;
1806{
1807 Lisp_Object prop, pos;
1808 enum prop_handled handled = HANDLED_NORMALLY;
1809
1810 /* Get the value of the `fontified' property at IT's current buffer
1811 position. (The `fontified' property doesn't have a special
1812 meaning in strings.) If the value is nil, call functions from
1813 Qfontification_functions. */
1814 if (!STRINGP (it->string)
1815 && it->s == NULL
1816 && !NILP (Vfontification_functions)
1817 && (pos = make_number (IT_CHARPOS (*it)),
1818 prop = Fget_char_property (pos, Qfontified, Qnil),
1819 NILP (prop)))
1820 {
1821 Lisp_Object args[2];
1822
1823 /* Run the hook functions. */
1824 args[0] = Qfontification_functions;
1825 args[1] = pos;
1826 Frun_hook_with_args (make_number (2), args);
1827
1828 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1829 something. This avoids an endless loop if they failed to
1830 fontify the text for which reason ever. */
1831 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1832 handled = HANDLED_RECOMPUTE_PROPS;
1833 }
1834
1835 return handled;
1836}
1837
1838
1839\f
1840/***********************************************************************
1841 Faces
1842 ***********************************************************************/
1843
1844/* Set up iterator IT from face properties at its current position.
1845 Called from handle_stop. */
1846
1847static enum prop_handled
1848handle_face_prop (it)
1849 struct it *it;
1850{
1851 int new_face_id, next_stop;
1852
1853 if (!STRINGP (it->string))
1854 {
1855 new_face_id
1856 = face_at_buffer_position (it->w,
1857 IT_CHARPOS (*it),
1858 it->region_beg_charpos,
1859 it->region_end_charpos,
1860 &next_stop,
1861 (IT_CHARPOS (*it)
1862 + TEXT_PROP_DISTANCE_LIMIT),
1863 0);
1864
1865 /* Is this a start of a run of characters with box face?
1866 Caveat: this can be called for a freshly initialized
1867 iterator; face_id is -1 is this case. We know that the new
1868 face will not change until limit, i.e. if the new face has a
1869 box, all characters up to limit will have one. But, as
1870 usual, we don't know whether limit is really the end. */
1871 if (new_face_id != it->face_id)
1872 {
1873 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1874
1875 /* If new face has a box but old face has not, this is
1876 the start of a run of characters with box, i.e. it has
1877 a shadow on the left side. The value of face_id of the
1878 iterator will be -1 if this is the initial call that gets
1879 the face. In this case, we have to look in front of IT's
1880 position and see whether there is a face != new_face_id. */
1881 it->start_of_box_run_p
1882 = (new_face->box != FACE_NO_BOX
1883 && (it->face_id >= 0
1884 || IT_CHARPOS (*it) == BEG
1885 || new_face_id != face_before_it_pos (it)));
1886 it->face_box_p = new_face->box != FACE_NO_BOX;
1887 }
1888 }
1889 else
1890 {
1891 new_face_id
1892 = face_at_string_position (it->w,
1893 it->string,
1894 IT_STRING_CHARPOS (*it),
1895 (it->current.overlay_string_index >= 0
1896 ? IT_CHARPOS (*it)
1897 : 0),
1898 it->region_beg_charpos,
1899 it->region_end_charpos,
1900 &next_stop,
1901 it->base_face_id);
1902
1903#if 0 /* This shouldn't be neccessary. Let's check it. */
1904 /* If IT is used to display a mode line we would really like to
1905 use the mode line face instead of the frame's default face. */
1906 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1907 && new_face_id == DEFAULT_FACE_ID)
1908 new_face_id = MODE_LINE_FACE_ID;
1909#endif
1910
1911 /* Is this a start of a run of characters with box? Caveat:
1912 this can be called for a freshly allocated iterator; face_id
1913 is -1 is this case. We know that the new face will not
1914 change until the next check pos, i.e. if the new face has a
1915 box, all characters up to that position will have a
1916 box. But, as usual, we don't know whether that position
1917 is really the end. */
1918 if (new_face_id != it->face_id)
1919 {
1920 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1921 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1922
1923 /* If new face has a box but old face hasn't, this is the
1924 start of a run of characters with box, i.e. it has a
1925 shadow on the left side. */
1926 it->start_of_box_run_p
1927 = new_face->box && (old_face == NULL || !old_face->box);
1928 it->face_box_p = new_face->box != FACE_NO_BOX;
1929 }
1930 }
1931
1932 it->face_id = new_face_id;
1933 it->charset = CHARSET_ASCII;
1934 return HANDLED_NORMALLY;
1935}
1936
1937
1938/* Compute the face one character before or after the current position
1939 of IT. BEFORE_P non-zero means get the face in front of IT's
1940 position. Value is the id of the face. */
1941
1942static int
1943face_before_or_after_it_pos (it, before_p)
1944 struct it *it;
1945 int before_p;
1946{
1947 int face_id, limit;
1948 int next_check_charpos;
1949 struct text_pos pos;
1950
1951 xassert (it->s == NULL);
1952
1953 if (STRINGP (it->string))
1954 {
1955 /* No face change past the end of the string (for the case
1956 we are padding with spaces). No face change before the
1957 string start. */
1958 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1959 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1960 return it->face_id;
1961
1962 /* Set pos to the position before or after IT's current position. */
1963 if (before_p)
1964 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1965 else
1966 pos = string_pos (IT_STRING_CHARPOS (*it) + 1, it->string);
1967
1968 /* Get the face for ASCII, or unibyte. */
1969 face_id
1970 = face_at_string_position (it->w,
1971 it->string,
1972 CHARPOS (pos),
1973 (it->current.overlay_string_index >= 0
1974 ? IT_CHARPOS (*it)
1975 : 0),
1976 it->region_beg_charpos,
1977 it->region_end_charpos,
1978 &next_check_charpos,
1979 it->base_face_id);
1980
1981 /* Correct the face for charsets different from ASCII. Do it
1982 for the multibyte case only. The face returned above is
1983 suitable for unibyte text if IT->string is unibyte. */
1984 if (STRING_MULTIBYTE (it->string))
1985 {
1986 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1987 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1988 int c, len, charset;
1989
4fdb80f2 1990 c = string_char_and_length (p, rest, &len);
5f5c8ee5
GM
1991 charset = CHAR_CHARSET (c);
1992 if (charset != CHARSET_ASCII)
1993 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
1994 }
1995 }
1996 else
1997 {
70851746
GM
1998 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1999 || (IT_CHARPOS (*it) <= BEGV && before_p))
2000 return it->face_id;
2001
5f5c8ee5
GM
2002 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2003 pos = it->current.pos;
2004
2005 if (before_p)
2006 DEC_TEXT_POS (pos);
2007 else
2008 INC_TEXT_POS (pos);
70851746 2009
5f5c8ee5
GM
2010 /* Determine face for CHARSET_ASCII, or unibyte. */
2011 face_id = face_at_buffer_position (it->w,
2012 CHARPOS (pos),
2013 it->region_beg_charpos,
2014 it->region_end_charpos,
2015 &next_check_charpos,
2016 limit, 0);
2017
2018 /* Correct the face for charsets different from ASCII. Do it
2019 for the multibyte case only. The face returned above is
2020 suitable for unibyte text if current_buffer is unibyte. */
2021 if (it->multibyte_p)
2022 {
2023 int charset = charset_at_position (pos);
2024 if (charset != CHARSET_ASCII)
2025 face_id = FACE_FOR_CHARSET (it->f, face_id, charset);
2026 }
2027 }
2028
2029 return face_id;
2030}
2031
2032
2033\f
2034/***********************************************************************
2035 Invisible text
2036 ***********************************************************************/
2037
2038/* Set up iterator IT from invisible properties at its current
2039 position. Called from handle_stop. */
2040
2041static enum prop_handled
2042handle_invisible_prop (it)
2043 struct it *it;
2044{
2045 enum prop_handled handled = HANDLED_NORMALLY;
2046
2047 if (STRINGP (it->string))
2048 {
2049 extern Lisp_Object Qinvisible;
2050 Lisp_Object prop, end_charpos, limit, charpos;
2051
2052 /* Get the value of the invisible text property at the
2053 current position. Value will be nil if there is no such
2054 property. */
2055 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2056 prop = Fget_text_property (charpos, Qinvisible, it->string);
2057
2058 if (!NILP (prop))
2059 {
2060 handled = HANDLED_RECOMPUTE_PROPS;
2061
2062 /* Get the position at which the next change of the
2063 invisible text property can be found in IT->string.
2064 Value will be nil if the property value is the same for
2065 all the rest of IT->string. */
2066 XSETINT (limit, XSTRING (it->string)->size);
2067 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2068 it->string, limit);
2069
2070 /* Text at current position is invisible. The next
2071 change in the property is at position end_charpos.
2072 Move IT's current position to that position. */
2073 if (INTEGERP (end_charpos)
2074 && XFASTINT (end_charpos) < XFASTINT (limit))
2075 {
2076 struct text_pos old;
2077 old = it->current.string_pos;
2078 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2079 compute_string_pos (&it->current.string_pos, old, it->string);
2080 }
2081 else
2082 {
2083 /* The rest of the string is invisible. If this is an
2084 overlay string, proceed with the next overlay string
2085 or whatever comes and return a character from there. */
2086 if (it->current.overlay_string_index >= 0)
2087 {
2088 next_overlay_string (it);
2089 /* Don't check for overlay strings when we just
2090 finished processing them. */
2091 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2092 }
2093 else
2094 {
2095 struct Lisp_String *s = XSTRING (it->string);
2096 IT_STRING_CHARPOS (*it) = s->size;
2097 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2098 }
2099 }
2100 }
2101 }
2102 else
2103 {
2104 int visible_p, newpos, next_stop;
2105 Lisp_Object pos, prop;
2106
2107 /* First of all, is there invisible text at this position? */
2108 XSETFASTINT (pos, IT_CHARPOS (*it));
2109 prop = Fget_char_property (pos, Qinvisible, it->window);
2110
2111 /* If we are on invisible text, skip over it. */
2112 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2113 {
2114 /* Record whether we have to display an ellipsis for the
2115 invisible text. */
2116 int display_ellipsis_p
2117 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2118
2119 handled = HANDLED_RECOMPUTE_PROPS;
2120
2121 /* Loop skipping over invisible text. The loop is left at
2122 ZV or with IT on the first char being visible again. */
2123 do
2124 {
2125 /* Try to skip some invisible text. Return value is the
2126 position reached which can be equal to IT's position
2127 if there is nothing invisible here. This skips both
2128 over invisible text properties and overlays with
2129 invisible property. */
2130 newpos = skip_invisible (IT_CHARPOS (*it),
2131 &next_stop, ZV, it->window);
2132
2133 /* If we skipped nothing at all we weren't at invisible
2134 text in the first place. If everything to the end of
2135 the buffer was skipped, end the loop. */
2136 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2137 visible_p = 1;
2138 else
2139 {
2140 /* We skipped some characters but not necessarily
2141 all there are. Check if we ended up on visible
2142 text. Fget_char_property returns the property of
2143 the char before the given position, i.e. if we
2144 get visible_p = 1, this means that the char at
2145 newpos is visible. */
2146 XSETFASTINT (pos, newpos);
2147 prop = Fget_char_property (pos, Qinvisible, it->window);
2148 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2149 }
2150
2151 /* If we ended up on invisible text, proceed to
2152 skip starting with next_stop. */
2153 if (!visible_p)
2154 IT_CHARPOS (*it) = next_stop;
2155 }
2156 while (!visible_p);
2157
2158 /* The position newpos is now either ZV or on visible text. */
2159 IT_CHARPOS (*it) = newpos;
2160 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2161
2162 /* Maybe return `...' next for the end of the invisible text. */
2163 if (display_ellipsis_p)
2164 {
2165 if (it->dp
2166 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2167 {
2168 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2169 it->dpvec = v->contents;
2170 it->dpend = v->contents + v->size;
2171 }
2172 else
2173 {
2174 /* Default `...'. */
2175 it->dpvec = default_invis_vector;
2176 it->dpend = default_invis_vector + 3;
2177 }
2178
2179 /* The ellipsis display does not replace the display of
2180 the character at the new position. Indicate this by
2181 setting IT->dpvec_char_len to zero. */
2182 it->dpvec_char_len = 0;
2183
2184 it->current.dpvec_index = 0;
2185 it->method = next_element_from_display_vector;
2186 }
2187 }
2188 }
2189
2190 return handled;
2191}
2192
2193
2194\f
2195/***********************************************************************
2196 'display' property
2197 ***********************************************************************/
2198
2199/* Set up iterator IT from `display' property at its current position.
2200 Called from handle_stop. */
2201
2202static enum prop_handled
2203handle_display_prop (it)
2204 struct it *it;
2205{
2206 Lisp_Object prop, object;
2207 struct text_pos *position;
2208 int space_or_image_found_p;
2209
2210 if (STRINGP (it->string))
2211 {
2212 object = it->string;
2213 position = &it->current.string_pos;
2214 }
2215 else
2216 {
2217 object = Qnil;
2218 position = &it->current.pos;
2219 }
2220
2221 /* Reset those iterator values set from display property values. */
2222 it->font_height = Qnil;
2223 it->space_width = Qnil;
2224 it->voffset = 0;
2225
2226 /* We don't support recursive `display' properties, i.e. string
2227 values that have a string `display' property, that have a string
2228 `display' property etc. */
2229 if (!it->string_from_display_prop_p)
2230 it->area = TEXT_AREA;
2231
2232 prop = Fget_char_property (make_number (position->charpos),
2233 Qdisplay, object);
2234 if (NILP (prop))
2235 return HANDLED_NORMALLY;
2236
2237 space_or_image_found_p = 0;
2238 if (CONSP (prop) && CONSP (XCAR (prop)))
2239 {
2240 while (CONSP (prop))
2241 {
2242 if (handle_single_display_prop (it, XCAR (prop), object, position))
2243 space_or_image_found_p = 1;
2244 prop = XCDR (prop);
2245 }
2246 }
2247 else if (VECTORP (prop))
2248 {
2249 int i;
2250 for (i = 0; i < XVECTOR (prop)->size; ++i)
2251 if (handle_single_display_prop (it, XVECTOR (prop)->contents[i],
2252 object, position))
2253 space_or_image_found_p = 1;
2254 }
2255 else
2256 {
2257 if (handle_single_display_prop (it, prop, object, position))
2258 space_or_image_found_p = 1;
2259 }
2260
2261 return space_or_image_found_p ? HANDLED_RETURN : HANDLED_NORMALLY;
2262}
2263
2264
2265/* Value is the position of the end of the `display' property stating
2266 at START_POS in OBJECT. */
2267
2268static struct text_pos
2269display_prop_end (it, object, start_pos)
2270 struct it *it;
2271 Lisp_Object object;
2272 struct text_pos start_pos;
2273{
2274 Lisp_Object end;
2275 struct text_pos end_pos;
2276
2277 /* Characters having this form of property are not displayed, so
2278 we have to find the end of the property. */
2279 end = Fnext_single_property_change (make_number (start_pos.charpos),
2280 Qdisplay, object, Qnil);
2281 if (NILP (end))
2282 {
2283 /* A nil value of `end' means there are no changes of the
2284 property to the end of the buffer or string. */
2285 if (it->current.overlay_string_index >= 0)
2286 end_pos.charpos = XSTRING (it->string)->size;
2287 else
2288 end_pos.charpos = it->end_charpos;
2289 }
2290 else
2291 end_pos.charpos = XFASTINT (end);
2292
2293 if (STRINGP (it->string))
2294 compute_string_pos (&end_pos, start_pos, it->string);
2295 else
2296 end_pos.bytepos = CHAR_TO_BYTE (end_pos.charpos);
2297
2298 return end_pos;
2299}
2300
2301
2302/* Set up IT from a single `display' sub-property value PROP. OBJECT
2303 is the object in which the `display' property was found. *POSITION
2304 is the position at which it was found.
2305
2306 If PROP is a `space' or `image' sub-property, set *POSITION to the
2307 end position of the `display' property.
2308
2309 Value is non-zero if a `space' or `image' property value was found. */
2310
2311static int
2312handle_single_display_prop (it, prop, object, position)
2313 struct it *it;
2314 Lisp_Object prop;
2315 Lisp_Object object;
2316 struct text_pos *position;
2317{
2318 Lisp_Object value;
2319 int space_or_image_found_p = 0;
2320
2321 Lisp_Object form;
2322
2323 /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
2324 evaluated. If the result is nil, VALUE is ignored. */
2325 form = Qt;
2326 if (CONSP (prop) && EQ (XCAR (prop), QCwhen))
2327 {
2328 prop = XCDR (prop);
2329 if (!CONSP (prop))
2330 return 0;
2331 form = XCAR (prop);
2332 prop = XCDR (prop);
2333 if (!CONSP (prop))
2334 return 0;
2335 prop = XCAR (prop);
2336 }
2337
2338 if (!NILP (form) && !EQ (form, Qt))
2339 {
2340 struct gcpro gcpro1;
2341 struct text_pos end_pos, pt;
2342
2343 end_pos = display_prop_end (it, object, *position);
2344 GCPRO1 (form);
2345
2346 /* Temporarily set point to the end position, and then evaluate
2347 the form. This makes `(eolp)' work as FORM. */
2348 CHARPOS (pt) = PT;
2349 BYTEPOS (pt) = PT_BYTE;
2350 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2351 form = eval_form (form);
2352 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2353 UNGCPRO;
2354 }
2355
2356 if (NILP (form))
2357 return 0;
2358
2359 if (CONSP (prop)
2360 && EQ (XCAR (prop), Qheight)
2361 && CONSP (XCDR (prop)))
2362 {
2363 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2364 return 0;
2365
2366 /* `(height HEIGHT)'. */
2367 it->font_height = XCAR (XCDR (prop));
2368 if (!NILP (it->font_height))
2369 {
2370 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2371 int new_height = -1;
2372
2373 if (CONSP (it->font_height)
2374 && (EQ (XCAR (it->font_height), Qplus)
2375 || EQ (XCAR (it->font_height), Qminus))
2376 && CONSP (XCDR (it->font_height))
2377 && INTEGERP (XCAR (XCDR (it->font_height))))
2378 {
2379 /* `(+ N)' or `(- N)' where N is an integer. */
2380 int steps = XINT (XCAR (XCDR (it->font_height)));
2381 if (EQ (XCAR (it->font_height), Qplus))
2382 steps = - steps;
2383 it->face_id = smaller_face (it->f, it->face_id, steps);
2384 }
2385 else if (SYMBOLP (it->font_height))
2386 {
2387 /* Call function with current height as argument.
2388 Value is the new height. */
2389 Lisp_Object form, height;
2390 struct gcpro gcpro1;
2391
2392 height = face->lface[LFACE_HEIGHT_INDEX];
2393 form = Fcons (it->font_height, Fcons (height, Qnil));
2394 GCPRO1 (form);
2395 height = eval_form (form);
2396 if (NUMBERP (height))
2397 new_height = XFLOATINT (height);
2398 UNGCPRO;
2399 }
2400 else if (NUMBERP (it->font_height))
2401 {
2402 /* Value is a multiple of the canonical char height. */
2403 struct face *face;
2404
2405 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2406 new_height = (XFLOATINT (it->font_height)
2407 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2408 }
2409 else
2410 {
2411 /* Evaluate IT->font_height with `height' bound to the
2412 current specified height to get the new height. */
2413 Lisp_Object value;
2414 int count = specpdl_ptr - specpdl;
2415
2416 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2417 value = eval_form (it->font_height);
2418 unbind_to (count, Qnil);
2419
2420 if (NUMBERP (value))
2421 new_height = XFLOATINT (value);
2422 }
2423
2424 if (new_height > 0)
2425 it->face_id = face_with_height (it->f, it->face_id, new_height);
2426 }
2427 }
2428 else if (CONSP (prop)
2429 && EQ (XCAR (prop), Qspace_width)
2430 && CONSP (XCDR (prop)))
2431 {
2432 /* `(space_width WIDTH)'. */
2433 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2434 return 0;
2435
2436 value = XCAR (XCDR (prop));
2437 if (NUMBERP (value) && XFLOATINT (value) > 0)
2438 it->space_width = value;
2439 }
2440 else if (CONSP (prop)
2441 && EQ (XCAR (prop), Qraise)
2442 && CONSP (XCDR (prop)))
2443 {
2444#ifdef HAVE_WINDOW_SYSTEM
2445 /* `(raise FACTOR)'. */
2446 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2447 return 0;
2448
2449 value = XCAR (XCDR (prop));
2450 if (NUMBERP (value))
2451 {
2452 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2453 it->voffset = - (XFLOATINT (value)
2454 * (face->font->ascent + face->font->descent));
2455 }
2456#endif /* HAVE_WINDOW_SYSTEM */
2457 }
2458 else if (!it->string_from_display_prop_p)
2459 {
2460 /* `(left-margin VALUE)' or `(right-margin VALUE)
2461 or `(nil VALUE)' or VALUE. */
2462 Lisp_Object location, value;
2463 struct text_pos start_pos;
2464 int valid_p;
2465
2466 /* Characters having this form of property are not displayed, so
2467 we have to find the end of the property. */
2468 space_or_image_found_p = 1;
2469 start_pos = *position;
2470 *position = display_prop_end (it, object, start_pos);
2471
2472 /* Let's stop at the new position and assume that all
2473 text properties change there. */
2474 it->stop_charpos = position->charpos;
2475
2476 if (CONSP (prop)
2477 && !EQ (XCAR (prop), Qspace)
2478 && !EQ (XCAR (prop), Qimage))
2479 {
2480 location = XCAR (prop);
2481 value = XCDR (prop);
2482 }
2483 else
2484 {
2485 location = Qnil;
2486 value = prop;
2487 }
2488
2489#ifdef HAVE_WINDOW_SYSTEM
2490 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2491 valid_p = STRINGP (value);
2492 else
2493 valid_p = (STRINGP (value)
2494 || (CONSP (value) && EQ (XCAR (value), Qspace))
2495 || valid_image_p (value));
2496#else /* not HAVE_WINDOW_SYSTEM */
2497 valid_p = STRINGP (value);
2498#endif /* not HAVE_WINDOW_SYSTEM */
2499
2500 if ((EQ (location, Qleft_margin)
2501 || EQ (location, Qright_margin)
2502 || NILP (location))
2503 && valid_p)
2504 {
2505 /* Save current settings of IT so that we can restore them
2506 when we are finished with the glyph property value. */
2507 push_it (it);
2508
2509 if (NILP (location))
2510 it->area = TEXT_AREA;
2511 else if (EQ (location, Qleft_margin))
2512 it->area = LEFT_MARGIN_AREA;
2513 else
2514 it->area = RIGHT_MARGIN_AREA;
2515
2516 if (STRINGP (value))
2517 {
2518 it->string = value;
2519 it->multibyte_p = STRING_MULTIBYTE (it->string);
2520 it->current.overlay_string_index = -1;
2521 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2522 it->end_charpos = it->string_nchars
2523 = XSTRING (it->string)->size;
2524 it->method = next_element_from_string;
2525 it->stop_charpos = 0;
2526 it->string_from_display_prop_p = 1;
2527 }
2528 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2529 {
2530 it->method = next_element_from_stretch;
2531 it->object = value;
2532 it->current.pos = it->position = start_pos;
2533 }
2534#ifdef HAVE_WINDOW_SYSTEM
2535 else
2536 {
2537 it->what = IT_IMAGE;
2538 it->image_id = lookup_image (it->f, value);
2539 it->position = start_pos;
2540 it->object = NILP (object) ? it->w->buffer : object;
2541 it->method = next_element_from_image;
2542
2543 /* Say that we don't have consumed the characters with
2544 `display' property yet. The call to pop_it in
2545 set_iterator_to_next will clean this up. */
2546 *position = start_pos;
2547 }
2548#endif /* HAVE_WINDOW_SYSTEM */
2549 }
2550 }
2551
2552 return space_or_image_found_p;
2553}
2554
2555
2556\f
2557/***********************************************************************
2558 Overlay strings
2559 ***********************************************************************/
2560
2561/* The following structure is used to record overlay strings for
2562 later sorting in load_overlay_strings. */
2563
2564struct overlay_entry
2565{
2566 Lisp_Object string;
2567 int priority;
2568 int after_string_p;
2569};
2570
2571
2572/* Set up iterator IT from overlay strings at its current position.
2573 Called from handle_stop. */
2574
2575static enum prop_handled
2576handle_overlay_change (it)
2577 struct it *it;
2578{
2579 /* Overlays are handled in current_buffer only. */
2580 if (STRINGP (it->string))
2581 return HANDLED_NORMALLY;
2582 else
2583 return (get_overlay_strings (it)
2584 ? HANDLED_RECOMPUTE_PROPS
2585 : HANDLED_NORMALLY);
2586}
2587
2588
2589/* Set up the next overlay string for delivery by IT, if there is an
2590 overlay string to deliver. Called by set_iterator_to_next when the
2591 end of the current overlay string is reached. If there are more
2592 overlay strings to display, IT->string and
2593 IT->current.overlay_string_index are set appropriately here.
2594 Otherwise IT->string is set to nil. */
2595
2596static void
2597next_overlay_string (it)
2598 struct it *it;
2599{
2600 ++it->current.overlay_string_index;
2601 if (it->current.overlay_string_index == it->n_overlay_strings)
2602 {
2603 /* No more overlay strings. Restore IT's settings to what
2604 they were before overlay strings were processed, and
2605 continue to deliver from current_buffer. */
2606 pop_it (it);
2607 xassert (it->stop_charpos >= BEGV
2608 && it->stop_charpos <= it->end_charpos);
2609 it->string = Qnil;
2610 it->current.overlay_string_index = -1;
2611 SET_TEXT_POS (it->current.string_pos, -1, -1);
2612 it->n_overlay_strings = 0;
2613 it->method = next_element_from_buffer;
2614 }
2615 else
2616 {
2617 /* There are more overlay strings to process. If
2618 IT->current.overlay_string_index has advanced to a position
2619 where we must load IT->overlay_strings with more strings, do
2620 it. */
2621 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2622
2623 if (it->current.overlay_string_index && i == 0)
2624 load_overlay_strings (it);
2625
2626 /* Initialize IT to deliver display elements from the overlay
2627 string. */
2628 it->string = it->overlay_strings[i];
2629 it->multibyte_p = STRING_MULTIBYTE (it->string);
2630 SET_TEXT_POS (it->current.string_pos, 0, 0);
2631 it->method = next_element_from_string;
2632 it->stop_charpos = 0;
2633 }
2634
2635 CHECK_IT (it);
2636}
2637
2638
2639/* Compare two overlay_entry structures E1 and E2. Used as a
2640 comparison function for qsort in load_overlay_strings. Overlay
2641 strings for the same position are sorted so that
2642
2643 1. All after-strings come in front of before-strings.
2644
2645 2. Within after-strings, strings are sorted so that overlay strings
2646 from overlays with higher priorities come first.
2647
2648 2. Within before-strings, strings are sorted so that overlay
2649 strings from overlays with higher priorities come last.
2650
2651 Value is analogous to strcmp. */
2652
2653
2654static int
2655compare_overlay_entries (e1, e2)
2656 void *e1, *e2;
2657{
2658 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2659 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2660 int result;
2661
2662 if (entry1->after_string_p != entry2->after_string_p)
2663 /* Let after-strings appear in front of before-strings. */
2664 result = entry1->after_string_p ? -1 : 1;
2665 else if (entry1->after_string_p)
2666 /* After-strings sorted in order of decreasing priority. */
2667 result = entry2->priority - entry1->priority;
2668 else
2669 /* Before-strings sorted in order of increasing priority. */
2670 result = entry1->priority - entry2->priority;
2671
2672 return result;
2673}
2674
2675
2676/* Load the vector IT->overlay_strings with overlay strings from IT's
2677 current buffer position. Set IT->n_overlays to the total number of
2678 overlay strings found.
2679
2680 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2681 a time. On entry into load_overlay_strings,
2682 IT->current.overlay_string_index gives the number of overlay
2683 strings that have already been loaded by previous calls to this
2684 function.
2685
2686 Overlay strings are sorted so that after-string strings come in
2687 front of before-string strings. Within before and after-strings,
2688 strings are sorted by overlay priority. See also function
2689 compare_overlay_entries. */
2690
2691static void
2692load_overlay_strings (it)
2693 struct it *it;
2694{
2695 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2696 Lisp_Object ov, overlay, window, str;
2697 int start, end;
2698 int size = 20;
2699 int n = 0, i, j;
2700 struct overlay_entry *entries
2701 = (struct overlay_entry *) alloca (size * sizeof *entries);
2702
2703 /* Append the overlay string STRING of overlay OVERLAY to vector
2704 `entries' which has size `size' and currently contains `n'
2705 elements. AFTER_P non-zero means STRING is an after-string of
2706 OVERLAY. */
2707#define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2708 do \
2709 { \
2710 Lisp_Object priority; \
2711 \
2712 if (n == size) \
2713 { \
2714 int new_size = 2 * size; \
2715 struct overlay_entry *old = entries; \
2716 entries = \
2717 (struct overlay_entry *) alloca (new_size \
2718 * sizeof *entries); \
2719 bcopy (old, entries, size * sizeof *entries); \
2720 size = new_size; \
2721 } \
2722 \
2723 entries[n].string = (STRING); \
2724 priority = Foverlay_get ((OVERLAY), Qpriority); \
2725 entries[n].priority \
2726 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2727 entries[n].after_string_p = (AFTER_P); \
2728 ++n; \
2729 } \
2730 while (0)
2731
2732 /* Process overlay before the overlay center. */
2733 for (ov = current_buffer->overlays_before;
2734 CONSP (ov);
2735 ov = XCONS (ov)->cdr)
2736 {
2737 overlay = XCONS (ov)->car;
2738 xassert (OVERLAYP (overlay));
2739 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2740 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2741
2742 if (end < IT_CHARPOS (*it))
2743 break;
2744
2745 /* Skip this overlay if it doesn't start or end at IT's current
2746 position. */
2747 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2748 continue;
2749
2750 /* Skip this overlay if it doesn't apply to IT->w. */
2751 window = Foverlay_get (overlay, Qwindow);
2752 if (WINDOWP (window) && XWINDOW (window) != it->w)
2753 continue;
2754
2755 /* If overlay has a non-empty before-string, record it. */
2756 if (start == IT_CHARPOS (*it)
2757 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2758 && XSTRING (str)->size)
2759 RECORD_OVERLAY_STRING (overlay, str, 0);
2760
2761 /* If overlay has a non-empty after-string, record it. */
2762 if (end == IT_CHARPOS (*it)
2763 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2764 && XSTRING (str)->size)
2765 RECORD_OVERLAY_STRING (overlay, str, 1);
2766 }
2767
2768 /* Process overlays after the overlay center. */
2769 for (ov = current_buffer->overlays_after;
2770 CONSP (ov);
2771 ov = XCONS (ov)->cdr)
2772 {
2773 overlay = XCONS (ov)->car;
2774 xassert (OVERLAYP (overlay));
2775 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2776 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2777
2778 if (start > IT_CHARPOS (*it))
2779 break;
2780
2781 /* Skip this overlay if it doesn't start or end at IT's current
2782 position. */
2783 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2784 continue;
2785
2786 /* Skip this overlay if it doesn't apply to IT->w. */
2787 window = Foverlay_get (overlay, Qwindow);
2788 if (WINDOWP (window) && XWINDOW (window) != it->w)
2789 continue;
2790
2791 /* If overlay has a non-empty before-string, record it. */
2792 if (start == IT_CHARPOS (*it)
2793 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2794 && XSTRING (str)->size)
2795 RECORD_OVERLAY_STRING (overlay, str, 0);
2796
2797 /* If overlay has a non-empty after-string, record it. */
2798 if (end == IT_CHARPOS (*it)
2799 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2800 && XSTRING (str)->size)
2801 RECORD_OVERLAY_STRING (overlay, str, 1);
2802 }
2803
2804#undef RECORD_OVERLAY_STRING
2805
2806 /* Sort entries. */
2807 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2808
2809 /* Record the total number of strings to process. */
2810 it->n_overlay_strings = n;
2811
2812 /* IT->current.overlay_string_index is the number of overlay strings
2813 that have already been consumed by IT. Copy some of the
2814 remaining overlay strings to IT->overlay_strings. */
2815 i = 0;
2816 j = it->current.overlay_string_index;
2817 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2818 it->overlay_strings[i++] = entries[j++].string;
2819
2820 CHECK_IT (it);
2821}
2822
2823
2824/* Get the first chunk of overlay strings at IT's current buffer
2825 position. Value is non-zero if at least one overlay string was
2826 found. */
2827
2828static int
2829get_overlay_strings (it)
2830 struct it *it;
2831{
2832 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2833 process. This fills IT->overlay_strings with strings, and sets
2834 IT->n_overlay_strings to the total number of strings to process.
2835 IT->pos.overlay_string_index has to be set temporarily to zero
2836 because load_overlay_strings needs this; it must be set to -1
2837 when no overlay strings are found because a zero value would
2838 indicate a position in the first overlay string. */
2839 it->current.overlay_string_index = 0;
2840 load_overlay_strings (it);
2841
2842 /* If we found overlay strings, set up IT to deliver display
2843 elements from the first one. Otherwise set up IT to deliver
2844 from current_buffer. */
2845 if (it->n_overlay_strings)
2846 {
2847 /* Make sure we know settings in current_buffer, so that we can
2848 restore meaningful values when we're done with the overlay
2849 strings. */
2850 compute_stop_pos (it);
2851 xassert (it->face_id >= 0);
2852
2853 /* Save IT's settings. They are restored after all overlay
2854 strings have been processed. */
2855 xassert (it->sp == 0);
2856 push_it (it);
2857
2858 /* Set up IT to deliver display elements from the first overlay
2859 string. */
2860 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2861 it->stop_charpos = 0;
2862 it->string = it->overlay_strings[0];
2863 it->multibyte_p = STRING_MULTIBYTE (it->string);
2864 xassert (STRINGP (it->string));
2865 it->method = next_element_from_string;
2866 }
2867 else
2868 {
2869 it->string = Qnil;
2870 it->current.overlay_string_index = -1;
2871 it->method = next_element_from_buffer;
2872 }
2873
2874 CHECK_IT (it);
2875
2876 /* Value is non-zero if we found at least one overlay string. */
2877 return STRINGP (it->string);
2878}
2879
2880
2881\f
2882/***********************************************************************
2883 Saving and restoring state
2884 ***********************************************************************/
2885
2886/* Save current settings of IT on IT->stack. Called, for example,
2887 before setting up IT for an overlay string, to be able to restore
2888 IT's settings to what they were after the overlay string has been
2889 processed. */
2890
2891static void
2892push_it (it)
2893 struct it *it;
2894{
2895 struct iterator_stack_entry *p;
2896
2897 xassert (it->sp < 2);
2898 p = it->stack + it->sp;
2899
2900 p->stop_charpos = it->stop_charpos;
2901 xassert (it->face_id >= 0);
2902 p->face_id = it->face_id;
2903 p->string = it->string;
2904 p->pos = it->current;
2905 p->end_charpos = it->end_charpos;
2906 p->string_nchars = it->string_nchars;
2907 p->area = it->area;
2908 p->multibyte_p = it->multibyte_p;
2909 p->space_width = it->space_width;
2910 p->font_height = it->font_height;
2911 p->voffset = it->voffset;
2912 p->string_from_display_prop_p = it->string_from_display_prop_p;
2913 ++it->sp;
2914}
2915
2916
2917/* Restore IT's settings from IT->stack. Called, for example, when no
2918 more overlay strings must be processed, and we return to delivering
2919 display elements from a buffer, or when the end of a string from a
2920 `display' property is reached and we return to delivering display
2921 elements from an overlay string, or from a buffer. */
2922
2923static void
2924pop_it (it)
2925 struct it *it;
2926{
2927 struct iterator_stack_entry *p;
2928
2929 xassert (it->sp > 0);
2930 --it->sp;
2931 p = it->stack + it->sp;
2932 it->stop_charpos = p->stop_charpos;
2933 it->face_id = p->face_id;
2934 it->string = p->string;
2935 it->current = p->pos;
2936 it->end_charpos = p->end_charpos;
2937 it->string_nchars = p->string_nchars;
2938 it->area = p->area;
2939 it->multibyte_p = p->multibyte_p;
2940 it->space_width = p->space_width;
2941 it->font_height = p->font_height;
2942 it->voffset = p->voffset;
2943 it->string_from_display_prop_p = p->string_from_display_prop_p;
2944}
2945
2946
2947\f
2948/***********************************************************************
2949 Moving over lines
2950 ***********************************************************************/
2951
2952/* Set IT's current position to the previous line start. */
2953
2954static void
2955back_to_previous_line_start (it)
2956 struct it *it;
2957{
2958 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
2959 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2960}
2961
2962
2963/* Set IT's current position to the next line start. */
2964
2965static void
2966forward_to_next_line_start (it)
2967 struct it *it;
2968{
2969 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
2970 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
2971}
2972
2973
2974/* Set IT's current position to the previous visible line start. Skip
2975 invisible text that is so either due to text properties or due to
2976 selective display. Caution: this does not change IT->current_x and
2977 IT->hpos. */
2978
2979static void
2980back_to_previous_visible_line_start (it)
2981 struct it *it;
2982{
2983 int visible_p = 0;
2984
2985 /* Go back one newline if not on BEGV already. */
2986 if (IT_CHARPOS (*it) > BEGV)
2987 back_to_previous_line_start (it);
2988
2989 /* Move over lines that are invisible because of selective display
2990 or text properties. */
2991 while (IT_CHARPOS (*it) > BEGV
2992 && !visible_p)
2993 {
2994 visible_p = 1;
2995
2996 /* If selective > 0, then lines indented more than that values
2997 are invisible. */
2998 if (it->selective > 0
2999 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3000 it->selective))
3001 visible_p = 0;
3002#ifdef USE_TEXT_PROPERTIES
3003 else
3004 {
3005 Lisp_Object prop;
3006
3007 prop = Fget_char_property (IT_CHARPOS (*it), Qinvisible, it->window);
3008 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3009 visible_p = 0;
3010 }
3011#endif /* USE_TEXT_PROPERTIES */
3012
3013 /* Back one more newline if the current one is invisible. */
3014 if (!visible_p)
3015 back_to_previous_line_start (it);
3016 }
3017
3018 xassert (IT_CHARPOS (*it) >= BEGV);
3019 xassert (IT_CHARPOS (*it) == BEGV
3020 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3021 CHECK_IT (it);
3022}
3023
3024
3025/* Reseat iterator IT at the previous visible line start. Skip
3026 invisible text that is so either due to text properties or due to
3027 selective display. At the end, update IT's overlay information,
3028 face information etc. */
3029
3030static void
3031reseat_at_previous_visible_line_start (it)
3032 struct it *it;
3033{
3034 back_to_previous_visible_line_start (it);
3035 reseat (it, it->current.pos, 1);
3036 CHECK_IT (it);
3037}
3038
3039
3040/* Reseat iterator IT on the next visible line start in the current
312246d1
GM
3041 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3042 preceding the line start. Skip over invisible text that is so
3043 because of selective display. Compute faces, overlays etc at the
3044 new position. Note that this function does not skip over text that
3045 is invisible because of text properties. */
5f5c8ee5
GM
3046
3047static void
312246d1 3048reseat_at_next_visible_line_start (it, on_newline_p)
5f5c8ee5 3049 struct it *it;
312246d1 3050 int on_newline_p;
5f5c8ee5
GM
3051{
3052 /* Restore the buffer position when currently not delivering display
3053 elements from the current buffer. This is the case, for example,
3054 when called at the end of a truncated overlay string. */
3055 while (it->sp)
3056 pop_it (it);
3057 it->method = next_element_from_buffer;
3058
3059 /* Otherwise, scan_buffer would not work. */
3060 if (IT_CHARPOS (*it) < ZV)
3061 {
3062 /* If on a newline, advance past it. Otherwise, find the next
3063 newline which automatically gives us the position following
3064 the newline. */
3065 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3066 {
3067 ++IT_CHARPOS (*it);
3068 ++IT_BYTEPOS (*it);
3069 }
3070 else
3071 forward_to_next_line_start (it);
3072
3073 /* We must either have reached the end of the buffer or end up
3074 after a newline. */
3075 xassert (IT_CHARPOS (*it) == ZV
3076 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3077
3078 /* Skip over lines that are invisible because they are indented
3079 more than the value of IT->selective. */
3080 if (it->selective > 0)
3081 while (IT_CHARPOS (*it) < ZV
3082 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3083 it->selective))
3084 forward_to_next_line_start (it);
312246d1
GM
3085
3086 /* Position on the newline if we should. */
3087 if (on_newline_p && IT_CHARPOS (*it) > BEGV)
3088 {
3089 --IT_CHARPOS (*it);
3090 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3091 }
5f5c8ee5
GM
3092
3093 /* Set the iterator there. The 0 as the last parameter of
3094 reseat means don't force a text property lookup. The lookup
3095 is then only done if we've skipped past the iterator's
3096 check_charpos'es. This optimization is important because
3097 text property lookups tend to be expensive. */
3098 reseat (it, it->current.pos, 0);
3099 }
3100
3101 CHECK_IT (it);
3102}
3103
3104
3105\f
3106/***********************************************************************
3107 Changing an iterator's position
3108***********************************************************************/
3109
3110/* Change IT's current position to POS in current_buffer. If FORCE_P
3111 is non-zero, always check for text properties at the new position.
3112 Otherwise, text properties are only looked up if POS >=
3113 IT->check_charpos of a property. */
3114
3115static void
3116reseat (it, pos, force_p)
3117 struct it *it;
3118 struct text_pos pos;
3119 int force_p;
3120{
3121 int original_pos = IT_CHARPOS (*it);
3122
3123 reseat_1 (it, pos, 0);
3124
3125 /* Determine where to check text properties. Avoid doing it
3126 where possible because text property lookup is very expensive. */
3127 if (force_p
3128 || CHARPOS (pos) > it->stop_charpos
3129 || CHARPOS (pos) < original_pos)
3130 handle_stop (it);
3131
3132 CHECK_IT (it);
3133}
3134
3135
3136/* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3137 IT->stop_pos to POS, also. */
3138
3139static void
3140reseat_1 (it, pos, set_stop_p)
3141 struct it *it;
3142 struct text_pos pos;
3143 int set_stop_p;
3144{
3145 /* Don't call this function when scanning a C string. */
3146 xassert (it->s == NULL);
3147
3148 /* POS must be a reasonable value. */
3149 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3150
3151 it->current.pos = it->position = pos;
3152 XSETBUFFER (it->object, current_buffer);
3153 it->dpvec = NULL;
3154 it->current.dpvec_index = -1;
3155 it->current.overlay_string_index = -1;
3156 IT_STRING_CHARPOS (*it) = -1;
3157 IT_STRING_BYTEPOS (*it) = -1;
3158 it->string = Qnil;
3159 it->method = next_element_from_buffer;
3160 it->sp = 0;
3161
3162 if (set_stop_p)
3163 it->stop_charpos = CHARPOS (pos);
3164}
3165
3166
3167/* Set up IT for displaying a string, starting at CHARPOS in window W.
3168 If S is non-null, it is a C string to iterate over. Otherwise,
3169 STRING gives a Lisp string to iterate over.
3170
3171 If PRECISION > 0, don't return more then PRECISION number of
3172 characters from the string.
3173
3174 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3175 characters have been returned. FIELD_WIDTH < 0 means an infinite
3176 field width.
3177
3178 MULTIBYTE = 0 means disable processing of multibyte characters,
3179 MULTIBYTE > 0 means enable it,
3180 MULTIBYTE < 0 means use IT->multibyte_p.
3181
3182 IT must be initialized via a prior call to init_iterator before
3183 calling this function. */
3184
3185static void
3186reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3187 struct it *it;
3188 unsigned char *s;
3189 Lisp_Object string;
3190 int charpos;
3191 int precision, field_width, multibyte;
3192{
3193 /* No region in strings. */
3194 it->region_beg_charpos = it->region_end_charpos = -1;
3195
3196 /* No text property checks performed by default, but see below. */
3197 it->stop_charpos = -1;
3198
3199 /* Set iterator position and end position. */
3200 bzero (&it->current, sizeof it->current);
3201 it->current.overlay_string_index = -1;
3202 it->current.dpvec_index = -1;
3203 it->charset = CHARSET_ASCII;
3204 xassert (charpos >= 0);
3205
3206 /* Use the setting of MULTIBYTE if specified. */
3207 if (multibyte >= 0)
3208 it->multibyte_p = multibyte > 0;
3209
3210 if (s == NULL)
3211 {
3212 xassert (STRINGP (string));
3213 it->string = string;
3214 it->s = NULL;
3215 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3216 it->method = next_element_from_string;
3217 it->current.string_pos = string_pos (charpos, string);
3218 }
3219 else
3220 {
3221 it->s = s;
3222 it->string = Qnil;
3223
3224 /* Note that we use IT->current.pos, not it->current.string_pos,
3225 for displaying C strings. */
3226 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3227 if (it->multibyte_p)
3228 {
3229 it->current.pos = c_string_pos (charpos, s, 1);
3230 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3231 }
3232 else
3233 {
3234 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3235 it->end_charpos = it->string_nchars = strlen (s);
3236 }
3237
3238 it->method = next_element_from_c_string;
3239 }
3240
3241 /* PRECISION > 0 means don't return more than PRECISION characters
3242 from the string. */
3243 if (precision > 0 && it->end_charpos - charpos > precision)
3244 it->end_charpos = it->string_nchars = charpos + precision;
3245
3246 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3247 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3248 FIELD_WIDTH < 0 means infinite field width. This is useful for
3249 padding with `-' at the end of a mode line. */
3250 if (field_width < 0)
3251 field_width = INFINITY;
3252 if (field_width > it->end_charpos - charpos)
3253 it->end_charpos = charpos + field_width;
3254
3255 /* Use the standard display table for displaying strings. */
3256 if (DISP_TABLE_P (Vstandard_display_table))
3257 it->dp = XCHAR_TABLE (Vstandard_display_table);
3258
3259 it->stop_charpos = charpos;
3260 CHECK_IT (it);
3261}
3262
3263
3264\f
3265/***********************************************************************
3266 Iteration
3267 ***********************************************************************/
3268
3269/* Load IT's display element fields with information about the next
3270 display element from the current position of IT. Value is zero if
3271 end of buffer (or C string) is reached. */
3272
3273int
3274get_next_display_element (it)
3275 struct it *it;
3276{
3277 /* Non-zero means that we found an display element. Zero means that
3278 we hit the end of what we iterate over. Performance note: the
3279 function pointer `method' used here turns out to be faster than
3280 using a sequence of if-statements. */
3281 int success_p = (*it->method) (it);
3282 int charset;
3283
3284 if (it->what == IT_CHARACTER)
3285 {
3286 /* Map via display table or translate control characters.
3287 IT->c, IT->len etc. have been set to the next character by
3288 the function call above. If we have a display table, and it
3289 contains an entry for IT->c, translate it. Don't do this if
3290 IT->c itself comes from a display table, otherwise we could
3291 end up in an infinite recursion. (An alternative could be to
3292 count the recursion depth of this function and signal an
3293 error when a certain maximum depth is reached.) Is it worth
3294 it? */
3295 if (success_p && it->dpvec == NULL)
3296 {
3297 Lisp_Object dv;
3298
3299 if (it->dp
3300 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3301 VECTORP (dv)))
3302 {
3303 struct Lisp_Vector *v = XVECTOR (dv);
3304
3305 /* Return the first character from the display table
3306 entry, if not empty. If empty, don't display the
3307 current character. */
3308 if (v->size)
3309 {
3310 it->dpvec_char_len = it->len;
3311 it->dpvec = v->contents;
3312 it->dpend = v->contents + v->size;
3313 it->current.dpvec_index = 0;
3314 it->method = next_element_from_display_vector;
3315 }
3316
3317 success_p = get_next_display_element (it);
3318 }
3319
3320 /* Translate control characters into `\003' or `^C' form.
3321 Control characters coming from a display table entry are
3322 currently not translated because we use IT->dpvec to hold
3323 the translation. This could easily be changed but I
3324 don't believe that it is worth doing. */
3325 else if ((it->c < ' '
3326 && (it->area != TEXT_AREA
3327 || (it->c != '\n'
3328 && it->c != '\t'
3329 && it->c != '\r')))
54c85a23 3330 || (it->c >= 127
5f5c8ee5
GM
3331 && it->len == 1))
3332 {
3333 /* IT->c is a control character which must be displayed
3334 either as '\003' or as `^C' where the '\\' and '^'
3335 can be defined in the display table. Fill
3336 IT->ctl_chars with glyphs for what we have to
3337 display. Then, set IT->dpvec to these glyphs. */
3338 GLYPH g;
3339
54c85a23 3340 if (it->c < 128 && it->ctl_arrow_p)
5f5c8ee5
GM
3341 {
3342 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3343 if (it->dp
3344 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3345 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3346 g = XINT (DISP_CTRL_GLYPH (it->dp));
3347 else
3348 g = FAST_MAKE_GLYPH ('^', 0);
3349 XSETINT (it->ctl_chars[0], g);
3350
3351 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3352 XSETINT (it->ctl_chars[1], g);
3353
3354 /* Set up IT->dpvec and return first character from it. */
3355 it->dpvec_char_len = it->len;
3356 it->dpvec = it->ctl_chars;
3357 it->dpend = it->dpvec + 2;
3358 it->current.dpvec_index = 0;
3359 it->method = next_element_from_display_vector;
3360 get_next_display_element (it);
3361 }
3362 else
3363 {
3364 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3365 if (it->dp
3366 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3367 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3368 g = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3369 else
3370 g = FAST_MAKE_GLYPH ('\\', 0);
3371 XSETINT (it->ctl_chars[0], g);
3372
3373 /* Insert three more glyphs into IT->ctl_chars for
3374 the octal display of the character. */
3375 g = FAST_MAKE_GLYPH (((it->c >> 6) & 7) + '0', 0);
3376 XSETINT (it->ctl_chars[1], g);
3377 g = FAST_MAKE_GLYPH (((it->c >> 3) & 7) + '0', 0);
3378 XSETINT (it->ctl_chars[2], g);
3379 g = FAST_MAKE_GLYPH ((it->c & 7) + '0', 0);
3380 XSETINT (it->ctl_chars[3], g);
3381
3382 /* Set up IT->dpvec and return the first character
3383 from it. */
3384 it->dpvec_char_len = it->len;
3385 it->dpvec = it->ctl_chars;
3386 it->dpend = it->dpvec + 4;
3387 it->current.dpvec_index = 0;
3388 it->method = next_element_from_display_vector;
3389 get_next_display_element (it);
3390 }
3391 }
3392 }
3393
3394 /* Adjust face id if charset changes. There are no charset
3395 changes in unibyte text because Emacs' charsets are not
3396 applicable there. */
3397 if (it->multibyte_p
3398 && success_p
3399 && (charset = CHAR_CHARSET (it->c),
3400 charset != it->charset))
3401 {
3402 it->charset = charset;
3403 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, charset);
3404 }
3405 }
3406
3407 /* Is this character the last one of a run of characters with
3408 box? If yes, set IT->end_of_box_run_p to 1. */
3409 if (it->face_box_p
3410 && it->s == NULL)
3411 {
3412 int face_id;
3413 struct face *face;
3414
3415 it->end_of_box_run_p
3416 = ((face_id = face_after_it_pos (it),
3417 face_id != it->face_id)
3418 && (face = FACE_FROM_ID (it->f, face_id),
3419 face->box == FACE_NO_BOX));
3420 }
3421
3422 /* Value is 0 if end of buffer or string reached. */
3423 return success_p;
3424}
3425
3426
3427/* Move IT to the next display element.
3428
3429 Functions get_next_display_element and set_iterator_to_next are
3430 separate because I find this arrangement easier to handle than a
3431 get_next_display_element function that also increments IT's
3432 position. The way it is we can first look at an iterator's current
3433 display element, decide whether it fits on a line, and if it does,
3434 increment the iterator position. The other way around we probably
3435 would either need a flag indicating whether the iterator has to be
3436 incremented the next time, or we would have to implement a
3437 decrement position function which would not be easy to write. */
3438
3439void
3440set_iterator_to_next (it)
3441 struct it *it;
3442{
3443 if (it->method == next_element_from_buffer)
3444 {
3445 /* The current display element of IT is a character from
3446 current_buffer. Advance in the buffer, and maybe skip over
3447 invisible lines that are so because of selective display. */
3448 if (ITERATOR_AT_END_OF_LINE_P (it))
312246d1 3449 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
3450 else
3451 {
3452 xassert (it->len != 0);
3453 IT_BYTEPOS (*it) += it->len;
3454 IT_CHARPOS (*it) += 1;
3455 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3456 }
3457 }
3458 else if (it->method == next_element_from_c_string)
3459 {
3460 /* Current display element of IT is from a C string. */
3461 IT_BYTEPOS (*it) += it->len;
3462 IT_CHARPOS (*it) += 1;
3463 }
3464 else if (it->method == next_element_from_display_vector)
3465 {
3466 /* Current display element of IT is from a display table entry.
3467 Advance in the display table definition. Reset it to null if
3468 end reached, and continue with characters from buffers/
3469 strings. */
286bcbc9
GM
3470 struct face *face;
3471
5f5c8ee5 3472 ++it->current.dpvec_index;
286bcbc9
GM
3473
3474 /* Restore face and charset of the iterator to what they were
3475 before the display vector entry (these entries may contain
3476 faces, and of course characters of different charsets). */
5f5c8ee5 3477 it->face_id = it->saved_face_id;
286bcbc9
GM
3478 it->charset = FACE_FROM_ID (it->f, it->face_id)->charset;
3479
5f5c8ee5
GM
3480 if (it->dpvec + it->current.dpvec_index == it->dpend)
3481 {
3482 if (it->s)
3483 it->method = next_element_from_c_string;
3484 else if (STRINGP (it->string))
3485 it->method = next_element_from_string;
3486 else
3487 it->method = next_element_from_buffer;
3488
3489 it->dpvec = NULL;
3490 it->current.dpvec_index = -1;
3491
312246d1
GM
3492 /* Skip over characters which were displayed via IT->dpvec. */
3493 if (it->dpvec_char_len < 0)
3494 reseat_at_next_visible_line_start (it, 1);
3495 else if (it->dpvec_char_len > 0)
5f5c8ee5
GM
3496 {
3497 it->len = it->dpvec_char_len;
3498 set_iterator_to_next (it);
3499 }
3500 }
3501 }
3502 else if (it->method == next_element_from_string)
3503 {
3504 /* Current display element is a character from a Lisp string. */
3505 xassert (it->s == NULL && STRINGP (it->string));
3506 IT_STRING_BYTEPOS (*it) += it->len;
3507 IT_STRING_CHARPOS (*it) += 1;
3508
3509 consider_string_end:
3510
3511 if (it->current.overlay_string_index >= 0)
3512 {
3513 /* IT->string is an overlay string. Advance to the
3514 next, if there is one. */
3515 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3516 next_overlay_string (it);
3517 }
3518 else
3519 {
3520 /* IT->string is not an overlay string. If we reached
3521 its end, and there is something on IT->stack, proceed
3522 with what is on the stack. This can be either another
3523 string, this time an overlay string, or a buffer. */
3524 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3525 && it->sp > 0)
3526 {
3527 pop_it (it);
3528 if (!STRINGP (it->string))
3529 it->method = next_element_from_buffer;
3530 }
3531 }
3532 }
3533 else if (it->method == next_element_from_image
3534 || it->method == next_element_from_stretch)
3535 {
3536 /* The position etc with which we have to proceed are on
3537 the stack. The position may be at the end of a string,
3538 if the `display' property takes up the whole string. */
3539 pop_it (it);
3540 it->image_id = 0;
3541 if (STRINGP (it->string))
3542 {
3543 it->method = next_element_from_string;
3544 goto consider_string_end;
3545 }
3546 else
3547 it->method = next_element_from_buffer;
3548 }
3549 else
3550 /* There are no other methods defined, so this should be a bug. */
3551 abort ();
3552
3553 /* Reset flags indicating start and end of a sequence of
3554 characters with box. */
3555 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3556
3557 xassert (it->method != next_element_from_string
3558 || (STRINGP (it->string)
3559 && IT_STRING_CHARPOS (*it) >= 0));
3560}
3561
3562
3563/* Load IT's display element fields with information about the next
3564 display element which comes from a display table entry or from the
3565 result of translating a control character to one of the forms `^C'
3566 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3567
3568static int
3569next_element_from_display_vector (it)
3570 struct it *it;
3571{
3572 /* Precondition. */
3573 xassert (it->dpvec && it->current.dpvec_index >= 0);
3574
3575 /* Remember the current face id in case glyphs specify faces.
3576 IT's face is restored in set_iterator_to_next. */
3577 it->saved_face_id = it->face_id;
3578
3579 if (INTEGERP (*it->dpvec)
3580 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3581 {
3582 int lface_id;
3583 GLYPH g;
3584
3585 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3586 it->c = FAST_GLYPH_CHAR (g);
3587 it->len = CHAR_LEN (it->c);
3588
3589 /* The entry may contain a face id to use. Such a face id is
3590 the id of a Lisp face, not a realized face. A face id of
3591 zero means no face. */
3592 lface_id = FAST_GLYPH_FACE (g);
3593 if (lface_id)
3594 {
3595 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3596 if (face_id >= 0)
3597 {
3598 it->face_id = face_id;
3599 it->charset = CHARSET_ASCII;
3600 }
3601 }
3602 }
3603 else
3604 /* Display table entry is invalid. Return a space. */
3605 it->c = ' ', it->len = 1;
3606
3607 /* Don't change position and object of the iterator here. They are
3608 still the values of the character that had this display table
3609 entry or was translated, and that's what we want. */
3610 it->what = IT_CHARACTER;
3611 return 1;
3612}
3613
3614
3615/* Load IT with the next display element from Lisp string IT->string.
3616 IT->current.string_pos is the current position within the string.
3617 If IT->current.overlay_string_index >= 0, the Lisp string is an
3618 overlay string. */
3619
3620static int
3621next_element_from_string (it)
3622 struct it *it;
3623{
3624 struct text_pos position;
3625
3626 xassert (STRINGP (it->string));
3627 xassert (IT_STRING_CHARPOS (*it) >= 0);
3628 position = it->current.string_pos;
3629
3630 /* Time to check for invisible text? */
3631 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3632 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3633 {
3634 handle_stop (it);
3635
3636 /* Since a handler may have changed IT->method, we must
3637 recurse here. */
3638 return get_next_display_element (it);
3639 }
3640
3641 if (it->current.overlay_string_index >= 0)
3642 {
3643 /* Get the next character from an overlay string. In overlay
3644 strings, There is no field width or padding with spaces to
3645 do. */
3646 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3647 {
3648 it->what = IT_EOB;
3649 return 0;
3650 }
3651 else if (STRING_MULTIBYTE (it->string))
3652 {
3653 int remaining = (STRING_BYTES (XSTRING (it->string))
3654 - IT_STRING_BYTEPOS (*it));
3655 unsigned char *s = (XSTRING (it->string)->data
3656 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3657 it->c = string_char_and_length (s, remaining, &it->len);
5f5c8ee5
GM
3658 }
3659 else
3660 {
3661 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3662 it->len = 1;
3663 }
3664 }
3665 else
3666 {
3667 /* Get the next character from a Lisp string that is not an
3668 overlay string. Such strings come from the mode line, for
3669 example. We may have to pad with spaces, or truncate the
3670 string. See also next_element_from_c_string. */
3671 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3672 {
3673 it->what = IT_EOB;
3674 return 0;
3675 }
3676 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3677 {
3678 /* Pad with spaces. */
3679 it->c = ' ', it->len = 1;
3680 CHARPOS (position) = BYTEPOS (position) = -1;
3681 }
3682 else if (STRING_MULTIBYTE (it->string))
3683 {
3684 int maxlen = (STRING_BYTES (XSTRING (it->string))
3685 - IT_STRING_BYTEPOS (*it));
3686 unsigned char *s = (XSTRING (it->string)->data
3687 + IT_STRING_BYTEPOS (*it));
4fdb80f2 3688 it->c = string_char_and_length (s, maxlen, &it->len);
5f5c8ee5
GM
3689 }
3690 else
3691 {
3692 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3693 it->len = 1;
3694 }
3695 }
3696
3697 /* Record what we have and where it came from. Note that we store a
3698 buffer position in IT->position although it could arguably be a
3699 string position. */
3700 it->what = IT_CHARACTER;
3701 it->object = it->string;
3702 it->position = position;
3703 return 1;
3704}
3705
3706
3707/* Load IT with next display element from C string IT->s.
3708 IT->string_nchars is the maximum number of characters to return
3709 from the string. IT->end_charpos may be greater than
3710 IT->string_nchars when this function is called, in which case we
3711 may have to return padding spaces. Value is zero if end of string
3712 reached, including padding spaces. */
3713
3714static int
3715next_element_from_c_string (it)
3716 struct it *it;
3717{
3718 int success_p = 1;
3719
3720 xassert (it->s);
3721 it->what = IT_CHARACTER;
3722 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3723 it->object = Qnil;
3724
3725 /* IT's position can be greater IT->string_nchars in case a field
3726 width or precision has been specified when the iterator was
3727 initialized. */
3728 if (IT_CHARPOS (*it) >= it->end_charpos)
3729 {
3730 /* End of the game. */
3731 it->what = IT_EOB;
3732 success_p = 0;
3733 }
3734 else if (IT_CHARPOS (*it) >= it->string_nchars)
3735 {
3736 /* Pad with spaces. */
3737 it->c = ' ', it->len = 1;
3738 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3739 }
3740 else if (it->multibyte_p)
3741 {
3742 /* Implementation note: The calls to strlen apparently aren't a
3743 performance problem because there is no noticeable performance
3744 difference between Emacs running in unibyte or multibyte mode. */
3745 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
4fdb80f2
GM
3746 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3747 maxlen, &it->len);
5f5c8ee5
GM
3748 }
3749 else
3750 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3751
3752 return success_p;
3753}
3754
3755
3756/* Set up IT to return characters from an ellipsis, if appropriate.
3757 The definition of the ellipsis glyphs may come from a display table
3758 entry. This function Fills IT with the first glyph from the
3759 ellipsis if an ellipsis is to be displayed. */
3760
3761static void
3762next_element_from_ellipsis (it)
3763 struct it *it;
3764{
3765 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3766 {
3767 /* Use the display table definition for `...'. Invalid glyphs
3768 will be handled by the method returning elements from dpvec. */
3769 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3770 it->dpvec_char_len = it->len;
3771 it->dpvec = v->contents;
3772 it->dpend = v->contents + v->size;
3773 it->current.dpvec_index = 0;
3774 it->method = next_element_from_display_vector;
3775 get_next_display_element (it);
3776 }
3777 else if (it->selective_display_ellipsis_p)
3778 {
3779 /* Use default `...' which is stored in default_invis_vector. */
3780 it->dpvec_char_len = it->len;
3781 it->dpvec = default_invis_vector;
3782 it->dpend = default_invis_vector + 3;
3783 it->current.dpvec_index = 0;
3784 it->method = next_element_from_display_vector;
3785 get_next_display_element (it);
3786 }
3787}
3788
3789
3790/* Deliver an image display element. The iterator IT is already
3791 filled with image information (done in handle_display_prop). Value
3792 is always 1. */
3793
3794
3795static int
3796next_element_from_image (it)
3797 struct it *it;
3798{
3799 it->what = IT_IMAGE;
3800 return 1;
3801}
3802
3803
3804/* Fill iterator IT with next display element from a stretch glyph
3805 property. IT->object is the value of the text property. Value is
3806 always 1. */
3807
3808static int
3809next_element_from_stretch (it)
3810 struct it *it;
3811{
3812 it->what = IT_STRETCH;
3813 return 1;
3814}
3815
3816
3817/* Load IT with the next display element from current_buffer. Value
3818 is zero if end of buffer reached. IT->stop_charpos is the next
3819 position at which to stop and check for text properties or buffer
3820 end. */
3821
3822static int
3823next_element_from_buffer (it)
3824 struct it *it;
3825{
3826 int success_p = 1;
3827
3828 /* Check this assumption, otherwise, we would never enter the
3829 if-statement, below. */
3830 xassert (IT_CHARPOS (*it) >= BEGV
3831 && IT_CHARPOS (*it) <= it->stop_charpos);
3832
3833 if (IT_CHARPOS (*it) >= it->stop_charpos)
3834 {
3835 if (IT_CHARPOS (*it) >= it->end_charpos)
3836 {
3837 int overlay_strings_follow_p;
3838
3839 /* End of the game, except when overlay strings follow that
3840 haven't been returned yet. */
3841 if (it->overlay_strings_at_end_processed_p)
3842 overlay_strings_follow_p = 0;
3843 else
3844 {
3845 it->overlay_strings_at_end_processed_p = 1;
3846 overlay_strings_follow_p
3847 = get_overlay_strings (it);
3848 }
3849
3850 if (overlay_strings_follow_p)
3851 success_p = get_next_display_element (it);
3852 else
3853 {
3854 it->what = IT_EOB;
3855 it->position = it->current.pos;
3856 success_p = 0;
3857 }
3858 }
3859 else
3860 {
3861 handle_stop (it);
3862 return get_next_display_element (it);
3863 }
3864 }
3865 else
3866 {
3867 /* No face changes, overlays etc. in sight, so just return a
3868 character from current_buffer. */
3869 unsigned char *p;
3870
3871 /* Maybe run the redisplay end trigger hook. Performance note:
3872 This doesn't seem to cost measurable time. */
3873 if (it->redisplay_end_trigger_charpos
3874 && it->glyph_row
3875 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3876 run_redisplay_end_trigger_hook (it);
3877
3878 /* Get the next character, maybe multibyte. */
3879 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3880 if (it->multibyte_p)
3881 {
3882 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3883 - IT_BYTEPOS (*it));
4fdb80f2 3884 it->c = string_char_and_length (p, maxlen, &it->len);
5f5c8ee5
GM
3885 }
3886 else
3887 it->c = *p, it->len = 1;
3888
3889 /* Record what we have and where it came from. */
3890 it->what = IT_CHARACTER;;
3891 it->object = it->w->buffer;
3892 it->position = it->current.pos;
3893
3894 /* Normally we return the character found above, except when we
3895 really want to return an ellipsis for selective display. */
3896 if (it->selective)
3897 {
3898 if (it->c == '\n')
3899 {
3900 /* A value of selective > 0 means hide lines indented more
3901 than that number of columns. */
3902 if (it->selective > 0
3903 && IT_CHARPOS (*it) + 1 < ZV
3904 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3905 IT_BYTEPOS (*it) + 1,
3906 it->selective))
312246d1
GM
3907 {
3908 next_element_from_ellipsis (it);
3909 it->dpvec_char_len = -1;
3910 }
5f5c8ee5
GM
3911 }
3912 else if (it->c == '\r' && it->selective == -1)
3913 {
3914 /* A value of selective == -1 means that everything from the
3915 CR to the end of the line is invisible, with maybe an
3916 ellipsis displayed for it. */
3917 next_element_from_ellipsis (it);
312246d1 3918 it->dpvec_char_len = -1;
5f5c8ee5
GM
3919 }
3920 }
3921 }
3922
3923 /* Value is zero if end of buffer reached. */
3924 xassert (!success_p || it->len > 0);
3925 return success_p;
3926}
3927
3928
3929/* Run the redisplay end trigger hook for IT. */
3930
3931static void
3932run_redisplay_end_trigger_hook (it)
3933 struct it *it;
3934{
3935 Lisp_Object args[3];
3936
3937 /* IT->glyph_row should be non-null, i.e. we should be actually
3938 displaying something, or otherwise we should not run the hook. */
3939 xassert (it->glyph_row);
3940
3941 /* Set up hook arguments. */
3942 args[0] = Qredisplay_end_trigger_functions;
3943 args[1] = it->window;
3944 XSETINT (args[2], it->redisplay_end_trigger_charpos);
3945 it->redisplay_end_trigger_charpos = 0;
3946
3947 /* Since we are *trying* to run these functions, don't try to run
3948 them again, even if they get an error. */
3949 it->w->redisplay_end_trigger = Qnil;
3950 Frun_hook_with_args (3, args);
3951
3952 /* Notice if it changed the face of the character we are on. */
3953 handle_face_prop (it);
3954}
3955
3956
3957\f
3958/***********************************************************************
3959 Moving an iterator without producing glyphs
3960 ***********************************************************************/
3961
3962/* Move iterator IT to a specified buffer or X position within one
3963 line on the display without producing glyphs.
3964
3965 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
3966 whichever is reached first.
3967
3968 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
3969
3970 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
3971 0 <= TO_X <= IT->last_visible_x. This means in particular, that
3972 TO_X includes the amount by which a window is horizontally
3973 scrolled.
3974
3975 Value is
3976
3977 MOVE_POS_MATCH_OR_ZV
3978 - when TO_POS or ZV was reached.
3979
3980 MOVE_X_REACHED
3981 -when TO_X was reached before TO_POS or ZV were reached.
3982
3983 MOVE_LINE_CONTINUED
3984 - when we reached the end of the display area and the line must
3985 be continued.
3986
3987 MOVE_LINE_TRUNCATED
3988 - when we reached the end of the display area and the line is
3989 truncated.
3990
3991 MOVE_NEWLINE_OR_CR
3992 - when we stopped at a line end, i.e. a newline or a CR and selective
3993 display is on. */
3994
3995enum move_it_result
3996move_it_in_display_line_to (it, to_charpos, to_x, op)
3997 struct it *it;
3998 int to_charpos, to_x, op;
3999{
4000 enum move_it_result result = MOVE_UNDEFINED;
4001 struct glyph_row *saved_glyph_row;
4002
4003 /* Don't produce glyphs in produce_glyphs. */
4004 saved_glyph_row = it->glyph_row;
4005 it->glyph_row = NULL;
4006
4007#if NO_PROMPT_IN_BUFFER
4008 /* Take a mini-buffer prompt into account. */
4009 if (MINI_WINDOW_P (it->w)
4010 && IT_CHARPOS (*it) == BEGV)
4011 {
4012 it->current_x = minibuf_prompt_pixel_width;
4013 it->hpos = minibuf_prompt_width;
4014 }
4015#endif
4016
4017 while (1)
4018 {
4019 int x, i;
4020
4021 /* Stop when ZV or TO_CHARPOS reached. */
4022 if (!get_next_display_element (it)
4023 || ((op & MOVE_TO_POS) != 0
4024 && BUFFERP (it->object)
4025 && IT_CHARPOS (*it) >= to_charpos))
4026 {
4027 result = MOVE_POS_MATCH_OR_ZV;
4028 break;
4029 }
4030
4031 /* The call to produce_glyphs will get the metrics of the
4032 display element IT is loaded with. We record in x the
4033 x-position before this display element in case it does not
4034 fit on the line. */
4035 x = it->current_x;
4036 PRODUCE_GLYPHS (it);
4037
4038 if (it->area != TEXT_AREA)
4039 {
4040 set_iterator_to_next (it);
4041 continue;
4042 }
4043
4044 /* The number of glyphs we get back in IT->nglyphs will normally
4045 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4046 character on a terminal frame, or (iii) a line end. For the
4047 second case, IT->nglyphs - 1 padding glyphs will be present
4048 (on X frames, there is only one glyph produced for a
4049 composite character.
4050
4051 The behavior implemented below means, for continuation lines,
4052 that as many spaces of a TAB as fit on the current line are
4053 displayed there. For terminal frames, as many glyphs of a
4054 multi-glyph character are displayed in the current line, too.
4055 This is what the old redisplay code did, and we keep it that
4056 way. Under X, the whole shape of a complex character must
4057 fit on the line or it will be completely displayed in the
4058 next line.
4059
4060 Note that both for tabs and padding glyphs, all glyphs have
4061 the same width. */
4062 if (it->nglyphs)
4063 {
4064 /* More than one glyph or glyph doesn't fit on line. All
4065 glyphs have the same width. */
4066 int single_glyph_width = it->pixel_width / it->nglyphs;
4067 int new_x;
4068
4069 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4070 {
4071 new_x = x + single_glyph_width;
4072
4073 /* We want to leave anything reaching TO_X to the caller. */
4074 if ((op & MOVE_TO_X) && new_x > to_x)
4075 {
4076 it->current_x = x;
4077 result = MOVE_X_REACHED;
4078 break;
4079 }
4080 else if (/* Lines are continued. */
4081 !it->truncate_lines_p
4082 && (/* And glyph doesn't fit on the line. */
4083 new_x > it->last_visible_x
4084 /* Or it fits exactly and we're on a window
4085 system frame. */
4086 || (new_x == it->last_visible_x
4087 && FRAME_WINDOW_P (it->f))))
4088 {
4089 if (/* IT->hpos == 0 means the very first glyph
4090 doesn't fit on the line, e.g. a wide image. */
4091 it->hpos == 0
4092 || (new_x == it->last_visible_x
4093 && FRAME_WINDOW_P (it->f)))
4094 {
4095 ++it->hpos;
4096 it->current_x = new_x;
4097 if (i == it->nglyphs - 1)
4098 set_iterator_to_next (it);
4099 }
4100 else
4101 it->current_x = x;
4102
4103 result = MOVE_LINE_CONTINUED;
4104 break;
4105 }
4106 else if (new_x > it->first_visible_x)
4107 {
4108 /* Glyph is visible. Increment number of glyphs that
4109 would be displayed. */
4110 ++it->hpos;
4111 }
4112 else
4113 {
4114 /* Glyph is completely off the left margin of the display
4115 area. Nothing to do. */
4116 }
4117 }
4118
4119 if (result != MOVE_UNDEFINED)
4120 break;
4121 }
4122 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4123 {
4124 /* Stop when TO_X specified and reached. This check is
4125 necessary here because of lines consisting of a line end,
4126 only. The line end will not produce any glyphs and we
4127 would never get MOVE_X_REACHED. */
4128 xassert (it->nglyphs == 0);
4129 result = MOVE_X_REACHED;
4130 break;
4131 }
4132
4133 /* Is this a line end? If yes, we're done. */
4134 if (ITERATOR_AT_END_OF_LINE_P (it))
4135 {
4136 result = MOVE_NEWLINE_OR_CR;
4137 break;
4138 }
4139
4140 /* The current display element has been consumed. Advance
4141 to the next. */
4142 set_iterator_to_next (it);
4143
4144 /* Stop if lines are truncated and IT's current x-position is
4145 past the right edge of the window now. */
4146 if (it->truncate_lines_p
4147 && it->current_x >= it->last_visible_x)
4148 {
4149 result = MOVE_LINE_TRUNCATED;
4150 break;
4151 }
4152 }
4153
4154 /* Restore the iterator settings altered at the beginning of this
4155 function. */
4156 it->glyph_row = saved_glyph_row;
4157 return result;
4158}
4159
4160
4161/* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4162 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4163 the description of enum move_operation_enum.
4164
4165 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4166 screen line, this function will set IT to the next position >
4167 TO_CHARPOS. */
4168
4169void
4170move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4171 struct it *it;
4172 int to_charpos, to_x, to_y, to_vpos;
4173 int op;
4174{
4175 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4176 int line_height;
4177
4178 xassert (XBUFFER (it->w->buffer) == current_buffer);
4179
4180 while (1)
4181 {
4182 if (op & MOVE_TO_VPOS)
4183 {
4184 /* If no TO_CHARPOS and no TO_X specified, stop at the
4185 start of the line TO_VPOS. */
4186 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4187 {
4188 if (it->vpos == to_vpos)
4189 break;
4190 skip = move_it_in_display_line_to (it, -1, -1, 0);
4191 }
4192 else
4193 {
4194 /* TO_VPOS >= 0 means stop at TO_X in the line at
4195 TO_VPOS, or at TO_POS, whichever comes first. */
4196 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4197
4198 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4199 break;
4200 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4201 {
4202 /* We have reached TO_X but not in the line we want. */
4203 skip = move_it_in_display_line_to (it, to_charpos,
4204 -1, MOVE_TO_POS);
4205 if (skip == MOVE_POS_MATCH_OR_ZV)
4206 break;
4207 }
4208 }
4209 }
4210 else if (op & MOVE_TO_Y)
4211 {
4212 struct it it_backup;
4213 int done_p;
4214
4215 /* TO_Y specified means stop at TO_X in the line containing
4216 TO_Y---or at TO_CHARPOS if this is reached first. The
4217 problem is that we can't really tell whether the line
4218 contains TO_Y before we have completely scanned it, and
4219 this may skip past TO_X. What we do is to first scan to
4220 TO_X.
4221
4222 If TO_X is not specified, use a TO_X of zero. The reason
4223 is to make the outcome of this function more predictable.
4224 If we didn't use TO_X == 0, we would stop at the end of
4225 the line which is probably not what a caller would expect
4226 to happen. */
4227 skip = move_it_in_display_line_to (it, to_charpos,
4228 ((op & MOVE_TO_X)
4229 ? to_x : 0),
4230 (MOVE_TO_X
4231 | (op & MOVE_TO_POS)));
4232
4233 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4234 if (skip == MOVE_POS_MATCH_OR_ZV)
4235 break;
4236
4237 /* If TO_X was reached, we would like to know whether TO_Y
4238 is in the line. This can only be said if we know the
4239 total line height which requires us to scan the rest of
4240 the line. */
4241 done_p = 0;
4242 if (skip == MOVE_X_REACHED)
4243 {
4244 it_backup = *it;
4245 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4246 op & MOVE_TO_POS);
4247 }
4248
4249 /* Now, decide whether TO_Y is in this line. */
4250 line_height = it->max_ascent + it->max_descent;
4251
4252 if (to_y >= it->current_y
4253 && to_y < it->current_y + line_height)
4254 {
4255 if (skip == MOVE_X_REACHED)
4256 /* If TO_Y is in this line and TO_X was reached above,
4257 we scanned too far. We have to restore IT's settings
4258 to the ones before skipping. */
4259 *it = it_backup;
4260 done_p = 1;
4261 }
4262 else if (skip == MOVE_X_REACHED)
4263 {
4264 skip = skip2;
4265 if (skip == MOVE_POS_MATCH_OR_ZV)
4266 done_p = 1;
4267 }
4268
4269 if (done_p)
4270 break;
4271 }
4272 else
4273 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4274
4275 switch (skip)
4276 {
4277 case MOVE_POS_MATCH_OR_ZV:
4278 return;
4279
4280 case MOVE_NEWLINE_OR_CR:
4281 set_iterator_to_next (it);
4282 it->continuation_lines_width = 0;
4283 break;
4284
4285 case MOVE_LINE_TRUNCATED:
4286 it->continuation_lines_width = 0;
312246d1 4287 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
4288 if ((op & MOVE_TO_POS) != 0
4289 && IT_CHARPOS (*it) > to_charpos)
4290 goto out;
4291 break;
4292
4293 case MOVE_LINE_CONTINUED:
4294 it->continuation_lines_width += it->current_x;
4295 break;
4296
4297 default:
4298 abort ();
4299 }
4300
4301 /* Reset/increment for the next run. */
4302 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4303 it->current_x = it->hpos = 0;
4304 it->current_y += it->max_ascent + it->max_descent;
4305 ++it->vpos;
4306 last_height = it->max_ascent + it->max_descent;
4307 last_max_ascent = it->max_ascent;
4308 it->max_ascent = it->max_descent = 0;
4309 }
4310 out:;
4311}
4312
4313
4314/* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4315
4316 If DY > 0, move IT backward at least that many pixels. DY = 0
4317 means move IT backward to the preceding line start or BEGV. This
4318 function may move over more than DY pixels if IT->current_y - DY
4319 ends up in the middle of a line; in this case IT->current_y will be
4320 set to the top of the line moved to. */
4321
4322void
4323move_it_vertically_backward (it, dy)
4324 struct it *it;
4325 int dy;
4326{
4327 int nlines, h, line_height;
4328 struct it it2;
4329 int start_pos = IT_CHARPOS (*it);
4330
4331 xassert (dy >= 0);
4332
4333 /* Estimate how many newlines we must move back. */
4334 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4335
4336 /* Set the iterator's position that many lines back. */
4337 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4338 back_to_previous_visible_line_start (it);
4339
4340 /* Reseat the iterator here. When moving backward, we don't want
4341 reseat to skip forward over invisible text, set up the iterator
4342 to deliver from overlay strings at the new position etc. So,
4343 use reseat_1 here. */
4344 reseat_1 (it, it->current.pos, 1);
4345
4346 /* We are now surely at a line start. */
4347 it->current_x = it->hpos = 0;
4348
4349 /* Move forward and see what y-distance we moved. First move to the
4350 start of the next line so that we get its height. We need this
4351 height to be able to tell whether we reached the specified
4352 y-distance. */
4353 it2 = *it;
4354 it2.max_ascent = it2.max_descent = 0;
4355 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4356 MOVE_TO_POS | MOVE_TO_VPOS);
4357 xassert (IT_CHARPOS (*it) >= BEGV);
4358 line_height = it2.max_ascent + it2.max_descent;
4359 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4360 xassert (IT_CHARPOS (*it) >= BEGV);
4361 h = it2.current_y - it->current_y;
4362 nlines = it2.vpos - it->vpos;
4363
4364 /* Correct IT's y and vpos position. */
4365 it->vpos -= nlines;
4366 it->current_y -= h;
4367
4368 if (dy == 0)
4369 {
4370 /* DY == 0 means move to the start of the screen line. The
4371 value of nlines is > 0 if continuation lines were involved. */
4372 if (nlines > 0)
4373 move_it_by_lines (it, nlines, 1);
4374 xassert (IT_CHARPOS (*it) <= start_pos);
4375 }
4376 else if (nlines)
4377 {
4378 /* The y-position we try to reach. Note that h has been
4379 subtracted in front of the if-statement. */
4380 int target_y = it->current_y + h - dy;
4381
4382 /* If we did not reach target_y, try to move further backward if
4383 we can. If we moved too far backward, try to move forward. */
4384 if (target_y < it->current_y
4385 && IT_CHARPOS (*it) > BEGV)
4386 {
4387 move_it_vertically (it, target_y - it->current_y);
4388 xassert (IT_CHARPOS (*it) >= BEGV);
4389 }
4390 else if (target_y >= it->current_y + line_height
4391 && IT_CHARPOS (*it) < ZV)
4392 {
4393 move_it_vertically (it, target_y - (it->current_y + line_height));
4394 xassert (IT_CHARPOS (*it) >= BEGV);
4395 }
4396 }
4397}
4398
4399
4400/* Move IT by a specified amount of pixel lines DY. DY negative means
4401 move backwards. DY = 0 means move to start of screen line. At the
4402 end, IT will be on the start of a screen line. */
4403
4404void
4405move_it_vertically (it, dy)
4406 struct it *it;
4407 int dy;
4408{
4409 if (dy <= 0)
4410 move_it_vertically_backward (it, -dy);
4411 else if (dy > 0)
4412 {
4413 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4414 MOVE_TO_POS | MOVE_TO_Y);
4415
4416 /* If buffer ends in ZV without a newline, move to the start of
4417 the line to satisfy the post-condition. */
4418 if (IT_CHARPOS (*it) == ZV
4419 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4420 move_it_by_lines (it, 0, 0);
4421 }
4422}
4423
4424
4425/* Return non-zero if some text between buffer positions START_CHARPOS
4426 and END_CHARPOS is invisible. IT->window is the window for text
4427 property lookup. */
4428
4429static int
4430invisible_text_between_p (it, start_charpos, end_charpos)
4431 struct it *it;
4432 int start_charpos, end_charpos;
4433{
4434#ifdef USE_TEXT_PROPERTIES
4435 Lisp_Object prop, limit;
4436 int invisible_found_p;
4437
4438 xassert (it != NULL && start_charpos <= end_charpos);
4439
4440 /* Is text at START invisible? */
4441 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4442 it->window);
4443 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4444 invisible_found_p = 1;
4445 else
4446 {
4447 limit = Fnext_single_property_change (make_number (start_charpos),
4448 Qinvisible,
4449 Fcurrent_buffer (),
4450 make_number (end_charpos));
4451 invisible_found_p = XFASTINT (limit) < end_charpos;
4452 }
4453
4454 return invisible_found_p;
4455
4456#else /* not USE_TEXT_PROPERTIES */
4457 return 0;
4458#endif /* not USE_TEXT_PROPERTIES */
4459}
4460
4461
4462/* Move IT by a specified number DVPOS of screen lines down. DVPOS
4463 negative means move up. DVPOS == 0 means move to the start of the
4464 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4465 NEED_Y_P is zero, IT->current_y will be left unchanged.
4466
4467 Further optimization ideas: If we would know that IT->f doesn't use
4468 a face with proportional font, we could be faster for
4469 truncate-lines nil. */
4470
4471void
4472move_it_by_lines (it, dvpos, need_y_p)
4473 struct it *it;
4474 int dvpos, need_y_p;
4475{
4476 struct position pos;
4477
4478 if (!FRAME_WINDOW_P (it->f))
4479 {
4480 struct text_pos textpos;
4481
4482 /* We can use vmotion on frames without proportional fonts. */
4483 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4484 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4485 reseat (it, textpos, 1);
4486 it->vpos += pos.vpos;
4487 it->current_y += pos.vpos;
4488 }
4489 else if (dvpos == 0)
4490 {
4491 /* DVPOS == 0 means move to the start of the screen line. */
4492 move_it_vertically_backward (it, 0);
4493 xassert (it->current_x == 0 && it->hpos == 0);
4494 }
4495 else if (dvpos > 0)
4496 {
4497 /* If there are no continuation lines, and if there is no
4498 selective display, try the simple method of moving forward
4499 DVPOS newlines, then see where we are. */
4500 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4501 {
4502 int shortage = 0, charpos;
4503
4504 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4505 charpos = IT_CHARPOS (*it) + 1;
4506 else
4507 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4508 &shortage, 0);
4509
4510 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4511 {
4512 struct text_pos pos;
4513 CHARPOS (pos) = charpos;
4514 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4515 reseat (it, pos, 1);
4516 it->vpos += dvpos - shortage;
4517 it->hpos = it->current_x = 0;
4518 return;
4519 }
4520 }
4521
4522 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4523 }
4524 else
4525 {
4526 struct it it2;
4527 int start_charpos, i;
4528
4529 /* If there are no continuation lines, and if there is no
4530 selective display, try the simple method of moving backward
4531 -DVPOS newlines. */
4532 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4533 {
4534 int shortage;
4535 int charpos = IT_CHARPOS (*it);
4536 int bytepos = IT_BYTEPOS (*it);
4537
4538 /* If in the middle of a line, go to its start. */
4539 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4540 {
4541 charpos = find_next_newline_no_quit (charpos, -1);
4542 bytepos = CHAR_TO_BYTE (charpos);
4543 }
4544
4545 if (charpos == BEGV)
4546 {
4547 struct text_pos pos;
4548 CHARPOS (pos) = charpos;
4549 BYTEPOS (pos) = bytepos;
4550 reseat (it, pos, 1);
4551 it->hpos = it->current_x = 0;
4552 return;
4553 }
4554 else
4555 {
4556 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4557 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4558 {
4559 struct text_pos pos;
4560 CHARPOS (pos) = charpos;
4561 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4562 reseat (it, pos, 1);
4563 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4564 it->hpos = it->current_x = 0;
4565 return;
4566 }
4567 }
4568 }
4569
4570 /* Go back -DVPOS visible lines and reseat the iterator there. */
4571 start_charpos = IT_CHARPOS (*it);
4572 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4573 back_to_previous_visible_line_start (it);
4574 reseat (it, it->current.pos, 1);
4575 it->current_x = it->hpos = 0;
4576
4577 /* Above call may have moved too far if continuation lines
4578 are involved. Scan forward and see if it did. */
4579 it2 = *it;
4580 it2.vpos = it2.current_y = 0;
4581 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4582 it->vpos -= it2.vpos;
4583 it->current_y -= it2.current_y;
4584 it->current_x = it->hpos = 0;
4585
4586 /* If we moved too far, move IT some lines forward. */
4587 if (it2.vpos > -dvpos)
4588 {
4589 int delta = it2.vpos + dvpos;
4590 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4591 }
4592 }
4593}
4594
4595
4596\f
4597/***********************************************************************
4598 Messages
4599 ***********************************************************************/
4600
4601
4602/* Output a newline in the *Messages* buffer if "needs" one. */
4603
4604void
4605message_log_maybe_newline ()
4606{
4607 if (message_log_need_newline)
4608 message_dolog ("", 0, 1, 0);
4609}
4610
4611
4612/* Add a string M of length LEN to the message log, optionally
4613 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4614 nonzero, means interpret the contents of M as multibyte. This
4615 function calls low-level routines in order to bypass text property
4616 hooks, etc. which might not be safe to run. */
4617
4618void
4619message_dolog (m, len, nlflag, multibyte)
4620 char *m;
4621 int len, nlflag, multibyte;
4622{
4623 if (!NILP (Vmessage_log_max))
4624 {
4625 struct buffer *oldbuf;
4626 Lisp_Object oldpoint, oldbegv, oldzv;
4627 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4628 int point_at_end = 0;
4629 int zv_at_end = 0;
4630 Lisp_Object old_deactivate_mark, tem;
4631 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4632
4633 old_deactivate_mark = Vdeactivate_mark;
4634 oldbuf = current_buffer;
4635 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4636 current_buffer->undo_list = Qt;
4637
4638 oldpoint = Fpoint_marker ();
4639 oldbegv = Fpoint_min_marker ();
4640 oldzv = Fpoint_max_marker ();
4641 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4642
4643 if (PT == Z)
4644 point_at_end = 1;
4645 if (ZV == Z)
4646 zv_at_end = 1;
4647
4648 BEGV = BEG;
4649 BEGV_BYTE = BEG_BYTE;
4650 ZV = Z;
4651 ZV_BYTE = Z_BYTE;
4652 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4653
4654 /* Insert the string--maybe converting multibyte to single byte
4655 or vice versa, so that all the text fits the buffer. */
4656 if (multibyte
4657 && NILP (current_buffer->enable_multibyte_characters))
4658 {
4659 int i, c, nbytes;
4660 unsigned char work[1];
4661
4662 /* Convert a multibyte string to single-byte
4663 for the *Message* buffer. */
4664 for (i = 0; i < len; i += nbytes)
4665 {
4fdb80f2 4666 c = string_char_and_length (m + i, len - i, &nbytes);
5f5c8ee5
GM
4667 work[0] = (SINGLE_BYTE_CHAR_P (c)
4668 ? c
4669 : multibyte_char_to_unibyte (c, Qnil));
4670 insert_1_both (work, 1, 1, 1, 0, 0);
4671 }
4672 }
4673 else if (! multibyte
4674 && ! NILP (current_buffer->enable_multibyte_characters))
4675 {
4676 int i, c, nbytes;
4677 unsigned char *msg = (unsigned char *) m;
4678 unsigned char *str, work[4];
4679 /* Convert a single-byte string to multibyte
4680 for the *Message* buffer. */
4681 for (i = 0; i < len; i++)
4682 {
4683 c = unibyte_char_to_multibyte (msg[i]);
4684 nbytes = CHAR_STRING (c, work, str);
4685 insert_1_both (work, 1, nbytes, 1, 0, 0);
4686 }
4687 }
4688 else if (len)
4689 insert_1 (m, len, 1, 0, 0);
4690
4691 if (nlflag)
4692 {
4693 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4694 insert_1 ("\n", 1, 1, 0, 0);
4695
4696 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4697 this_bol = PT;
4698 this_bol_byte = PT_BYTE;
4699
4700 if (this_bol > BEG)
4701 {
4702 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4703 prev_bol = PT;
4704 prev_bol_byte = PT_BYTE;
4705
4706 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4707 this_bol, this_bol_byte);
4708 if (dup)
4709 {
4710 del_range_both (prev_bol, prev_bol_byte,
4711 this_bol, this_bol_byte, 0);
4712 if (dup > 1)
4713 {
4714 char dupstr[40];
4715 int duplen;
4716
4717 /* If you change this format, don't forget to also
4718 change message_log_check_duplicate. */
4719 sprintf (dupstr, " [%d times]", dup);
4720 duplen = strlen (dupstr);
4721 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4722 insert_1 (dupstr, duplen, 1, 0, 1);
4723 }
4724 }
4725 }
4726
4727 if (NATNUMP (Vmessage_log_max))
4728 {
4729 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4730 -XFASTINT (Vmessage_log_max) - 1, 0);
4731 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4732 }
4733 }
4734 BEGV = XMARKER (oldbegv)->charpos;
4735 BEGV_BYTE = marker_byte_position (oldbegv);
4736
4737 if (zv_at_end)
4738 {
4739 ZV = Z;
4740 ZV_BYTE = Z_BYTE;
4741 }
4742 else
4743 {
4744 ZV = XMARKER (oldzv)->charpos;
4745 ZV_BYTE = marker_byte_position (oldzv);
4746 }
4747
4748 if (point_at_end)
4749 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4750 else
4751 /* We can't do Fgoto_char (oldpoint) because it will run some
4752 Lisp code. */
4753 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4754 XMARKER (oldpoint)->bytepos);
4755
4756 UNGCPRO;
4757 free_marker (oldpoint);
4758 free_marker (oldbegv);
4759 free_marker (oldzv);
4760
4761 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4762 set_buffer_internal (oldbuf);
4763 if (NILP (tem))
4764 windows_or_buffers_changed = old_windows_or_buffers_changed;
4765 message_log_need_newline = !nlflag;
4766 Vdeactivate_mark = old_deactivate_mark;
4767 }
4768}
4769
4770
4771/* We are at the end of the buffer after just having inserted a newline.
4772 (Note: We depend on the fact we won't be crossing the gap.)
4773 Check to see if the most recent message looks a lot like the previous one.
4774 Return 0 if different, 1 if the new one should just replace it, or a
4775 value N > 1 if we should also append " [N times]". */
4776
4777static int
4778message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4779 int prev_bol, this_bol;
4780 int prev_bol_byte, this_bol_byte;
4781{
4782 int i;
4783 int len = Z_BYTE - 1 - this_bol_byte;
4784 int seen_dots = 0;
4785 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4786 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4787
4788 for (i = 0; i < len; i++)
4789 {
4790 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4791 && p1[i] != '\n')
4792 seen_dots = 1;
4793 if (p1[i] != p2[i])
4794 return seen_dots;
4795 }
4796 p1 += len;
4797 if (*p1 == '\n')
4798 return 2;
4799 if (*p1++ == ' ' && *p1++ == '[')
4800 {
4801 int n = 0;
4802 while (*p1 >= '0' && *p1 <= '9')
4803 n = n * 10 + *p1++ - '0';
4804 if (strncmp (p1, " times]\n", 8) == 0)
4805 return n+1;
4806 }
4807 return 0;
4808}
4809
4810
4811/* Display an echo area message M with a specified length of LEN
4812 chars. The string may include null characters. If M is 0, clear
4813 out any existing message, and let the mini-buffer text show through.
4814
4815 The buffer M must continue to exist until after the echo area gets
4816 cleared or some other message gets displayed there. This means do
4817 not pass text that is stored in a Lisp string; do not pass text in
4818 a buffer that was alloca'd. */
4819
4820void
4821message2 (m, len, multibyte)
4822 char *m;
4823 int len;
4824 int multibyte;
4825{
4826 /* First flush out any partial line written with print. */
4827 message_log_maybe_newline ();
4828 if (m)
4829 message_dolog (m, len, 1, multibyte);
4830 message2_nolog (m, len, multibyte);
4831}
4832
4833
4834/* The non-logging counterpart of message2. */
4835
4836void
4837message2_nolog (m, len, multibyte)
4838 char *m;
4839 int len;
4840{
4841 message_enable_multibyte = multibyte;
4842
4843 if (noninteractive)
4844 {
4845 if (noninteractive_need_newline)
4846 putc ('\n', stderr);
4847 noninteractive_need_newline = 0;
4848 if (m)
4849 fwrite (m, len, 1, stderr);
4850 if (cursor_in_echo_area == 0)
4851 fprintf (stderr, "\n");
4852 fflush (stderr);
4853 }
4854 /* A null message buffer means that the frame hasn't really been
4855 initialized yet. Error messages get reported properly by
4856 cmd_error, so this must be just an informative message; toss it. */
4857 else if (INTERACTIVE
4858 && selected_frame->glyphs_initialized_p
4859 && FRAME_MESSAGE_BUF (selected_frame))
4860 {
4861 Lisp_Object mini_window;
4862 struct frame *f;
4863
4864 /* Get the frame containing the mini-buffer
4865 that the selected frame is using. */
4866 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4867 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4868
4869 FRAME_SAMPLE_VISIBILITY (f);
4870 if (FRAME_VISIBLE_P (selected_frame)
4871 && ! FRAME_VISIBLE_P (f))
4872 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4873
4874 if (m)
4875 {
4876 echo_area_glyphs = m;
4877 echo_area_glyphs_length = len;
4878 echo_area_message = Qnil;
4879
4880 if (minibuffer_auto_raise)
4881 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4882 }
4883 else
4884 {
4885 echo_area_glyphs = previous_echo_glyphs = NULL;
4886 echo_area_message = previous_echo_area_message = Qnil;
4887 }
4888
4889 do_pending_window_change ();
4890 echo_area_display (1);
4891 do_pending_window_change ();
4892 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4893 (*frame_up_to_date_hook) (f);
4894 }
4895}
4896
4897
4898/* Display an echo area message M with a specified length of LEN
4899 chars. The string may include null characters. If M is not a
4900 string, clear out any existing message, and let the mini-buffer
4901 text show through. */
4902
4903void
4904message3 (m, len, multibyte)
4905 Lisp_Object m;
4906 int len;
4907 int multibyte;
4908{
4909 struct gcpro gcpro1;
4910
4911 GCPRO1 (m);
4912
4913 /* First flush out any partial line written with print. */
4914 message_log_maybe_newline ();
4915 if (STRINGP (m))
4916 message_dolog (XSTRING (m)->data, len, 1, multibyte);
4917 message3_nolog (m, len, multibyte);
4918
4919 UNGCPRO;
4920}
4921
4922
4923/* The non-logging version of message3. */
4924
4925void
4926message3_nolog (m, len, multibyte)
4927 Lisp_Object m;
4928 int len, multibyte;
4929{
4930 message_enable_multibyte = multibyte;
4931
4932 if (noninteractive)
4933 {
4934 if (noninteractive_need_newline)
4935 putc ('\n', stderr);
4936 noninteractive_need_newline = 0;
4937 if (STRINGP (m))
4938 fwrite (XSTRING (m)->data, len, 1, stderr);
4939 if (cursor_in_echo_area == 0)
4940 fprintf (stderr, "\n");
4941 fflush (stderr);
4942 }
4943 /* A null message buffer means that the frame hasn't really been
4944 initialized yet. Error messages get reported properly by
4945 cmd_error, so this must be just an informative message; toss it. */
4946 else if (INTERACTIVE
4947 && selected_frame->glyphs_initialized_p
4948 && FRAME_MESSAGE_BUF (selected_frame))
4949 {
4950 Lisp_Object mini_window;
4951 struct frame *f;
4952
4953 /* Get the frame containing the mini-buffer
4954 that the selected frame is using. */
4955 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
4956 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4957
4958 FRAME_SAMPLE_VISIBILITY (f);
4959 if (FRAME_VISIBLE_P (selected_frame)
4960 && ! FRAME_VISIBLE_P (f))
4961 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4962
4963 if (STRINGP (m))
4964 {
4965 echo_area_glyphs = NULL;
4966 echo_area_message = m;
4967 echo_area_glyphs_length = len;
4968
4969 if (minibuffer_auto_raise)
4970 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
4971 }
4972 else
4973 {
4974 echo_area_glyphs = previous_echo_glyphs = NULL;
4975 echo_area_message = previous_echo_area_message = Qnil;
4976 }
4977
4978 do_pending_window_change ();
4979 echo_area_display (1);
4980 do_pending_window_change ();
4981 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
4982 (*frame_up_to_date_hook) (f);
4983 }
4984}
4985
4986
4987/* Display a null-terminated echo area message M. If M is 0, clear
4988 out any existing message, and let the mini-buffer text show through.
4989
4990 The buffer M must continue to exist until after the echo area gets
4991 cleared or some other message gets displayed there. Do not pass
4992 text that is stored in a Lisp string. Do not pass text in a buffer
4993 that was alloca'd. */
4994
4995void
4996message1 (m)
4997 char *m;
4998{
4999 message2 (m, (m ? strlen (m) : 0), 0);
5000}
5001
5002
5003/* The non-logging counterpart of message1. */
5004
5005void
5006message1_nolog (m)
5007 char *m;
5008{
5009 message2_nolog (m, (m ? strlen (m) : 0), 0);
5010}
5011
5012/* Display a message M which contains a single %s
5013 which gets replaced with STRING. */
5014
5015void
5016message_with_string (m, string, log)
5017 char *m;
5018 Lisp_Object string;
5019 int log;
5020{
5021 if (noninteractive)
5022 {
5023 if (m)
5024 {
5025 if (noninteractive_need_newline)
5026 putc ('\n', stderr);
5027 noninteractive_need_newline = 0;
5028 fprintf (stderr, m, XSTRING (string)->data);
5029 if (cursor_in_echo_area == 0)
5030 fprintf (stderr, "\n");
5031 fflush (stderr);
5032 }
5033 }
5034 else if (INTERACTIVE)
5035 {
5036 /* The frame whose minibuffer we're going to display the message on.
5037 It may be larger than the selected frame, so we need
5038 to use its buffer, not the selected frame's buffer. */
5039 Lisp_Object mini_window;
5040 FRAME_PTR f;
5041
5042 /* Get the frame containing the minibuffer
5043 that the selected frame is using. */
5044 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5045 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5046
5047 /* A null message buffer means that the frame hasn't really been
5048 initialized yet. Error messages get reported properly by
5049 cmd_error, so this must be just an informative message; toss it. */
5050 if (FRAME_MESSAGE_BUF (f))
5051 {
5052 int len;
5053 char *a[1];
5054 a[0] = (char *) XSTRING (string)->data;
5055
5056 len = doprnt (FRAME_MESSAGE_BUF (f),
5057 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5058
5059 if (log)
5060 message2 (FRAME_MESSAGE_BUF (f), len,
5061 STRING_MULTIBYTE (string));
5062 else
5063 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5064 STRING_MULTIBYTE (string));
5065
5066 /* Print should start at the beginning of the message
5067 buffer next time. */
5068 message_buf_print = 0;
5069 }
5070 }
5071}
5072
5073
5074/* Truncate what will be displayed in the echo area
5075 the next time we display it--but don't redisplay it now. */
5076
5077void
5078truncate_echo_area (len)
5079 int len;
5080{
5081 /* A null message buffer means that the frame hasn't really been
5082 initialized yet. Error messages get reported properly by
5083 cmd_error, so this must be just an informative message; toss it. */
5084 if (!noninteractive && INTERACTIVE && FRAME_MESSAGE_BUF (selected_frame))
5085 echo_area_glyphs_length = len;
5086}
5087
5088
5089/* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by
5090 print; zero if being used by message. */
5091
5092int message_buf_print;
5093
5094
5095/* Dump an informative message to the minibuf. If M is 0, clear out
5096 any existing message, and let the mini-buffer text show through. */
5097
5098/* VARARGS 1 */
5099void
5100message (m, a1, a2, a3)
5101 char *m;
5102 EMACS_INT a1, a2, a3;
5103{
5104 if (noninteractive)
5105 {
5106 if (m)
5107 {
5108 if (noninteractive_need_newline)
5109 putc ('\n', stderr);
5110 noninteractive_need_newline = 0;
5111 fprintf (stderr, m, a1, a2, a3);
5112 if (cursor_in_echo_area == 0)
5113 fprintf (stderr, "\n");
5114 fflush (stderr);
5115 }
5116 }
5117 else if (INTERACTIVE)
5118 {
5119 /* The frame whose mini-buffer we're going to display the message
5120 on. It may be larger than the selected frame, so we need to
5121 use its buffer, not the selected frame's buffer. */
5122 Lisp_Object mini_window;
5123 struct frame *f;
5124
5125 /* Get the frame containing the mini-buffer
5126 that the selected frame is using. */
5127 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5128 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5129
5130 /* A null message buffer means that the frame hasn't really been
5131 initialized yet. Error messages get reported properly by
5132 cmd_error, so this must be just an informative message; toss
5133 it. */
5134 if (FRAME_MESSAGE_BUF (f))
5135 {
5136 if (m)
5137 {
5138 int len;
5139#ifdef NO_ARG_ARRAY
5140 char *a[3];
5141 a[0] = (char *) a1;
5142 a[1] = (char *) a2;
5143 a[2] = (char *) a3;
5144
5145 len = doprnt (FRAME_MESSAGE_BUF (f),
5146 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5147#else
5148 len = doprnt (FRAME_MESSAGE_BUF (f),
5149 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5150 (char **) &a1);
5151#endif /* NO_ARG_ARRAY */
5152
5153 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5154 }
5155 else
5156 message1 (0);
5157
5158 /* Print should start at the beginning of the message
5159 buffer next time. */
5160 message_buf_print = 0;
5161 }
5162 }
5163}
5164
5165
5166/* The non-logging version of message. */
5167
5168void
5169message_nolog (m, a1, a2, a3)
5170 char *m;
5171 EMACS_INT a1, a2, a3;
5172{
5173 Lisp_Object old_log_max;
5174 old_log_max = Vmessage_log_max;
5175 Vmessage_log_max = Qnil;
5176 message (m, a1, a2, a3);
5177 Vmessage_log_max = old_log_max;
5178}
5179
5180
5181/* Display echo_area_message or echo_area_glyphs in the current
5182 mini-buffer. */
5183
5184void
5185update_echo_area ()
5186{
5187 if (STRINGP (echo_area_message))
5188 message3 (echo_area_message, echo_area_glyphs_length,
5189 !NILP (current_buffer->enable_multibyte_characters));
5190 else
5191 message2 (echo_area_glyphs, echo_area_glyphs_length,
5192 !NILP (current_buffer->enable_multibyte_characters));
5193}
5194
5195
5196/* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
5197 non-zero update selected_frame. */
5198
5199static void
5200echo_area_display (update_frame_p)
5201 int update_frame_p;
5202{
5203 Lisp_Object mini_window;
5204 struct window *w;
5205 struct frame *f;
5206
5207 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
5208 w = XWINDOW (mini_window);
5209 f = XFRAME (WINDOW_FRAME (w));
5210
5211 /* Don't display if frame is invisible or not yet initialized. */
5212 if (!FRAME_VISIBLE_P (f)
5213 || !f->glyphs_initialized_p)
5214 return;
5215
5216 /* When Emacs starts, selected_frame may be a visible terminal
5217 frame, even if we run under a window system. If we let this
5218 through, a message would be displayed on the terminal. */
5219#ifdef HAVE_WINDOW_SYSTEM
5220 if (!inhibit_window_system && !FRAME_WINDOW_P (selected_frame))
5221 return;
5222#endif /* HAVE_WINDOW_SYSTEM */
5223
5224 /* Redraw garbaged frames. */
5225 if (frame_garbaged)
5226 {
5227 /* Old redisplay called redraw_garbaged_frames here which in
5228 turn called redraw_frame which in turn called clear_frame.
5229 The call to clear_frame is a source of flickering. After
5230 checking the places where SET_FRAME_GARBAGED is called, I
5231 believe a clear_frame is not necessary. It should suffice in
5232 the new redisplay to invalidate all current matrices, and
5233 ensure a complete redisplay of all windows. */
5234 Lisp_Object tail, frame;
5235
5236 FOR_EACH_FRAME (tail, frame)
5237 {
5238 struct frame *f = XFRAME (frame);
5239
5240 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5241 {
5242 clear_current_matrices (f);
5243 f->garbaged = 0;
5244 }
5245 }
5246
5247 frame_garbaged = 0;
5248 ++windows_or_buffers_changed;
5249 }
5250
5251 if (echo_area_glyphs
5252 || STRINGP (echo_area_message)
5253 || minibuf_level == 0)
5254 {
5255 struct it it;
5256
5257 echo_area_window = mini_window;
5258 clear_glyph_matrix (w->desired_matrix);
5259 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, DEFAULT_FACE_ID);
5260
5261 if (STRINGP (echo_area_message)
5262 && echo_area_glyphs_length)
5263 {
5264 prepare_desired_row (it.glyph_row);
5265 display_string (NULL, echo_area_message, Qnil, 0, 0,
5266 &it, -1, echo_area_glyphs_length, 0,
5267 message_enable_multibyte);
5268 it.glyph_row->truncated_on_right_p = 0;
5269 compute_line_metrics (&it);
5270 }
5271 else if (echo_area_glyphs
5272 && echo_area_glyphs_length)
5273 {
5274 prepare_desired_row (it.glyph_row);
5275 display_string (echo_area_glyphs, Qnil, Qnil, 0, 0, &it,
5276 -1, echo_area_glyphs_length, 0,
5277 message_enable_multibyte);
5278 it.glyph_row->truncated_on_right_p = 0;
5279 compute_line_metrics (&it);
5280 }
5281 else
5282 blank_row (w, it.glyph_row, 0);
5283
5284 it.glyph_row->y = it.current_y;
5285 it.current_y += it.glyph_row->height;
5286
5287 /* Clear the rest of the lines. */
5288 while (it.current_y < it.last_visible_y)
5289 {
5290 ++it.glyph_row;
5291 blank_row (w, it.glyph_row, it.current_y);
5292 it.current_y += it.glyph_row->height;
5293 }
5294
5295 w->must_be_updated_p = 1;
5296 if (update_frame_p)
5297 {
5298 /* Calling update_single_window is faster when we can use
5299 window-based redisplay. */
5300 if (FRAME_WINDOW_P (f))
5301 {
5302 update_single_window (w, 1);
5303 rif->flush_display (f);
5304 }
5305 else
5306 update_frame (f, 1, 1);
5307 }
5308 }
5309 else if (!EQ (mini_window, selected_window))
5310 windows_or_buffers_changed++;
5311
5312 /* Prevent redisplay optimization in redisplay_internal by resetting
5313 this_line_start_pos. This is done because the mini-buffer now
5314 displays the message instead of its buffer text. */
5315 if (EQ (mini_window, selected_window))
5316 CHARPOS (this_line_start_pos) = 0;
5317
5318 previous_echo_glyphs = echo_area_glyphs;
5319 previous_echo_area_message = echo_area_message;
5320 previous_echo_glyphs_length = echo_area_glyphs_length;
5321}
5322
5323
5324\f
5325/***********************************************************************
5326 Frame Titles
5327 ***********************************************************************/
5328
5329
5330#ifdef HAVE_WINDOW_SYSTEM
5331
5332/* A buffer for constructing frame titles in it; allocated from the
5333 heap in init_xdisp and resized as needed in store_frame_title_char. */
5334
5335static char *frame_title_buf;
5336
5337/* The buffer's end, and a current output position in it. */
5338
5339static char *frame_title_buf_end;
5340static char *frame_title_ptr;
5341
5342
5343/* Store a single character C for the frame title in frame_title_buf.
5344 Re-allocate frame_title_buf if necessary. */
5345
5346static void
5347store_frame_title_char (c)
5348 char c;
5349{
5350 /* If output position has reached the end of the allocated buffer,
5351 double the buffer's size. */
5352 if (frame_title_ptr == frame_title_buf_end)
5353 {
5354 int len = frame_title_ptr - frame_title_buf;
5355 int new_size = 2 * len * sizeof *frame_title_buf;
5356 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
5357 frame_title_buf_end = frame_title_buf + new_size;
5358 frame_title_ptr = frame_title_buf + len;
5359 }
5360
5361 *frame_title_ptr++ = c;
5362}
5363
5364
5365/* Store part of a frame title in frame_title_buf, beginning at
5366 frame_title_ptr. STR is the string to store. Do not copy more
5367 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
5368 the whole string. Pad with spaces until FIELD_WIDTH number of
5369 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
5370 Called from display_mode_element when it is used to build a frame
5371 title. */
5372
5373static int
5374store_frame_title (str, field_width, precision)
5375 unsigned char *str;
5376 int field_width, precision;
5377{
5378 int n = 0;
5379
5380 /* Copy at most PRECISION chars from STR. */
5381 while ((precision <= 0 || n < precision)
5382 && *str)
5383 {
5384 store_frame_title_char (*str++);
5385 ++n;
5386 }
5387
5388 /* Fill up with spaces until FIELD_WIDTH reached. */
5389 while (field_width > 0
5390 && n < field_width)
5391 {
5392 store_frame_title_char (' ');
5393 ++n;
5394 }
5395
5396 return n;
5397}
5398
5399
5400/* Set the title of FRAME, if it has changed. The title format is
5401 Vicon_title_format if FRAME is iconified, otherwise it is
5402 frame_title_format. */
5403
5404static void
5405x_consider_frame_title (frame)
5406 Lisp_Object frame;
5407{
5408 struct frame *f = XFRAME (frame);
5409
5410 if (FRAME_WINDOW_P (f)
5411 || FRAME_MINIBUF_ONLY_P (f)
5412 || f->explicit_name)
5413 {
5414 /* Do we have more than one visible frame on this X display? */
5415 Lisp_Object tail;
5416 Lisp_Object fmt;
5417 struct buffer *obuf;
5418 int len;
5419 struct it it;
5420
5421 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
5422 {
5423 struct frame *tf = XFRAME (XCONS (tail)->car);
5424
5425 if (tf != f
5426 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
5427 && !FRAME_MINIBUF_ONLY_P (tf)
5428 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
5429 break;
5430 }
5431
5432 /* Set global variable indicating that multiple frames exist. */
5433 multiple_frames = CONSP (tail);
5434
5435 /* Switch to the buffer of selected window of the frame. Set up
5436 frame_title_ptr so that display_mode_element will output into it;
5437 then display the title. */
5438 obuf = current_buffer;
5439 Fset_buffer (XWINDOW (f->selected_window)->buffer);
5440 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
5441 frame_title_ptr = frame_title_buf;
5442 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
5443 NULL, DEFAULT_FACE_ID);
5444 len = display_mode_element (&it, 0, -1, -1, fmt);
5445 frame_title_ptr = NULL;
5446 set_buffer_internal (obuf);
5447
5448 /* Set the title only if it's changed. This avoids consing in
5449 the common case where it hasn't. (If it turns out that we've
5450 already wasted too much time by walking through the list with
5451 display_mode_element, then we might need to optimize at a
5452 higher level than this.) */
5453 if (! STRINGP (f->name)
5454 || STRING_BYTES (XSTRING (f->name)) != len
5455 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
5456 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
5457 }
5458}
5459
5460#else /* not HAVE_WINDOW_SYSTEM */
5461
5462#define frame_title_ptr ((char *)0)
5463#define store_frame_title(str, mincol, maxcol) 0
5464
5465#endif /* not HAVE_WINDOW_SYSTEM */
5466
5467
5468
5469\f
5470/***********************************************************************
5471 Menu Bars
5472 ***********************************************************************/
5473
5474
5475/* Prepare for redisplay by updating menu-bar item lists when
5476 appropriate. This can call eval. */
5477
5478void
5479prepare_menu_bars ()
5480{
5481 int all_windows;
5482 struct gcpro gcpro1, gcpro2;
5483 struct frame *f;
5484 struct frame *tooltip_frame;
5485
5486#ifdef HAVE_X_WINDOWS
5487 tooltip_frame = tip_frame;
5488#else
5489 tooltip_frame = NULL;
5490#endif
5491
5492 /* Update all frame titles based on their buffer names, etc. We do
5493 this before the menu bars so that the buffer-menu will show the
5494 up-to-date frame titles. */
5495#ifdef HAVE_WINDOW_SYSTEM
5496 if (windows_or_buffers_changed || update_mode_lines)
5497 {
5498 Lisp_Object tail, frame;
5499
5500 FOR_EACH_FRAME (tail, frame)
5501 {
5502 f = XFRAME (frame);
5503 if (f != tooltip_frame
5504 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
5505 x_consider_frame_title (frame);
5506 }
5507 }
5508#endif /* HAVE_WINDOW_SYSTEM */
5509
5510 /* Update the menu bar item lists, if appropriate. This has to be
5511 done before any actual redisplay or generation of display lines. */
5512 all_windows = (update_mode_lines
5513 || buffer_shared > 1
5514 || windows_or_buffers_changed);
5515 if (all_windows)
5516 {
5517 Lisp_Object tail, frame;
5518 int count = specpdl_ptr - specpdl;
5519
5520 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5521
5522 FOR_EACH_FRAME (tail, frame)
5523 {
5524 f = XFRAME (frame);
5525
5526 /* Ignore tooltip frame. */
5527 if (f == tooltip_frame)
5528 continue;
5529
5530 /* If a window on this frame changed size, report that to
5531 the user and clear the size-change flag. */
5532 if (FRAME_WINDOW_SIZES_CHANGED (f))
5533 {
5534 Lisp_Object functions;
5535
5536 /* Clear flag first in case we get an error below. */
5537 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
5538 functions = Vwindow_size_change_functions;
5539 GCPRO2 (tail, functions);
5540
5541 while (CONSP (functions))
5542 {
5543 call1 (XCAR (functions), frame);
5544 functions = XCDR (functions);
5545 }
5546 UNGCPRO;
5547 }
5548
5549 GCPRO1 (tail);
5550 update_menu_bar (f, 0);
5551#ifdef HAVE_WINDOW_SYSTEM
5552 update_toolbar (f, 0);
5553#endif
5554 UNGCPRO;
5555 }
5556
5557 unbind_to (count, Qnil);
5558 }
5559 else
5560 {
5561 update_menu_bar (selected_frame, 1);
5562#ifdef HAVE_WINDOW_SYSTEM
5563 update_toolbar (selected_frame, 1);
5564#endif
5565 }
5566
5567 /* Motif needs this. See comment in xmenu.c. Turn it off when
5568 pending_menu_activation is not defined. */
5569#ifdef USE_X_TOOLKIT
5570 pending_menu_activation = 0;
5571#endif
5572}
5573
5574
5575/* Update the menu bar item list for frame F. This has to be done
5576 before we start to fill in any display lines, because it can call
5577 eval.
5578
5579 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
5580
5581static void
5582update_menu_bar (f, save_match_data)
5583 struct frame *f;
5584 int save_match_data;
5585{
5586 Lisp_Object window;
5587 register struct window *w;
5588
5589 window = FRAME_SELECTED_WINDOW (f);
5590 w = XWINDOW (window);
5591
5592 if (update_mode_lines)
5593 w->update_mode_line = Qt;
5594
5595 if (FRAME_WINDOW_P (f)
5596 ?
5597#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5598 FRAME_EXTERNAL_MENU_BAR (f)
5599#else
5600 FRAME_MENU_BAR_LINES (f) > 0
5601#endif
5602 : FRAME_MENU_BAR_LINES (f) > 0)
5603 {
5604 /* If the user has switched buffers or windows, we need to
5605 recompute to reflect the new bindings. But we'll
5606 recompute when update_mode_lines is set too; that means
5607 that people can use force-mode-line-update to request
5608 that the menu bar be recomputed. The adverse effect on
5609 the rest of the redisplay algorithm is about the same as
5610 windows_or_buffers_changed anyway. */
5611 if (windows_or_buffers_changed
5612 || !NILP (w->update_mode_line)
5613 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
5614 < BUF_MODIFF (XBUFFER (w->buffer)))
5615 != !NILP (w->last_had_star))
5616 || ((!NILP (Vtransient_mark_mode)
5617 && !NILP (XBUFFER (w->buffer)->mark_active))
5618 != !NILP (w->region_showing)))
5619 {
5620 struct buffer *prev = current_buffer;
5621 int count = specpdl_ptr - specpdl;
5622
5623 set_buffer_internal_1 (XBUFFER (w->buffer));
5624 if (save_match_data)
5625 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5626 if (NILP (Voverriding_local_map_menu_flag))
5627 {
5628 specbind (Qoverriding_terminal_local_map, Qnil);
5629 specbind (Qoverriding_local_map, Qnil);
5630 }
5631
5632 /* Run the Lucid hook. */
5633 call1 (Vrun_hooks, Qactivate_menubar_hook);
5634
5635 /* If it has changed current-menubar from previous value,
5636 really recompute the menu-bar from the value. */
5637 if (! NILP (Vlucid_menu_bar_dirty_flag))
5638 call0 (Qrecompute_lucid_menubar);
5639
5640 safe_run_hooks (Qmenu_bar_update_hook);
5641 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
5642
5643 /* Redisplay the menu bar in case we changed it. */
5644#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5645 if (FRAME_WINDOW_P (f))
5646 set_frame_menubar (f, 0, 0);
5647 else
5648 /* On a terminal screen, the menu bar is an ordinary screen
5649 line, and this makes it get updated. */
5650 w->update_mode_line = Qt;
5651#else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5652 /* In the non-toolkit version, the menu bar is an ordinary screen
5653 line, and this makes it get updated. */
5654 w->update_mode_line = Qt;
5655#endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5656
5657 unbind_to (count, Qnil);
5658 set_buffer_internal_1 (prev);
5659 }
5660 }
5661}
5662
5663
5664\f
5665/***********************************************************************
5666 Toolbars
5667 ***********************************************************************/
5668
5669#ifdef HAVE_WINDOW_SYSTEM
5670
5671/* Update the toolbar item list for frame F. This has to be done
5672 before we start to fill in any display lines. Called from
5673 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
5674 and restore it here. */
5675
5676static void
5677update_toolbar (f, save_match_data)
5678 struct frame *f;
5679 int save_match_data;
5680{
5681 if (WINDOWP (f->toolbar_window)
5682 && XFASTINT (XWINDOW (f->toolbar_window)->height) > 0)
5683 {
5684 Lisp_Object window;
5685 struct window *w;
5686
5687 window = FRAME_SELECTED_WINDOW (f);
5688 w = XWINDOW (window);
5689
5690 /* If the user has switched buffers or windows, we need to
5691 recompute to reflect the new bindings. But we'll
5692 recompute when update_mode_lines is set too; that means
5693 that people can use force-mode-line-update to request
5694 that the menu bar be recomputed. The adverse effect on
5695 the rest of the redisplay algorithm is about the same as
5696 windows_or_buffers_changed anyway. */
5697 if (windows_or_buffers_changed
5698 || !NILP (w->update_mode_line)
5699 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
5700 < BUF_MODIFF (XBUFFER (w->buffer)))
5701 != !NILP (w->last_had_star))
5702 || ((!NILP (Vtransient_mark_mode)
5703 && !NILP (XBUFFER (w->buffer)->mark_active))
5704 != !NILP (w->region_showing)))
5705 {
5706 struct buffer *prev = current_buffer;
5707 int count = specpdl_ptr - specpdl;
a2889657 5708
5f5c8ee5
GM
5709 /* Set current_buffer to the buffer of the selected
5710 window of the frame, so that we get the right local
5711 keymaps. */
5712 set_buffer_internal_1 (XBUFFER (w->buffer));
1f40cad2 5713
5f5c8ee5
GM
5714 /* Save match data, if we must. */
5715 if (save_match_data)
5716 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
5717
5718 /* Make sure that we don't accidentally use bogus keymaps. */
5719 if (NILP (Voverriding_local_map_menu_flag))
5720 {
5721 specbind (Qoverriding_terminal_local_map, Qnil);
5722 specbind (Qoverriding_local_map, Qnil);
1f40cad2 5723 }
1f40cad2 5724
5f5c8ee5
GM
5725 /* Build desired toolbar items from keymaps. */
5726 f->desired_toolbar_items
5727 = toolbar_items (f->desired_toolbar_items,
5728 &f->n_desired_toolbar_items);
5729
5730 /* Redisplay the toolbar in case we changed it. */
5731 w->update_mode_line = Qt;
5732
5733 unbind_to (count, Qnil);
5734 set_buffer_internal_1 (prev);
81d478f3 5735 }
a2889657
JB
5736 }
5737}
5738
6c4429a5 5739
5f5c8ee5
GM
5740/* Set F->desired_toolbar_string to a Lisp string representing frame
5741 F's desired toolbar contents. F->desired_toolbar_items must have
5742 been set up previously by calling prepare_menu_bars. */
5743
a2889657 5744static void
5f5c8ee5
GM
5745build_desired_toolbar_string (f)
5746 struct frame *f;
a2889657 5747{
5f5c8ee5
GM
5748 int i, size, size_needed, string_idx;
5749 struct gcpro gcpro1, gcpro2, gcpro3;
5750 Lisp_Object image, plist, props;
a2889657 5751
5f5c8ee5
GM
5752 image = plist = props = Qnil;
5753 GCPRO3 (image, plist, props);
a2889657 5754
5f5c8ee5
GM
5755 /* Prepare F->desired_toolbar_string. If we can reuse it, do so.
5756 Otherwise, make a new string. */
5757
5758 /* The size of the string we might be able to reuse. */
5759 size = (STRINGP (f->desired_toolbar_string)
5760 ? XSTRING (f->desired_toolbar_string)->size
5761 : 0);
5762
5763 /* Each image in the string we build is preceded by a space,
5764 and there is a space at the end. */
5765 size_needed = f->n_desired_toolbar_items + 1;
5766
5767 /* Reuse f->desired_toolbar_string, if possible. */
5768 if (size < size_needed)
5769 f->desired_toolbar_string = Fmake_string (make_number (size_needed), ' ');
5770 else
5771 {
5772 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
5773 Fremove_text_properties (make_number (0), make_number (size),
5774 props, f->desired_toolbar_string);
5775 }
a2889657 5776
5f5c8ee5
GM
5777 /* Put a `display' property on the string for the images to display,
5778 put a `menu_item' property on toolbar items with a value that
5779 is the index of the item in F's toolbar item vector. */
5780 for (i = 0, string_idx = 0;
5781 i < f->n_desired_toolbar_items;
5782 ++i, string_idx += 1)
a2889657 5783 {
5f5c8ee5
GM
5784#define PROP(IDX) \
5785 (XVECTOR (f->desired_toolbar_items) \
5786 ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
5787
5788 int enabled_p = !NILP (PROP (TOOLBAR_ITEM_ENABLED_P));
5789 int selected_p = !NILP (PROP (TOOLBAR_ITEM_SELECTED_P));
5790 int margin, relief;
5791 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
5792 extern Lisp_Object Qlaplace;
5793
5794 /* If image is a vector, choose the image according to the
5795 button state. */
5796 image = PROP (TOOLBAR_ITEM_IMAGES);
5797 if (VECTORP (image))
5798 {
5799 enum toolbar_item_image idx;
5800
5801 if (enabled_p)
5802 idx = (selected_p
5803 ? TOOLBAR_IMAGE_ENABLED_SELECTED
5804 : TOOLBAR_IMAGE_ENABLED_DESELECTED);
5805 else
5806 idx = (selected_p
5807 ? TOOLBAR_IMAGE_DISABLED_SELECTED
5808 : TOOLBAR_IMAGE_DISABLED_DESELECTED);
5809
5810 xassert (XVECTOR (image)->size >= idx);
5811 image = XVECTOR (image)->contents[idx];
5812 }
5813
5814 /* Ignore invalid image specifications. */
5815 if (!valid_image_p (image))
5816 continue;
5817
5818 /* Display the toolbar button pressed, or depressed. */
5819 plist = Fcopy_sequence (XCDR (image));
5820
5821 /* Compute margin and relief to draw. */
5822 relief = toolbar_button_relief > 0 ? toolbar_button_relief : 3;
5823 margin = relief + max (0, toolbar_button_margin);
5824
5825 if (auto_raise_toolbar_buttons_p)
5826 {
5827 /* Add a `:relief' property to the image spec if the item is
5828 selected. */
5829 if (selected_p)
5830 {
5831 plist = Fplist_put (plist, QCrelief, make_number (-relief));
5832 margin -= relief;
5833 }
5834 }
5835 else
5836 {
5837 /* If image is selected, display it pressed, i.e. with a
5838 negative relief. If it's not selected, display it with a
5839 raised relief. */
5840 plist = Fplist_put (plist, QCrelief,
5841 (selected_p
5842 ? make_number (-relief)
5843 : make_number (relief)));
5844 margin -= relief;
5845 }
5846
5847 /* Put a margin around the image. */
5848 if (margin)
5849 plist = Fplist_put (plist, QCmargin, make_number (margin));
5850
5851 /* If button is not enabled, make the image appear disabled by
5852 applying an appropriate algorithm to it. */
5853 if (!enabled_p)
5854 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
5855
5856 /* Put a `display' text property on the string for the image to
5857 display. Put a `menu-item' property on the string that gives
5858 the start of this item's properties in the toolbar items
5859 vector. */
5860 image = Fcons (Qimage, plist);
5861 props = list4 (Qdisplay, image,
5862 Qmenu_item, make_number (i * TOOLBAR_ITEM_NSLOTS)),
5863 Fadd_text_properties (make_number (string_idx),
5864 make_number (string_idx + 1),
5865 props, f->desired_toolbar_string);
5866#undef PROP
a2889657
JB
5867 }
5868
5f5c8ee5
GM
5869 UNGCPRO;
5870}
5871
5872
5873/* Display one line of the toolbar of frame IT->f. */
5874
5875static void
5876display_toolbar_line (it)
5877 struct it *it;
5878{
5879 struct glyph_row *row = it->glyph_row;
5880 int max_x = it->last_visible_x;
5881 struct glyph *last;
5882
5883 prepare_desired_row (row);
5884 row->y = it->current_y;
5885
5886 while (it->current_x < max_x)
a2889657 5887 {
5f5c8ee5 5888 int x_before, x, n_glyphs_before, i, nglyphs;
a2f016e3 5889
5f5c8ee5
GM
5890 /* Get the next display element. */
5891 if (!get_next_display_element (it))
5892 break;
73af359d 5893
5f5c8ee5
GM
5894 /* Produce glyphs. */
5895 x_before = it->current_x;
5896 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
5897 PRODUCE_GLYPHS (it);
daa37602 5898
5f5c8ee5
GM
5899 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
5900 i = 0;
5901 x = x_before;
5902 while (i < nglyphs)
5903 {
5904 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
5905
5906 if (x + glyph->pixel_width > max_x)
5907 {
5908 /* Glyph doesn't fit on line. */
5909 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
5910 it->current_x = x;
5911 goto out;
5912 }
daa37602 5913
5f5c8ee5
GM
5914 ++it->hpos;
5915 x += glyph->pixel_width;
5916 ++i;
5917 }
5918
5919 /* Stop at line ends. */
5920 if (ITERATOR_AT_END_OF_LINE_P (it))
5921 break;
5922
5923 set_iterator_to_next (it);
a2889657 5924 }
a2889657 5925
5f5c8ee5 5926 out:;
a2889657 5927
5f5c8ee5
GM
5928 row->displays_text_p = row->used[TEXT_AREA] != 0;
5929 extend_face_to_end_of_line (it);
5930 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
5931 last->right_box_line_p = 1;
5932 compute_line_metrics (it);
5933
5934 /* If line is empty, make it occupy the rest of the toolbar. */
5935 if (!row->displays_text_p)
5936 {
312246d1
GM
5937 row->height = row->phys_height = it->last_visible_y - row->y;
5938 row->ascent = row->phys_ascent = 0;
5f5c8ee5
GM
5939 }
5940
5941 row->full_width_p = 1;
5942 row->continued_p = 0;
5943 row->truncated_on_left_p = 0;
5944 row->truncated_on_right_p = 0;
5945
5946 it->current_x = it->hpos = 0;
5947 it->current_y += row->height;
5948 ++it->vpos;
5949 ++it->glyph_row;
a2889657 5950}
96a410bc 5951
5f5c8ee5
GM
5952
5953/* Value is the number of screen lines needed to make all toolbar
5954 items of frame F visible. */
96a410bc 5955
d39b6696 5956static int
5f5c8ee5
GM
5957toolbar_lines_needed (f)
5958 struct frame *f;
d39b6696 5959{
5f5c8ee5
GM
5960 struct window *w = XWINDOW (f->toolbar_window);
5961 struct it it;
5962
5963 /* Initialize an iterator for iteration over F->desired_toolbar_string
5964 in the toolbar window of frame F. */
5965 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
5966 it.first_visible_x = 0;
5967 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
5968 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
5969
5970 while (!ITERATOR_AT_END_P (&it))
5971 {
5972 it.glyph_row = w->desired_matrix->rows;
5973 clear_glyph_row (it.glyph_row);
5974 display_toolbar_line (&it);
5975 }
5976
5977 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
d39b6696 5978}
96a410bc 5979
5f5c8ee5
GM
5980
5981/* Display the toolbar of frame F. Value is non-zero if toolbar's
5982 height should be changed. */
5983
5984static int
5985redisplay_toolbar (f)
5986 struct frame *f;
96a410bc 5987{
5f5c8ee5
GM
5988 struct window *w;
5989 struct it it;
5990 struct glyph_row *row;
5991 int change_height_p = 0;
5992
5993 /* If frame hasn't a toolbar window or if it is zero-height, don't
5994 do anything. This means you must start with toolbar-lines
5995 non-zero to get the auto-sizing effect. Or in other words, you
5996 can turn off toolbars by specifying toolbar-lines zero. */
5997 if (!WINDOWP (f->toolbar_window)
5998 || (w = XWINDOW (f->toolbar_window),
5999 XFASTINT (w->height) == 0))
6000 return 0;
96a410bc 6001
5f5c8ee5
GM
6002 /* Set up an iterator for the toolbar window. */
6003 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOLBAR_FACE_ID);
6004 it.first_visible_x = 0;
6005 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6006 row = it.glyph_row;
3450d04c 6007
5f5c8ee5
GM
6008 /* Build a string that represents the contents of the toolbar. */
6009 build_desired_toolbar_string (f);
6010 reseat_to_string (&it, NULL, f->desired_toolbar_string, 0, 0, 0, -1);
3450d04c 6011
5f5c8ee5
GM
6012 /* Display as many lines as needed to display all toolbar items. */
6013 while (it.current_y < it.last_visible_y)
6014 display_toolbar_line (&it);
3450d04c 6015
5f5c8ee5
GM
6016 /* It doesn't make much sense to try scrolling in the toolbar
6017 window, so don't do it. */
6018 w->desired_matrix->no_scrolling_p = 1;
6019 w->must_be_updated_p = 1;
3450d04c 6020
5f5c8ee5
GM
6021 if (auto_resize_toolbars_p)
6022 {
6023 int nlines;
6024
6025 /* If there are blank lines at the end, except for a partially
6026 visible blank line at the end that is smaller than
6027 CANON_Y_UNIT, change the toolbar's height. */
6028 row = it.glyph_row - 1;
6029 if (!row->displays_text_p
6030 && row->height >= CANON_Y_UNIT (f))
6031 change_height_p = 1;
6032
6033 /* If row displays toolbar items, but is partially visible,
6034 change the toolbar's height. */
6035 if (row->displays_text_p
6036 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6037 change_height_p = 1;
6038
6039 /* Resize windows as needed by changing the `toolbar-lines'
6040 frame parameter. */
6041 if (change_height_p
6042 && (nlines = toolbar_lines_needed (f),
6043 nlines != XFASTINT (w->height)))
6044 {
6045 extern Lisp_Object Qtoolbar_lines;
6046 Lisp_Object frame;
6047
6048 XSETFRAME (frame, f);
6049 clear_glyph_matrix (w->desired_matrix);
6050 Fmodify_frame_parameters (frame,
6051 Fcons (Fcons (Qtoolbar_lines,
6052 make_number (nlines)),
6053 Qnil));
6054 fonts_changed_p = 1;
6055 }
6056 }
3450d04c 6057
5f5c8ee5 6058 return change_height_p;
96a410bc 6059}
90adcf20 6060
5f5c8ee5
GM
6061
6062/* Get information about the toolbar item which is displayed in GLYPH
6063 on frame F. Return in *PROP_IDX the index where toolbar item
6064 properties start in F->current_toolbar_items. Value is zero if
6065 GLYPH doesn't display a toolbar item. */
6066
6067int
6068toolbar_item_info (f, glyph, prop_idx)
6069 struct frame *f;
6070 struct glyph *glyph;
6071 int *prop_idx;
90adcf20 6072{
5f5c8ee5
GM
6073 Lisp_Object prop;
6074 int success_p;
6075
6076 /* Get the text property `menu-item' at pos. The value of that
6077 property is the start index of this item's properties in
6078 F->current_toolbar_items. */
6079 prop = Fget_text_property (make_number (glyph->charpos),
6080 Qmenu_item, f->current_toolbar_string);
6081 if (INTEGERP (prop))
6082 {
6083 *prop_idx = XINT (prop);
6084 success_p = 1;
6085 }
6086 else
6087 success_p = 0;
90adcf20 6088
5f5c8ee5
GM
6089 return success_p;
6090}
6091
6092#endif /* HAVE_WINDOW_SYSTEM */
90adcf20 6093
feb0c42f 6094
5f5c8ee5
GM
6095\f
6096/************************************************************************
6097 Horizontal scrolling
6098 ************************************************************************/
feb0c42f 6099
5f5c8ee5
GM
6100static int hscroll_window_tree P_ ((Lisp_Object));
6101static int hscroll_windows P_ ((Lisp_Object));
feb0c42f 6102
5f5c8ee5
GM
6103/* For all leaf windows in the window tree rooted at WINDOW, set their
6104 hscroll value so that PT is (i) visible in the window, and (ii) so
6105 that it is not within a certain margin at the window's left and
6106 right border. Value is non-zero if any window's hscroll has been
6107 changed. */
6108
6109static int
6110hscroll_window_tree (window)
6111 Lisp_Object window;
6112{
6113 int hscrolled_p = 0;
6114
6115 while (WINDOWP (window))
90adcf20 6116 {
5f5c8ee5
GM
6117 struct window *w = XWINDOW (window);
6118
6119 if (WINDOWP (w->hchild))
6120 hscrolled_p |= hscroll_window_tree (w->hchild);
6121 else if (WINDOWP (w->vchild))
6122 hscrolled_p |= hscroll_window_tree (w->vchild);
6123 else if (w->cursor.vpos >= 0)
6124 {
6125 int hscroll_margin, text_area_x, text_area_y;
6126 int text_area_width, text_area_height;
6127 struct glyph_row *cursor_row = MATRIX_ROW (w->current_matrix,
6128 w->cursor.vpos);
a2725ab2 6129
5f5c8ee5
GM
6130 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6131 &text_area_width, &text_area_height);
90adcf20 6132
5f5c8ee5
GM
6133 /* Scroll when cursor is inside this scroll margin. */
6134 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6135
6136 if ((XFASTINT (w->hscroll)
6137 && w->cursor.x < hscroll_margin)
6138 || (cursor_row->truncated_on_right_p
6139 && (w->cursor.x > text_area_width - hscroll_margin)))
08b610e4 6140 {
5f5c8ee5
GM
6141 struct it it;
6142 int hscroll;
6143 struct buffer *saved_current_buffer;
6144 int pt;
6145
6146 /* Find point in a display of infinite width. */
6147 saved_current_buffer = current_buffer;
6148 current_buffer = XBUFFER (w->buffer);
6149
6150 if (w == XWINDOW (selected_window))
6151 pt = BUF_PT (current_buffer);
6152 else
08b610e4 6153 {
5f5c8ee5
GM
6154 pt = marker_position (w->pointm);
6155 pt = max (BEGV, pt);
6156 pt = min (ZV, pt);
6157 }
6158
6159 /* Move iterator to pt starting at cursor_row->start in
6160 a line with infinite width. */
6161 init_to_row_start (&it, w, cursor_row);
6162 it.last_visible_x = INFINITY;
6163 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6164 current_buffer = saved_current_buffer;
6165
6166 /* Center cursor in window. */
6167 hscroll = (max (0, it.current_x - text_area_width / 2)
6168 / CANON_X_UNIT (it.f));
6169
6170 /* Don't call Fset_window_hscroll if value hasn't
6171 changed because it will prevent redisplay
6172 optimizations. */
6173 if (XFASTINT (w->hscroll) != hscroll)
6174 {
6175 Fset_window_hscroll (window, make_number (hscroll));
6176 hscrolled_p = 1;
08b610e4 6177 }
08b610e4 6178 }
08b610e4 6179 }
a2725ab2 6180
5f5c8ee5 6181 window = w->next;
90adcf20 6182 }
cd6dfed6 6183
5f5c8ee5
GM
6184 /* Value is non-zero if hscroll of any leaf window has been changed. */
6185 return hscrolled_p;
6186}
6187
6188
6189/* Set hscroll so that cursor is visible and not inside horizontal
6190 scroll margins for all windows in the tree rooted at WINDOW. See
6191 also hscroll_window_tree above. Value is non-zero if any window's
6192 hscroll has been changed. If it has, desired matrices on the frame
6193 of WINDOW are cleared. */
6194
6195static int
6196hscroll_windows (window)
6197 Lisp_Object window;
6198{
6199 int hscrolled_p = hscroll_window_tree (window);
6200 if (hscrolled_p)
6201 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6202 return hscrolled_p;
90adcf20 6203}
5f5c8ee5
GM
6204
6205
90adcf20 6206\f
5f5c8ee5
GM
6207/************************************************************************
6208 Redisplay
6209 ************************************************************************/
6210
6211/* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6212 to a non-zero value. This is sometimes handy to have in a debugger
6213 session. */
6214
6215#if GLYPH_DEBUG
a2889657 6216
5f5c8ee5
GM
6217/* Values of beg_unchanged and end_unchanged as of last call to
6218 try_window_id. */
6219
6220int debug_beg_unchanged, debug_end_unchanged;
6221
6222/* First and last unchanged row for try_window_id. */
6223
6224int debug_first_unchanged_at_end_vpos;
6225int debug_last_unchanged_at_beg_vpos;
6226
6227/* Delta vpos and y. */
6228
6229int debug_dvpos, debug_dy;
6230
6231/* Delta in characters and bytes for try_window_id. */
6232
6233int debug_delta, debug_delta_bytes;
6234
6235/* Values of window_end_pos and window_end_vpos at the end of
6236 try_window_id. */
6237
6238int debug_end_pos, debug_end_vpos;
6239
6240/* Append a string to W->desired_matrix->method. FMT is a printf
6241 format string. A1...A9 are a supplement for a variable-length
6242 argument list. If trace_redisplay_p is non-zero also printf the
6243 resulting string to stderr. */
6244
6245static void
6246debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
6247 struct window *w;
6248 char *fmt;
6249 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
6250{
6251 char buffer[512];
6252 char *method = w->desired_matrix->method;
6253 int len = strlen (method);
6254 int size = sizeof w->desired_matrix->method;
6255 int remaining = size - len - 1;
6256
6257 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
6258 if (len && remaining)
6259 {
6260 method[len] = '|';
6261 --remaining, ++len;
6262 }
6263
6264 strncpy (method + len, buffer, remaining);
6265
6266 if (trace_redisplay_p)
6267 fprintf (stderr, "%p (%s): %s\n",
6268 w,
6269 ((BUFFERP (w->buffer)
6270 && STRINGP (XBUFFER (w->buffer)->name))
6271 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
6272 : "no buffer"),
6273 buffer);
6274}
a2889657 6275
5f5c8ee5 6276#endif /* GLYPH_DEBUG */
90adcf20 6277
a2889657 6278
5f5c8ee5
GM
6279/* This counter is used to clear the face cache every once in a while
6280 in redisplay_internal. It is incremented for each redisplay.
6281 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
6282 cleared. */
0d231165 6283
5f5c8ee5 6284#define CLEAR_FACE_CACHE_COUNT 10000
463f6b91
RS
6285static int clear_face_cache_count;
6286
20de20dc 6287/* Record the previous terminal frame we displayed. */
5f5c8ee5
GM
6288
6289static struct frame *previous_terminal_frame;
6290
6291/* Non-zero while redisplay_internal is in progress. */
6292
6293int redisplaying_p;
6294
6295
6296/* Value is non-zero if all changes in window W, which displays
6297 current_buffer, are in the text between START and END. START is a
6298 buffer position, END is given as a distance from Z. Used in
6299 redisplay_internal for display optimization. */
6300
6301static INLINE int
6302text_outside_line_unchanged_p (w, start, end)
6303 struct window *w;
6304 int start, end;
6305{
6306 int unchanged_p = 1;
6307
6308 /* If text or overlays have changed, see where. */
6309 if (XFASTINT (w->last_modified) < MODIFF
6310 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
6311 {
6312 /* Gap in the line? */
6313 if (GPT < start || Z - GPT < end)
6314 unchanged_p = 0;
6315
6316 /* Changes start in front of the line, or end after it? */
6317 if (unchanged_p
6318 && (beg_unchanged < start - 1
6319 || end_unchanged < end))
6320 unchanged_p = 0;
6321
6322 /* If selective display, can't optimize if changes start at the
6323 beginning of the line. */
6324 if (unchanged_p
6325 && INTEGERP (current_buffer->selective_display)
6326 && XINT (current_buffer->selective_display) > 0
6327 && (beg_unchanged < start || GPT <= start))
6328 unchanged_p = 0;
6329 }
6330
6331 return unchanged_p;
6332}
6333
6334
6335/* Do a frame update, taking possible shortcuts into account. This is
6336 the main external entry point for redisplay.
6337
6338 If the last redisplay displayed an echo area message and that message
6339 is no longer requested, we clear the echo area or bring back the
6340 mini-buffer if that is in use. */
20de20dc 6341
a2889657
JB
6342void
6343redisplay ()
e9874cee
RS
6344{
6345 redisplay_internal (0);
6346}
6347
5f5c8ee5
GM
6348
6349/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
6350 response to any user action; therefore, we should preserve the echo
6351 area. (Actually, our caller does that job.) Perhaps in the future
6352 avoid recentering windows if it is not necessary; currently that
6353 causes some problems. */
e9874cee
RS
6354
6355static void
6356redisplay_internal (preserve_echo_area)
6357 int preserve_echo_area;
a2889657 6358{
5f5c8ee5
GM
6359 struct window *w = XWINDOW (selected_window);
6360 struct frame *f = XFRAME (w->frame);
6361 int pause;
a2889657 6362 int must_finish = 0;
5f5c8ee5 6363 struct text_pos tlbufpos, tlendpos;
89819bdd 6364 int number_of_visible_frames;
a2889657 6365
5f5c8ee5
GM
6366 /* Non-zero means redisplay has to consider all windows on all
6367 frames. Zero means, only selected_window is considered. */
6368 int consider_all_windows_p;
6369
6370 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
6371
6372 /* No redisplay if running in batch mode or frame is not yet fully
6373 initialized, or redisplay is explicitly turned off by setting
6374 Vinhibit_redisplay. */
6375 if (noninteractive
6376 || !NILP (Vinhibit_redisplay)
6377 || !f->glyphs_initialized_p)
a2889657
JB
6378 return;
6379
5f5c8ee5
GM
6380 /* The flag redisplay_performed_directly_p is set by
6381 direct_output_for_insert when it already did the whole screen
6382 update necessary. */
6383 if (redisplay_performed_directly_p)
6384 {
6385 redisplay_performed_directly_p = 0;
6386 if (!hscroll_windows (selected_window))
6387 return;
6388 }
6389
15f0cf78
RS
6390#ifdef USE_X_TOOLKIT
6391 if (popup_activated ())
6392 return;
6393#endif
6394
5f5c8ee5 6395 if (redisplaying_p)
735c094c 6396 return;
5f5c8ee5 6397 ++redisplaying_p;
735c094c 6398
8b32d885
RS
6399 retry:
6400
5f5c8ee5
GM
6401 /* If new fonts have been loaded that make a glyph matrix adjustment
6402 necessary, do it. */
6403 if (fonts_changed_p)
6404 {
6405 adjust_glyphs (NULL);
6406 ++windows_or_buffers_changed;
6407 fonts_changed_p = 0;
6408 }
6409
fd8ff63d 6410 if (! FRAME_WINDOW_P (selected_frame)
20de20dc
RS
6411 && previous_terminal_frame != selected_frame)
6412 {
5f5c8ee5
GM
6413 /* Since frames on an ASCII terminal share the same display
6414 area, displaying a different frame means redisplay the whole
6415 thing. */
20de20dc
RS
6416 windows_or_buffers_changed++;
6417 SET_FRAME_GARBAGED (selected_frame);
6418 XSETFRAME (Vterminal_frame, selected_frame);
6419 }
6420 previous_terminal_frame = selected_frame;
20de20dc 6421
5f5c8ee5
GM
6422 /* Set the visible flags for all frames. Do this before checking
6423 for resized or garbaged frames; they want to know if their frames
6424 are visible. See the comment in frame.h for
6425 FRAME_SAMPLE_VISIBILITY. */
d724d989 6426 {
35f56f96 6427 Lisp_Object tail, frame;
d724d989 6428
89819bdd
RS
6429 number_of_visible_frames = 0;
6430
35f56f96 6431 FOR_EACH_FRAME (tail, frame)
f82aff7c 6432 {
5f5c8ee5
GM
6433 struct frame *f = XFRAME (frame);
6434
6435 FRAME_SAMPLE_VISIBILITY (f);
6436 if (FRAME_VISIBLE_P (f))
6437 ++number_of_visible_frames;
6438 clear_desired_matrices (f);
f82aff7c 6439 }
d724d989
JB
6440 }
6441
44fa5b1e 6442 /* Notice any pending interrupt request to change frame size. */
a2889657
JB
6443 do_pending_window_change ();
6444
5f5c8ee5 6445 /* Clear frames marked as garbaged. */
44fa5b1e 6446 if (frame_garbaged)
a2889657 6447 {
5f5c8ee5
GM
6448 /* Old redisplay called redraw_garbaged_frames here which in
6449 turn called redraw_frame which in turn called clear_frame.
6450 The call to clear_frame is a source of flickering. After
6451 checking the places where SET_FRAME_GARBAGED is called, I
6452 believe a clear_frame is not necessary. It should suffice in
6453 the new redisplay to invalidate all current matrices, and
6454 ensure a complete redisplay of all windows. */
6455 Lisp_Object tail, frame;
6456
6457 FOR_EACH_FRAME (tail, frame)
6458 {
6459 struct frame *f = XFRAME (frame);
6460
6461 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
6462 {
6463 clear_current_matrices (f);
6464 f->garbaged = 0;
6465 }
6466 }
6467
44fa5b1e 6468 frame_garbaged = 0;
5f5c8ee5 6469 ++windows_or_buffers_changed;
a2889657
JB
6470 }
6471
5f5c8ee5 6472 /* Build menubar and toolbar items. */
f82aff7c
RS
6473 prepare_menu_bars ();
6474
28995e67 6475 if (windows_or_buffers_changed)
a2889657
JB
6476 update_mode_lines++;
6477
538f13d4
RS
6478 /* Detect case that we need to write or remove a star in the mode line. */
6479 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
a2889657
JB
6480 {
6481 w->update_mode_line = Qt;
6482 if (buffer_shared > 1)
6483 update_mode_lines++;
6484 }
6485
5f5c8ee5 6486 /* If %c is in the mode line, update it if needed. */
28995e67
RS
6487 if (!NILP (w->column_number_displayed)
6488 /* This alternative quickly identifies a common case
6489 where no change is needed. */
6490 && !(PT == XFASTINT (w->last_point)
8850a573
RS
6491 && XFASTINT (w->last_modified) >= MODIFF
6492 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
6493 && XFASTINT (w->column_number_displayed) != current_column ())
6494 w->update_mode_line = Qt;
6495
44fa5b1e 6496 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
a2889657 6497
5f5c8ee5
GM
6498 /* The variable buffer_shared is set in redisplay_window and
6499 indicates that we redisplay a buffer in different windows. See
6500 there. */
6501 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
a2889657
JB
6502
6503 /* If specs for an arrow have changed, do thorough redisplay
6504 to ensure we remove any arrow that should no longer exist. */
d45de95b 6505 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
ded34426 6506 || ! EQ (Voverlay_arrow_string, last_arrow_string))
5f5c8ee5 6507 consider_all_windows_p = windows_or_buffers_changed = 1;
a2889657 6508
90adcf20
RS
6509 /* Normally the message* functions will have already displayed and
6510 updated the echo area, but the frame may have been trashed, or
6511 the update may have been preempted, so display the echo area
6512 again here. */
5f5c8ee5
GM
6513 if (echo_area_glyphs
6514 || STRINGP (echo_area_message)
6515 || previous_echo_glyphs
6516 || STRINGP (previous_echo_area_message))
90adcf20 6517 {
5f5c8ee5 6518 echo_area_display (0);
90adcf20
RS
6519 must_finish = 1;
6520 }
6521
5f5c8ee5
GM
6522 /* If showing the region, and mark has changed, we must redisplay
6523 the whole window. The assignment to this_line_start_pos prevents
6524 the optimization directly below this if-statement. */
bd66d1ba
RS
6525 if (((!NILP (Vtransient_mark_mode)
6526 && !NILP (XBUFFER (w->buffer)->mark_active))
6527 != !NILP (w->region_showing))
82d04750
JB
6528 || (!NILP (w->region_showing)
6529 && !EQ (w->region_showing,
6530 Fmarker_position (XBUFFER (w->buffer)->mark))))
5f5c8ee5
GM
6531 CHARPOS (this_line_start_pos) = 0;
6532
6533 /* Optimize the case that only the line containing the cursor in the
6534 selected window has changed. Variables starting with this_ are
6535 set in display_line and record information about the line
6536 containing the cursor. */
6537 tlbufpos = this_line_start_pos;
6538 tlendpos = this_line_end_pos;
6539 if (!consider_all_windows_p
6540 && CHARPOS (tlbufpos) > 0
6541 && NILP (w->update_mode_line)
73af359d 6542 && !current_buffer->clip_changed
44fa5b1e 6543 && FRAME_VISIBLE_P (XFRAME (w->frame))
f21ef775 6544 && !FRAME_OBSCURED_P (XFRAME (w->frame))
5f5c8ee5 6545 /* Make sure recorded data applies to current buffer, etc. */
a2889657
JB
6546 && this_line_buffer == current_buffer
6547 && current_buffer == XBUFFER (w->buffer)
265a9e55 6548 && NILP (w->force_start)
5f5c8ee5
GM
6549 /* Point must be on the line that we have info recorded about. */
6550 && PT >= CHARPOS (tlbufpos)
6551 && PT <= Z - CHARPOS (tlendpos)
a2889657
JB
6552 /* All text outside that line, including its final newline,
6553 must be unchanged */
5f5c8ee5
GM
6554 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
6555 CHARPOS (tlendpos)))
6556 {
6557 if (CHARPOS (tlbufpos) > BEGV
6558 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
6559 && (CHARPOS (tlbufpos) == ZV
6560 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
a2889657
JB
6561 /* Former continuation line has disappeared by becoming empty */
6562 goto cancel;
6563 else if (XFASTINT (w->last_modified) < MODIFF
8850a573 6564 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
a2889657
JB
6565 || MINI_WINDOW_P (w))
6566 {
1c9241f5
KH
6567 /* We have to handle the case of continuation around a
6568 wide-column character (See the comment in indent.c around
6569 line 885).
6570
6571 For instance, in the following case:
6572
6573 -------- Insert --------
6574 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
6575 J_I_ ==> J_I_ `^^' are cursors.
6576 ^^ ^^
6577 -------- --------
6578
6579 As we have to redraw the line above, we should goto cancel. */
6580
5f5c8ee5
GM
6581 struct it it;
6582 int line_height_before = this_line_pixel_height;
6583
6584 /* Note that start_display will handle the case that the
6585 line starting at tlbufpos is a continuation lines. */
6586 start_display (&it, w, tlbufpos);
6587
6588 /* Implementation note: It this still necessary? */
6589 if (it.current_x != this_line_start_x)
1c9241f5
KH
6590 goto cancel;
6591
5f5c8ee5
GM
6592 TRACE ((stderr, "trying display optimization 1\n"));
6593 w->cursor.vpos = -1;
a2889657 6594 overlay_arrow_seen = 0;
5f5c8ee5
GM
6595 it.vpos = this_line_vpos;
6596 it.current_y = this_line_y;
6597 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
6598 display_line (&it);
6599
a2889657 6600 /* If line contains point, is not continued,
5f5c8ee5
GM
6601 and ends at same distance from eob as before, we win */
6602 if (w->cursor.vpos >= 0
6603 /* Line is not continued, otherwise this_line_start_pos
6604 would have been set to 0 in display_line. */
6605 && CHARPOS (this_line_start_pos)
6606 /* Line ends as before. */
6607 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
6608 /* Line has same height as before. Otherwise other lines
6609 would have to be shifted up or down. */
6610 && this_line_pixel_height == line_height_before)
a2889657 6611 {
5f5c8ee5
GM
6612 /* If this is not the window's last line, we must adjust
6613 the charstarts of the lines below. */
6614 if (it.current_y < it.last_visible_y)
6615 {
6616 struct glyph_row *row
6617 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
6618 int delta, delta_bytes;
6619
6620 if (Z - CHARPOS (tlendpos) == ZV)
6621 {
6622 /* This line ends at end of (accessible part of)
6623 buffer. There is no newline to count. */
6624 delta = (Z
6625 - CHARPOS (tlendpos)
6626 - MATRIX_ROW_START_CHARPOS (row));
6627 delta_bytes = (Z_BYTE
6628 - BYTEPOS (tlendpos)
6629 - MATRIX_ROW_START_BYTEPOS (row));
6630 }
6631 else
6632 {
6633 /* This line ends in a newline. Must take
6634 account of the newline and the rest of the
6635 text that follows. */
6636 delta = (Z
6637 - CHARPOS (tlendpos)
6638 - MATRIX_ROW_START_CHARPOS (row));
6639 delta_bytes = (Z_BYTE
6640 - BYTEPOS (tlendpos)
6641 - MATRIX_ROW_START_BYTEPOS (row));
6642 }
6643
6644 increment_glyph_matrix_buffer_positions (w->current_matrix,
6645 this_line_vpos + 1,
6646 w->current_matrix->nrows,
6647 delta, delta_bytes);
85bcef6c 6648 }
46db8486 6649
5f5c8ee5
GM
6650 /* If this row displays text now but previously didn't,
6651 or vice versa, w->window_end_vpos may have to be
6652 adjusted. */
6653 if ((it.glyph_row - 1)->displays_text_p)
6654 {
6655 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
6656 XSETINT (w->window_end_vpos, this_line_vpos);
6657 }
6658 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
6659 && this_line_vpos > 0)
6660 XSETINT (w->window_end_vpos, this_line_vpos - 1);
6661 w->window_end_valid = Qnil;
6662
6663 /* Update hint: No need to try to scroll in update_window. */
6664 w->desired_matrix->no_scrolling_p = 1;
6665
6666#if GLYPH_DEBUG
6667 *w->desired_matrix->method = 0;
6668 debug_method_add (w, "optimization 1");
6669#endif
a2889657
JB
6670 goto update;
6671 }
6672 else
6673 goto cancel;
6674 }
5f5c8ee5
GM
6675 else if (/* Cursor position hasn't changed. */
6676 PT == XFASTINT (w->last_point)
b6f0fe04
RS
6677 /* Make sure the cursor was last displayed
6678 in this window. Otherwise we have to reposition it. */
5f5c8ee5
GM
6679 && 0 <= w->cursor.vpos
6680 && XINT (w->height) > w->cursor.vpos)
a2889657
JB
6681 {
6682 if (!must_finish)
6683 {
6684 do_pending_window_change ();
5f5c8ee5
GM
6685
6686 /* We used to always goto end_of_redisplay here, but this
6687 isn't enough if we have a blinking cursor. */
6688 if (w->cursor_off_p == w->last_cursor_off_p)
6689 goto end_of_redisplay;
a2889657
JB
6690 }
6691 goto update;
6692 }
8b51f1e3
KH
6693 /* If highlighting the region, or if the cursor is in the echo area,
6694 then we can't just move the cursor. */
bd66d1ba
RS
6695 else if (! (!NILP (Vtransient_mark_mode)
6696 && !NILP (current_buffer->mark_active))
293a54ce
RS
6697 && (w == XWINDOW (current_buffer->last_selected_window)
6698 || highlight_nonselected_windows)
8b51f1e3
KH
6699 && NILP (w->region_showing)
6700 && !cursor_in_echo_area)
a2889657 6701 {
5f5c8ee5
GM
6702 struct it it;
6703 struct glyph_row *row;
6704
6705 /* Skip from tlbufpos to PT and see where it is. Note that
6706 PT may be in invisible text. If so, we will end at the
6707 next visible position. */
6708 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
6709 NULL, DEFAULT_FACE_ID);
6710 it.current_x = this_line_start_x;
6711 it.current_y = this_line_y;
6712 it.vpos = this_line_vpos;
6713
6714 /* The call to move_it_to stops in front of PT, but
6715 moves over before-strings. */
6716 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6717
6718 if (it.vpos == this_line_vpos
6719 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
6720 row->enabled_p))
a2889657 6721 {
5f5c8ee5
GM
6722 xassert (this_line_vpos == it.vpos);
6723 xassert (this_line_y == it.current_y);
6724 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
a2889657
JB
6725 goto update;
6726 }
6727 else
6728 goto cancel;
6729 }
5f5c8ee5 6730
a2889657 6731 cancel:
5f5c8ee5
GM
6732 /* Text changed drastically or point moved off of line. */
6733 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
a2889657
JB
6734 }
6735
5f5c8ee5
GM
6736 CHARPOS (this_line_start_pos) = 0;
6737 consider_all_windows_p |= buffer_shared > 1;
6738 ++clear_face_cache_count;
a2889657 6739
5f5c8ee5
GM
6740
6741 /* Build desired matrices. If consider_all_windows_p is non-zero,
6742 do it for all windows on all frames. Otherwise do it for
6743 selected_window, only. */
463f6b91 6744
5f5c8ee5 6745 if (consider_all_windows_p)
a2889657 6746 {
35f56f96 6747 Lisp_Object tail, frame;
a2889657 6748
5f5c8ee5
GM
6749 /* Clear the face cache eventually. */
6750 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
463f6b91 6751 {
5f5c8ee5 6752 clear_face_cache (0);
463f6b91
RS
6753 clear_face_cache_count = 0;
6754 }
31b24551 6755
5f5c8ee5
GM
6756 /* Recompute # windows showing selected buffer. This will be
6757 incremented each time such a window is displayed. */
a2889657
JB
6758 buffer_shared = 0;
6759
35f56f96 6760 FOR_EACH_FRAME (tail, frame)
30c566e4 6761 {
5f5c8ee5 6762 struct frame *f = XFRAME (frame);
fd8ff63d 6763 if (FRAME_WINDOW_P (f) || f == selected_frame)
9769686d 6764 {
5f5c8ee5
GM
6765 /* Mark all the scroll bars to be removed; we'll redeem
6766 the ones we want when we redisplay their windows. */
9769686d
RS
6767 if (condemn_scroll_bars_hook)
6768 (*condemn_scroll_bars_hook) (f);
30c566e4 6769
f21ef775 6770 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
5f5c8ee5 6771 redisplay_windows (FRAME_ROOT_WINDOW (f));
30c566e4 6772
5f5c8ee5
GM
6773 /* Any scroll bars which redisplay_windows should have
6774 nuked should now go away. */
9769686d
RS
6775 if (judge_scroll_bars_hook)
6776 (*judge_scroll_bars_hook) (f);
6777 }
30c566e4 6778 }
a2889657 6779 }
5f5c8ee5
GM
6780 else if (FRAME_VISIBLE_P (selected_frame)
6781 && !FRAME_OBSCURED_P (selected_frame))
6782 redisplay_window (selected_window, 1);
6783
6784
6785 /* Compare desired and current matrices, perform output. */
6786
6787update:
6788
6789 /* If fonts changed, display again. */
6790 if (fonts_changed_p)
6791 goto retry;
a2889657 6792
a2889657
JB
6793 /* Prevent various kinds of signals during display update.
6794 stdio is not robust about handling signals,
6795 which can cause an apparent I/O error. */
6796 if (interrupt_input)
6797 unrequest_sigio ();
6798 stop_polling ();
6799
5f5c8ee5 6800 if (consider_all_windows_p)
a2889657
JB
6801 {
6802 Lisp_Object tail;
6803
6804 pause = 0;
6805
44fa5b1e 6806 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
a2889657 6807 {
5f5c8ee5 6808 struct frame *f;
a2889657 6809
e24c997d 6810 if (!FRAMEP (XCONS (tail)->car))
a2889657
JB
6811 continue;
6812
44fa5b1e 6813 f = XFRAME (XCONS (tail)->car);
1af9f229 6814
fd8ff63d 6815 if ((FRAME_WINDOW_P (f) || f == selected_frame)
f21ef775 6816 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
a2889657 6817 {
5f5c8ee5
GM
6818 /* Mark all windows as to be updated. */
6819 set_window_update_flags (XWINDOW (f->root_window), 1);
44fa5b1e 6820 pause |= update_frame (f, 0, 0);
a2889657 6821 if (!pause)
efc63ef0 6822 {
5f5c8ee5
GM
6823 if (hscroll_windows (f->root_window))
6824 goto retry;
6825
efc63ef0
RS
6826 mark_window_display_accurate (f->root_window, 1);
6827 if (frame_up_to_date_hook != 0)
6828 (*frame_up_to_date_hook) (f);
6829 }
a2889657
JB
6830 }
6831 }
6832 }
6833 else
6e8290aa 6834 {
5f5c8ee5
GM
6835 if (FRAME_VISIBLE_P (selected_frame)
6836 && !FRAME_OBSCURED_P (selected_frame))
6837 {
6838 XWINDOW (selected_window)->must_be_updated_p = 1;
6839 pause = update_frame (selected_frame, 0, 0);
6840 if (!pause && hscroll_windows (selected_window))
6841 goto retry;
6842 }
4d641a15
KH
6843 else
6844 pause = 0;
d724d989 6845
8de2d90b 6846 /* We may have called echo_area_display at the top of this
44fa5b1e
JB
6847 function. If the echo area is on another frame, that may
6848 have put text on a frame other than the selected one, so the
6849 above call to update_frame would not have caught it. Catch
8de2d90b
JB
6850 it here. */
6851 {
84faf44c 6852 Lisp_Object mini_window;
5f5c8ee5 6853 struct frame *mini_frame;
84faf44c
RS
6854
6855 mini_window = FRAME_MINIBUF_WINDOW (selected_frame);
6856 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8de2d90b 6857
fd8ff63d 6858 if (mini_frame != selected_frame && FRAME_WINDOW_P (mini_frame))
5f5c8ee5
GM
6859 {
6860 XWINDOW (mini_window)->must_be_updated_p = 1;
6861 pause |= update_frame (mini_frame, 0, 0);
6862 if (!pause && hscroll_windows (mini_window))
6863 goto retry;
6864 }
8de2d90b 6865 }
6e8290aa 6866 }
a2889657 6867
5f5c8ee5
GM
6868 /* If display was paused because of pending input, make sure we do a
6869 thorough update the next time. */
a2889657
JB
6870 if (pause)
6871 {
5f5c8ee5
GM
6872 /* Prevent the optimization at the beginning of
6873 redisplay_internal that tries a single-line update of the
6874 line containing the cursor in the selected window. */
6875 CHARPOS (this_line_start_pos) = 0;
6876
6877 /* Let the overlay arrow be updated the next time. */
265a9e55 6878 if (!NILP (last_arrow_position))
a2889657
JB
6879 {
6880 last_arrow_position = Qt;
6881 last_arrow_string = Qt;
6882 }
5f5c8ee5
GM
6883
6884 /* If we pause after scrolling, some rows in the current
6885 matrices of some windows are not valid. */
6886 if (!WINDOW_FULL_WIDTH_P (w)
6887 && !FRAME_WINDOW_P (XFRAME (w->frame)))
a2889657
JB
6888 update_mode_lines = 1;
6889 }
6890
5f5c8ee5
GM
6891 /* Now text on frame agrees with windows, so put info into the
6892 windows for partial redisplay to follow. */
a2889657
JB
6893 if (!pause)
6894 {
6895 register struct buffer *b = XBUFFER (w->buffer);
6896
a2889657 6897 unchanged_modified = BUF_MODIFF (b);
8850a573 6898 overlay_unchanged_modified = BUF_OVERLAY_MODIFF (b);
a2889657
JB
6899 beg_unchanged = BUF_GPT (b) - BUF_BEG (b);
6900 end_unchanged = BUF_Z (b) - BUF_GPT (b);
6901
5f5c8ee5 6902 if (consider_all_windows_p)
11e82b76 6903 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame), 1);
a2889657
JB
6904 else
6905 {
5f5c8ee5
GM
6906 XSETFASTINT (w->last_point, BUF_PT (b));
6907 w->last_cursor = w->cursor;
6908 w->last_cursor_off_p = w->cursor_off_p;
6909
28995e67 6910 b->clip_changed = 0;
a2889657 6911 w->update_mode_line = Qnil;
c2213350 6912 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
8850a573 6913 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
538f13d4
RS
6914 w->last_had_star
6915 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6916 ? Qt : Qnil);
3ee4159a
RS
6917
6918 /* Record if we are showing a region, so can make sure to
6919 update it fully at next redisplay. */
6920 w->region_showing = (!NILP (Vtransient_mark_mode)
293a54ce
RS
6921 && (w == XWINDOW (current_buffer->last_selected_window)
6922 || highlight_nonselected_windows)
3ee4159a
RS
6923 && !NILP (XBUFFER (w->buffer)->mark_active)
6924 ? Fmarker_position (XBUFFER (w->buffer)->mark)
6925 : Qnil);
6926
d2f84654 6927 w->window_end_valid = w->buffer;
d45de95b 6928 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657 6929 last_arrow_string = Voverlay_arrow_string;
efc63ef0
RS
6930 if (frame_up_to_date_hook != 0)
6931 (*frame_up_to_date_hook) (selected_frame);
a2889657 6932 }
5f5c8ee5 6933
a2889657
JB
6934 update_mode_lines = 0;
6935 windows_or_buffers_changed = 0;
6936 }
6937
5f5c8ee5
GM
6938 /* Start SIGIO interrupts coming again. Having them off during the
6939 code above makes it less likely one will discard output, but not
6940 impossible, since there might be stuff in the system buffer here.
a2889657 6941 But it is much hairier to try to do anything about that. */
a2889657
JB
6942 if (interrupt_input)
6943 request_sigio ();
6944 start_polling ();
6945
5f5c8ee5
GM
6946 /* If a frame has become visible which was not before, redisplay
6947 again, so that we display it. Expose events for such a frame
6948 (which it gets when becoming visible) don't call the parts of
6949 redisplay constructing glyphs, so simply exposing a frame won't
6950 display anything in this case. So, we have to display these
6951 frames here explicitly. */
11c52c4f
RS
6952 if (!pause)
6953 {
6954 Lisp_Object tail, frame;
6955 int new_count = 0;
6956
6957 FOR_EACH_FRAME (tail, frame)
6958 {
6959 int this_is_visible = 0;
8e83f802
RS
6960
6961 if (XFRAME (frame)->visible)
6962 this_is_visible = 1;
6963 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
6964 if (XFRAME (frame)->visible)
6965 this_is_visible = 1;
11c52c4f
RS
6966
6967 if (this_is_visible)
6968 new_count++;
6969 }
6970
89819bdd 6971 if (new_count != number_of_visible_frames)
11c52c4f
RS
6972 windows_or_buffers_changed++;
6973 }
6974
44fa5b1e 6975 /* Change frame size now if a change is pending. */
a2889657 6976 do_pending_window_change ();
d8e242fd 6977
8b32d885
RS
6978 /* If we just did a pending size change, or have additional
6979 visible frames, redisplay again. */
3c8c72e0 6980 if (windows_or_buffers_changed && !pause)
8b32d885 6981 goto retry;
5f5c8ee5
GM
6982
6983 end_of_redisplay:;
6984
6985 if (--redisplaying_p < 0)
6986 redisplaying_p = 0;
a2889657
JB
6987}
6988
5f5c8ee5
GM
6989
6990/* Redisplay, but leave alone any recent echo area message unless
6991 another message has been requested in its place.
a2889657
JB
6992
6993 This is useful in situations where you need to redisplay but no
6994 user action has occurred, making it inappropriate for the message
6995 area to be cleared. See tracking_off and
6996 wait_reading_process_input for examples of these situations. */
6997
8991bb31 6998void
a2889657
JB
6999redisplay_preserve_echo_area ()
7000{
5f5c8ee5
GM
7001 if (!echo_area_glyphs
7002 && !STRINGP (echo_area_message)
7003 && (previous_echo_glyphs
7004 || STRINGP (previous_echo_area_message)))
a2889657
JB
7005 {
7006 echo_area_glyphs = previous_echo_glyphs;
5f5c8ee5
GM
7007 echo_area_message = previous_echo_area_message;
7008 echo_area_glyphs_length = previous_echo_glyphs_length;
e9874cee 7009 redisplay_internal (1);
5f5c8ee5
GM
7010 echo_area_glyphs = NULL;
7011 echo_area_message = Qnil;
a2889657
JB
7012 }
7013 else
e9874cee 7014 redisplay_internal (1);
a2889657
JB
7015}
7016
5f5c8ee5
GM
7017
7018/* Mark the display of windows in the window tree rooted at WINDOW as
7019 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7020 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7021 the next time redisplay_internal is called. */
7022
a2889657 7023void
5f5c8ee5 7024mark_window_display_accurate (window, accurate_p)
a2889657 7025 Lisp_Object window;
5f5c8ee5 7026 int accurate_p;
a2889657 7027{
5f5c8ee5
GM
7028 struct window *w;
7029
7030 for (; !NILP (window); window = w->next)
a2889657
JB
7031 {
7032 w = XWINDOW (window);
7033
5f5c8ee5 7034 if (BUFFERP (w->buffer))
bd66d1ba 7035 {
5f5c8ee5
GM
7036 struct buffer *b = XBUFFER (w->buffer);
7037
c2213350 7038 XSETFASTINT (w->last_modified,
5f5c8ee5 7039 accurate_p ? BUF_MODIFF (b) : 0);
8850a573 7040 XSETFASTINT (w->last_overlay_modified,
5f5c8ee5
GM
7041 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7042 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7043 ? Qt : Qnil);
bd66d1ba 7044
5f5c8ee5
GM
7045#if 0 /* I don't think this is necessary because display_line does it.
7046 Let's check it. */
bd66d1ba
RS
7047 /* Record if we are showing a region, so can make sure to
7048 update it fully at next redisplay. */
5f5c8ee5
GM
7049 w->region_showing
7050 = (!NILP (Vtransient_mark_mode)
7051 && (w == XWINDOW (current_buffer->last_selected_window)
7052 || highlight_nonselected_windows)
7053 && (!NILP (b->mark_active)
7054 ? Fmarker_position (b->mark)
7055 : Qnil));
7056#endif
7057
7058 if (accurate_p)
7059 {
7060 b->clip_changed = 0;
7061 w->last_cursor = w->cursor;
7062 w->last_cursor_off_p = w->cursor_off_p;
7063 if (w == XWINDOW (selected_window))
7064 w->last_point = BUF_PT (b);
7065 else
7066 w->last_point = XMARKER (w->pointm)->charpos;
7067 }
bd66d1ba
RS
7068 }
7069
d2f84654 7070 w->window_end_valid = w->buffer;
a2889657
JB
7071 w->update_mode_line = Qnil;
7072
265a9e55 7073 if (!NILP (w->vchild))
5f5c8ee5 7074 mark_window_display_accurate (w->vchild, accurate_p);
265a9e55 7075 if (!NILP (w->hchild))
5f5c8ee5 7076 mark_window_display_accurate (w->hchild, accurate_p);
a2889657
JB
7077 }
7078
5f5c8ee5 7079 if (accurate_p)
a2889657 7080 {
d45de95b 7081 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
a2889657
JB
7082 last_arrow_string = Voverlay_arrow_string;
7083 }
7084 else
7085 {
5f5c8ee5
GM
7086 /* Force a thorough redisplay the next time by setting
7087 last_arrow_position and last_arrow_string to t, which is
7088 unequal to any useful value of Voverlay_arrow_... */
a2889657
JB
7089 last_arrow_position = Qt;
7090 last_arrow_string = Qt;
7091 }
7092}
5f5c8ee5
GM
7093
7094
7095/* Return value in display table DP (Lisp_Char_Table *) for character
7096 C. Since a display table doesn't have any parent, we don't have to
7097 follow parent. Do not call this function directly but use the
7098 macro DISP_CHAR_VECTOR. */
7099
7100Lisp_Object
7101disp_char_vector (dp, c)
7102 struct Lisp_Char_Table *dp;
7103 int c;
7104{
7105 int code[4], i;
7106 Lisp_Object val;
7107
7108 if (SINGLE_BYTE_CHAR_P (c))
7109 return (dp->contents[c]);
7110
7111 SPLIT_NON_ASCII_CHAR (c, code[0], code[1], code[2]);
7112 if (code[0] != CHARSET_COMPOSITION)
7113 {
7114 if (code[1] < 32)
7115 code[1] = -1;
7116 else if (code[2] < 32)
7117 code[2] = -1;
7118 }
7119
7120 /* Here, the possible range of code[0] (== charset ID) is
7121 128..max_charset. Since the top level char table contains data
7122 for multibyte characters after 256th element, we must increment
7123 code[0] by 128 to get a correct index. */
7124 code[0] += 128;
7125 code[3] = -1; /* anchor */
7126
7127 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
7128 {
7129 val = dp->contents[code[i]];
7130 if (!SUB_CHAR_TABLE_P (val))
7131 return (NILP (val) ? dp->defalt : val);
7132 }
7133
7134 /* Here, val is a sub char table. We return the default value of
7135 it. */
7136 return (dp->defalt);
7137}
7138
7139
a2889657 7140\f
5f5c8ee5
GM
7141/***********************************************************************
7142 Window Redisplay
7143 ***********************************************************************/
a2725ab2 7144
5f5c8ee5 7145/* Redisplay all leaf windows in the window tree rooted at WINDOW. */
90adcf20
RS
7146
7147static void
5f5c8ee5
GM
7148redisplay_windows (window)
7149 Lisp_Object window;
90adcf20 7150{
5f5c8ee5
GM
7151 while (!NILP (window))
7152 {
7153 struct window *w = XWINDOW (window);
7154
7155 if (!NILP (w->hchild))
7156 redisplay_windows (w->hchild);
7157 else if (!NILP (w->vchild))
7158 redisplay_windows (w->vchild);
7159 else
7160 redisplay_window (window, 0);
a2725ab2 7161
5f5c8ee5
GM
7162 window = w->next;
7163 }
7164}
7165
7166
7167/* Set cursor position of W. PT is assumed to be displayed in ROW.
7168 DELTA is the number of bytes by which positions recorded in ROW
7169 differ from current buffer positions. */
7170
7171void
7172set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
7173 struct window *w;
7174 struct glyph_row *row;
7175 struct glyph_matrix *matrix;
7176 int delta, delta_bytes, dy, dvpos;
7177{
7178 struct glyph *glyph = row->glyphs[TEXT_AREA];
7179 struct glyph *end = glyph + row->used[TEXT_AREA];
7180 int x = row->x;
7181 int pt_old = PT - delta;
7182
7183 /* Skip over glyphs not having an object at the start of the row.
7184 These are special glyphs like truncation marks on terminal
7185 frames. */
7186 if (row->displays_text_p)
7187 while (glyph < end
7188 && !glyph->object
7189 && glyph->charpos < 0)
7190 {
7191 x += glyph->pixel_width;
7192 ++glyph;
7193 }
7194
7195 while (glyph < end
7196 && glyph->object
7197 && (!BUFFERP (glyph->object)
7198 || glyph->charpos < pt_old))
7199 {
7200 x += glyph->pixel_width;
7201 ++glyph;
7202 }
7203
7204 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
7205 w->cursor.x = x;
7206 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
7207 w->cursor.y = row->y + dy;
7208
7209 if (w == XWINDOW (selected_window))
7210 {
7211 if (!row->continued_p
7212 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
7213 && row->x == 0)
7214 {
7215 this_line_buffer = XBUFFER (w->buffer);
7216
7217 CHARPOS (this_line_start_pos)
7218 = MATRIX_ROW_START_CHARPOS (row) + delta;
7219 BYTEPOS (this_line_start_pos)
7220 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
7221
7222 CHARPOS (this_line_end_pos)
7223 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
7224 BYTEPOS (this_line_end_pos)
7225 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
7226
7227 this_line_y = w->cursor.y;
7228 this_line_pixel_height = row->height;
7229 this_line_vpos = w->cursor.vpos;
7230 this_line_start_x = row->x;
7231 }
7232 else
7233 CHARPOS (this_line_start_pos) = 0;
7234 }
7235}
7236
7237
7238/* Run window scroll functions, if any, for WINDOW with new window
7239 start STARTP. Sets the window start of WINDOW to that position. */
7240
7241static INLINE struct text_pos
7242run_window_scroll_functions (window, startp)
7243 Lisp_Object window;
7244 struct text_pos startp;
7245{
7246 struct window *w = XWINDOW (window);
7247 SET_MARKER_FROM_TEXT_POS (w->start, startp);
90adcf20 7248
5f5c8ee5
GM
7249 if (!NILP (Vwindow_scroll_functions))
7250 {
7251 run_hook_with_args_2 (Qwindow_scroll_functions, window,
7252 make_number (CHARPOS (startp)));
7253 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7254 }
90adcf20 7255
5f5c8ee5
GM
7256 return startp;
7257}
7258
7259
7260/* Modify the desired matrix of window W and W->vscroll so that the
7261 line containing the cursor is fully visible. */
7262
7263static void
7264make_cursor_line_fully_visible (w)
7265 struct window *w;
7266{
7267 struct glyph_matrix *matrix;
7268 struct glyph_row *row;
7269 int top_line_height;
7270
7271 /* It's not always possible to find the cursor, e.g, when a window
7272 is full of overlay strings. Don't do anything in that case. */
7273 if (w->cursor.vpos < 0)
7274 return;
7275
7276 matrix = w->desired_matrix;
7277 row = MATRIX_ROW (matrix, w->cursor.vpos);
7278
7279 /* If row->y == top y of window display area, the window isn't tall
7280 enough to display a single line. There is nothing we can do
7281 about it. */
7282 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
7283 if (row->y == top_line_height)
7284 return;
7285
7286 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
7287 {
7288 int dy = row->height - row->visible_height;
7289 w->vscroll = 0;
7290 w->cursor.y += dy;
7291 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7292 }
7293 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
7294 {
7295 int dy = - (row->height - row->visible_height);
7296 w->vscroll = dy;
7297 w->cursor.y += dy;
7298 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
7299 }
7300
7301 /* When we change the cursor y-position of the selected window,
7302 change this_line_y as well so that the display optimization for
7303 the cursor line of the selected window in redisplay_internal uses
7304 the correct y-position. */
7305 if (w == XWINDOW (selected_window))
7306 this_line_y = w->cursor.y;
7307}
7308
7309
7310/* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
7311 non-zero means only WINDOW is redisplayed in redisplay_internal.
7312 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
7313 in redisplay_window to bring a partially visible line into view in
7314 the case that only the cursor has moved.
7315
7316 Value is
7317
7318 1 if scrolling succeeded
7319
7320 0 if scrolling didn't find point.
7321
7322 -1 if new fonts have been loaded so that we must interrupt
7323 redisplay, adjust glyph matrices, and try again. */
7324
7325static int
7326try_scrolling (window, just_this_one_p, scroll_conservatively,
7327 scroll_step, temp_scroll_step)
7328 Lisp_Object window;
7329 int just_this_one_p;
7330 int scroll_conservatively, scroll_step;
7331 int temp_scroll_step;
7332{
7333 struct window *w = XWINDOW (window);
7334 struct frame *f = XFRAME (w->frame);
7335 struct text_pos scroll_margin_pos;
7336 struct text_pos pos;
7337 struct text_pos startp;
7338 struct it it;
7339 Lisp_Object window_end;
7340 int this_scroll_margin;
7341 int dy = 0;
7342 int scroll_max;
7343 int line_height, rc;
7344 int amount_to_scroll = 0;
7345 Lisp_Object aggressive;
7346 int height;
7347
7348#if GLYPH_DEBUG
7349 debug_method_add (w, "try_scrolling");
78614721 7350#endif
5f5c8ee5
GM
7351
7352 SET_TEXT_POS_FROM_MARKER (startp, w->start);
7353
7354 /* Compute scroll margin height in pixels. We scroll when point is
7355 within this distance from the top or bottom of the window. */
7356 if (scroll_margin > 0)
90adcf20 7357 {
5f5c8ee5
GM
7358 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
7359 this_scroll_margin *= CANON_Y_UNIT (f);
7360 }
7361 else
7362 this_scroll_margin = 0;
7363
7364 /* Compute how much we should try to scroll maximally to bring point
7365 into view. */
7366 if (scroll_step)
7367 scroll_max = scroll_step;
7368 else if (scroll_conservatively)
7369 scroll_max = scroll_conservatively;
7370 else if (temp_scroll_step)
7371 scroll_max = temp_scroll_step;
7372 else if (NUMBERP (current_buffer->scroll_down_aggressively)
7373 || NUMBERP (current_buffer->scroll_up_aggressively))
7374 /* We're trying to scroll because of aggressive scrolling
7375 but no scroll_step is set. Choose an arbitrary one. Maybe
7376 there should be a variable for this. */
7377 scroll_max = 10;
7378 else
7379 scroll_max = 0;
7380 scroll_max *= CANON_Y_UNIT (f);
7381
7382 /* Decide whether we have to scroll down. Start at the window end
7383 and move this_scroll_margin up to find the position of the scroll
7384 margin. */
7385 window_end = Fwindow_end (window, Qt);
7386 CHARPOS (scroll_margin_pos) = XINT (window_end);
7387 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
7388 if (this_scroll_margin)
7389 {
7390 start_display (&it, w, scroll_margin_pos);
7391 move_it_vertically (&it, - this_scroll_margin);
7392 scroll_margin_pos = it.current.pos;
7393 }
7394
7395 if (PT >= CHARPOS (scroll_margin_pos))
7396 {
7397 int y0;
7398
7399 /* Point is in the scroll margin at the bottom of the window, or
7400 below. Compute a new window start that makes point visible. */
7401
7402 /* Compute the distance from the scroll margin to PT.
7403 Give up if the distance is greater than scroll_max. */
7404 start_display (&it, w, scroll_margin_pos);
7405 y0 = it.current_y;
7406 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7407 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7408 line_height = (it.max_ascent + it.max_descent
7409 ? it.max_ascent + it.max_descent
7410 : last_height);
7411 dy = it.current_y + line_height - y0;
7412 if (dy > scroll_max)
7413 return 0;
7414
7415 /* Move the window start down. If scrolling conservatively,
7416 move it just enough down to make point visible. If
7417 scroll_step is set, move it down by scroll_step. */
7418 start_display (&it, w, startp);
7419
7420 if (scroll_conservatively)
7421 amount_to_scroll = dy;
7422 else if (scroll_step || temp_scroll_step)
7423 amount_to_scroll = scroll_max;
7424 else
90adcf20 7425 {
5f5c8ee5
GM
7426 aggressive = current_buffer->scroll_down_aggressively;
7427 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7428 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7429 if (NUMBERP (aggressive))
7430 amount_to_scroll = XFLOATINT (aggressive) * height;
7431 }
a2725ab2 7432
5f5c8ee5
GM
7433 if (amount_to_scroll <= 0)
7434 return 0;
a2725ab2 7435
5f5c8ee5
GM
7436 move_it_vertically (&it, amount_to_scroll);
7437 startp = it.current.pos;
7438 }
7439 else
7440 {
7441 /* See if point is inside the scroll margin at the top of the
7442 window. */
7443 scroll_margin_pos = startp;
7444 if (this_scroll_margin)
7445 {
7446 start_display (&it, w, startp);
7447 move_it_vertically (&it, this_scroll_margin);
7448 scroll_margin_pos = it.current.pos;
7449 }
7450
7451 if (PT < CHARPOS (scroll_margin_pos))
7452 {
7453 /* Point is in the scroll margin at the top of the window or
7454 above what is displayed in the window. */
7455 int y0;
7456
7457 /* Compute the vertical distance from PT to the scroll
7458 margin position. Give up if distance is greater than
7459 scroll_max. */
7460 SET_TEXT_POS (pos, PT, PT_BYTE);
7461 start_display (&it, w, pos);
7462 y0 = it.current_y;
7463 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
7464 it.last_visible_y, -1,
7465 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7466 dy = it.current_y - y0;
7467 if (dy > scroll_max)
7468 return 0;
7469
7470 /* Compute new window start. */
7471 start_display (&it, w, startp);
7472
7473 if (scroll_conservatively)
7474 amount_to_scroll = dy;
7475 else if (scroll_step || temp_scroll_step)
7476 amount_to_scroll = scroll_max;
538f13d4 7477 else
5f5c8ee5
GM
7478 {
7479 aggressive = current_buffer->scroll_up_aggressively;
7480 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
7481 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w));
7482 if (NUMBERP (aggressive))
7483 amount_to_scroll = XFLOATINT (aggressive) * height;
7484 }
a2725ab2 7485
5f5c8ee5
GM
7486 if (amount_to_scroll <= 0)
7487 return 0;
7488
7489 move_it_vertically (&it, - amount_to_scroll);
7490 startp = it.current.pos;
90adcf20
RS
7491 }
7492 }
a2889657 7493
5f5c8ee5
GM
7494 /* Run window scroll functions. */
7495 startp = run_window_scroll_functions (window, startp);
90adcf20 7496
5f5c8ee5
GM
7497 /* Display the window. Give up if new fonts are loaded, or if point
7498 doesn't appear. */
7499 if (!try_window (window, startp))
7500 rc = -1;
7501 else if (w->cursor.vpos < 0)
7502 {
7503 clear_glyph_matrix (w->desired_matrix);
7504 rc = 0;
7505 }
7506 else
7507 {
7508 /* Maybe forget recorded base line for line number display. */
7509 if (!just_this_one_p
7510 || current_buffer->clip_changed
7511 || beg_unchanged < CHARPOS (startp))
7512 w->base_line_number = Qnil;
7513
7514 /* If cursor ends up on a partially visible line, shift display
7515 lines up or down. */
7516 make_cursor_line_fully_visible (w);
7517 rc = 1;
7518 }
7519
7520 return rc;
a2889657
JB
7521}
7522
5f5c8ee5
GM
7523
7524/* Compute a suitable window start for window W if display of W starts
7525 on a continuation line. Value is non-zero if a new window start
7526 was computed.
7527
7528 The new window start will be computed, based on W's width, starting
7529 from the start of the continued line. It is the start of the
7530 screen line with the minimum distance from the old start W->start. */
7531
7532static int
7533compute_window_start_on_continuation_line (w)
7534 struct window *w;
1f1ff51d 7535{
5f5c8ee5
GM
7536 struct text_pos pos, start_pos;
7537 int window_start_changed_p = 0;
1f1ff51d 7538
5f5c8ee5 7539 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
1f1ff51d 7540
5f5c8ee5
GM
7541 /* If window start is on a continuation line... Window start may be
7542 < BEGV in case there's invisible text at the start of the
7543 buffer (M-x rmail, for example). */
7544 if (CHARPOS (start_pos) > BEGV
7545 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
1f1ff51d 7546 {
5f5c8ee5
GM
7547 struct it it;
7548 struct glyph_row *row;
7549
7550 /* Find the start of the continued line. This should be fast
7551 because scan_buffer is fast (newline cache). */
7552 row = w->desired_matrix->rows + (WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0);
7553 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
7554 row, DEFAULT_FACE_ID);
7555 reseat_at_previous_visible_line_start (&it);
7556
7557 /* If the line start is "too far" away from the window start,
7558 say it takes too much time to compute a new window start. */
7559 if (CHARPOS (start_pos) - IT_CHARPOS (it)
7560 < XFASTINT (w->height) * XFASTINT (w->width))
7561 {
7562 int min_distance, distance;
7563
7564 /* Move forward by display lines to find the new window
7565 start. If window width was enlarged, the new start can
7566 be expected to be > the old start. If window width was
7567 decreased, the new window start will be < the old start.
7568 So, we're looking for the display line start with the
7569 minimum distance from the old window start. */
7570 pos = it.current.pos;
7571 min_distance = INFINITY;
7572 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
7573 distance < min_distance)
7574 {
7575 min_distance = distance;
7576 pos = it.current.pos;
7577 move_it_by_lines (&it, 1, 0);
7578 }
7579
7580 /* Set the window start there. */
7581 SET_MARKER_FROM_TEXT_POS (w->start, pos);
7582 window_start_changed_p = 1;
7583 }
1f1ff51d 7584 }
5f5c8ee5
GM
7585
7586 return window_start_changed_p;
1f1ff51d
KH
7587}
7588
5f5c8ee5
GM
7589
7590/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
7591 selected_window is redisplayed. */
90adcf20 7592
a2889657 7593static void
5f5c8ee5 7594redisplay_window (window, just_this_one_p)
a2889657 7595 Lisp_Object window;
5f5c8ee5 7596 int just_this_one_p;
a2889657 7597{
5f5c8ee5
GM
7598 struct window *w = XWINDOW (window);
7599 struct frame *f = XFRAME (w->frame);
7600 struct buffer *buffer = XBUFFER (w->buffer);
a2889657 7601 struct buffer *old = current_buffer;
5f5c8ee5 7602 struct text_pos lpoint, opoint, startp;
e481f960 7603 int update_mode_line;
5f5c8ee5
GM
7604 int tem;
7605 struct it it;
7606 /* Record it now because it's overwritten. */
7607 int current_matrix_up_to_date_p = 0;
5ba50c51 7608 int really_switched_buffer = 0;
5f5c8ee5 7609 int temp_scroll_step = 0;
2e54982e 7610 int count = specpdl_ptr - specpdl;
a2889657 7611
5f5c8ee5
GM
7612 SET_TEXT_POS (lpoint, PT, PT_BYTE);
7613 opoint = lpoint;
a2889657 7614
5f5c8ee5
GM
7615 /* W must be a leaf window here. */
7616 xassert (!NILP (w->buffer));
7617#if GLYPH_DEBUG
7618 *w->desired_matrix->method = 0;
7619#endif
2e54982e
RS
7620
7621 specbind (Qinhibit_point_motion_hooks, Qt);
5f5c8ee5
GM
7622
7623 /* Has the mode line to be updated? */
7624 update_mode_line = (!NILP (w->update_mode_line)
7625 || update_mode_lines
7626 || buffer->clip_changed);
8de2d90b
JB
7627
7628 if (MINI_WINDOW_P (w))
7629 {
5f5c8ee5
GM
7630 if (w == XWINDOW (echo_area_window)
7631 && (echo_area_glyphs
7632 || STRINGP (echo_area_message)))
7633 {
7634 if (update_mode_line)
7635 /* We may have to update a tty frame's menu bar or a
7636 toolbar. Example `M-x C-h C-h C-g'. */
7637 goto finish_menu_bars;
7638 else
7639 /* We've already displayed the echo area glyphs in this window. */
7640 goto finish_scroll_bars;
7641 }
73af359d 7642 else if (w != XWINDOW (minibuf_window))
8de2d90b 7643 {
5f5c8ee5
GM
7644 /* W is a mini-buffer window, but it's not the currently
7645 active one, so clear it. */
7646 int yb = window_text_bottom_y (w);
7647 struct glyph_row *row;
7648 int y;
7649
7650 for (y = 0, row = w->desired_matrix->rows;
7651 y < yb;
7652 y += row->height, ++row)
7653 blank_row (w, row, y);
88f22aff 7654 goto finish_scroll_bars;
8de2d90b
JB
7655 }
7656 }
a2889657 7657
5f5c8ee5
GM
7658 /* Otherwise set up data on this window; select its buffer and point
7659 value. */
e481f960 7660 if (update_mode_line)
5ba50c51 7661 {
5f5c8ee5
GM
7662 /* Really select the buffer, for the sake of buffer-local
7663 variables. */
5ba50c51
RS
7664 set_buffer_internal_1 (XBUFFER (w->buffer));
7665 really_switched_buffer = 1;
7666 }
e481f960
RS
7667 else
7668 set_buffer_temp (XBUFFER (w->buffer));
5f5c8ee5
GM
7669 SET_TEXT_POS (opoint, PT, PT_BYTE);
7670
7671 current_matrix_up_to_date_p
7672 = (!NILP (w->window_end_valid)
7673 && !current_buffer->clip_changed
7674 && XFASTINT (w->last_modified) >= MODIFF
7675 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
e481f960 7676
5f5c8ee5
GM
7677 /* When windows_or_buffers_changed is non-zero, we can't rely on
7678 the window end being valid, so set it to nil there. */
7679 if (windows_or_buffers_changed)
7680 {
7681 /* If window starts on a continuation line, maybe adjust the
7682 window start in case the window's width changed. */
7683 if (XMARKER (w->start)->buffer == current_buffer)
7684 compute_window_start_on_continuation_line (w);
7685
7686 w->window_end_valid = Qnil;
7687 }
12adba34 7688
5f5c8ee5
GM
7689 /* Some sanity checks. */
7690 CHECK_WINDOW_END (w);
7691 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12adba34 7692 abort ();
5f5c8ee5 7693 if (BYTEPOS (opoint) < CHARPOS (opoint))
12adba34 7694 abort ();
a2889657 7695
28995e67
RS
7696 /* If %c is in mode line, update it if needed. */
7697 if (!NILP (w->column_number_displayed)
7698 /* This alternative quickly identifies a common case
7699 where no change is needed. */
7700 && !(PT == XFASTINT (w->last_point)
8850a573
RS
7701 && XFASTINT (w->last_modified) >= MODIFF
7702 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
28995e67
RS
7703 && XFASTINT (w->column_number_displayed) != current_column ())
7704 update_mode_line = 1;
7705
5f5c8ee5
GM
7706 /* Count number of windows showing the selected buffer. An indirect
7707 buffer counts as its base buffer. */
7708 if (!just_this_one_p)
42640f83
RS
7709 {
7710 struct buffer *current_base, *window_base;
7711 current_base = current_buffer;
7712 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
7713 if (current_base->base_buffer)
7714 current_base = current_base->base_buffer;
7715 if (window_base->base_buffer)
7716 window_base = window_base->base_buffer;
7717 if (current_base == window_base)
7718 buffer_shared++;
7719 }
a2889657 7720
5f5c8ee5
GM
7721 /* Point refers normally to the selected window. For any other
7722 window, set up appropriate value. */
a2889657
JB
7723 if (!EQ (window, selected_window))
7724 {
12adba34
RS
7725 int new_pt = XMARKER (w->pointm)->charpos;
7726 int new_pt_byte = marker_byte_position (w->pointm);
f67a0f51 7727 if (new_pt < BEGV)
a2889657 7728 {
f67a0f51 7729 new_pt = BEGV;
12adba34
RS
7730 new_pt_byte = BEGV_BYTE;
7731 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
a2889657 7732 }
f67a0f51 7733 else if (new_pt > (ZV - 1))
a2889657 7734 {
f67a0f51 7735 new_pt = ZV;
12adba34
RS
7736 new_pt_byte = ZV_BYTE;
7737 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
a2889657 7738 }
5f5c8ee5 7739
f67a0f51 7740 /* We don't use SET_PT so that the point-motion hooks don't run. */
12adba34 7741 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
a2889657
JB
7742 }
7743
f4faa47c 7744 /* If any of the character widths specified in the display table
5f5c8ee5
GM
7745 have changed, invalidate the width run cache. It's true that
7746 this may be a bit late to catch such changes, but the rest of
f4faa47c
JB
7747 redisplay goes (non-fatally) haywire when the display table is
7748 changed, so why should we worry about doing any better? */
7749 if (current_buffer->width_run_cache)
7750 {
f908610f 7751 struct Lisp_Char_Table *disptab = buffer_display_table ();
f4faa47c
JB
7752
7753 if (! disptab_matches_widthtab (disptab,
7754 XVECTOR (current_buffer->width_table)))
7755 {
7756 invalidate_region_cache (current_buffer,
7757 current_buffer->width_run_cache,
7758 BEG, Z);
7759 recompute_width_table (current_buffer, disptab);
7760 }
7761 }
7762
a2889657 7763 /* If window-start is screwed up, choose a new one. */
a2889657
JB
7764 if (XMARKER (w->start)->buffer != current_buffer)
7765 goto recenter;
7766
5f5c8ee5 7767 SET_TEXT_POS_FROM_MARKER (startp, w->start);
a2889657 7768
cf0df6ab
RS
7769 /* If someone specified a new starting point but did not insist,
7770 check whether it can be used. */
5f5c8ee5 7771 if (!NILP (w->optional_new_start))
cf0df6ab
RS
7772 {
7773 w->optional_new_start = Qnil;
5f5c8ee5
GM
7774 /* This takes a mini-buffer prompt into account. */
7775 start_display (&it, w, startp);
7776 move_it_to (&it, PT, 0, it.last_visible_y, -1,
7777 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
7778 if (IT_CHARPOS (it) == PT)
cf0df6ab
RS
7779 w->force_start = Qt;
7780 }
7781
8de2d90b 7782 /* Handle case where place to start displaying has been specified,
aa6d10fa 7783 unless the specified location is outside the accessible range. */
265a9e55 7784 if (!NILP (w->force_start))
a2889657 7785 {
e63574d7 7786 w->force_start = Qnil;
5f5c8ee5 7787 w->vscroll = 0;
b5174a51 7788 w->window_end_valid = Qnil;
5f5c8ee5
GM
7789
7790 /* Forget any recorded base line for line number display. */
7791 if (!current_matrix_up_to_date_p
7792 || current_buffer->clip_changed)
7793 w->base_line_number = Qnil;
7794
75c43375
RS
7795 /* Redisplay the mode line. Select the buffer properly for that.
7796 Also, run the hook window-scroll-functions
7797 because we have scrolled. */
e63574d7
RS
7798 /* Note, we do this after clearing force_start because
7799 if there's an error, it is better to forget about force_start
7800 than to get into an infinite loop calling the hook functions
7801 and having them get more errors. */
75c43375
RS
7802 if (!update_mode_line
7803 || ! NILP (Vwindow_scroll_functions))
e481f960 7804 {
5ba50c51
RS
7805 if (!really_switched_buffer)
7806 {
7807 set_buffer_temp (old);
7808 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 7809 really_switched_buffer = 1;
5ba50c51 7810 }
5f5c8ee5 7811
e481f960
RS
7812 update_mode_line = 1;
7813 w->update_mode_line = Qt;
5f5c8ee5 7814 startp = run_window_scroll_functions (window, startp);
e481f960 7815 }
5f5c8ee5 7816
c2213350 7817 XSETFASTINT (w->last_modified, 0);
8850a573 7818 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5
GM
7819 if (CHARPOS (startp) < BEGV)
7820 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
7821 else if (CHARPOS (startp) > ZV)
7822 SET_TEXT_POS (startp, ZV, ZV_BYTE);
7823
7824 /* Redisplay, then check if cursor has been set during the
7825 redisplay. Give up if new fonts were loaded. */
7826 if (!try_window (window, startp))
7827 {
7828 w->force_start = Qt;
7829 clear_glyph_matrix (w->desired_matrix);
7830 goto restore_buffers;
7831 }
7832
7833 if (w->cursor.vpos < 0)
7834 {
7835 /* If point does not appear, or on a line that is not fully
7836 visible, move point so it does appear. The desired
7837 matrix has been built above, so we can use it. */
7838 int height = window_box_height (w) / 2;
7839 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
7840
7841 while (row->y < height)
7842 ++row;
7843
7844 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
7845 MATRIX_ROW_START_BYTEPOS (row));
7846
90adcf20 7847 if (w != XWINDOW (selected_window))
12adba34 7848 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5f5c8ee5
GM
7849 else if (current_buffer == old)
7850 SET_TEXT_POS (lpoint, PT, PT_BYTE);
7851
7852 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
7853
7854 /* If we are highlighting the region, then we just changed
7855 the region, so redisplay to show it. */
df0b5ea1
RS
7856 if (!NILP (Vtransient_mark_mode)
7857 && !NILP (current_buffer->mark_active))
6f27fa9b 7858 {
5f5c8ee5
GM
7859 clear_glyph_matrix (w->desired_matrix);
7860 if (!try_window (window, startp))
7861 goto restore_buffers;
6f27fa9b 7862 }
a2889657 7863 }
5f5c8ee5
GM
7864
7865 make_cursor_line_fully_visible (w);
7866#if GLYPH_DEBUG
7867 debug_method_add (w, "forced window start");
7868#endif
a2889657
JB
7869 goto done;
7870 }
7871
5f5c8ee5
GM
7872 /* Handle case where text has not changed, only point, and it has
7873 not moved off the frame. */
7874 if (current_matrix_up_to_date_p
7875 /* Point may be in this window. */
7876 && PT >= CHARPOS (startp)
7877 /* If we don't check this, we are called to move the cursor in a
7878 horizontally split window with a current matrix that doesn't
7879 fit the display. */
7880 && !windows_or_buffers_changed
7881 /* Selective display hasn't changed. */
7882 && !current_buffer->clip_changed
b1aa6cb3
RS
7883 /* If force-mode-line-update was called, really redisplay;
7884 that's how redisplay is forced after e.g. changing
7885 buffer-invisibility-spec. */
632ab665 7886 && NILP (w->update_mode_line)
5f5c8ee5
GM
7887 /* Can't use this case if highlighting a region. When a
7888 region exists, cursor movement has to do more than just
7889 set the cursor. */
7890 && !(!NILP (Vtransient_mark_mode)
7891 && !NILP (current_buffer->mark_active))
bd66d1ba 7892 && NILP (w->region_showing)
5f5c8ee5
GM
7893 /* Right after splitting windows, last_point may be nil. */
7894 && INTEGERP (w->last_point)
7895 /* This code is not used for mini-buffer for the sake of the case
7896 of redisplaying to replace an echo area message; since in
7897 that case the mini-buffer contents per se are usually
7898 unchanged. This code is of no real use in the mini-buffer
7899 since the handling of this_line_start_pos, etc., in redisplay
7900 handles the same cases. */
d45de95b 7901 && !EQ (window, minibuf_window)
5f5c8ee5
GM
7902 /* When splitting windows or for new windows, it happens that
7903 redisplay is called with a nil window_end_vpos or one being
7904 larger than the window. This should really be fixed in
7905 window.c. I don't have this on my list, now, so we do
7906 approximately the same as the old redisplay code. --gerd. */
7907 && INTEGERP (w->window_end_vpos)
7908 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
7909 && (FRAME_WINDOW_P (f)
7910 || !MARKERP (Voverlay_arrow_position)
377dbd97 7911 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
a2889657 7912 {
5f5c8ee5
GM
7913 int this_scroll_margin;
7914 struct glyph_row *row;
7915 int scroll_p;
a2889657 7916
5f5c8ee5
GM
7917#if GLYPH_DEBUG
7918 debug_method_add (w, "cursor movement");
7919#endif
9afd2168 7920
5f5c8ee5
GM
7921 /* Scroll if point within this distance from the top or bottom
7922 of the window. This is a pixel value. */
7923 this_scroll_margin = max (0, scroll_margin);
7924 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
7925 this_scroll_margin *= CANON_Y_UNIT (f);
7926
7927 /* Start with the row the cursor was displayed during the last
7928 not paused redisplay. Give up if that row is not valid. */
7929 if (w->last_cursor.vpos >= w->current_matrix->nrows)
7930 goto try_to_scroll;
7931 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
7932 if (row->mode_line_p)
7933 ++row;
7934 if (!row->enabled_p)
7935 goto try_to_scroll;
7936
7937 scroll_p = 0;
7938 if (PT > XFASTINT (w->last_point))
7939 {
7940 /* Point has moved forward. */
7941 int last_y = window_text_bottom_y (w) - this_scroll_margin;
7942
7943 while ((MATRIX_ROW_END_CHARPOS (row) < PT
7944 /* The end position of a row equals the start
7945 position of the next row. If PT is there, we
7946 would rather display it in the next line, except
7947 when this line ends in ZV. */
7948 || (MATRIX_ROW_END_CHARPOS (row) == PT
7949 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
7950 || !row->ends_at_zv_p)))
7951 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
7952 {
7953 xassert (row->enabled_p);
7954 ++row;
7955 }
9afd2168 7956
5f5c8ee5
GM
7957 /* If within the scroll margin, scroll. Note that
7958 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
7959 next line would be drawn, and that this_scroll_margin can
7960 be zero. */
7961 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
7962 || PT > MATRIX_ROW_END_CHARPOS (row)
7963 /* Line is completely visible last line in window and PT
7964 is to be set in the next line. */
7965 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
7966 && PT == MATRIX_ROW_END_CHARPOS (row)
7967 && !row->ends_at_zv_p
7968 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
7969 scroll_p = 1;
7970 }
7971 else if (PT < XFASTINT (w->last_point))
a2889657 7972 {
5f5c8ee5
GM
7973 /* Cursor has to be moved backward. Note that PT >=
7974 CHARPOS (startp) because of the outer if-statement. */
7975 while (!row->mode_line_p
7976 && (MATRIX_ROW_START_CHARPOS (row) > PT
7977 || (MATRIX_ROW_START_CHARPOS (row) == PT
7978 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
7979 && (row->y > this_scroll_margin
7980 || CHARPOS (startp) == BEGV))
a2889657 7981 {
5f5c8ee5
GM
7982 xassert (row->enabled_p);
7983 --row;
a2889657 7984 }
abb4c08f 7985
5f5c8ee5
GM
7986 /* Consider the following case: Window starts at BEGV, there
7987 is invisible, intangible text at BEGV, so that display
7988 starts at some point START > BEGV. It can happen that
7989 we are called with PT somewhere between BEGV and START.
7990 Try to handle that case. */
7991 if (row < w->current_matrix->rows
7992 || row->mode_line_p)
7993 {
7994 row = w->current_matrix->rows;
7995 if (row->mode_line_p)
7996 ++row;
7997 }
7998
7999 /* Due to newlines in overlay strings, we may have to skip
8000 forward over overlay strings. */
8001 while (MATRIX_ROW_END_CHARPOS (row) == PT
8002 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8003 && !row->ends_at_zv_p)
8004 ++row;
8005
8006 /* If within the scroll margin, scroll. */
8007 if (row->y < this_scroll_margin
8008 && CHARPOS (startp) != BEGV)
8009 scroll_p = 1;
8010 }
8011
8012 /* if PT is not in the glyph row, give up. */
8013 if (PT < MATRIX_ROW_START_CHARPOS (row)
8014 || PT > MATRIX_ROW_END_CHARPOS (row))
8015 goto try_to_scroll;
8016
8017 /* If we end up in a partially visible line, let's make it fully
8018 visible. This can be done most easily by using the existing
8019 scrolling code. */
8020 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8021 {
8022 temp_scroll_step = 1;
8023 goto try_to_scroll;
a2889657 8024 }
5f5c8ee5
GM
8025 else if (scroll_p)
8026 goto try_to_scroll;
8027
8028 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8029 goto done;
a2889657 8030 }
5f5c8ee5 8031
a2889657
JB
8032 /* If current starting point was originally the beginning of a line
8033 but no longer is, find a new starting point. */
265a9e55 8034 else if (!NILP (w->start_at_line_beg)
5f5c8ee5
GM
8035 && !(CHARPOS (startp) <= BEGV
8036 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
a2889657 8037 {
5f5c8ee5
GM
8038#if GLYPH_DEBUG
8039 debug_method_add (w, "recenter 1");
8040#endif
a2889657
JB
8041 goto recenter;
8042 }
5f5c8ee5
GM
8043
8044 /* Try scrolling with try_window_id. */
8045 else if (!windows_or_buffers_changed
8046 /* Window must be either use window-based redisplay or
8047 be full width. */
8048 && (FRAME_WINDOW_P (f)
8049 || ((line_ins_del_ok && WINDOW_FULL_WIDTH_P (w))
8050 && just_this_one_p))
8051 && !MINI_WINDOW_P (w)
8052 /* Point is not known NOT to appear in window. */
8053 && PT >= CHARPOS (startp)
a2889657 8054 && XFASTINT (w->last_modified)
5f5c8ee5
GM
8055 /* Window is not hscrolled. */
8056 && XFASTINT (w->hscroll) == 0
8057 /* Selective display has not changed. */
8058 && !current_buffer->clip_changed
8059 /* Current matrix is up to date. */
8060 && !NILP (w->window_end_valid)
8061 /* Can't use this case if highlighting a region because
8062 a cursor movement will do more than just set the cursor. */
bd66d1ba
RS
8063 && !(!NILP (Vtransient_mark_mode)
8064 && !NILP (current_buffer->mark_active))
8065 && NILP (w->region_showing)
5f5c8ee5 8066 /* Overlay arrow position and string not changed. */
d45de95b 8067 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
a2889657 8068 && EQ (last_arrow_string, Voverlay_arrow_string)
5f5c8ee5
GM
8069 /* Value is > 0 if update has been done, it is -1 if we
8070 know that the same window start will not work. It is 0
8071 if unsuccessful for some other reason. */
8072 && (tem = try_window_id (w)) != 0)
a2889657 8073 {
5f5c8ee5
GM
8074#if GLYPH_DEBUG
8075 debug_method_add (w, "try_window_id");
8076#endif
8077
8078 if (fonts_changed_p)
8079 goto restore_buffers;
a2889657
JB
8080 if (tem > 0)
8081 goto done;
5f5c8ee5
GM
8082 /* Otherwise try_window_id has returned -1 which means that we
8083 don't want the alternative below this comment to execute. */
a2889657 8084 }
5f5c8ee5
GM
8085 else if (CHARPOS (startp) >= BEGV
8086 && CHARPOS (startp) <= ZV
8087 && PT >= CHARPOS (startp)
8088 && (CHARPOS (startp) < ZV
e9874cee 8089 /* Avoid starting at end of buffer. */
5f5c8ee5 8090 || CHARPOS (startp) == BEGV
8850a573
RS
8091 || (XFASTINT (w->last_modified) >= MODIFF
8092 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
a2889657 8093 {
5f5c8ee5
GM
8094#if GLYPH_DEBUG
8095 debug_method_add (w, "same window start");
8096#endif
8097
8098 /* Try to redisplay starting at same place as before.
8099 If point has not moved off frame, accept the results. */
8100 if (!current_matrix_up_to_date_p
8101 /* Don't use try_window_reusing_current_matrix in this case
8102 because it can have changed the buffer. */
8103 || !NILP (Vwindow_scroll_functions)
8104 || MINI_WINDOW_P (w)
8105 || !try_window_reusing_current_matrix (w))
8106 {
8107 IF_DEBUG (debug_method_add (w, "1"));
8108 try_window (window, startp);
8109 }
8110
8111 if (fonts_changed_p)
8112 goto restore_buffers;
8113
8114 if (w->cursor.vpos >= 0)
aa6d10fa 8115 {
5f5c8ee5
GM
8116 if (!just_this_one_p
8117 || current_buffer->clip_changed
8118 || beg_unchanged < CHARPOS (startp))
aa6d10fa
RS
8119 /* Forget any recorded base line for line number display. */
8120 w->base_line_number = Qnil;
5f5c8ee5
GM
8121
8122 make_cursor_line_fully_visible (w);
aa6d10fa
RS
8123 goto done;
8124 }
a2889657 8125 else
5f5c8ee5 8126 clear_glyph_matrix (w->desired_matrix);
a2889657
JB
8127 }
8128
5f5c8ee5
GM
8129 try_to_scroll:
8130
c2213350 8131 XSETFASTINT (w->last_modified, 0);
8850a573 8132 XSETFASTINT (w->last_overlay_modified, 0);
5f5c8ee5 8133
e481f960
RS
8134 /* Redisplay the mode line. Select the buffer properly for that. */
8135 if (!update_mode_line)
8136 {
5ba50c51
RS
8137 if (!really_switched_buffer)
8138 {
8139 set_buffer_temp (old);
8140 set_buffer_internal_1 (XBUFFER (w->buffer));
5f5c8ee5 8141 really_switched_buffer = 1;
5ba50c51 8142 }
e481f960
RS
8143 update_mode_line = 1;
8144 w->update_mode_line = Qt;
8145 }
a2889657 8146
5f5c8ee5
GM
8147 /* Try to scroll by specified few lines. */
8148 if ((scroll_conservatively
8149 || scroll_step
8150 || temp_scroll_step
8151 || NUMBERP (current_buffer->scroll_up_aggressively)
8152 || NUMBERP (current_buffer->scroll_down_aggressively))
09cacf9c 8153 && !current_buffer->clip_changed
5f5c8ee5
GM
8154 && CHARPOS (startp) >= BEGV
8155 && CHARPOS (startp) <= ZV)
0789adb2 8156 {
5f5c8ee5
GM
8157 /* The function returns -1 if new fonts were loaded, 1 if
8158 successful, 0 if not successful. */
8159 int rc = try_scrolling (window, just_this_one_p,
8160 scroll_conservatively,
8161 scroll_step,
8162 temp_scroll_step);
8163 if (rc > 0)
8164 goto done;
8165 else if (rc < 0)
8166 goto restore_buffers;
8167 }
f9c8af06 8168
5f5c8ee5 8169 /* Finally, just choose place to start which centers point */
5936754e 8170
5f5c8ee5 8171 recenter:
44173109 8172
5f5c8ee5
GM
8173#if GLYPH_DEBUG
8174 debug_method_add (w, "recenter");
8175#endif
0789adb2 8176
5f5c8ee5 8177 /* w->vscroll = 0; */
0789adb2 8178
5f5c8ee5
GM
8179 /* Forget any previously recorded base line for line number display. */
8180 if (!current_matrix_up_to_date_p
8181 || current_buffer->clip_changed)
8182 w->base_line_number = Qnil;
8183
8184 /* Move backward half the height of the window. */
8185 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8186 it.current_y = it.last_visible_y;
8187 move_it_vertically_backward (&it, it.last_visible_y / 2);
8188 xassert (IT_CHARPOS (it) >= BEGV);
8189
8190 /* The function move_it_vertically_backward may move over more
8191 than the specified y-distance. If it->w is small, e.g. a
8192 mini-buffer window, we may end up in front of the window's
8193 display area. Start displaying at the start of the line
8194 containing PT in this case. */
8195 if (it.current_y <= 0)
8196 {
8197 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
8198 move_it_vertically (&it, 0);
8199 xassert (IT_CHARPOS (it) <= PT);
8200 it.current_y = 0;
0789adb2
RS
8201 }
8202
5f5c8ee5
GM
8203 it.current_x = it.hpos = 0;
8204
8205 /* Set startp here explicitly in case that helps avoid an infinite loop
8206 in case the window-scroll-functions functions get errors. */
8207 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
8208
8209 /* Run scroll hooks. */
8210 startp = run_window_scroll_functions (window, it.current.pos);
8211
8212 /* Redisplay the window. */
8213 if (!current_matrix_up_to_date_p
8214 || windows_or_buffers_changed
8215 /* Don't use try_window_reusing_current_matrix in this case
8216 because it can have changed the buffer. */
8217 || !NILP (Vwindow_scroll_functions)
8218 || !just_this_one_p
8219 || MINI_WINDOW_P (w)
8220 || !try_window_reusing_current_matrix (w))
8221 try_window (window, startp);
8222
8223 /* If new fonts have been loaded (due to fontsets), give up. We
8224 have to start a new redisplay since we need to re-adjust glyph
8225 matrices. */
8226 if (fonts_changed_p)
8227 goto restore_buffers;
8228
8229 /* If cursor did not appear assume that the middle of the window is
8230 in the first line of the window. Do it again with the next line.
8231 (Imagine a window of height 100, displaying two lines of height
8232 60. Moving back 50 from it->last_visible_y will end in the first
8233 line.) */
8234 if (w->cursor.vpos < 0)
a2889657 8235 {
5f5c8ee5
GM
8236 if (!NILP (w->window_end_valid)
8237 && PT >= Z - XFASTINT (w->window_end_pos))
a2889657 8238 {
5f5c8ee5
GM
8239 clear_glyph_matrix (w->desired_matrix);
8240 move_it_by_lines (&it, 1, 0);
8241 try_window (window, it.current.pos);
a2889657 8242 }
5f5c8ee5 8243 else if (PT < IT_CHARPOS (it))
a2889657 8244 {
5f5c8ee5
GM
8245 clear_glyph_matrix (w->desired_matrix);
8246 move_it_by_lines (&it, -1, 0);
8247 try_window (window, it.current.pos);
8248 }
8249 else
8250 {
8251 /* Not much we can do about it. */
a2889657 8252 }
a2889657 8253 }
010494d0 8254
5f5c8ee5
GM
8255 /* Consider the following case: Window starts at BEGV, there is
8256 invisible, intangible text at BEGV, so that display starts at
8257 some point START > BEGV. It can happen that we are called with
8258 PT somewhere between BEGV and START. Try to handle that case. */
8259 if (w->cursor.vpos < 0)
835766b6 8260 {
5f5c8ee5
GM
8261 struct glyph_row *row = w->current_matrix->rows;
8262 if (row->mode_line_p)
8263 ++row;
8264 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
835766b6 8265 }
5f5c8ee5
GM
8266
8267 make_cursor_line_fully_visible (w);
b5174a51 8268
5f5c8ee5
GM
8269 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8270 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
8271 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
8272 ? Qt : Qnil);
a2889657 8273
5f5c8ee5 8274 done:
a2889657 8275
5f5c8ee5 8276 /* Display the mode line, if we must. */
e481f960 8277 if ((update_mode_line
aa6d10fa 8278 /* If window not full width, must redo its mode line
5f5c8ee5
GM
8279 if (a) the window to its side is being redone and
8280 (b) we do a frame-based redisplay. This is a consequence
8281 of how inverted lines are drawn in frame-based redisplay. */
8282 || (!just_this_one_p
8283 && !FRAME_WINDOW_P (f)
8284 && !WINDOW_FULL_WIDTH_P (w))
8285 /* Line number to display. */
155ef550 8286 || INTEGERP (w->base_line_pos)
5f5c8ee5 8287 /* Column number is displayed and different from the one displayed. */
155ef550
KH
8288 || (!NILP (w->column_number_displayed)
8289 && XFASTINT (w->column_number_displayed) != current_column ()))
5f5c8ee5
GM
8290 /* This means that the window has a mode line. */
8291 && (WINDOW_WANTS_MODELINE_P (w)
8292 || WINDOW_WANTS_TOP_LINE_P (w)))
5ba50c51 8293 {
5f5c8ee5
GM
8294 display_mode_lines (w);
8295
8296 /* If mode line height has changed, arrange for a thorough
8297 immediate redisplay using the correct mode line height. */
8298 if (WINDOW_WANTS_MODELINE_P (w)
8299 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
5ba50c51 8300 {
5f5c8ee5
GM
8301 fonts_changed_p = 1;
8302 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
8303 = DESIRED_MODE_LINE_HEIGHT (w);
5ba50c51 8304 }
5f5c8ee5
GM
8305
8306 /* If top line height has changed, arrange for a thorough
8307 immediate redisplay using the correct mode line height. */
8308 if (WINDOW_WANTS_TOP_LINE_P (w)
8309 && CURRENT_TOP_LINE_HEIGHT (w) != DESIRED_TOP_LINE_HEIGHT (w))
8310 {
8311 fonts_changed_p = 1;
8312 MATRIX_TOP_LINE_ROW (w->current_matrix)->height
8313 = DESIRED_TOP_LINE_HEIGHT (w);
8314 }
8315
8316 if (fonts_changed_p)
8317 goto restore_buffers;
5ba50c51 8318 }
5f5c8ee5
GM
8319
8320 if (!line_number_displayed
8321 && !BUFFERP (w->base_line_pos))
aa6d10fa
RS
8322 {
8323 w->base_line_pos = Qnil;
8324 w->base_line_number = Qnil;
8325 }
a2889657 8326
5f5c8ee5
GM
8327 finish_menu_bars:
8328
7ce2c095 8329 /* When we reach a frame's selected window, redo the frame's menu bar. */
e481f960 8330 if (update_mode_line
5f5c8ee5
GM
8331 && EQ (FRAME_SELECTED_WINDOW (f), window))
8332 {
8333 int redisplay_menu_p = 0;
8334
8335 if (FRAME_WINDOW_P (f))
8336 {
dc937613 8337#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5f5c8ee5 8338 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
76412d64 8339#else
5f5c8ee5 8340 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
76412d64 8341#endif
5f5c8ee5
GM
8342 }
8343 else
8344 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
8345
8346 if (redisplay_menu_p)
8347 display_menu_bar (w);
8348
8349#ifdef HAVE_WINDOW_SYSTEM
8350 if (WINDOWP (f->toolbar_window)
8351 && (FRAME_TOOLBAR_LINES (f) > 0
8352 || auto_resize_toolbars_p))
8353 redisplay_toolbar (f);
8354#endif
8355 }
7ce2c095 8356
88f22aff 8357 finish_scroll_bars:
5f5c8ee5 8358
88f22aff 8359 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
30c566e4 8360 {
b1d1124b 8361 int start, end, whole;
30c566e4 8362
b1d1124b 8363 /* Calculate the start and end positions for the current window.
3505ea70
JB
8364 At some point, it would be nice to choose between scrollbars
8365 which reflect the whole buffer size, with special markers
8366 indicating narrowing, and scrollbars which reflect only the
8367 visible region.
8368
5f5c8ee5 8369 Note that mini-buffers sometimes aren't displaying any text. */
b1d1124b 8370 if (! MINI_WINDOW_P (w)
5f5c8ee5
GM
8371 || (w == XWINDOW (minibuf_window)
8372 && !echo_area_glyphs
8373 && !STRINGP (echo_area_message)))
b1d1124b 8374 {
8a9311d7 8375 whole = ZV - BEGV;
4d641a15 8376 start = marker_position (w->start) - BEGV;
b1d1124b
JB
8377 /* I don't think this is guaranteed to be right. For the
8378 moment, we'll pretend it is. */
5f5c8ee5 8379 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
3505ea70 8380
5f5c8ee5
GM
8381 if (end < start)
8382 end = start;
8383 if (whole < (end - start))
8384 whole = end - start;
b1d1124b
JB
8385 }
8386 else
8387 start = end = whole = 0;
30c566e4 8388
88f22aff 8389 /* Indicate what this scroll bar ought to be displaying now. */
7eb9ba41 8390 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
30c566e4 8391
5f5c8ee5
GM
8392 /* Note that we actually used the scroll bar attached to this
8393 window, so it shouldn't be deleted at the end of redisplay. */
88f22aff 8394 (*redeem_scroll_bar_hook) (w);
30c566e4 8395 }
b1d1124b 8396
5f5c8ee5
GM
8397 restore_buffers:
8398
8399 /* Restore current_buffer and value of point in it. */
8400 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
5ba50c51 8401 if (really_switched_buffer)
f72df6ac 8402 set_buffer_internal_1 (old);
e481f960
RS
8403 else
8404 set_buffer_temp (old);
5f5c8ee5 8405 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
2e54982e
RS
8406
8407 unbind_to (count, Qnil);
a2889657 8408}
a2889657 8409
5f5c8ee5
GM
8410
8411/* Build the complete desired matrix of WINDOW with a window start
8412 buffer position POS. Value is non-zero if successful. It is zero
8413 if fonts were loaded during redisplay which makes re-adjusting
8414 glyph matrices necessary. */
8415
8416int
a2889657
JB
8417try_window (window, pos)
8418 Lisp_Object window;
5f5c8ee5
GM
8419 struct text_pos pos;
8420{
8421 struct window *w = XWINDOW (window);
8422 struct it it;
8423 struct glyph_row *last_text_row = NULL;
9cbab4ff 8424
5f5c8ee5
GM
8425 /* Make POS the new window start. */
8426 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12adba34 8427
5f5c8ee5
GM
8428 /* Mark cursor position as unknown. No overlay arrow seen. */
8429 w->cursor.vpos = -1;
a2889657 8430 overlay_arrow_seen = 0;
642eefc6 8431
5f5c8ee5
GM
8432 /* Initialize iterator and info to start at POS. */
8433 start_display (&it, w, pos);
a2889657 8434
5f5c8ee5
GM
8435 /* Display all lines of W. */
8436 while (it.current_y < it.last_visible_y)
8437 {
8438 if (display_line (&it))
8439 last_text_row = it.glyph_row - 1;
8440 if (fonts_changed_p)
8441 return 0;
8442 }
a2889657 8443
5f5c8ee5
GM
8444 /* If bottom moved off end of frame, change mode line percentage. */
8445 if (XFASTINT (w->window_end_pos) <= 0
8446 && Z != IT_CHARPOS (it))
a2889657
JB
8447 w->update_mode_line = Qt;
8448
5f5c8ee5
GM
8449 /* Set window_end_pos to the offset of the last character displayed
8450 on the window from the end of current_buffer. Set
8451 window_end_vpos to its row number. */
8452 if (last_text_row)
8453 {
8454 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
8455 w->window_end_bytepos
8456 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8457 XSETFASTINT (w->window_end_pos,
8458 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8459 XSETFASTINT (w->window_end_vpos,
8460 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8461 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
8462 ->displays_text_p);
8463 }
8464 else
8465 {
8466 w->window_end_bytepos = 0;
8467 XSETFASTINT (w->window_end_pos, 0);
8468 XSETFASTINT (w->window_end_vpos, 0);
8469 }
8470
a2889657
JB
8471 /* But that is not valid info until redisplay finishes. */
8472 w->window_end_valid = Qnil;
5f5c8ee5 8473 return 1;
a2889657 8474}
5f5c8ee5
GM
8475
8476
a2889657 8477\f
5f5c8ee5
GM
8478/************************************************************************
8479 Window redisplay reusing current matrix when buffer has not changed
8480 ************************************************************************/
8481
8482/* Try redisplay of window W showing an unchanged buffer with a
8483 different window start than the last time it was displayed by
8484 reusing its current matrix. Value is non-zero if successful.
8485 W->start is the new window start. */
a2889657
JB
8486
8487static int
5f5c8ee5
GM
8488try_window_reusing_current_matrix (w)
8489 struct window *w;
a2889657 8490{
5f5c8ee5
GM
8491 struct frame *f = XFRAME (w->frame);
8492 struct glyph_row *row, *bottom_row;
8493 struct it it;
8494 struct run run;
8495 struct text_pos start, new_start;
8496 int nrows_scrolled, i;
8497 struct glyph_row *last_text_row;
8498 struct glyph_row *last_reused_text_row;
8499 struct glyph_row *start_row;
8500 int start_vpos, min_y, max_y;
8501
8502 /* Right now this function doesn't handle terminal frames. */
8503 if (!FRAME_WINDOW_P (f))
8504 return 0;
a2889657 8505
5f5c8ee5
GM
8506 /* Can't do this if region may have changed. */
8507 if ((!NILP (Vtransient_mark_mode)
8508 && !NILP (current_buffer->mark_active))
8509 || !NILP (w->region_showing))
8510 return 0;
a2889657 8511
5f5c8ee5
GM
8512 /* If top-line visibility has changed, give up. */
8513 if (WINDOW_WANTS_TOP_LINE_P (w)
8514 != MATRIX_TOP_LINE_ROW (w->current_matrix)->mode_line_p)
8515 return 0;
8516
8517 /* Give up if old or new display is scrolled vertically. We could
8518 make this function handle this, but right now it doesn't. */
8519 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8520 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
8521 return 0;
8522
8523 /* The variable new_start now holds the new window start. The old
8524 start `start' can be determined from the current matrix. */
8525 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
8526 start = start_row->start.pos;
8527 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
a2889657 8528
5f5c8ee5
GM
8529 /* Clear the desired matrix for the display below. */
8530 clear_glyph_matrix (w->desired_matrix);
8531
8532 if (CHARPOS (new_start) <= CHARPOS (start))
8533 {
8534 int first_row_y;
8535
8536 IF_DEBUG (debug_method_add (w, "twu1"));
8537
8538 /* Display up to a row that can be reused. The variable
8539 last_text_row is set to the last row displayed that displays
8540 text. */
8541 start_display (&it, w, new_start);
8542 first_row_y = it.current_y;
8543 w->cursor.vpos = -1;
8544 last_text_row = last_reused_text_row = NULL;
8545 while (it.current_y < it.last_visible_y
8546 && IT_CHARPOS (it) < CHARPOS (start)
8547 && !fonts_changed_p)
8548 if (display_line (&it))
8549 last_text_row = it.glyph_row - 1;
8550
8551 /* A value of current_y < last_visible_y means that we stopped
8552 at the previous window start, which in turn means that we
8553 have at least one reusable row. */
8554 if (it.current_y < it.last_visible_y)
a2889657 8555 {
5f5c8ee5
GM
8556 nrows_scrolled = it.vpos;
8557
8558 /* Find PT if not already found in the lines displayed. */
8559 if (w->cursor.vpos < 0)
a2889657 8560 {
5f5c8ee5
GM
8561 int dy = it.current_y - first_row_y;
8562
8563 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8564 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8565 {
8566 if (PT >= MATRIX_ROW_START_CHARPOS (row)
8567 && PT < MATRIX_ROW_END_CHARPOS (row))
8568 {
8569 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
8570 dy, nrows_scrolled);
8571 break;
8572 }
8573
8574 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
8575 break;
8576
8577 ++row;
8578 }
8579
8580 /* Give up if point was not found. This shouldn't
8581 happen often; not more often than with try_window
8582 itself. */
8583 if (w->cursor.vpos < 0)
8584 {
8585 clear_glyph_matrix (w->desired_matrix);
8586 return 0;
8587 }
a2889657 8588 }
5f5c8ee5
GM
8589
8590 /* Scroll the display. Do it before the current matrix is
8591 changed. The problem here is that update has not yet
8592 run, i.e. part of the current matrix is not up to date.
8593 scroll_run_hook will clear the cursor, and use the
8594 current matrix to get the height of the row the cursor is
8595 in. */
8596 run.current_y = first_row_y;
8597 run.desired_y = it.current_y;
8598 run.height = it.last_visible_y - it.current_y;
8599 if (run.height > 0)
a2889657 8600 {
5f5c8ee5
GM
8601 update_begin (f);
8602 rif->update_window_begin_hook (w);
8603 rif->scroll_run_hook (w, &run);
8604 rif->update_window_end_hook (w, 0);
8605 update_end (f);
a2889657 8606 }
5f5c8ee5
GM
8607
8608 /* Shift current matrix down by nrows_scrolled lines. */
8609 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
8610 rotate_matrix (w->current_matrix,
8611 start_vpos,
8612 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
8613 nrows_scrolled);
8614
8615 /* Disable lines not reused. */
8616 for (i = 0; i < it.vpos; ++i)
8617 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
8618
8619 /* Re-compute Y positions. */
8620 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
8621 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8622 max_y = it.last_visible_y;
8623 while (row < bottom_row)
d2f84654 8624 {
5f5c8ee5
GM
8625 row->y = it.current_y;
8626
8627 if (row->y < min_y)
8628 row->visible_height = row->height - (min_y - row->y);
8629 else if (row->y + row->height > max_y)
8630 row->visible_height
8631 = row->height - (row->y + row->height - max_y);
8632 else
8633 row->visible_height = row->height;
8634
8635 it.current_y += row->height;
8636 ++it.vpos;
8637
8638 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8639 last_reused_text_row = row;
8640 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
8641 break;
8642 ++row;
d2f84654 8643 }
a2889657 8644 }
5f5c8ee5
GM
8645
8646 /* Update window_end_pos etc.; last_reused_text_row is the last
8647 reused row from the current matrix containing text, if any.
8648 The value of last_text_row is the last displayed line
8649 containing text. */
8650 if (last_reused_text_row)
a2889657 8651 {
5f5c8ee5
GM
8652 w->window_end_bytepos
8653 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
8654 XSETFASTINT (w->window_end_pos,
8655 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
8656 XSETFASTINT (w->window_end_vpos,
8657 MATRIX_ROW_VPOS (last_reused_text_row,
8658 w->current_matrix));
a2889657 8659 }
5f5c8ee5
GM
8660 else if (last_text_row)
8661 {
8662 w->window_end_bytepos
8663 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8664 XSETFASTINT (w->window_end_pos,
8665 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8666 XSETFASTINT (w->window_end_vpos,
8667 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8668 }
8669 else
8670 {
8671 /* This window must be completely empty. */
8672 w->window_end_bytepos = 0;
8673 XSETFASTINT (w->window_end_pos, 0);
8674 XSETFASTINT (w->window_end_vpos, 0);
8675 }
8676 w->window_end_valid = Qnil;
a2889657 8677
5f5c8ee5
GM
8678 /* Update hint: don't try scrolling again in update_window. */
8679 w->desired_matrix->no_scrolling_p = 1;
8680
8681#if GLYPH_DEBUG
8682 debug_method_add (w, "try_window_reusing_current_matrix 1");
8683#endif
8684 return 1;
a2889657 8685 }
5f5c8ee5
GM
8686 else if (CHARPOS (new_start) > CHARPOS (start))
8687 {
8688 struct glyph_row *pt_row, *row;
8689 struct glyph_row *first_reusable_row;
8690 struct glyph_row *first_row_to_display;
8691 int dy;
8692 int yb = window_text_bottom_y (w);
8693
8694 IF_DEBUG (debug_method_add (w, "twu2"));
8695
8696 /* Find the row starting at new_start, if there is one. Don't
8697 reuse a partially visible line at the end. */
8698 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8699 while (first_reusable_row->enabled_p
8700 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
8701 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
8702 < CHARPOS (new_start)))
8703 ++first_reusable_row;
8704
8705 /* Give up if there is no row to reuse. */
8706 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
8707 || !first_reusable_row->enabled_p)
8708 return 0;
8709
8710 /* The row we found must start at new_start, or else something
8711 is broken. */
8712 xassert (MATRIX_ROW_START_CHARPOS (first_reusable_row)
8713 == CHARPOS (new_start));
8714
8715 /* We can reuse fully visible rows beginning with
8716 first_reusable_row to the end of the window. Set
8717 first_row_to_display to the first row that cannot be reused.
8718 Set pt_row to the row containing point, if there is any. */
8719 first_row_to_display = first_reusable_row;
8720 pt_row = NULL;
8721 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
8722 {
8723 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
8724 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
8725 pt_row = first_row_to_display;
a2889657 8726
5f5c8ee5
GM
8727 ++first_row_to_display;
8728 }
a2889657 8729
5f5c8ee5
GM
8730 /* Start displaying at the start of first_row_to_display. */
8731 xassert (first_row_to_display->y < yb);
8732 init_to_row_start (&it, w, first_row_to_display);
8733 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
8734 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
8735 - nrows_scrolled);
8736 it.current_y = first_row_to_display->y - first_reusable_row->y;
8737
8738 /* Display lines beginning with first_row_to_display in the
8739 desired matrix. Set last_text_row to the last row displayed
8740 that displays text. */
8741 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
8742 if (pt_row == NULL)
8743 w->cursor.vpos = -1;
8744 last_text_row = NULL;
8745 while (it.current_y < it.last_visible_y && !fonts_changed_p)
8746 if (display_line (&it))
8747 last_text_row = it.glyph_row - 1;
8748
8749 /* Give up If point isn't in a row displayed or reused. */
8750 if (w->cursor.vpos < 0)
8751 {
8752 clear_glyph_matrix (w->desired_matrix);
8753 return 0;
8754 }
12adba34 8755
5f5c8ee5
GM
8756 /* If point is in a reused row, adjust y and vpos of the cursor
8757 position. */
8758 if (pt_row)
8759 {
8760 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
8761 w->current_matrix);
8762 w->cursor.y -= first_reusable_row->y;
a2889657
JB
8763 }
8764
5f5c8ee5
GM
8765 /* Scroll the display. */
8766 run.current_y = first_reusable_row->y;
8767 run.desired_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8768 run.height = it.last_visible_y - run.current_y;
8769 if (run.height)
8770 {
8771 struct frame *f = XFRAME (WINDOW_FRAME (w));
8772 update_begin (f);
8773 rif->update_window_begin_hook (w);
8774 rif->scroll_run_hook (w, &run);
8775 rif->update_window_end_hook (w, 0);
8776 update_end (f);
8777 }
a2889657 8778
5f5c8ee5
GM
8779 /* Adjust Y positions of reused rows. */
8780 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
8781 row = first_reusable_row;
8782 dy = first_reusable_row->y;
8783 min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
8784 max_y = it.last_visible_y;
8785 while (row < first_row_to_display)
8786 {
8787 row->y -= dy;
8788 if (row->y < min_y)
8789 row->visible_height = row->height - (min_y - row->y);
8790 else if (row->y + row->height > max_y)
8791 row->visible_height
8792 = row->height - (row->y + row->height - max_y);
8793 else
8794 row->visible_height = row->height;
8795 ++row;
8796 }
a2889657 8797
5f5c8ee5
GM
8798 /* Disable rows not reused. */
8799 while (row < bottom_row)
8800 {
8801 row->enabled_p = 0;
8802 ++row;
8803 }
8804
8805 /* Scroll the current matrix. */
8806 xassert (nrows_scrolled > 0);
8807 rotate_matrix (w->current_matrix,
8808 start_vpos,
8809 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
8810 -nrows_scrolled);
8811
8812 /* Adjust window end. A null value of last_text_row means that
8813 the window end is in reused rows which in turn means that
8814 only its vpos can have changed. */
8815 if (last_text_row)
8816 {
8817 w->window_end_bytepos
8818 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
8819 XSETFASTINT (w->window_end_pos,
8820 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
8821 XSETFASTINT (w->window_end_vpos,
8822 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
8823 }
8824 else
a2889657 8825 {
e8e536a9 8826 XSETFASTINT (w->window_end_vpos,
5f5c8ee5 8827 XFASTINT (w->window_end_vpos) - nrows_scrolled);
a2889657 8828 }
5f5c8ee5
GM
8829
8830 w->window_end_valid = Qnil;
8831 w->desired_matrix->no_scrolling_p = 1;
8832
8833#if GLYPH_DEBUG
8834 debug_method_add (w, "try_window_reusing_current_matrix 2");
8835#endif
8836 return 1;
a2889657 8837 }
5f5c8ee5
GM
8838
8839 return 0;
8840}
a2889657 8841
a2889657 8842
5f5c8ee5
GM
8843\f
8844/************************************************************************
8845 Window redisplay reusing current matrix when buffer has changed
8846 ************************************************************************/
8847
8848static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
8849static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
8850 int *, int *));
8851static struct glyph_row *
8852find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
8853 struct glyph_row *));
8854
8855
8856/* Return the last row in MATRIX displaying text. If row START is
8857 non-null, start searching with that row. IT gives the dimensions
8858 of the display. Value is null if matrix is empty; otherwise it is
8859 a pointer to the row found. */
8860
8861static struct glyph_row *
8862find_last_row_displaying_text (matrix, it, start)
8863 struct glyph_matrix *matrix;
8864 struct it *it;
8865 struct glyph_row *start;
8866{
8867 struct glyph_row *row, *row_found;
8868
8869 /* Set row_found to the last row in IT->w's current matrix
8870 displaying text. The loop looks funny but think of partially
8871 visible lines. */
8872 row_found = NULL;
8873 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
8874 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8875 {
8876 xassert (row->enabled_p);
8877 row_found = row;
8878 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
8879 break;
8880 ++row;
a2889657 8881 }
5f5c8ee5
GM
8882
8883 return row_found;
8884}
8885
a2889657 8886
5f5c8ee5
GM
8887/* Return the last row in the current matrix of W that is not affected
8888 by changes at the start of current_buffer that occurred since the
8889 last time W was redisplayed. Value is null if no such row exists.
a2889657 8890
5f5c8ee5
GM
8891 The global variable beg_unchanged has to contain the number of
8892 bytes unchanged at the start of current_buffer. BEG +
8893 beg_unchanged is the buffer position of the first changed byte in
8894 current_buffer. Characters at positions < BEG + beg_unchanged are
8895 at the same buffer positions as they were when the current matrix
8896 was built. */
8897
8898static struct glyph_row *
8899get_last_unchanged_at_beg_row (w)
8900 struct window *w;
8901{
8902 int first_changed_pos = BEG + beg_unchanged;
8903 struct glyph_row *row;
8904 struct glyph_row *row_found = NULL;
8905 int yb = window_text_bottom_y (w);
8906
8907 /* Find the last row displaying unchanged text. */
8908 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8909 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
8910 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
a2889657 8911 {
5f5c8ee5
GM
8912 if (/* If row ends before first_changed_pos, it is unchanged,
8913 except in some case. */
8914 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
8915 /* When row ends in ZV and we write at ZV it is not
8916 unchanged. */
8917 && !row->ends_at_zv_p
8918 /* When first_changed_pos is the end of a continued line,
8919 row is not unchanged because it may be no longer
8920 continued. */
8921 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
8922 && row->continued_p))
8923 row_found = row;
8924
8925 /* Stop if last visible row. */
8926 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
8927 break;
8928
8929 ++row;
a2889657
JB
8930 }
8931
5f5c8ee5 8932 return row_found;
a2889657 8933}
5f5c8ee5
GM
8934
8935
8936/* Find the first glyph row in the current matrix of W that is not
8937 affected by changes at the end of current_buffer since the last
8938 time the window was redisplayed. Return in *DELTA the number of
8939 bytes by which buffer positions in unchanged text at the end of
8940 current_buffer must be adjusted. Value is null if no such row
8941 exists, i.e. all rows are affected by changes.
8942
8943 The global variable end_unchanged is assumed to contain the number
8944 of unchanged bytes at the end of current_buffer. The buffer
8945 position of the last changed byte in current_buffer is then Z -
8946 end_unchanged. */
8947
8948static struct glyph_row *
8949get_first_unchanged_at_end_row (w, delta, delta_bytes)
8950 struct window *w;
8951 int *delta, *delta_bytes;
a2889657 8952{
5f5c8ee5
GM
8953 struct glyph_row *row;
8954 struct glyph_row *row_found = NULL;
c581d710 8955
5f5c8ee5 8956 *delta = *delta_bytes = 0;
b2a76982 8957
5f5c8ee5
GM
8958 /* A value of window_end_pos >= end_unchanged means that the window
8959 end is in the range of changed text. If so, there is no
8960 unchanged row at the end of W's current matrix. */
8961 xassert (!NILP (w->window_end_valid));
8962 if (XFASTINT (w->window_end_pos) >= end_unchanged)
8963 return NULL;
8964
8965 /* Set row to the last row in W's current matrix displaying text. */
8966 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
8967
8968 /* End vpos should always be on text, except in an entirely empty
8969 matrix. */
8970 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row)
8971 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0);
8972
8973 /* If matrix is entirely empty, no unchanged row exists. */
8974 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
8975 {
8976 /* The value of row is the last glyph row in the matrix having a
8977 meaningful buffer position in it. The end position of row
8978 corresponds to window_end_pos. This allows us to translate
8979 buffer positions in the current matrix to current buffer
8980 positions for characters not in changed text. */
8981 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
8982 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
8983 int last_unchanged_pos, last_unchanged_pos_old;
8984 struct glyph_row *first_text_row
8985 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
8986
8987 *delta = Z - Z_old;
8988 *delta_bytes = Z_BYTE - Z_BYTE_old;
8989
8990 /* Set last_unchanged_pos to the buffer position of the last
8991 character in the buffer that has not been changed. Z is the
8992 index + 1 of the last byte in current_buffer, i.e. by
8993 subtracting end_unchanged we get the index of the last
8994 unchanged character, and we have to add BEG to get its buffer
8995 position. */
8996 last_unchanged_pos = Z - end_unchanged + BEG;
8997 last_unchanged_pos_old = last_unchanged_pos - *delta;
8998
8999 /* Search backward from ROW for a row displaying a line that
9000 starts at a minimum position >= last_unchanged_pos_old. */
9001 while (row >= first_text_row)
9002 {
9003 xassert (row->enabled_p);
9004 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9005
9006 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9007 row_found = row;
9008 --row;
9009 }
9010 }
9011
9012 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9013 return row_found;
c581d710
RS
9014}
9015
c581d710 9016
5f5c8ee5
GM
9017/* Make sure that glyph rows in the current matrix of window W
9018 reference the same glyph memory as corresponding rows in the
9019 frame's frame matrix. This function is called after scrolling W's
9020 current matrix on a terminal frame in try_window_id and
9021 try_window_reusing_current_matrix. */
9022
9023static void
9024sync_frame_with_window_matrix_rows (w)
9025 struct window *w;
c581d710 9026{
5f5c8ee5
GM
9027 struct frame *f = XFRAME (w->frame);
9028 struct glyph_row *window_row, *window_row_end, *frame_row;
9029
9030 /* Preconditions: W must be a leaf window and full-width. Its frame
9031 must have a frame matrix. */
9032 xassert (NILP (w->hchild) && NILP (w->vchild));
9033 xassert (WINDOW_FULL_WIDTH_P (w));
9034 xassert (!FRAME_WINDOW_P (f));
9035
9036 /* If W is a full-width window, glyph pointers in W's current matrix
9037 have, by definition, to be the same as glyph pointers in the
9038 corresponding frame matrix. */
9039 window_row = w->current_matrix->rows;
9040 window_row_end = window_row + w->current_matrix->nrows;
9041 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9042 while (window_row < window_row_end)
659a218f 9043 {
5f5c8ee5
GM
9044 int area;
9045 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9046 frame_row->glyphs[area] = window_row->glyphs[area];
9047 ++window_row, ++frame_row;
659a218f 9048 }
a2889657 9049}
5f5c8ee5
GM
9050
9051
9052/* Try to redisplay window W by reusing its existing display. W's
9053 current matrix must be up to date when this function is called,
9054 i.e. window_end_valid must not be nil.
9055
9056 Value is
9057
9058 1 if display has been updated
9059 0 if otherwise unsuccessful
9060 -1 if redisplay with same window start is known not to succeed
9061
9062 The following steps are performed:
9063
9064 1. Find the last row in the current matrix of W that is not
9065 affected by changes at the start of current_buffer. If no such row
9066 is found, give up.
9067
9068 2. Find the first row in W's current matrix that is not affected by
9069 changes at the end of current_buffer. Maybe there is no such row.
9070
9071 3. Display lines beginning with the row + 1 found in step 1 to the
9072 row found in step 2 or, if step 2 didn't find a row, to the end of
9073 the window.
9074
9075 4. If cursor is not known to appear on the window, give up.
9076
9077 5. If display stopped at the row found in step 2, scroll the
9078 display and current matrix as needed.
9079
9080 6. Maybe display some lines at the end of W, if we must. This can
9081 happen under various circumstances, like a partially visible line
9082 becoming fully visible, or because newly displayed lines are displayed
9083 in smaller font sizes.
9084
9085 7. Update W's window end information. */
9086
9087 /* Check that window end is what we expect it to be. */
12adba34
RS
9088
9089static int
5f5c8ee5 9090try_window_id (w)
12adba34 9091 struct window *w;
12adba34 9092{
5f5c8ee5
GM
9093 struct frame *f = XFRAME (w->frame);
9094 struct glyph_matrix *current_matrix = w->current_matrix;
9095 struct glyph_matrix *desired_matrix = w->desired_matrix;
9096 struct glyph_row *last_unchanged_at_beg_row;
9097 struct glyph_row *first_unchanged_at_end_row;
9098 struct glyph_row *row;
9099 struct glyph_row *bottom_row;
9100 int bottom_vpos;
9101 struct it it;
9102 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
9103 struct text_pos start_pos;
9104 struct run run;
9105 int first_unchanged_at_end_vpos = 0;
9106 struct glyph_row *last_text_row, *last_text_row_at_end;
9107 struct text_pos start;
9108
9109 SET_TEXT_POS_FROM_MARKER (start, w->start);
9110
9111 /* Check pre-conditions. Window end must be valid, otherwise
9112 the current matrix would not be up to date. */
9113 xassert (!NILP (w->window_end_valid));
9114 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
9115 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
9116
9117 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
9118 only if buffer has really changed. The reason is that the gap is
9119 initially at Z for freshly visited files. The code below would
9120 set end_unchanged to 0 in that case. */
9121 if (MODIFF > SAVE_MODIFF)
9122 {
9123 if (GPT - BEG < beg_unchanged)
9124 beg_unchanged = GPT - BEG;
9125 if (Z - GPT < end_unchanged)
9126 end_unchanged = Z - GPT;
9127 }
9128
9129 /* If window starts after a line end, and the last change is in
9130 front of that newline, then changes don't affect the display.
9131 This case happens with stealth-fontification. */
9132 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9133 if (CHARPOS (start) > BEGV
9134 && Z - end_unchanged < CHARPOS (start) - 1
9135 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
9136 && PT < MATRIX_ROW_END_CHARPOS (row))
9137 {
9138 /* We have to update window end positions because the buffer's
9139 size has changed. */
9140 w->window_end_pos
9141 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9142 w->window_end_bytepos
9143 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9144 return 1;
9145 }
9146
9147 /* Return quickly if changes are all below what is displayed in the
9148 window, and if PT is in the window. */
9149 if (beg_unchanged > MATRIX_ROW_END_CHARPOS (row)
9150 && PT < MATRIX_ROW_END_CHARPOS (row))
9151 {
9152 /* We have to update window end positions because the buffer's
9153 size has changed. */
9154 w->window_end_pos
9155 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
9156 w->window_end_bytepos
9157 = make_number (Z_BYTE - MATRIX_ROW_END_BYTEPOS (row));
9158 return 1;
9159 }
9160
9161 /* Check that window start agrees with the start of the first glyph
9162 row in its current matrix. Check this after we know the window
9163 start is not in changed text, otherwise positions would not be
9164 comparable. */
9165 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9166 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
9167 return 0;
9168
9169 /* Remember beg_unchanged and end_unchanged for debugging purposes. */
9170 IF_DEBUG (debug_beg_unchanged = beg_unchanged;
9171 debug_end_unchanged = end_unchanged);
9172
9173 /* Compute the position at which we have to start displaying new
9174 lines. Some of the lines at the top of the window might be
9175 reusable because they are not displaying changed text. Find the
9176 last row in W's current matrix not affected by changes at the
9177 start of current_buffer. Value is null if changes start in the
9178 first line of window. */
9179 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
9180 if (last_unchanged_at_beg_row)
9181 {
9182 init_to_row_end (&it, w, last_unchanged_at_beg_row);
9183 start_pos = it.current.pos;
9184
9185 /* Start displaying new lines in the desired matrix at the same
9186 vpos we would use in the current matrix, i.e. below
9187 last_unchanged_at_beg_row. */
9188 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
9189 current_matrix);
9190 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9191 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
9192
9193 xassert (it.hpos == 0 && it.current_x == 0);
9194 }
9195 else
9196 {
9197 /* There are no reusable lines at the start of the window.
9198 Start displaying in the first line. */
9199 start_display (&it, w, start);
9200 start_pos = it.current.pos;
9201 }
9202
9203 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
9204 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
9205
9206 /* Find the first row that is not affected by changes at the end of
9207 the buffer. Value will be null if there is no unchanged row, in
9208 which case we must redisplay to the end of the window. delta
9209 will be set to the value by which buffer positions beginning with
9210 first_unchanged_at_end_row have to be adjusted due to text
9211 changes. */
9212 first_unchanged_at_end_row
9213 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
9214 IF_DEBUG (debug_delta = delta);
9215 IF_DEBUG (debug_delta_bytes = delta_bytes);
9216
9217 /* Set stop_pos to the buffer position up to which we will have to
9218 display new lines. If first_unchanged_at_end_row != NULL, this
9219 is the buffer position of the start of the line displayed in that
9220 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
9221 that we don't stop at a buffer position. */
9222 stop_pos = 0;
9223 if (first_unchanged_at_end_row)
9224 {
9225 xassert (last_unchanged_at_beg_row == NULL
9226 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
9227
9228 /* If this is a continuation line, move forward to the next one
9229 that isn't. Changes in lines above affect this line.
9230 Caution: this may move first_unchanged_at_end_row to a row
9231 not displaying text. */
9232 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
9233 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9234 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9235 < it.last_visible_y))
9236 ++first_unchanged_at_end_row;
9237
9238 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
9239 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
9240 >= it.last_visible_y))
9241 first_unchanged_at_end_row = NULL;
9242 else
9243 {
9244 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
9245 + delta);
9246 first_unchanged_at_end_vpos
9247 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
9248 xassert (stop_pos >= Z - end_unchanged);
9249 }
9250 }
9251 else if (last_unchanged_at_beg_row == NULL)
9252 return 0;
9253
9254
9255#if GLYPH_DEBUG
9256
9257 /* Either there is no unchanged row at the end, or the one we have
9258 now displays text. This is a necessary condition for the window
9259 end pos calculation at the end of this function. */
9260 xassert (first_unchanged_at_end_row == NULL
9261 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
9262
9263 debug_last_unchanged_at_beg_vpos
9264 = (last_unchanged_at_beg_row
9265 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
9266 : -1);
9267 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
9268
9269#endif /* GLYPH_DEBUG != 0 */
9270
9271
9272 /* Display new lines. Set last_text_row to the last new line
9273 displayed which has text on it, i.e. might end up as being the
9274 line where the window_end_vpos is. */
9275 w->cursor.vpos = -1;
9276 last_text_row = NULL;
9277 overlay_arrow_seen = 0;
9278 while (it.current_y < it.last_visible_y
9279 && !fonts_changed_p
9280 && (first_unchanged_at_end_row == NULL
9281 || IT_CHARPOS (it) < stop_pos))
9282 {
9283 if (display_line (&it))
9284 last_text_row = it.glyph_row - 1;
9285 }
9286
9287 if (fonts_changed_p)
9288 return -1;
9289
9290
9291 /* Compute differences in buffer positions, y-positions etc. for
9292 lines reused at the bottom of the window. Compute what we can
9293 scroll. */
9294 if (first_unchanged_at_end_row)
9295 {
9296 dvpos = (it.vpos
9297 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
9298 current_matrix));
9299 dy = it.current_y - first_unchanged_at_end_row->y;
9300 run.current_y = first_unchanged_at_end_row->y;
9301 run.desired_y = run.current_y + dy;
9302 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
9303 }
9304 else
9305 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
9306 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
9307
9308
9309 /* Find the cursor if not already found. We have to decide whether
9310 PT will appear on this window (it sometimes doesn't, but this is
9311 not a very frequent case.) This decision has to be made before
9312 the current matrix is altered. A value of cursor.vpos < 0 means
9313 that PT is either in one of the lines beginning at
9314 first_unchanged_at_end_row or below the window. Don't care for
9315 lines that might be displayed later at the window end; as
9316 mentioned, this is not a frequent case. */
9317 if (w->cursor.vpos < 0)
9318 {
9319 int last_y = min (it.last_visible_y, it.last_visible_y + dy);
9320
9321 /* Cursor in unchanged rows at the top? */
9322 if (PT < CHARPOS (start_pos)
9323 && last_unchanged_at_beg_row)
9324 {
9325 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9326 while (row <= last_unchanged_at_beg_row
9327 && MATRIX_ROW_END_CHARPOS (row) <= PT)
9328 ++row;
9329 xassert (row <= last_unchanged_at_beg_row);
9330 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9331 }
9332
9333 /* Start from first_unchanged_at_end_row looking for PT. */
9334 else if (first_unchanged_at_end_row)
9335 {
9336 row = first_unchanged_at_end_row;
9337 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9338 {
9339 if (PT - delta >= MATRIX_ROW_START_CHARPOS (row)
9340 && PT - delta < MATRIX_ROW_END_CHARPOS (row))
9341 {
9342 set_cursor_from_row (w, row, w->current_matrix, delta,
9343 delta_bytes, dy, dvpos);
9344 break;
9345 }
9346 else if (MATRIX_ROW_BOTTOM_Y (row) >= last_y)
9347 break;
9348 ++row;
9349 }
9350 }
9351
9352 /* Give up if cursor was not found. */
9353 if (w->cursor.vpos < 0)
9354 {
9355 clear_glyph_matrix (w->desired_matrix);
9356 return -1;
9357 }
9358 }
9359
9360 /* Don't let the cursor end in the scroll margins. */
9361 {
9362 int this_scroll_margin, cursor_height;
9363
9364 this_scroll_margin = max (0, scroll_margin);
9365 this_scroll_margin = min (this_scroll_margin,
9366 XFASTINT (w->height) / 4);
9367 this_scroll_margin *= CANON_Y_UNIT (it.f);
9368 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
9369
9370 if ((w->cursor.y < this_scroll_margin
9371 && CHARPOS (start) > BEGV)
9372 /* Don't take scroll margin into account at the bottom because
9373 old redisplay didn't do it either. */
9374 || w->cursor.y + cursor_height > it.last_visible_y)
9375 {
9376 w->cursor.vpos = -1;
9377 clear_glyph_matrix (w->desired_matrix);
9378 return -1;
9379 }
9380 }
9381
9382 /* Scroll the display. Do it before changing the current matrix so
9383 that xterm.c doesn't get confused about where the cursor glyph is
9384 found. */
9385 if (dy)
9386 {
9387 update_begin (f);
9388
9389 if (FRAME_WINDOW_P (f))
9390 {
9391 rif->update_window_begin_hook (w);
9392 rif->scroll_run_hook (w, &run);
9393 rif->update_window_end_hook (w, 0);
9394 }
9395 else
9396 {
9397 /* Terminal frame. In this case, dvpos gives the number of
9398 lines to scroll by; dvpos < 0 means scroll up. */
9399 int first_unchanged_at_end_vpos
9400 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
9401 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
9402 int end = XFASTINT (w->top) + window_internal_height (w);
9403
9404 /* Perform the operation on the screen. */
9405 if (dvpos > 0)
9406 {
9407 /* Scroll last_unchanged_at_beg_row to the end of the
9408 window down dvpos lines. */
9409 set_terminal_window (end);
9410
9411 /* On dumb terminals delete dvpos lines at the end
9412 before inserting dvpos empty lines. */
9413 if (!scroll_region_ok)
9414 ins_del_lines (end - dvpos, -dvpos);
9415
9416 /* Insert dvpos empty lines in front of
9417 last_unchanged_at_beg_row. */
9418 ins_del_lines (from, dvpos);
9419 }
9420 else if (dvpos < 0)
9421 {
9422 /* Scroll up last_unchanged_at_beg_vpos to the end of
9423 the window to last_unchanged_at_beg_vpos - |dvpos|. */
9424 set_terminal_window (end);
9425
9426 /* Delete dvpos lines in front of
9427 last_unchanged_at_beg_vpos. ins_del_lines will set
9428 the cursor to the given vpos and emit |dvpos| delete
9429 line sequences. */
9430 ins_del_lines (from + dvpos, dvpos);
9431
9432 /* On a dumb terminal insert dvpos empty lines at the
9433 end. */
9434 if (!scroll_region_ok)
9435 ins_del_lines (end + dvpos, -dvpos);
9436 }
9437
9438 set_terminal_window (0);
9439 }
9440
9441 update_end (f);
9442 }
9443
9444 /* Shift reused rows of the current matrix to the right position. */
9445 if (dvpos < 0)
9446 {
9447 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
9448 bottom_vpos, dvpos);
9449 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
9450 bottom_vpos, 0);
9451 }
9452 else if (dvpos > 0)
9453 {
9454 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
9455 bottom_vpos, dvpos);
9456 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
9457 first_unchanged_at_end_vpos + dvpos, 0);
9458 }
9459
9460 /* For frame-based redisplay, make sure that current frame and window
9461 matrix are in sync with respect to glyph memory. */
9462 if (!FRAME_WINDOW_P (f))
9463 sync_frame_with_window_matrix_rows (w);
9464
9465 /* Adjust buffer positions in reused rows. */
9466 if (delta)
9467 increment_glyph_matrix_buffer_positions (current_matrix,
9468 first_unchanged_at_end_vpos + dvpos,
9469 bottom_vpos, delta, delta_bytes);
9470
9471 /* Adjust Y positions. */
9472 if (dy)
9473 shift_glyph_matrix (w, current_matrix,
9474 first_unchanged_at_end_vpos + dvpos,
9475 bottom_vpos, dy);
9476
9477 if (first_unchanged_at_end_row)
9478 first_unchanged_at_end_row += dvpos;
9479
9480 /* If scrolling up, there may be some lines to display at the end of
9481 the window. */
9482 last_text_row_at_end = NULL;
9483 if (dy < 0)
9484 {
9485 /* Set last_row to the glyph row in the current matrix where the
9486 window end line is found. It has been moved up or down in
9487 the matrix by dvpos. */
9488 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
9489 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
9490
9491 /* If last_row is the window end line, it should display text. */
9492 xassert (last_row->displays_text_p);
9493
9494 /* If window end line was partially visible before, begin
9495 displaying at that line. Otherwise begin displaying with the
9496 line following it. */
9497 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
9498 {
9499 init_to_row_start (&it, w, last_row);
9500 it.vpos = last_vpos;
9501 it.current_y = last_row->y;
9502 }
9503 else
9504 {
9505 init_to_row_end (&it, w, last_row);
9506 it.vpos = 1 + last_vpos;
9507 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
9508 ++last_row;
9509 }
12adba34 9510
5f5c8ee5
GM
9511 /* We may start in a continuation line. If so, we have to get
9512 the right continuation_lines_width and current_x. */
9513 it.continuation_lines_width = last_row->continuation_lines_width;
9514 it.hpos = it.current_x = 0;
9515
9516 /* Display the rest of the lines at the window end. */
9517 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
9518 while (it.current_y < it.last_visible_y
9519 && !fonts_changed_p)
9520 {
9521 /* Is it always sure that the display agrees with lines in
9522 the current matrix? I don't think so, so we mark rows
9523 displayed invalid in the current matrix by setting their
9524 enabled_p flag to zero. */
9525 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
9526 if (display_line (&it))
9527 last_text_row_at_end = it.glyph_row - 1;
9528 }
9529 }
12adba34 9530
5f5c8ee5
GM
9531 /* Update window_end_pos and window_end_vpos. */
9532 if (first_unchanged_at_end_row
9533 && first_unchanged_at_end_row->y < it.last_visible_y
9534 && !last_text_row_at_end)
9535 {
9536 /* Window end line if one of the preserved rows from the current
9537 matrix. Set row to the last row displaying text in current
9538 matrix starting at first_unchanged_at_end_row, after
9539 scrolling. */
9540 xassert (first_unchanged_at_end_row->displays_text_p);
9541 row = find_last_row_displaying_text (w->current_matrix, &it,
9542 first_unchanged_at_end_row);
9543 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
9544
9545 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
9546 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
9547 XSETFASTINT (w->window_end_vpos,
9548 MATRIX_ROW_VPOS (row, w->current_matrix));
9549 }
9550 else if (last_text_row_at_end)
9551 {
9552 XSETFASTINT (w->window_end_pos,
9553 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
9554 w->window_end_bytepos
9555 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
9556 XSETFASTINT (w->window_end_vpos,
9557 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
9558 }
9559 else if (last_text_row)
9560 {
9561 /* We have displayed either to the end of the window or at the
9562 end of the window, i.e. the last row with text is to be found
9563 in the desired matrix. */
9564 XSETFASTINT (w->window_end_pos,
9565 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9566 w->window_end_bytepos
9567 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9568 XSETFASTINT (w->window_end_vpos,
9569 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
9570 }
9571 else if (first_unchanged_at_end_row == NULL
9572 && last_text_row == NULL
9573 && last_text_row_at_end == NULL)
9574 {
9575 /* Displayed to end of window, but no line containing text was
9576 displayed. Lines were deleted at the end of the window. */
9577 int vpos;
9578 int top_line_p = WINDOW_WANTS_TOP_LINE_P (w) ? 1 : 0;
9579
9580 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
9581 if ((w->desired_matrix->rows[vpos + top_line_p].enabled_p
9582 && w->desired_matrix->rows[vpos + top_line_p].displays_text_p)
9583 || (!w->desired_matrix->rows[vpos + top_line_p].enabled_p
9584 && w->current_matrix->rows[vpos + top_line_p].displays_text_p))
9585 break;
12adba34 9586
5f5c8ee5
GM
9587 w->window_end_vpos = make_number (vpos);
9588 }
9589 else
9590 abort ();
9591
9592 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
9593 debug_end_vpos = XFASTINT (w->window_end_vpos));
12adba34 9594
5f5c8ee5
GM
9595 /* Record that display has not been completed. */
9596 w->window_end_valid = Qnil;
9597 w->desired_matrix->no_scrolling_p = 1;
9598 return 1;
12adba34 9599}
0f9c0ff0 9600
a2889657 9601
5f5c8ee5
GM
9602\f
9603/***********************************************************************
9604 More debugging support
9605 ***********************************************************************/
a2889657 9606
5f5c8ee5 9607#if GLYPH_DEBUG
a2889657 9608
5f5c8ee5
GM
9609 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
9610static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
1c9241f5 9611
31b24551 9612
5f5c8ee5
GM
9613/* Dump the contents of glyph matrix MATRIX on stderr. If
9614 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
ca26e1c8 9615
5f5c8ee5
GM
9616void
9617dump_glyph_matrix (matrix, with_glyphs_p)
9618 struct glyph_matrix *matrix;
9619 int with_glyphs_p;
9620{
efc63ef0 9621 int i;
5f5c8ee5
GM
9622 for (i = 0; i < matrix->nrows; ++i)
9623 dump_glyph_row (matrix, i, with_glyphs_p);
9624}
31b24551 9625
68a37fa8 9626
5f5c8ee5
GM
9627/* Dump the contents of glyph row at VPOS in MATRIX to stderr.
9628 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
a2889657 9629
5f5c8ee5
GM
9630void
9631dump_glyph_row (matrix, vpos, with_glyphs_p)
9632 struct glyph_matrix *matrix;
9633 int vpos, with_glyphs_p;
9634{
9635 struct glyph_row *row;
9636
9637 if (vpos < 0 || vpos >= matrix->nrows)
9638 return;
9639
9640 row = MATRIX_ROW (matrix, vpos);
9641
9642 fprintf (stderr, "Row Start End Used oEI><O\\CTZF X Y W\n");
9643 fprintf (stderr, "=============================================\n");
9644
9645 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",
9646 row - matrix->rows,
9647 MATRIX_ROW_START_CHARPOS (row),
9648 MATRIX_ROW_END_CHARPOS (row),
9649 row->used[TEXT_AREA],
9650 row->contains_overlapping_glyphs_p,
9651 row->enabled_p,
9652 row->inverse_p,
9653 row->truncated_on_left_p,
9654 row->truncated_on_right_p,
9655 row->overlay_arrow_p,
9656 row->continued_p,
9657 MATRIX_ROW_CONTINUATION_LINE_P (row),
9658 row->displays_text_p,
9659 row->ends_at_zv_p,
9660 row->fill_line_p,
9661 row->x,
9662 row->y,
9663 row->pixel_width);
9664 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
9665 row->end.overlay_string_index);
9666 fprintf (stderr, "%9d %5d\n",
9667 CHARPOS (row->start.string_pos),
9668 CHARPOS (row->end.string_pos));
9669 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
9670 row->end.dpvec_index);
9671
9672 if (with_glyphs_p)
bd66d1ba 9673 {
5f5c8ee5
GM
9674 struct glyph *glyph, *glyph_end;
9675 int prev_had_glyphs_p;
9676
9677 glyph = row->glyphs[TEXT_AREA];
9678 glyph_end = glyph + row->used[TEXT_AREA];
9679
9680 /* Glyph for a line end in text. */
9681 if (glyph == glyph_end && glyph->charpos > 0)
9682 ++glyph_end;
9683
9684 if (glyph < glyph_end)
bd66d1ba 9685 {
5f5c8ee5
GM
9686 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
9687 prev_had_glyphs_p = 1;
bd66d1ba
RS
9688 }
9689 else
5f5c8ee5
GM
9690 prev_had_glyphs_p = 0;
9691
9692 while (glyph < glyph_end)
f7b4b63a 9693 {
5f5c8ee5
GM
9694 if (glyph->type == CHAR_GLYPH)
9695 {
9696 fprintf (stderr,
9697 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9698 glyph - row->glyphs[TEXT_AREA],
9699 'C',
9700 glyph->charpos,
9701 glyph->pixel_width,
9702 glyph->u.ch.code,
9703 (glyph->u.ch.code < 0x80 && glyph->u.ch.code >= ' '
9704 ? glyph->u.ch.code
9705 : '.'),
9706 glyph->u.ch.face_id,
9707 glyph->left_box_line_p,
9708 glyph->right_box_line_p);
9709 }
9710 else if (glyph->type == STRETCH_GLYPH)
9711 {
9712 fprintf (stderr,
9713 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9714 glyph - row->glyphs[TEXT_AREA],
9715 'S',
9716 glyph->charpos,
9717 glyph->pixel_width,
9718 0,
9719 '.',
9720 glyph->u.stretch.face_id,
9721 glyph->left_box_line_p,
9722 glyph->right_box_line_p);
9723 }
9724 else if (glyph->type == IMAGE_GLYPH)
9725 {
9726 fprintf (stderr,
9727 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9728 glyph - row->glyphs[TEXT_AREA],
9729 'I',
9730 glyph->charpos,
9731 glyph->pixel_width,
9732 glyph->u.img.id,
9733 '.',
9734 glyph->u.img.face_id,
9735 glyph->left_box_line_p,
9736 glyph->right_box_line_p);
9737 }
9738 ++glyph;
f7b4b63a 9739 }
f4faa47c 9740 }
5f5c8ee5 9741}
f4faa47c 9742
a2889657 9743
5f5c8ee5
GM
9744DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
9745 Sdump_glyph_matrix, 0, 1, "p",
9746 "Dump the current matrix of the selected window to stderr.\n\
9747Shows contents of glyph row structures. With non-nil optional\n\
9748parameter WITH-GLYPHS-P, dump glyphs as well.")
9749 (with_glyphs_p)
9750{
9751 struct window *w = XWINDOW (selected_window);
9752 struct buffer *buffer = XBUFFER (w->buffer);
9753
9754 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
9755 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
9756 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
9757 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
9758 fprintf (stderr, "=============================================\n");
9759 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
9760 return Qnil;
9761}
1c2250c2 9762
1fca3fae 9763
5f5c8ee5
GM
9764DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
9765 "Dump glyph row ROW to stderr.")
9766 (row)
9767 Lisp_Object row;
9768{
9769 CHECK_NUMBER (row, 0);
9770 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
9771 return Qnil;
9772}
1fca3fae 9773
67481ae5 9774
5f5c8ee5
GM
9775DEFUN ("dump-toolbar-row", Fdump_toolbar_row, Sdump_toolbar_row,
9776 0, 0, "", "")
9777 ()
9778{
9779 struct glyph_matrix *m = (XWINDOW (selected_frame->toolbar_window)
9780 ->current_matrix);
9781 dump_glyph_row (m, 0, 1);
9782 return Qnil;
9783}
ca26e1c8 9784
0f9c0ff0 9785
5f5c8ee5
GM
9786DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
9787 Strace_redisplay_toggle, 0, 0, "",
9788 "Toggle tracing of redisplay.")
9789 ()
9790{
9791 trace_redisplay_p = !trace_redisplay_p;
9792 return Qnil;
9793}
9794
9795
9796#endif /* GLYPH_DEBUG */
ca26e1c8 9797
ca26e1c8 9798
5f5c8ee5
GM
9799\f
9800/***********************************************************************
9801 Building Desired Matrix Rows
9802 ***********************************************************************/
a2889657 9803
5f5c8ee5
GM
9804/* Return a temporary glyph row holding the glyphs of an overlay
9805 arrow. Only used for non-window-redisplay windows. */
ca26e1c8 9806
5f5c8ee5
GM
9807static struct glyph_row *
9808get_overlay_arrow_glyph_row (w)
9809 struct window *w;
9810{
9811 struct frame *f = XFRAME (WINDOW_FRAME (w));
9812 struct buffer *buffer = XBUFFER (w->buffer);
9813 struct buffer *old = current_buffer;
9814 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
9815 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
9816 unsigned char *arrow_end = arrow_string + arrow_len;
9817 unsigned char *p;
9818 struct it it;
9819 int multibyte_p;
9820 int n_glyphs_before;
9821
9822 set_buffer_temp (buffer);
9823 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
9824 it.glyph_row->used[TEXT_AREA] = 0;
9825 SET_TEXT_POS (it.position, 0, 0);
9826
9827 multibyte_p = !NILP (buffer->enable_multibyte_characters);
9828 p = arrow_string;
9829 while (p < arrow_end)
9830 {
9831 Lisp_Object face, ilisp;
9832
9833 /* Get the next character. */
9834 if (multibyte_p)
4fdb80f2 9835 it.c = string_char_and_length (p, arrow_len, &it.len);
5f5c8ee5
GM
9836 else
9837 it.c = *p, it.len = 1;
9838 p += it.len;
9839
9840 /* Get its face. */
9841 XSETFASTINT (ilisp, p - arrow_string);
9842 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
9843 it.face_id = compute_char_face (f, it.c, face);
9844
9845 /* Compute its width, get its glyphs. */
9846 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
337042a9 9847 SET_TEXT_POS (it.position, -1, -1);
5f5c8ee5
GM
9848 PRODUCE_GLYPHS (&it);
9849
9850 /* If this character doesn't fit any more in the line, we have
9851 to remove some glyphs. */
9852 if (it.current_x > it.last_visible_x)
9853 {
9854 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
9855 break;
9856 }
9857 }
9858
9859 set_buffer_temp (old);
9860 return it.glyph_row;
9861}
ca26e1c8 9862
b0a0fbda 9863
5f5c8ee5
GM
9864/* Insert truncation glyphs at the start of IT->glyph_row. Truncation
9865 glyphs are only inserted for terminal frames since we can't really
9866 win with truncation glyphs when partially visible glyphs are
9867 involved. Which glyphs to insert is determined by
9868 produce_special_glyphs. */
67481ae5 9869
5f5c8ee5
GM
9870static void
9871insert_left_trunc_glyphs (it)
9872 struct it *it;
9873{
9874 struct it truncate_it;
9875 struct glyph *from, *end, *to, *toend;
9876
9877 xassert (!FRAME_WINDOW_P (it->f));
9878
9879 /* Get the truncation glyphs. */
9880 truncate_it = *it;
9881 truncate_it.charset = -1;
9882 truncate_it.current_x = 0;
9883 truncate_it.face_id = DEFAULT_FACE_ID;
9884 truncate_it.glyph_row = &scratch_glyph_row;
9885 truncate_it.glyph_row->used[TEXT_AREA] = 0;
9886 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
9887 truncate_it.object = 0;
9888 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
9889
9890 /* Overwrite glyphs from IT with truncation glyphs. */
9891 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
9892 end = from + truncate_it.glyph_row->used[TEXT_AREA];
9893 to = it->glyph_row->glyphs[TEXT_AREA];
9894 toend = to + it->glyph_row->used[TEXT_AREA];
9895
9896 while (from < end)
9897 *to++ = *from++;
9898
9899 /* There may be padding glyphs left over. Remove them. */
9900 from = to;
9901 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
9902 ++from;
9903 while (from < toend)
9904 *to++ = *from++;
9905
9906 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
9907}
e0bfbde6 9908
e0bfbde6 9909
5f5c8ee5 9910/* Compute the pixel height and width of IT->glyph_row.
9c49d3d7 9911
5f5c8ee5
GM
9912 Most of the time, ascent and height of a display line will be equal
9913 to the max_ascent and max_height values of the display iterator
9914 structure. This is not the case if
67481ae5 9915
5f5c8ee5
GM
9916 1. We hit ZV without displaying anything. In this case, max_ascent
9917 and max_height will be zero.
1c9241f5 9918
5f5c8ee5
GM
9919 2. We have some glyphs that don't contribute to the line height.
9920 (The glyph row flag contributes_to_line_height_p is for future
9921 pixmap extensions).
f6fd109b 9922
5f5c8ee5
GM
9923 The first case is easily covered by using default values because in
9924 these cases, the line height does not really matter, except that it
9925 must not be zero. */
67481ae5 9926
5f5c8ee5
GM
9927static void
9928compute_line_metrics (it)
9929 struct it *it;
9930{
9931 struct glyph_row *row = it->glyph_row;
9932 int area, i;
1c2250c2 9933
5f5c8ee5
GM
9934 if (FRAME_WINDOW_P (it->f))
9935 {
9936 int i, top_line_height;
1c2250c2 9937
5f5c8ee5
GM
9938 /* The line may consist of one space only, that was added to
9939 place the cursor on it. If so, the row's height hasn't been
9940 computed yet. */
9941 if (row->height == 0)
9942 {
9943 if (it->max_ascent + it->max_descent == 0)
312246d1 9944 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
5f5c8ee5
GM
9945 row->ascent = it->max_ascent;
9946 row->height = it->max_ascent + it->max_descent;
312246d1
GM
9947 row->phys_ascent = it->max_phys_ascent;
9948 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
9949 }
9950
9951 /* Compute the width of this line. */
9952 row->pixel_width = row->x;
9953 for (i = 0; i < row->used[TEXT_AREA]; ++i)
9954 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
9955
9956 xassert (row->pixel_width >= 0);
9957 xassert (row->ascent >= 0 && row->height > 0);
9958
312246d1
GM
9959 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
9960 || MATRIX_ROW_OVERLAPS_PRED_P (row));
9961
9962 /* If first line's physical ascent is larger than its logical
9963 ascent, use the physical ascent, and make the row taller.
9964 This makes accented characters fully visible. */
9965 if (row == it->w->desired_matrix->rows
9966 && row->phys_ascent > row->ascent)
9967 {
9968 row->height += row->phys_ascent - row->ascent;
9969 row->ascent = row->phys_ascent;
9970 }
9971
5f5c8ee5
GM
9972 /* Compute how much of the line is visible. */
9973 row->visible_height = row->height;
9974
9975 top_line_height = WINDOW_DISPLAY_TOP_LINE_HEIGHT (it->w);
9976 if (row->y < top_line_height)
9977 row->visible_height -= top_line_height - row->y;
9978 else
9979 {
9980 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
9981 if (row->y + row->height > max_y)
9982 row->visible_height -= row->y + row->height - max_y;
9983 }
9984 }
9985 else
9986 {
9987 row->pixel_width = row->used[TEXT_AREA];
312246d1
GM
9988 row->ascent = row->phys_ascent = 0;
9989 row->height = row->phys_height = row->visible_height = 1;
5f5c8ee5 9990 }
67481ae5 9991
5f5c8ee5
GM
9992 /* Compute a hash code for this row. */
9993 row->hash = 0;
9994 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
9995 for (i = 0; i < row->used[area]; ++i)
9996 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
9997 + row->glyphs[area][i].u.val
9998 + (row->glyphs[area][i].type << 2));
a2889657 9999
5f5c8ee5 10000 it->max_ascent = it->max_descent = 0;
312246d1 10001 it->max_phys_ascent = it->max_phys_descent = 0;
5f5c8ee5 10002}
12adba34 10003
ca26e1c8 10004
5f5c8ee5
GM
10005/* Append one space to the glyph row of iterator IT if doing a
10006 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10007 space have the default face, otherwise let it have the same face as
10008 IT->face_id. This function is called to make sure that there is
10009 always one glyph at the end of a glyph row that the cursor can be
10010 set on under window-systems. (If there weren't such a glyph we
10011 would not know how wide and tall the cursor should be displayed). */
ca26e1c8 10012
5f5c8ee5
GM
10013static void
10014append_space (it, default_face_p)
10015 struct it *it;
10016 int default_face_p;
10017{
10018 if (FRAME_WINDOW_P (it->f))
10019 {
10020 int n = it->glyph_row->used[TEXT_AREA];
ca26e1c8 10021
5f5c8ee5
GM
10022 if (it->glyph_row->glyphs[TEXT_AREA] + n
10023 < it->glyph_row->glyphs[1 + TEXT_AREA])
a2889657 10024 {
5f5c8ee5
GM
10025 /* Save some values that must not be changed. */
10026 int saved_x = it->current_x;
10027 struct text_pos saved_pos;
10028 int saved_what = it->what;
10029 int saved_face_id = it->face_id;
10030 int saved_charset = it->charset;
10031 Lisp_Object saved_object;
10032
10033 saved_object = it->object;
10034 saved_pos = it->position;
10035
10036 it->what = IT_CHARACTER;
10037 bzero (&it->position, sizeof it->position);
10038 it->object = 0;
10039 it->c = ' ';
10040 it->len = 1;
10041 it->charset = CHARSET_ASCII;
10042
10043 if (default_face_p)
10044 it->face_id = DEFAULT_FACE_ID;
10045 if (it->multibyte_p)
10046 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, CHARSET_ASCII);
10047 else
10048 it->face_id = FACE_FOR_CHARSET (it->f, it->face_id, -1);
1842fc1a 10049
5f5c8ee5
GM
10050 PRODUCE_GLYPHS (it);
10051
10052 it->current_x = saved_x;
10053 it->object = saved_object;
10054 it->position = saved_pos;
10055 it->what = saved_what;
10056 it->face_id = saved_face_id;
10057 it->charset = saved_charset;
10058 }
10059 }
10060}
12adba34 10061
1842fc1a 10062
5f5c8ee5
GM
10063/* Extend the face of the last glyph in the text area of IT->glyph_row
10064 to the end of the display line. Called from display_line.
10065 If the glyph row is empty, add a space glyph to it so that we
10066 know the face to draw. Set the glyph row flag fill_line_p. */
10067
10068static void
10069extend_face_to_end_of_line (it)
10070 struct it *it;
10071{
10072 struct face *face;
10073 struct frame *f = it->f;
1842fc1a 10074
5f5c8ee5
GM
10075 /* If line is already filled, do nothing. */
10076 if (it->current_x >= it->last_visible_x)
10077 return;
10078
10079 /* Face extension extends the background and box of IT->face_id
10080 to the end of the line. If the background equals the background
10081 of the frame, we haven't to do anything. */
10082 face = FACE_FROM_ID (f, it->face_id);
10083 if (FRAME_WINDOW_P (f)
10084 && face->box == FACE_NO_BOX
10085 && face->background == FRAME_BACKGROUND_PIXEL (f)
10086 && !face->stipple)
10087 return;
1842fc1a 10088
5f5c8ee5
GM
10089 /* Set the glyph row flag indicating that the face of the last glyph
10090 in the text area has to be drawn to the end of the text area. */
10091 it->glyph_row->fill_line_p = 1;
545e04f6 10092
5f5c8ee5
GM
10093 /* If current charset of IT is not ASCII, make sure we have the
10094 ASCII face. This will be automatically undone the next time
10095 get_next_display_element returns a character from a different
10096 charset. Note that the charset will always be ASCII in unibyte
10097 text. */
10098 if (it->charset != CHARSET_ASCII)
10099 {
10100 it->charset = CHARSET_ASCII;
10101 it->face_id = FACE_FOR_CHARSET (f, it->face_id, CHARSET_ASCII);
10102 }
545e04f6 10103
5f5c8ee5
GM
10104 if (FRAME_WINDOW_P (f))
10105 {
10106 /* If the row is empty, add a space with the current face of IT,
10107 so that we know which face to draw. */
10108 if (it->glyph_row->used[TEXT_AREA] == 0)
a2889657 10109 {
5f5c8ee5
GM
10110 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
10111 it->glyph_row->glyphs[TEXT_AREA][0].u.ch.face_id = it->face_id;
10112 it->glyph_row->used[TEXT_AREA] = 1;
a2889657 10113 }
5f5c8ee5
GM
10114 }
10115 else
10116 {
10117 /* Save some values that must not be changed. */
10118 int saved_x = it->current_x;
10119 struct text_pos saved_pos;
10120 Lisp_Object saved_object;
10121 int saved_what = it->what;
10122
10123 saved_object = it->object;
10124 saved_pos = it->position;
10125
10126 it->what = IT_CHARACTER;
10127 bzero (&it->position, sizeof it->position);
10128 it->object = 0;
10129 it->c = ' ';
10130 it->len = 1;
10131
10132 PRODUCE_GLYPHS (it);
10133
10134 while (it->current_x <= it->last_visible_x)
10135 PRODUCE_GLYPHS (it);
10136
10137 /* Don't count these blanks really. It would let us insert a left
10138 truncation glyph below and make us set the cursor on them, maybe. */
10139 it->current_x = saved_x;
10140 it->object = saved_object;
10141 it->position = saved_pos;
10142 it->what = saved_what;
10143 }
10144}
12adba34 10145
545e04f6 10146
5f5c8ee5
GM
10147/* Value is non-zero if text starting at CHARPOS in current_buffer is
10148 trailing whitespace. */
1c9241f5 10149
5f5c8ee5
GM
10150static int
10151trailing_whitespace_p (charpos)
10152 int charpos;
10153{
10154 int bytepos = CHAR_TO_BYTE (charpos);
10155 int c = 0;
7bbe686f 10156
5f5c8ee5
GM
10157 while (bytepos < ZV_BYTE
10158 && (c = FETCH_CHAR (bytepos),
10159 c == ' ' || c == '\t'))
10160 ++bytepos;
0d09d1e6 10161
5f5c8ee5
GM
10162 return bytepos >= ZV_BYTE || c == '\n' || c == '\r';
10163}
31b24551 10164
545e04f6 10165
5f5c8ee5 10166/* Highlight trailing whitespace, if any, in ROW. */
545e04f6 10167
5f5c8ee5
GM
10168void
10169highlight_trailing_whitespace (f, row)
10170 struct frame *f;
10171 struct glyph_row *row;
10172{
10173 int used = row->used[TEXT_AREA];
10174
10175 if (used)
10176 {
10177 struct glyph *start = row->glyphs[TEXT_AREA];
10178 struct glyph *glyph = start + used - 1;
10179
10180 /* Skip over the space glyph inserted to display the
10181 cursor at the end of a line. */
10182 if (glyph->type == CHAR_GLYPH
10183 && glyph->u.ch.code == ' '
10184 && glyph->object == 0)
10185 --glyph;
10186
10187 /* If last glyph is a space or stretch, and it's trailing
10188 whitespace, set the face of all trailing whitespace glyphs in
10189 IT->glyph_row to `trailing-whitespace'. */
10190 if (glyph >= start
10191 && BUFFERP (glyph->object)
10192 && (glyph->type == STRETCH_GLYPH
10193 || (glyph->type == CHAR_GLYPH
10194 && glyph->u.ch.code == ' '))
10195 && trailing_whitespace_p (glyph->charpos))
545e04f6 10196 {
5f5c8ee5
GM
10197 int face_id = lookup_named_face (f, Qtrailing_whitespace,
10198 CHARSET_ASCII);
10199
10200 while (glyph >= start
10201 && BUFFERP (glyph->object)
10202 && (glyph->type == STRETCH_GLYPH
10203 || (glyph->type == CHAR_GLYPH
10204 && glyph->u.ch.code == ' ')))
545e04f6 10205 {
5f5c8ee5
GM
10206 if (glyph->type == STRETCH_GLYPH)
10207 glyph->u.stretch.face_id = face_id;
10208 else
10209 glyph->u.ch.face_id = face_id;
10210 --glyph;
545e04f6
KH
10211 }
10212 }
a2889657 10213 }
5f5c8ee5 10214}
a2889657 10215
5fcbb24d 10216
a2889657 10217
5f5c8ee5
GM
10218/* Construct the glyph row IT->glyph_row in the desired matrix of
10219 IT->w from text at the current position of IT. See dispextern.h
10220 for an overview of struct it. Value is non-zero if
10221 IT->glyph_row displays text, as opposed to a line displaying ZV
10222 only. */
10223
10224static int
10225display_line (it)
10226 struct it *it;
10227{
10228 struct glyph_row *row = it->glyph_row;
10229
10230 /* We always start displaying at hpos zero even if hscrolled. */
10231 xassert (it->hpos == 0 && it->current_x == 0);
a2889657 10232
5f5c8ee5
GM
10233 /* We must not display in a row that's not a text row. */
10234 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
10235 < it->w->desired_matrix->nrows);
12adba34 10236
5f5c8ee5
GM
10237 /* Is IT->w showing the region? */
10238 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
12adba34 10239
5f5c8ee5
GM
10240 /* Clear the result glyph row and enable it. */
10241 prepare_desired_row (row);
12adba34 10242
5f5c8ee5
GM
10243 row->y = it->current_y;
10244 row->start = it->current;
10245 row->continuation_lines_width = it->continuation_lines_width;
10246 row->displays_text_p = 1;
10247
10248 /* Arrange the overlays nicely for our purposes. Usually, we call
10249 display_line on only one line at a time, in which case this
10250 can't really hurt too much, or we call it on lines which appear
10251 one after another in the buffer, in which case all calls to
10252 recenter_overlay_lists but the first will be pretty cheap. */
10253 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
10254
10255#if NO_PROMPT_IN_BUFFER
10256 /* Show mini-buffer prompt, if at the beginning of a mini-buffer
10257 window. */
10258 if (MINI_WINDOW_P (it->w)
10259 && MATRIX_ROW_START_CHARPOS (row) == BEG
10260 && it->vpos == 0)
10261 {
10262 if (NILP (minibuf_prompt))
10263 minibuf_prompt_width = minibuf_prompt_pixel_width = 0;
a2889657 10264 else
a2889657 10265 {
5f5c8ee5
GM
10266 /* We would like to truncate the prompt a little bit before
10267 the right margin of the window, so that user input can
10268 start on the first line. Set max_x to this position. */
10269 int max_x = (it->last_visible_x - 4 * CANON_X_UNIT (it->f));
10270
10271 /* We use a temporary iterator different from IT so that
10272 IT's settings are not overwritten when displaying
10273 the prompt. */
10274 struct it ti;
10275
10276 ti = *it;
10277
10278 /* Display the prompt. Set minibuf_prompt_width to the
10279 number of glyphs generated for the prompt, set
10280 minibuf_prompt_pixel_width to its width in pixels. */
10281 xassert (it->current_x == 0);
10282 display_string (NULL, minibuf_prompt, Qnil, 0, 0, &ti,
10283 0, 0, max_x, -1);
10284 minibuf_prompt_width = ti.hpos;
10285 minibuf_prompt_pixel_width = ti.current_x;
10286
10287 /* Transfer pixel and hpos information to IT. */
10288 it->hpos = ti.hpos;
10289 it->current_x = ti.current_x;
10290 }
10291 }
10292#endif /* NO_PROMPT_IN_BUFFER */
10293
10294 /* Move over display elements that are not visible because we are
10295 hscrolled. This may stop at an x-position < IT->first_visible_x
10296 if the first glyph is partially visible or if we hit a line end. */
10297 if (it->current_x < it->first_visible_x)
10298 move_it_in_display_line_to (it, ZV, it->first_visible_x,
10299 MOVE_TO_POS | MOVE_TO_X);
10300
10301 /* Get the initial row height. This is either the height of the
10302 text hscrolled, if there is any, or zero. */
10303 row->ascent = it->max_ascent;
10304 row->height = it->max_ascent + it->max_descent;
312246d1
GM
10305 row->phys_ascent = it->max_phys_ascent;
10306 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
5f5c8ee5
GM
10307
10308 /* Loop generating characters. The loop is left with IT on the next
10309 character to display. */
10310 while (1)
10311 {
10312 int n_glyphs_before, hpos_before, x_before;
10313 int x, i, nglyphs;
10314
10315 /* Retrieve the next thing to display. Value is zero if end of
10316 buffer reached. */
10317 if (!get_next_display_element (it))
10318 {
10319 /* Maybe add a space at the end of this line that is used to
10320 display the cursor there under X. */
10321 append_space (it, 1);
10322
10323 /* The position -1 below indicates a blank line not
10324 corresponding to any text, as opposed to an empty line
10325 corresponding to a line end. */
10326 if (row->used[TEXT_AREA] <= 1)
a2889657 10327 {
5f5c8ee5
GM
10328 row->glyphs[TEXT_AREA]->charpos = -1;
10329 row->displays_text_p = 0;
10330
10331 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
10332 row->indicate_empty_line_p = 1;
a2889657 10333 }
5f5c8ee5
GM
10334
10335 it->continuation_lines_width = 0;
10336 row->ends_at_zv_p = 1;
10337 break;
a2889657 10338 }
a2889657 10339
5f5c8ee5
GM
10340 /* Now, get the metrics of what we want to display. This also
10341 generates glyphs in `row' (which is IT->glyph_row). */
10342 n_glyphs_before = row->used[TEXT_AREA];
10343 x = it->current_x;
10344 PRODUCE_GLYPHS (it);
a2889657 10345
5f5c8ee5
GM
10346 /* If this display element was in marginal areas, continue with
10347 the next one. */
10348 if (it->area != TEXT_AREA)
a2889657 10349 {
5f5c8ee5
GM
10350 row->ascent = max (row->ascent, it->max_ascent);
10351 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10352 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10353 row->phys_height = max (row->phys_height,
10354 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10355 set_iterator_to_next (it);
10356 continue;
10357 }
5936754e 10358
5f5c8ee5
GM
10359 /* Does the display element fit on the line? If we truncate
10360 lines, we should draw past the right edge of the window. If
10361 we don't truncate, we want to stop so that we can display the
10362 continuation glyph before the right margin. If lines are
10363 continued, there are two possible strategies for characters
10364 resulting in more than 1 glyph (e.g. tabs): Display as many
10365 glyphs as possible in this line and leave the rest for the
10366 continuation line, or display the whole element in the next
10367 line. Original redisplay did the former, so we do it also. */
10368 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10369 hpos_before = it->hpos;
10370 x_before = x;
10371
10372 if (nglyphs == 1
10373 && it->current_x < it->last_visible_x)
10374 {
10375 ++it->hpos;
10376 row->ascent = max (row->ascent, it->max_ascent);
10377 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10378 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10379 row->phys_height = max (row->phys_height,
10380 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10381 if (it->current_x - it->pixel_width < it->first_visible_x)
10382 row->x = x - it->first_visible_x;
10383 }
10384 else
10385 {
10386 int new_x;
10387 struct glyph *glyph;
10388
10389 for (i = 0; i < nglyphs; ++i, x = new_x)
b5bbc9a5 10390 {
5f5c8ee5
GM
10391 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10392 new_x = x + glyph->pixel_width;
10393
10394 if (/* Lines are continued. */
10395 !it->truncate_lines_p
10396 && (/* Glyph doesn't fit on the line. */
10397 new_x > it->last_visible_x
10398 /* Or it fits exactly on a window system frame. */
10399 || (new_x == it->last_visible_x
10400 && FRAME_WINDOW_P (it->f))))
a2889657 10401 {
5f5c8ee5
GM
10402 /* End of a continued line. */
10403
10404 if (it->hpos == 0
10405 || (new_x == it->last_visible_x
10406 && FRAME_WINDOW_P (it->f)))
10407 {
10408 /* Current glyph fits exactly on the line. We
10409 must continue the line because we can't draw
10410 the cursor after the glyph. */
10411 row->continued_p = 1;
10412 it->current_x = new_x;
10413 it->continuation_lines_width += new_x;
10414 ++it->hpos;
10415 if (i == nglyphs - 1)
10416 set_iterator_to_next (it);
10417 }
10418 else
5936754e 10419 {
5f5c8ee5
GM
10420 /* Display element draws past the right edge of
10421 the window. Restore positions to values
10422 before the element. The next line starts
10423 with current_x before the glyph that could
10424 not be displayed, so that TAB works right. */
10425 row->used[TEXT_AREA] = n_glyphs_before + i;
10426
10427 /* Display continuation glyphs. */
10428 if (!FRAME_WINDOW_P (it->f))
10429 produce_special_glyphs (it, IT_CONTINUATION);
10430 row->continued_p = 1;
10431
10432 it->current_x = x;
10433 it->continuation_lines_width += x;
5936754e 10434 }
5f5c8ee5
GM
10435 break;
10436 }
10437 else if (new_x > it->first_visible_x)
10438 {
10439 /* Increment number of glyphs actually displayed. */
10440 ++it->hpos;
10441
10442 if (x < it->first_visible_x)
10443 /* Glyph is partially visible, i.e. row starts at
10444 negative X position. */
10445 row->x = x - it->first_visible_x;
10446 }
10447 else
10448 {
10449 /* Glyph is completely off the left margin of the
10450 window. This should not happen because of the
10451 move_it_in_display_line at the start of
10452 this function. */
10453 abort ();
a2889657 10454 }
a2889657 10455 }
5f5c8ee5
GM
10456
10457 row->ascent = max (row->ascent, it->max_ascent);
10458 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
10459 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
10460 row->phys_height = max (row->phys_height,
10461 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
10462
10463 /* End of this display line if row is continued. */
10464 if (row->continued_p)
10465 break;
a2889657 10466 }
a2889657 10467
5f5c8ee5
GM
10468 /* Is this a line end? If yes, we're also done, after making
10469 sure that a non-default face is extended up to the right
10470 margin of the window. */
10471 if (ITERATOR_AT_END_OF_LINE_P (it))
1c9241f5 10472 {
5f5c8ee5
GM
10473 int used_before = row->used[TEXT_AREA];
10474
10475 /* Add a space at the end of the line that is used to
10476 display the cursor there. */
10477 append_space (it, 0);
10478
10479 /* Extend the face to the end of the line. */
10480 extend_face_to_end_of_line (it);
10481
10482 /* Make sure we have the position. */
10483 if (used_before == 0)
10484 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
10485
10486 /* Consume the line end. This skips over invisible lines. */
10487 set_iterator_to_next (it);
10488 it->continuation_lines_width = 0;
10489 break;
1c9241f5 10490 }
a2889657 10491
5f5c8ee5
GM
10492 /* Proceed with next display element. Note that this skips
10493 over lines invisible because of selective display. */
10494 set_iterator_to_next (it);
b1d1124b 10495
5f5c8ee5
GM
10496 /* If we truncate lines, we are done when the last displayed
10497 glyphs reach past the right margin of the window. */
10498 if (it->truncate_lines_p
10499 && (FRAME_WINDOW_P (it->f)
10500 ? (it->current_x >= it->last_visible_x)
10501 : (it->current_x > it->last_visible_x)))
75d13c64 10502 {
5f5c8ee5
GM
10503 /* Maybe add truncation glyphs. */
10504 if (!FRAME_WINDOW_P (it->f))
10505 {
10506 --it->glyph_row->used[TEXT_AREA];
10507 produce_special_glyphs (it, IT_TRUNCATION);
10508 }
10509
10510 row->truncated_on_right_p = 1;
10511 it->continuation_lines_width = 0;
312246d1 10512 reseat_at_next_visible_line_start (it, 0);
5f5c8ee5
GM
10513 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
10514 it->hpos = hpos_before;
10515 it->current_x = x_before;
10516 break;
75d13c64 10517 }
a2889657 10518 }
a2889657 10519
5f5c8ee5
GM
10520 /* If line is not empty and hscrolled, maybe insert truncation glyphs
10521 at the left window margin. */
10522 if (it->first_visible_x
10523 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
10524 {
10525 if (!FRAME_WINDOW_P (it->f))
10526 insert_left_trunc_glyphs (it);
10527 row->truncated_on_left_p = 1;
10528 }
a2889657 10529
5f5c8ee5
GM
10530 /* If the start of this line is the overlay arrow-position, then
10531 mark this glyph row as the one containing the overlay arrow.
10532 This is clearly a mess with variable size fonts. It would be
10533 better to let it be displayed like cursors under X. */
e24c997d 10534 if (MARKERP (Voverlay_arrow_position)
a2889657 10535 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
5f5c8ee5
GM
10536 && (MATRIX_ROW_START_CHARPOS (row)
10537 == marker_position (Voverlay_arrow_position))
e24c997d 10538 && STRINGP (Voverlay_arrow_string)
a2889657
JB
10539 && ! overlay_arrow_seen)
10540 {
5f5c8ee5
GM
10541 /* Overlay arrow in window redisplay is a bitmap. */
10542 if (!FRAME_WINDOW_P (it->f))
c4628384 10543 {
5f5c8ee5
GM
10544 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
10545 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
10546 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
10547 struct glyph *p = row->glyphs[TEXT_AREA];
10548 struct glyph *p2, *end;
10549
10550 /* Copy the arrow glyphs. */
10551 while (glyph < arrow_end)
10552 *p++ = *glyph++;
10553
10554 /* Throw away padding glyphs. */
10555 p2 = p;
10556 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
10557 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
10558 ++p2;
10559 if (p2 > p)
212e4f87 10560 {
5f5c8ee5
GM
10561 while (p2 < end)
10562 *p++ = *p2++;
10563 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
c4628384 10564 }
c4628384 10565 }
5f5c8ee5 10566
a2889657 10567 overlay_arrow_seen = 1;
5f5c8ee5 10568 row->overlay_arrow_p = 1;
a2889657
JB
10569 }
10570
5f5c8ee5
GM
10571 /* Compute pixel dimensions of this line. */
10572 compute_line_metrics (it);
10573
10574 /* Remember the position at which this line ends. */
10575 row->end = it->current;
10576
10577 /* Maybe set the cursor. If you change this, it's probably a good
10578 idea to also change the code in redisplay_window for cursor
10579 movement in an unchanged window. */
10580 if (it->w->cursor.vpos < 0
10581 && PT >= MATRIX_ROW_START_CHARPOS (row)
10582 && MATRIX_ROW_END_CHARPOS (row) >= PT
10583 && !(MATRIX_ROW_END_CHARPOS (row) == PT
10584 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
10585 || !row->ends_at_zv_p)))
10586 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
10587
10588 /* Highlight trailing whitespace. */
10589 if (it->show_trailing_whitespace_p)
10590 highlight_trailing_whitespace (it->f, it->glyph_row);
10591
10592 /* Prepare for the next line. This line starts horizontally at (X
10593 HPOS) = (0 0). Vertical positions are incremented. As a
10594 convenience for the caller, IT->glyph_row is set to the next
10595 row to be used. */
10596 it->current_x = it->hpos = 0;
10597 it->current_y += row->height;
10598 ++it->vpos;
10599 ++it->glyph_row;
10600 return row->displays_text_p;
a2889657 10601}
5f5c8ee5
GM
10602
10603
a2889657 10604\f
5f5c8ee5
GM
10605/***********************************************************************
10606 Menu Bar
10607 ***********************************************************************/
10608
10609/* Redisplay the menu bar in the frame for window W.
10610
10611 The menu bar of X frames that don't have X toolkit support is
10612 displayed in a special window W->frame->menu_bar_window.
10613
10614 The menu bar of terminal frames is treated specially as far as
10615 glyph matrices are concerned. Menu bar lines are not part of
10616 windows, so the update is done directly on the frame matrix rows
10617 for the menu bar. */
7ce2c095
RS
10618
10619static void
10620display_menu_bar (w)
10621 struct window *w;
10622{
5f5c8ee5
GM
10623 struct frame *f = XFRAME (WINDOW_FRAME (w));
10624 struct it it;
10625 Lisp_Object items;
8351baf2 10626 int i;
7ce2c095 10627
5f5c8ee5 10628 /* Don't do all this for graphical frames. */
dc937613 10629#ifdef HAVE_NTGUI
d129c4c2
KH
10630 if (!NILP (Vwindow_system))
10631 return;
dc937613 10632#endif
dc937613 10633#ifdef USE_X_TOOLKIT
d3413a53 10634 if (FRAME_X_P (f))
7ce2c095 10635 return;
5f5c8ee5
GM
10636#endif
10637
10638#ifdef USE_X_TOOLKIT
10639 xassert (!FRAME_WINDOW_P (f));
10640 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MODE_LINE_FACE_ID);
10641 it.first_visible_x = 0;
10642 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
10643#else /* not USE_X_TOOLKIT */
10644 if (FRAME_WINDOW_P (f))
10645 {
10646 /* Menu bar lines are displayed in the desired matrix of the
10647 dummy window menu_bar_window. */
10648 struct window *menu_w;
10649 xassert (WINDOWP (f->menu_bar_window));
10650 menu_w = XWINDOW (f->menu_bar_window);
10651 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
10652 MODE_LINE_FACE_ID);
10653 it.first_visible_x = 0;
10654 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
10655 }
10656 else
10657 {
10658 /* This is a TTY frame, i.e. character hpos/vpos are used as
10659 pixel x/y. */
10660 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
10661 MODE_LINE_FACE_ID);
10662 it.first_visible_x = 0;
10663 it.last_visible_x = FRAME_WIDTH (f);
10664 }
10665#endif /* not USE_X_TOOLKIT */
10666
10667 /* Clear all rows of the menu bar. */
10668 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
10669 {
10670 struct glyph_row *row = it.glyph_row + i;
10671 clear_glyph_row (row);
10672 row->enabled_p = 1;
10673 row->full_width_p = 1;
10674 }
7ce2c095 10675
5f5c8ee5
GM
10676 /* Make the first line of the menu bar appear in reverse video. */
10677 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
7ce2c095 10678
5f5c8ee5
GM
10679 /* Display all items of the menu bar. */
10680 items = FRAME_MENU_BAR_ITEMS (it.f);
469937ac 10681 for (i = 0; i < XVECTOR (items)->size; i += 4)
7ce2c095 10682 {
5f5c8ee5
GM
10683 Lisp_Object string;
10684
10685 /* Stop at nil string. */
8351baf2
RS
10686 string = XVECTOR (items)->contents[i + 1];
10687 if (NILP (string))
10688 break;
2d66ad19 10689
5f5c8ee5
GM
10690 /* Remember where item was displayed. */
10691 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
7ce2c095 10692
5f5c8ee5
GM
10693 /* Display the item, pad with one space. */
10694 if (it.current_x < it.last_visible_x)
10695 display_string (NULL, string, Qnil, 0, 0, &it,
10696 XSTRING (string)->size + 1, 0, 0, -1);
7ce2c095
RS
10697 }
10698
2d66ad19 10699 /* Fill out the line with spaces. */
5f5c8ee5
GM
10700 if (it.current_x < it.last_visible_x)
10701 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
db6f348c 10702
5f5c8ee5
GM
10703 /* Compute the total height of the lines. */
10704 compute_line_metrics (&it);
7ce2c095 10705}
5f5c8ee5
GM
10706
10707
7ce2c095 10708\f
5f5c8ee5
GM
10709/***********************************************************************
10710 Mode Line
10711 ***********************************************************************/
10712
10713/* Display the mode and/or top line of window W. */
a2889657
JB
10714
10715static void
5f5c8ee5 10716display_mode_lines (w)
a2889657
JB
10717 struct window *w;
10718{
5f5c8ee5 10719 /* These will be set while the mode line specs are processed. */
aa6d10fa 10720 line_number_displayed = 0;
155ef550 10721 w->column_number_displayed = Qnil;
aa6d10fa 10722
5f5c8ee5
GM
10723 if (WINDOW_WANTS_MODELINE_P (w))
10724 display_mode_line (w, MODE_LINE_FACE_ID, current_buffer->mode_line_format);
10725
10726 if (WINDOW_WANTS_TOP_LINE_P (w))
10727 display_mode_line (w, TOP_LINE_FACE_ID, current_buffer->top_line_format);
10728}
03b294dc 10729
03b294dc 10730
5f5c8ee5
GM
10731/* Display mode or top line of window W. FACE_ID specifies which line
10732 to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
10733 FORMAT is the mode line format to display. */
03b294dc 10734
5f5c8ee5
GM
10735static void
10736display_mode_line (w, face_id, format)
10737 struct window *w;
10738 enum face_id face_id;
10739 Lisp_Object format;
10740{
10741 struct it it;
10742 struct face *face;
03b294dc 10743
5f5c8ee5
GM
10744 init_iterator (&it, w, -1, -1, NULL, face_id);
10745 prepare_desired_row (it.glyph_row);
10746
10747 /* Temporarily make frame's keyboard the current kboard so that
10748 kboard-local variables in the mode_line_format will get the right
10749 values. */
10750 push_frame_kboard (it.f);
10751 display_mode_element (&it, 0, 0, 0, format);
10752 pop_frame_kboard ();
a2889657 10753
5f5c8ee5
GM
10754 /* Fill up with spaces. */
10755 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
10756
10757 compute_line_metrics (&it);
10758 it.glyph_row->full_width_p = 1;
10759 it.glyph_row->mode_line_p = 1;
10760 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
10761 it.glyph_row->continued_p = 0;
10762 it.glyph_row->truncated_on_left_p = 0;
10763 it.glyph_row->truncated_on_right_p = 0;
10764
10765 /* Make a 3D mode-line have a shadow at its right end. */
10766 face = FACE_FROM_ID (it.f, face_id);
10767 extend_face_to_end_of_line (&it);
10768 if (face->box != FACE_NO_BOX)
d7eb09a0 10769 {
5f5c8ee5
GM
10770 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
10771 + it.glyph_row->used[TEXT_AREA] - 1);
10772 last->right_box_line_p = 1;
d7eb09a0 10773 }
a2889657
JB
10774}
10775
a2889657 10776
5f5c8ee5
GM
10777/* Contribute ELT to the mode line for window IT->w. How it
10778 translates into text depends on its data type.
a2889657 10779
5f5c8ee5 10780 IT describes the display environment in which we display, as usual.
a2889657
JB
10781
10782 DEPTH is the depth in recursion. It is used to prevent
10783 infinite recursion here.
10784
5f5c8ee5
GM
10785 FIELD_WIDTH is the number of characters the display of ELT should
10786 occupy in the mode line, and PRECISION is the maximum number of
10787 characters to display from ELT's representation. See
10788 display_string for details. *
a2889657 10789
5f5c8ee5 10790 Returns the hpos of the end of the text generated by ELT. */
a2889657
JB
10791
10792static int
5f5c8ee5
GM
10793display_mode_element (it, depth, field_width, precision, elt)
10794 struct it *it;
a2889657 10795 int depth;
5f5c8ee5
GM
10796 int field_width, precision;
10797 Lisp_Object elt;
a2889657 10798{
5f5c8ee5
GM
10799 int n = 0, field, prec;
10800
a2889657
JB
10801 tail_recurse:
10802 if (depth > 10)
10803 goto invalid;
10804
10805 depth++;
10806
0220c518 10807 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
a2889657
JB
10808 {
10809 case Lisp_String:
10810 {
10811 /* A string: output it and check for %-constructs within it. */
5f5c8ee5
GM
10812 unsigned char c;
10813 unsigned char *this = XSTRING (elt)->data;
10814 unsigned char *lisp_string = this;
10815
10816 while ((precision <= 0 || n < precision)
10817 && *this
10818 && (frame_title_ptr
10819 || it->current_x < it->last_visible_x))
a2889657
JB
10820 {
10821 unsigned char *last = this;
5f5c8ee5
GM
10822
10823 /* Advance to end of string or next format specifier. */
a2889657
JB
10824 while ((c = *this++) != '\0' && c != '%')
10825 ;
5f5c8ee5 10826
a2889657
JB
10827 if (this - 1 != last)
10828 {
5f5c8ee5
GM
10829 /* Output to end of string or up to '%'. Field width
10830 is length of string. Don't output more than
10831 PRECISION allows us. */
10832 prec = --this - last;
10833 if (precision > 0 && prec > precision - n)
10834 prec = precision - n;
10835
d39b6696 10836 if (frame_title_ptr)
5f5c8ee5 10837 n += store_frame_title (last, prec, prec);
d39b6696 10838 else
5f5c8ee5
GM
10839 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
10840 it, 0, prec, 0, -1);
a2889657
JB
10841 }
10842 else /* c == '%' */
10843 {
5f5c8ee5
GM
10844 unsigned char *percent_position = this;
10845
10846 /* Get the specified minimum width. Zero means
10847 don't pad. */
10848 field = 0;
a2889657 10849 while ((c = *this++) >= '0' && c <= '9')
5f5c8ee5 10850 field = field * 10 + c - '0';
a2889657 10851
5f5c8ee5
GM
10852 /* Don't pad beyond the total padding allowed. */
10853 if (field_width - n > 0 && field > field_width - n)
10854 field = field_width - n;
a2889657 10855
5f5c8ee5
GM
10856 /* Note that either PRECISION <= 0 or N < PRECISION. */
10857 prec = precision - n;
10858
a2889657 10859 if (c == 'M')
5f5c8ee5
GM
10860 n += display_mode_element (it, depth, field, prec,
10861 Vglobal_mode_string);
a2889657 10862 else if (c != 0)
d39b6696 10863 {
5f5c8ee5
GM
10864 unsigned char *spec
10865 = decode_mode_spec (it->w, c, field, prec);
10866
d39b6696 10867 if (frame_title_ptr)
5f5c8ee5 10868 n += store_frame_title (spec, field, prec);
d39b6696 10869 else
5f5c8ee5
GM
10870 {
10871 int nglyphs_before
10872 = it->glyph_row->used[TEXT_AREA];
10873 int charpos
10874 = percent_position - XSTRING (elt)->data;
10875 int nwritten
10876 = display_string (spec, Qnil, elt, charpos, 0, it,
10877 field, prec, 0, -1);
10878
10879 /* Assign to the glyphs written above the
10880 string where the `%x' came from, position
10881 of the `%'. */
10882 if (nwritten > 0)
10883 {
10884 struct glyph *glyph
10885 = (it->glyph_row->glyphs[TEXT_AREA]
10886 + nglyphs_before);
10887 int i;
10888
10889 for (i = 0; i < nwritten; ++i)
10890 {
10891 glyph[i].object = elt;
10892 glyph[i].charpos = charpos;
10893 }
10894
10895 n += nwritten;
10896 }
10897 }
d39b6696 10898 }
a2889657
JB
10899 }
10900 }
10901 }
10902 break;
10903
10904 case Lisp_Symbol:
10905 /* A symbol: process the value of the symbol recursively
10906 as if it appeared here directly. Avoid error if symbol void.
10907 Special case: if value of symbol is a string, output the string
10908 literally. */
10909 {
10910 register Lisp_Object tem;
10911 tem = Fboundp (elt);
265a9e55 10912 if (!NILP (tem))
a2889657
JB
10913 {
10914 tem = Fsymbol_value (elt);
10915 /* If value is a string, output that string literally:
10916 don't check for % within it. */
e24c997d 10917 if (STRINGP (tem))
d39b6696 10918 {
5f5c8ee5
GM
10919 prec = XSTRING (tem)->size;
10920 if (precision > 0 && prec > precision - n)
10921 prec = precision - n;
d39b6696 10922 if (frame_title_ptr)
5f5c8ee5 10923 n += store_frame_title (XSTRING (tem)->data, -1, prec);
d39b6696 10924 else
5f5c8ee5
GM
10925 n += display_string (NULL, tem, Qnil, 0, 0, it,
10926 0, prec, 0, -1);
d39b6696 10927 }
a2889657 10928 else if (!EQ (tem, elt))
5f5c8ee5
GM
10929 {
10930 /* Give up right away for nil or t. */
10931 elt = tem;
10932 goto tail_recurse;
10933 }
a2889657
JB
10934 }
10935 }
10936 break;
10937
10938 case Lisp_Cons:
10939 {
10940 register Lisp_Object car, tem;
10941
10942 /* A cons cell: three distinct cases.
10943 If first element is a string or a cons, process all the elements
10944 and effectively concatenate them.
10945 If first element is a negative number, truncate displaying cdr to
10946 at most that many characters. If positive, pad (with spaces)
10947 to at least that many characters.
10948 If first element is a symbol, process the cadr or caddr recursively
10949 according to whether the symbol's value is non-nil or nil. */
10950 car = XCONS (elt)->car;
5f5c8ee5
GM
10951 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
10952 {
10953 /* An element of the form (:eval FORM) means evaluate FORM
10954 and use the result as mode line elements. */
10955 struct gcpro gcpro1;
10956 Lisp_Object spec;
10957
10958 spec = eval_form (XCAR (XCDR (elt)));
10959 GCPRO1 (spec);
10960 n += display_mode_element (it, depth, field_width - n,
10961 precision - n, spec);
10962 UNGCPRO;
10963 }
10964 else if (SYMBOLP (car))
a2889657
JB
10965 {
10966 tem = Fboundp (car);
10967 elt = XCONS (elt)->cdr;
e24c997d 10968 if (!CONSP (elt))
a2889657
JB
10969 goto invalid;
10970 /* elt is now the cdr, and we know it is a cons cell.
10971 Use its car if CAR has a non-nil value. */
265a9e55 10972 if (!NILP (tem))
a2889657
JB
10973 {
10974 tem = Fsymbol_value (car);
265a9e55 10975 if (!NILP (tem))
a2889657
JB
10976 { elt = XCONS (elt)->car; goto tail_recurse; }
10977 }
10978 /* Symbol's value is nil (or symbol is unbound)
10979 Get the cddr of the original list
10980 and if possible find the caddr and use that. */
10981 elt = XCONS (elt)->cdr;
265a9e55 10982 if (NILP (elt))
a2889657 10983 break;
e24c997d 10984 else if (!CONSP (elt))
a2889657
JB
10985 goto invalid;
10986 elt = XCONS (elt)->car;
10987 goto tail_recurse;
10988 }
e24c997d 10989 else if (INTEGERP (car))
a2889657
JB
10990 {
10991 register int lim = XINT (car);
10992 elt = XCONS (elt)->cdr;
10993 if (lim < 0)
5f5c8ee5
GM
10994 {
10995 /* Negative int means reduce maximum width. */
10996 if (precision <= 0)
10997 precision = -lim;
10998 else
10999 precision = min (precision, -lim);
11000 }
a2889657
JB
11001 else if (lim > 0)
11002 {
11003 /* Padding specified. Don't let it be more than
11004 current maximum. */
5f5c8ee5
GM
11005 if (precision > 0)
11006 lim = min (precision, lim);
11007
a2889657
JB
11008 /* If that's more padding than already wanted, queue it.
11009 But don't reduce padding already specified even if
11010 that is beyond the current truncation point. */
5f5c8ee5 11011 field_width = max (lim, field_width);
a2889657
JB
11012 }
11013 goto tail_recurse;
11014 }
e24c997d 11015 else if (STRINGP (car) || CONSP (car))
a2889657
JB
11016 {
11017 register int limit = 50;
5f5c8ee5
GM
11018 /* Limit is to protect against circular lists. */
11019 while (CONSP (elt)
11020 && --limit > 0
11021 && (precision <= 0 || n < precision))
a2889657 11022 {
5f5c8ee5
GM
11023 n += display_mode_element (it, depth, field_width - n,
11024 precision - n, XCONS (elt)->car);
a2889657
JB
11025 elt = XCONS (elt)->cdr;
11026 }
11027 }
11028 }
11029 break;
11030
11031 default:
11032 invalid:
d39b6696 11033 if (frame_title_ptr)
5f5c8ee5 11034 n += store_frame_title ("*invalid*", 0, precision - n);
d39b6696 11035 else
5f5c8ee5
GM
11036 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
11037 precision - n, 0, 0);
11038 return n;
a2889657
JB
11039 }
11040
5f5c8ee5
GM
11041 /* Pad to FIELD_WIDTH. */
11042 if (field_width > 0 && n < field_width)
11043 {
11044 if (frame_title_ptr)
11045 n += store_frame_title ("", field_width - n, 0);
11046 else
11047 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
11048 0, 0, 0);
11049 }
11050
11051 return n;
a2889657 11052}
5f5c8ee5
GM
11053
11054
766525bc
RS
11055/* Write a null-terminated, right justified decimal representation of
11056 the positive integer D to BUF using a minimal field width WIDTH. */
11057
11058static void
11059pint2str (buf, width, d)
11060 register char *buf;
11061 register int width;
11062 register int d;
11063{
11064 register char *p = buf;
11065
11066 if (d <= 0)
5f5c8ee5 11067 *p++ = '0';
766525bc 11068 else
5f5c8ee5 11069 {
766525bc 11070 while (d > 0)
5f5c8ee5 11071 {
766525bc
RS
11072 *p++ = d % 10 + '0';
11073 d /= 10;
5f5c8ee5
GM
11074 }
11075 }
11076
11077 for (width -= (int) (p - buf); width > 0; --width)
11078 *p++ = ' ';
766525bc
RS
11079 *p-- = '\0';
11080 while (p > buf)
5f5c8ee5 11081 {
766525bc
RS
11082 d = *buf;
11083 *buf++ = *p;
11084 *p-- = d;
5f5c8ee5 11085 }
766525bc
RS
11086}
11087
5f5c8ee5 11088/* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
1c9241f5
KH
11089 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
11090 type of CODING_SYSTEM. Return updated pointer into BUF. */
11091
6693a99a 11092static unsigned char invalid_eol_type[] = "(*invalid*)";
d24715e8 11093
1c9241f5
KH
11094static char *
11095decode_mode_spec_coding (coding_system, buf, eol_flag)
11096 Lisp_Object coding_system;
11097 register char *buf;
11098 int eol_flag;
11099{
1e1078d6 11100 Lisp_Object val;
916848d8 11101 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
302f2b38
EZ
11102 unsigned char *eol_str;
11103 int eol_str_len;
11104 /* The EOL conversion we are using. */
11105 Lisp_Object eoltype;
1e1078d6
RS
11106
11107 val = coding_system;
1c9241f5
KH
11108
11109 if (NILP (val)) /* Not yet decided. */
11110 {
916848d8
RS
11111 if (multibyte)
11112 *buf++ = '-';
21e989e3 11113 if (eol_flag)
302f2b38 11114 eoltype = eol_mnemonic_undecided;
1e1078d6 11115 /* Don't mention EOL conversion if it isn't decided. */
1c9241f5
KH
11116 }
11117 else
11118 {
1e1078d6
RS
11119 Lisp_Object eolvalue;
11120
11121 eolvalue = Fget (coding_system, Qeol_type);
11122
1c9241f5 11123 while (!NILP (val) && SYMBOLP (val))
1e1078d6
RS
11124 {
11125 val = Fget (val, Qcoding_system);
11126 if (NILP (eolvalue))
b070c1d7 11127 eolvalue = Fget (val, Qeol_type);
1e1078d6
RS
11128 }
11129
916848d8
RS
11130 if (multibyte)
11131 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
11132
1c9241f5
KH
11133 if (eol_flag)
11134 {
1e1078d6
RS
11135 /* The EOL conversion that is normal on this system. */
11136
11137 if (NILP (eolvalue)) /* Not yet decided. */
11138 eoltype = eol_mnemonic_undecided;
11139 else if (VECTORP (eolvalue)) /* Not yet decided. */
11140 eoltype = eol_mnemonic_undecided;
11141 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
11142 eoltype = (XFASTINT (eolvalue) == 0
11143 ? eol_mnemonic_unix
11144 : (XFASTINT (eolvalue) == 1
11145 ? eol_mnemonic_dos : eol_mnemonic_mac));
302f2b38
EZ
11146 }
11147 }
5f5c8ee5 11148
302f2b38
EZ
11149 if (eol_flag)
11150 {
11151 /* Mention the EOL conversion if it is not the usual one. */
11152 if (STRINGP (eoltype))
11153 {
11154 eol_str = XSTRING (eoltype)->data;
11155 eol_str_len = XSTRING (eoltype)->size;
11156 }
f30b3499
KH
11157 else if (INTEGERP (eoltype)
11158 && CHAR_VALID_P (XINT (eoltype), 0))
11159 {
11160 int c = XINT (eoltype);
11161 unsigned char work[4];
11162
11163 eol_str_len = CHAR_STRING (XINT (eoltype), work, eol_str);
11164 }
302f2b38
EZ
11165 else
11166 {
11167 eol_str = invalid_eol_type;
11168 eol_str_len = sizeof (invalid_eol_type) - 1;
1c9241f5 11169 }
f30b3499 11170 bcopy (eol_str, buf, eol_str_len);
302f2b38 11171 buf += eol_str_len;
1c9241f5 11172 }
302f2b38 11173
1c9241f5
KH
11174 return buf;
11175}
11176
a2889657 11177/* Return a string for the output of a mode line %-spec for window W,
5f5c8ee5
GM
11178 generated by character C. PRECISION >= 0 means don't return a
11179 string longer than that value. FIELD_WIDTH > 0 means pad the
11180 string returned with spaces to that value. */
a2889657 11181
11e82b76
JB
11182static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
11183
a2889657 11184static char *
5f5c8ee5 11185decode_mode_spec (w, c, field_width, precision)
a2889657
JB
11186 struct window *w;
11187 register char c;
5f5c8ee5 11188 int field_width, precision;
a2889657 11189{
0b67772d 11190 Lisp_Object obj;
5f5c8ee5
GM
11191 struct frame *f = XFRAME (WINDOW_FRAME (w));
11192 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
d39b6696 11193 struct buffer *b = XBUFFER (w->buffer);
a2889657 11194
0b67772d 11195 obj = Qnil;
a2889657
JB
11196
11197 switch (c)
11198 {
1af9f229
RS
11199 case '*':
11200 if (!NILP (b->read_only))
11201 return "%";
11202 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11203 return "*";
11204 return "-";
11205
11206 case '+':
11207 /* This differs from %* only for a modified read-only buffer. */
11208 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11209 return "*";
11210 if (!NILP (b->read_only))
11211 return "%";
11212 return "-";
11213
11214 case '&':
11215 /* This differs from %* in ignoring read-only-ness. */
11216 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
11217 return "*";
11218 return "-";
11219
11220 case '%':
11221 return "%";
11222
11223 case '[':
11224 {
11225 int i;
11226 char *p;
11227
11228 if (command_loop_level > 5)
11229 return "[[[... ";
11230 p = decode_mode_spec_buf;
11231 for (i = 0; i < command_loop_level; i++)
11232 *p++ = '[';
11233 *p = 0;
11234 return decode_mode_spec_buf;
11235 }
11236
11237 case ']':
11238 {
11239 int i;
11240 char *p;
11241
11242 if (command_loop_level > 5)
11243 return " ...]]]";
11244 p = decode_mode_spec_buf;
11245 for (i = 0; i < command_loop_level; i++)
11246 *p++ = ']';
11247 *p = 0;
11248 return decode_mode_spec_buf;
11249 }
11250
11251 case '-':
11252 {
1af9f229 11253 register int i;
5f5c8ee5
GM
11254
11255 /* Let lots_of_dashes be a string of infinite length. */
11256 if (field_width <= 0
11257 || field_width > sizeof (lots_of_dashes))
1af9f229 11258 {
5f5c8ee5
GM
11259 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
11260 decode_mode_spec_buf[i] = '-';
11261 decode_mode_spec_buf[i] = '\0';
11262 return decode_mode_spec_buf;
1af9f229 11263 }
5f5c8ee5
GM
11264 else
11265 return lots_of_dashes;
1af9f229
RS
11266 }
11267
a2889657 11268 case 'b':
d39b6696 11269 obj = b->name;
a2889657
JB
11270 break;
11271
1af9f229
RS
11272 case 'c':
11273 {
11274 int col = current_column ();
11275 XSETFASTINT (w->column_number_displayed, col);
5f5c8ee5 11276 pint2str (decode_mode_spec_buf, field_width, col);
1af9f229
RS
11277 return decode_mode_spec_buf;
11278 }
11279
11280 case 'F':
11281 /* %F displays the frame name. */
5f5c8ee5 11282 if (!NILP (f->title))
95184b48 11283 return (char *) XSTRING (f->title)->data;
fd8ff63d 11284 if (f->explicit_name || ! FRAME_WINDOW_P (f))
95184b48 11285 return (char *) XSTRING (f->name)->data;
9c6da96f 11286 return "Emacs";
1af9f229 11287
a2889657 11288 case 'f':
d39b6696 11289 obj = b->filename;
a2889657
JB
11290 break;
11291
aa6d10fa
RS
11292 case 'l':
11293 {
12adba34
RS
11294 int startpos = XMARKER (w->start)->charpos;
11295 int startpos_byte = marker_byte_position (w->start);
11296 int line, linepos, linepos_byte, topline;
aa6d10fa 11297 int nlines, junk;
aa6d10fa
RS
11298 int height = XFASTINT (w->height);
11299
11300 /* If we decided that this buffer isn't suitable for line numbers,
11301 don't forget that too fast. */
11302 if (EQ (w->base_line_pos, w->buffer))
766525bc 11303 goto no_value;
5300fd39
RS
11304 /* But do forget it, if the window shows a different buffer now. */
11305 else if (BUFFERP (w->base_line_pos))
11306 w->base_line_pos = Qnil;
aa6d10fa
RS
11307
11308 /* If the buffer is very big, don't waste time. */
d39b6696 11309 if (BUF_ZV (b) - BUF_BEGV (b) > line_number_display_limit)
aa6d10fa
RS
11310 {
11311 w->base_line_pos = Qnil;
11312 w->base_line_number = Qnil;
766525bc 11313 goto no_value;
aa6d10fa
RS
11314 }
11315
11316 if (!NILP (w->base_line_number)
11317 && !NILP (w->base_line_pos)
12adba34 11318 && XFASTINT (w->base_line_pos) <= startpos)
aa6d10fa
RS
11319 {
11320 line = XFASTINT (w->base_line_number);
11321 linepos = XFASTINT (w->base_line_pos);
12adba34 11322 linepos_byte = buf_charpos_to_bytepos (b, linepos);
aa6d10fa
RS
11323 }
11324 else
11325 {
11326 line = 1;
d39b6696 11327 linepos = BUF_BEGV (b);
12adba34 11328 linepos_byte = BUF_BEGV_BYTE (b);
aa6d10fa
RS
11329 }
11330
11331 /* Count lines from base line to window start position. */
12adba34
RS
11332 nlines = display_count_lines (linepos, linepos_byte,
11333 startpos_byte,
11334 startpos, &junk);
aa6d10fa
RS
11335
11336 topline = nlines + line;
11337
11338 /* Determine a new base line, if the old one is too close
11339 or too far away, or if we did not have one.
11340 "Too close" means it's plausible a scroll-down would
11341 go back past it. */
d39b6696 11342 if (startpos == BUF_BEGV (b))
aa6d10fa 11343 {
c2213350
KH
11344 XSETFASTINT (w->base_line_number, topline);
11345 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
aa6d10fa
RS
11346 }
11347 else if (nlines < height + 25 || nlines > height * 3 + 50
d39b6696 11348 || linepos == BUF_BEGV (b))
aa6d10fa 11349 {
d39b6696 11350 int limit = BUF_BEGV (b);
12adba34 11351 int limit_byte = BUF_BEGV_BYTE (b);
aa6d10fa 11352 int position;
5d121aec 11353 int distance = (height * 2 + 30) * line_number_display_limit_width;
aa6d10fa
RS
11354
11355 if (startpos - distance > limit)
12adba34
RS
11356 {
11357 limit = startpos - distance;
11358 limit_byte = CHAR_TO_BYTE (limit);
11359 }
aa6d10fa 11360
12adba34
RS
11361 nlines = display_count_lines (startpos, startpos_byte,
11362 limit_byte,
11363 - (height * 2 + 30),
aa6d10fa
RS
11364 &position);
11365 /* If we couldn't find the lines we wanted within
5d121aec 11366 line_number_display_limit_width chars per line,
aa6d10fa 11367 give up on line numbers for this window. */
12adba34 11368 if (position == limit_byte && limit == startpos - distance)
aa6d10fa
RS
11369 {
11370 w->base_line_pos = w->buffer;
11371 w->base_line_number = Qnil;
766525bc 11372 goto no_value;
aa6d10fa
RS
11373 }
11374
c2213350 11375 XSETFASTINT (w->base_line_number, topline - nlines);
12adba34 11376 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
aa6d10fa
RS
11377 }
11378
11379 /* Now count lines from the start pos to point. */
12adba34
RS
11380 nlines = display_count_lines (startpos, startpos_byte,
11381 PT_BYTE, PT, &junk);
aa6d10fa
RS
11382
11383 /* Record that we did display the line number. */
11384 line_number_displayed = 1;
11385
11386 /* Make the string to show. */
5f5c8ee5 11387 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
aa6d10fa 11388 return decode_mode_spec_buf;
766525bc
RS
11389 no_value:
11390 {
11391 char* p = decode_mode_spec_buf;
5f5c8ee5
GM
11392 int pad = field_width - 2;
11393 while (pad-- > 0)
11394 *p++ = ' ';
11395 *p++ = '?';
11396 *p = '?';
766525bc
RS
11397 return decode_mode_spec_buf;
11398 }
aa6d10fa
RS
11399 }
11400 break;
11401
a2889657 11402 case 'm':
d39b6696 11403 obj = b->mode_name;
a2889657
JB
11404 break;
11405
11406 case 'n':
d39b6696 11407 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
a2889657
JB
11408 return " Narrow";
11409 break;
11410
a2889657
JB
11411 case 'p':
11412 {
11413 int pos = marker_position (w->start);
d39b6696 11414 int total = BUF_ZV (b) - BUF_BEGV (b);
a2889657 11415
d39b6696 11416 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
a2889657 11417 {
d39b6696 11418 if (pos <= BUF_BEGV (b))
a2889657
JB
11419 return "All";
11420 else
11421 return "Bottom";
11422 }
d39b6696 11423 else if (pos <= BUF_BEGV (b))
a2889657
JB
11424 return "Top";
11425 else
11426 {
3c7d31b9
RS
11427 if (total > 1000000)
11428 /* Do it differently for a large value, to avoid overflow. */
11429 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11430 else
11431 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
a2889657
JB
11432 /* We can't normally display a 3-digit number,
11433 so get us a 2-digit number that is close. */
11434 if (total == 100)
11435 total = 99;
11436 sprintf (decode_mode_spec_buf, "%2d%%", total);
11437 return decode_mode_spec_buf;
11438 }
11439 }
11440
8ffcb79f
RS
11441 /* Display percentage of size above the bottom of the screen. */
11442 case 'P':
11443 {
11444 int toppos = marker_position (w->start);
d39b6696
KH
11445 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
11446 int total = BUF_ZV (b) - BUF_BEGV (b);
8ffcb79f 11447
d39b6696 11448 if (botpos >= BUF_ZV (b))
8ffcb79f 11449 {
d39b6696 11450 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11451 return "All";
11452 else
11453 return "Bottom";
11454 }
11455 else
11456 {
3c7d31b9
RS
11457 if (total > 1000000)
11458 /* Do it differently for a large value, to avoid overflow. */
11459 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
11460 else
11461 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
8ffcb79f
RS
11462 /* We can't normally display a 3-digit number,
11463 so get us a 2-digit number that is close. */
11464 if (total == 100)
11465 total = 99;
d39b6696 11466 if (toppos <= BUF_BEGV (b))
8ffcb79f
RS
11467 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
11468 else
11469 sprintf (decode_mode_spec_buf, "%2d%%", total);
11470 return decode_mode_spec_buf;
11471 }
11472 }
11473
1af9f229
RS
11474 case 's':
11475 /* status of process */
11476 obj = Fget_buffer_process (w->buffer);
11477 if (NILP (obj))
11478 return "no process";
11479#ifdef subprocesses
11480 obj = Fsymbol_name (Fprocess_status (obj));
11481#endif
11482 break;
d39b6696 11483
1af9f229
RS
11484 case 't': /* indicate TEXT or BINARY */
11485#ifdef MODE_LINE_BINARY_TEXT
11486 return MODE_LINE_BINARY_TEXT (b);
11487#else
11488 return "T";
11489#endif
1c9241f5
KH
11490
11491 case 'z':
11492 /* coding-system (not including end-of-line format) */
11493 case 'Z':
11494 /* coding-system (including end-of-line type) */
11495 {
11496 int eol_flag = (c == 'Z');
539b4d41 11497 char *p = decode_mode_spec_buf;
1c9241f5 11498
d30e754b 11499 if (! FRAME_WINDOW_P (f))
1c9241f5 11500 {
11c52c4f
RS
11501 /* No need to mention EOL here--the terminal never needs
11502 to do EOL conversion. */
11503 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
11504 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
1c9241f5 11505 }
f13c925f 11506 p = decode_mode_spec_coding (b->buffer_file_coding_system,
539b4d41 11507 p, eol_flag);
f13c925f 11508
11c52c4f 11509#if 0 /* This proves to be annoying; I think we can do without. -- rms. */
1c9241f5
KH
11510#ifdef subprocesses
11511 obj = Fget_buffer_process (Fcurrent_buffer ());
11512 if (PROCESSP (obj))
11513 {
11514 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
11515 p, eol_flag);
11516 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
11517 p, eol_flag);
11518 }
11519#endif /* subprocesses */
11c52c4f 11520#endif /* 0 */
1c9241f5
KH
11521 *p = 0;
11522 return decode_mode_spec_buf;
11523 }
a2889657 11524 }
d39b6696 11525
e24c997d 11526 if (STRINGP (obj))
a2889657
JB
11527 return (char *) XSTRING (obj)->data;
11528 else
11529 return "";
11530}
5f5c8ee5
GM
11531
11532
12adba34
RS
11533/* Count up to COUNT lines starting from START / START_BYTE.
11534 But don't go beyond LIMIT_BYTE.
11535 Return the number of lines thus found (always nonnegative).
59b49f63 11536
12adba34 11537 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
59b49f63
RS
11538
11539static int
12adba34
RS
11540display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
11541 int start, start_byte, limit_byte, count;
11542 int *byte_pos_ptr;
59b49f63 11543{
59b49f63
RS
11544 register unsigned char *cursor;
11545 unsigned char *base;
11546
11547 register int ceiling;
11548 register unsigned char *ceiling_addr;
12adba34 11549 int orig_count = count;
59b49f63
RS
11550
11551 /* If we are not in selective display mode,
11552 check only for newlines. */
12adba34
RS
11553 int selective_display = (!NILP (current_buffer->selective_display)
11554 && !INTEGERP (current_buffer->selective_display));
59b49f63
RS
11555
11556 if (count > 0)
12adba34
RS
11557 {
11558 while (start_byte < limit_byte)
11559 {
11560 ceiling = BUFFER_CEILING_OF (start_byte);
11561 ceiling = min (limit_byte - 1, ceiling);
11562 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
11563 base = (cursor = BYTE_POS_ADDR (start_byte));
11564 while (1)
11565 {
11566 if (selective_display)
11567 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
11568 ;
11569 else
11570 while (*cursor != '\n' && ++cursor != ceiling_addr)
11571 ;
11572
11573 if (cursor != ceiling_addr)
11574 {
11575 if (--count == 0)
11576 {
11577 start_byte += cursor - base + 1;
11578 *byte_pos_ptr = start_byte;
11579 return orig_count;
11580 }
11581 else
11582 if (++cursor == ceiling_addr)
11583 break;
11584 }
11585 else
11586 break;
11587 }
11588 start_byte += cursor - base;
11589 }
11590 }
59b49f63
RS
11591 else
11592 {
12adba34
RS
11593 while (start_byte > limit_byte)
11594 {
11595 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
11596 ceiling = max (limit_byte, ceiling);
11597 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
11598 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
59b49f63
RS
11599 while (1)
11600 {
12adba34
RS
11601 if (selective_display)
11602 while (--cursor != ceiling_addr
11603 && *cursor != '\n' && *cursor != 015)
11604 ;
11605 else
11606 while (--cursor != ceiling_addr && *cursor != '\n')
11607 ;
11608
59b49f63
RS
11609 if (cursor != ceiling_addr)
11610 {
11611 if (++count == 0)
11612 {
12adba34
RS
11613 start_byte += cursor - base + 1;
11614 *byte_pos_ptr = start_byte;
11615 /* When scanning backwards, we should
11616 not count the newline posterior to which we stop. */
11617 return - orig_count - 1;
59b49f63
RS
11618 }
11619 }
11620 else
11621 break;
11622 }
12adba34
RS
11623 /* Here we add 1 to compensate for the last decrement
11624 of CURSOR, which took it past the valid range. */
11625 start_byte += cursor - base + 1;
59b49f63
RS
11626 }
11627 }
11628
12adba34 11629 *byte_pos_ptr = limit_byte;
aa6d10fa 11630
12adba34
RS
11631 if (count < 0)
11632 return - orig_count + count;
11633 return orig_count - count;
aa6d10fa 11634
12adba34 11635}
a2889657 11636
a2889657 11637
5f5c8ee5
GM
11638\f
11639/***********************************************************************
11640 Displaying strings
11641 ***********************************************************************/
278feba9 11642
5f5c8ee5 11643/* Display a NUL-terminated string, starting with index START.
a3788d53 11644
5f5c8ee5
GM
11645 If STRING is non-null, display that C string. Otherwise, the Lisp
11646 string LISP_STRING is displayed.
a2889657 11647
5f5c8ee5
GM
11648 If FACE_STRING is not nil, FACE_STRING_POS is a position in
11649 FACE_STRING. Display STRING or LISP_STRING with the face at
11650 FACE_STRING_POS in FACE_STRING:
a2889657 11651
5f5c8ee5
GM
11652 Display the string in the environment given by IT, but use the
11653 standard display table, temporarily.
a3788d53 11654
5f5c8ee5
GM
11655 FIELD_WIDTH is the minimum number of output glyphs to produce.
11656 If STRING has fewer characters than FIELD_WIDTH, pad to the right
11657 with spaces. If STRING has more characters, more than FIELD_WIDTH
11658 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
11659
11660 PRECISION is the maximum number of characters to output from
11661 STRING. PRECISION < 0 means don't truncate the string.
a2889657 11662
5f5c8ee5 11663 This is roughly equivalent to printf format specifiers:
a2889657 11664
5f5c8ee5
GM
11665 FIELD_WIDTH PRECISION PRINTF
11666 ----------------------------------------
11667 -1 -1 %s
11668 -1 10 %.10s
11669 10 -1 %10s
11670 20 10 %20.10s
a2889657 11671
5f5c8ee5
GM
11672 MULTIBYTE zero means do not display multibyte chars, > 0 means do
11673 display them, and < 0 means obey the current buffer's value of
11674 enable_multibyte_characters.
278feba9 11675
5f5c8ee5 11676 Value is the number of glyphs produced. */
b1d1124b 11677
5f5c8ee5
GM
11678static int
11679display_string (string, lisp_string, face_string, face_string_pos,
11680 start, it, field_width, precision, max_x, multibyte)
11681 unsigned char *string;
11682 Lisp_Object lisp_string;
11683 int start;
11684 struct it *it;
11685 int field_width, precision, max_x;
11686 int multibyte;
11687{
11688 int hpos_at_start = it->hpos;
11689 int saved_face_id = it->face_id;
11690 struct glyph_row *row = it->glyph_row;
11691
11692 /* Initialize the iterator IT for iteration over STRING beginning
11693 with index START. We assume that IT may be modified here (which
11694 means that display_line has to do something when displaying a
11695 mini-buffer prompt, which it does). */
11696 reseat_to_string (it, string, lisp_string, start,
11697 precision, field_width, multibyte);
11698
11699 /* If displaying STRING, set up the face of the iterator
11700 from LISP_STRING, if that's given. */
11701 if (STRINGP (face_string))
11702 {
11703 int endptr;
11704 struct face *face;
11705
11706 it->face_id
11707 = face_at_string_position (it->w, face_string, face_string_pos,
11708 0, it->region_beg_charpos,
11709 it->region_end_charpos,
11710 &endptr, it->base_face_id);
11711 face = FACE_FROM_ID (it->f, it->face_id);
11712 it->face_box_p = face->box != FACE_NO_BOX;
b1d1124b 11713 }
a2889657 11714
5f5c8ee5
GM
11715 /* Set max_x to the maximum allowed X position. Don't let it go
11716 beyond the right edge of the window. */
11717 if (max_x <= 0)
11718 max_x = it->last_visible_x;
11719 else
11720 max_x = min (max_x, it->last_visible_x);
efc63ef0 11721
5f5c8ee5
GM
11722 /* Skip over display elements that are not visible. because IT->w is
11723 hscrolled. */
11724 if (it->current_x < it->first_visible_x)
11725 move_it_in_display_line_to (it, 100000, it->first_visible_x,
11726 MOVE_TO_POS | MOVE_TO_X);
a2889657 11727
5f5c8ee5
GM
11728 row->ascent = it->max_ascent;
11729 row->height = it->max_ascent + it->max_descent;
312246d1
GM
11730 row->phys_ascent = it->max_phys_ascent;
11731 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
1c9241f5 11732
5f5c8ee5
GM
11733 /* This condition is for the case that we are called with current_x
11734 past last_visible_x. */
11735 while (it->current_x < max_x)
a2889657 11736 {
5f5c8ee5 11737 int x_before, x, n_glyphs_before, i, nglyphs;
1c9241f5 11738
5f5c8ee5
GM
11739 /* Get the next display element. */
11740 if (!get_next_display_element (it))
90adcf20 11741 break;
1c9241f5 11742
5f5c8ee5
GM
11743 /* Produce glyphs. */
11744 x_before = it->current_x;
11745 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
11746 PRODUCE_GLYPHS (it);
90adcf20 11747
5f5c8ee5
GM
11748 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
11749 i = 0;
11750 x = x_before;
11751 while (i < nglyphs)
a2889657 11752 {
5f5c8ee5
GM
11753 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11754
11755 if (!it->truncate_lines_p
11756 && x + glyph->pixel_width > max_x)
11757 {
11758 /* End of continued line or max_x reached. */
11759 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
11760 it->current_x = x;
11761 break;
11762 }
11763 else if (x + glyph->pixel_width > it->first_visible_x)
11764 {
11765 /* Glyph is at least partially visible. */
11766 ++it->hpos;
11767 if (x < it->first_visible_x)
11768 it->glyph_row->x = x - it->first_visible_x;
11769 }
11770 else
a2889657 11771 {
5f5c8ee5
GM
11772 /* Glyph is off the left margin of the display area.
11773 Should not happen. */
11774 abort ();
a2889657 11775 }
5f5c8ee5
GM
11776
11777 row->ascent = max (row->ascent, it->max_ascent);
11778 row->height = max (row->height, it->max_ascent + it->max_descent);
312246d1
GM
11779 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11780 row->phys_height = max (row->phys_height,
11781 it->max_phys_ascent + it->max_phys_descent);
5f5c8ee5
GM
11782 x += glyph->pixel_width;
11783 ++i;
a2889657 11784 }
5f5c8ee5
GM
11785
11786 /* Stop if max_x reached. */
11787 if (i < nglyphs)
11788 break;
11789
11790 /* Stop at line ends. */
11791 if (ITERATOR_AT_END_OF_LINE_P (it))
a2889657 11792 {
5f5c8ee5
GM
11793 it->continuation_lines_width = 0;
11794 break;
a2889657 11795 }
1c9241f5 11796
5f5c8ee5 11797 set_iterator_to_next (it);
a688bb24 11798
5f5c8ee5
GM
11799 /* Stop if truncating at the right edge. */
11800 if (it->truncate_lines_p
11801 && it->current_x >= it->last_visible_x)
11802 {
11803 /* Add truncation mark, but don't do it if the line is
11804 truncated at a padding space. */
11805 if (IT_CHARPOS (*it) < it->string_nchars)
1c9241f5 11806 {
5f5c8ee5
GM
11807 if (!FRAME_WINDOW_P (it->f))
11808 produce_special_glyphs (it, IT_TRUNCATION);
11809 it->glyph_row->truncated_on_right_p = 1;
1c9241f5 11810 }
5f5c8ee5 11811 break;
1c9241f5 11812 }
a2889657
JB
11813 }
11814
5f5c8ee5
GM
11815 /* Maybe insert a truncation at the left. */
11816 if (it->first_visible_x
11817 && IT_CHARPOS (*it) > 0)
a2889657 11818 {
5f5c8ee5
GM
11819 if (!FRAME_WINDOW_P (it->f))
11820 insert_left_trunc_glyphs (it);
11821 it->glyph_row->truncated_on_left_p = 1;
a2889657
JB
11822 }
11823
5f5c8ee5
GM
11824 it->face_id = saved_face_id;
11825
11826 /* Value is number of columns displayed. */
11827 return it->hpos - hpos_at_start;
11828}
a2889657 11829
a2889657 11830
a2889657 11831\f
5f5c8ee5
GM
11832/* This is like a combination of memq and assq. Return 1 if PROPVAL
11833 appears as an element of LIST or as the car of an element of LIST.
11834 If PROPVAL is a list, compare each element against LIST in that
11835 way, and return 1 if any element of PROPVAL is found in LIST.
11836 Otherwise return 0. This function cannot quit. */
642eefc6
RS
11837
11838int
11839invisible_p (propval, list)
11840 register Lisp_Object propval;
11841 Lisp_Object list;
11842{
af460d46
RS
11843 register Lisp_Object tail, proptail;
11844 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
11845 {
11846 register Lisp_Object tem;
af460d46 11847 tem = XCONS (tail)->car;
642eefc6
RS
11848 if (EQ (propval, tem))
11849 return 1;
11850 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
11851 return 1;
11852 }
af460d46
RS
11853 if (CONSP (propval))
11854 for (proptail = propval; CONSP (proptail);
11855 proptail = XCONS (proptail)->cdr)
11856 {
11857 Lisp_Object propelt;
11858 propelt = XCONS (proptail)->car;
11859 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11860 {
11861 register Lisp_Object tem;
11862 tem = XCONS (tail)->car;
11863 if (EQ (propelt, tem))
11864 return 1;
11865 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
11866 return 1;
11867 }
11868 }
642eefc6
RS
11869 return 0;
11870}
11871
5f5c8ee5
GM
11872
11873/* Return 1 if PROPVAL appears as the car of an element of LIST and
11874 the cdr of that element is non-nil. If PROPVAL is a list, check
11875 each element of PROPVAL in that way, and the first time some
11876 element is found, return 1 if the cdr of that element is non-nil.
11877 Otherwise return 0. This function cannot quit. */
642eefc6
RS
11878
11879int
11880invisible_ellipsis_p (propval, list)
11881 register Lisp_Object propval;
11882 Lisp_Object list;
11883{
af460d46
RS
11884 register Lisp_Object tail, proptail;
11885 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
642eefc6
RS
11886 {
11887 register Lisp_Object tem;
af460d46 11888 tem = XCONS (tail)->car;
642eefc6
RS
11889 if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
11890 return ! NILP (XCONS (tem)->cdr);
11891 }
af460d46
RS
11892 if (CONSP (propval))
11893 for (proptail = propval; CONSP (proptail);
11894 proptail = XCONS (proptail)->cdr)
11895 {
11896 Lisp_Object propelt;
11897 propelt = XCONS (proptail)->car;
11898 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
11899 {
11900 register Lisp_Object tem;
11901 tem = XCONS (tail)->car;
11902 if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
11903 return ! NILP (XCONS (tem)->cdr);
11904 }
11905 }
642eefc6
RS
11906 return 0;
11907}
5f5c8ee5
GM
11908
11909
642eefc6 11910\f
5f5c8ee5
GM
11911/***********************************************************************
11912 Initialization
11913 ***********************************************************************/
11914
a2889657
JB
11915void
11916syms_of_xdisp ()
11917{
5f5c8ee5
GM
11918 echo_area_message = previous_echo_area_message = Qnil;
11919 staticpro (&echo_area_message);
11920 staticpro (&previous_echo_area_message);
11921
735c094c
KH
11922 staticpro (&Qinhibit_redisplay);
11923 Qinhibit_redisplay = intern ("inhibit-redisplay");
11924
5f5c8ee5
GM
11925#if GLYPH_DEBUG
11926 defsubr (&Sdump_glyph_matrix);
11927 defsubr (&Sdump_glyph_row);
11928 defsubr (&Sdump_toolbar_row);
11929 defsubr (&Strace_redisplay_toggle);
11930#endif
11931
cf074754
RS
11932 staticpro (&Qmenu_bar_update_hook);
11933 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
11934
d46fb96a 11935 staticpro (&Qoverriding_terminal_local_map);
7079aefa 11936 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
d46fb96a 11937
399164b4
KH
11938 staticpro (&Qoverriding_local_map);
11939 Qoverriding_local_map = intern ("overriding-local-map");
11940
75c43375
RS
11941 staticpro (&Qwindow_scroll_functions);
11942 Qwindow_scroll_functions = intern ("window-scroll-functions");
11943
e0bfbde6
RS
11944 staticpro (&Qredisplay_end_trigger_functions);
11945 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
5f5c8ee5 11946
2e54982e
RS
11947 staticpro (&Qinhibit_point_motion_hooks);
11948 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
11949
5f5c8ee5
GM
11950 staticpro (&Qdisplay);
11951 Qdisplay = intern ("display");
11952 staticpro (&Qleft_margin);
11953 Qspace_width = intern ("space-width");
11954 staticpro (&Qspace_width);
11955 Qheight = intern ("height");
11956 staticpro (&Qheight);
11957 Qraise = intern ("raise");
11958 staticpro (&Qraise);
11959 Qspace = intern ("space");
11960 staticpro (&Qspace);
11961 Qleft_margin = intern ("left-margin");
11962 staticpro (&Qright_margin);
11963 Qright_margin = intern ("right-margin");
11964 Qalign_to = intern ("align-to");
11965 staticpro (&Qalign_to);
11966 QCalign_to = intern (":align-to");
11967 staticpro (&QCalign_to);
11968 Qwidth = intern ("width");
11969 staticpro (&Qwidth);
11970 Qrelative_width = intern ("relative-width");
11971 staticpro (&Qrelative_width);
11972 QCrelative_width = intern (":relative-width");
11973 staticpro (&QCrelative_width);
11974 QCrelative_height = intern (":relative-height");
11975 staticpro (&QCrelative_height);
11976 QCeval = intern (":eval");
11977 staticpro (&QCeval);
11978 QCwhen = intern (":when");
11979 staticpro (&QCwhen);
11980 Qfontified = intern ("fontified");
11981 staticpro (&Qfontified);
11982 Qfontification_functions = intern ("fontification-functions");
11983 staticpro (&Qfontification_functions);
11984 Qshow_trailing_whitespace = intern ("show-trailing-whitespace");
11985 staticpro (&Qshow_trailing_whitespace);
11986 Qtrailing_whitespace = intern ("trailing-whitespace");
11987 staticpro (&Qtrailing_whitespace);
11988 Qimage = intern ("image");
11989 staticpro (&Qimage);
11990
a2889657
JB
11991 staticpro (&last_arrow_position);
11992 staticpro (&last_arrow_string);
11993 last_arrow_position = Qnil;
11994 last_arrow_string = Qnil;
11995
735c094c
KH
11996 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
11997 "Non-nil means don't actually do any redisplay.\n\
11998This is used for internal purposes.");
11999 Vinhibit_redisplay = Qnil;
12000
a2889657 12001 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
8c45d522 12002 "String (or mode line construct) included (normally) in `mode-line-format'.");
a2889657
JB
12003 Vglobal_mode_string = Qnil;
12004
12005 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
12006 "Marker for where to display an arrow on top of the buffer text.\n\
12007This must be the beginning of a line in order to work.\n\
12008See also `overlay-arrow-string'.");
12009 Voverlay_arrow_position = Qnil;
12010
12011 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
12012 "String to display as an arrow. See also `overlay-arrow-position'.");
12013 Voverlay_arrow_string = Qnil;
12014
12015 DEFVAR_INT ("scroll-step", &scroll_step,
12016 "*The number of lines to try scrolling a window by when point moves out.\n\
44fa5b1e
JB
12017If that fails to bring point back on frame, point is centered instead.\n\
12018If this is zero, point is always centered after it moves off frame.");
a2889657 12019
0789adb2
RS
12020 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
12021 "*Scroll up to this many lines, to bring point back on screen.");
12022 scroll_conservatively = 0;
12023
9afd2168
RS
12024 DEFVAR_INT ("scroll-margin", &scroll_margin,
12025 "*Number of lines of margin at the top and bottom of a window.\n\
12026Recenter the window whenever point gets within this many lines\n\
12027of the top or bottom of the window.");
12028 scroll_margin = 0;
12029
5f5c8ee5 12030#if GLYPH_DEBUG
a2889657 12031 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
5f5c8ee5 12032#endif
a2889657
JB
12033
12034 DEFVAR_BOOL ("truncate-partial-width-windows",
12035 &truncate_partial_width_windows,
44fa5b1e 12036 "*Non-nil means truncate lines in all windows less than full frame wide.");
a2889657
JB
12037 truncate_partial_width_windows = 1;
12038
12039 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
12040 "*Non-nil means use inverse video for the mode line.");
12041 mode_line_inverse_video = 1;
aa6d10fa
RS
12042
12043 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
5f5c8ee5 12044 "*Maximum buffer size for which line number should be displayed.\n\
db4f2bfa 12045If the buffer is bigger than this, the line number does not appear\n\
9f027393 12046in the mode line.");
aa6d10fa 12047 line_number_display_limit = 1000000;
fba9ce76 12048
5d121aec
KH
12049 DEFVAR_INT ("line-number-display-limit-width", &line_number_display_limit_width,
12050 "*Maximum line width (in characters) for line number display.\n\
12051If the average length of the lines near point is bigger than this, then the\n\
12052line number may be omitted from the mode line.");
12053 line_number_display_limit_width = 200;
12054
fba9ce76
RS
12055 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
12056 "*Non-nil means highlight region even in nonselected windows.");
293a54ce 12057 highlight_nonselected_windows = 0;
d39b6696
KH
12058
12059 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
3450d04c
KH
12060 "Non-nil if more than one frame is visible on this display.\n\
12061Minibuffer-only frames don't count, but iconified frames do.\n\
4c2eb242
RS
12062This variable is not guaranteed to be accurate except while processing\n\
12063`frame-title-format' and `icon-title-format'.");
d39b6696
KH
12064
12065 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
5f5c8ee5 12066 "Template for displaying the title bar of visible frames.\n\
d39b6696
KH
12067\(Assuming the window manager supports this feature.)\n\
12068This variable has the same structure as `mode-line-format' (which see),\n\
12069and is used only on frames for which no explicit name has been set\n\
12070\(see `modify-frame-parameters').");
12071 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
5f5c8ee5 12072 "Template for displaying the title bar of an iconified frame.\n\
d39b6696
KH
12073\(Assuming the window manager supports this feature.)\n\
12074This variable has the same structure as `mode-line-format' (which see),\n\
12075and is used only on frames for which no explicit name has been set\n\
12076\(see `modify-frame-parameters').");
12077 Vicon_title_format
12078 = Vframe_title_format
12079 = Fcons (intern ("multiple-frames"),
12080 Fcons (build_string ("%b"),
12081 Fcons (Fcons (build_string (""),
12082 Fcons (intern ("invocation-name"),
12083 Fcons (build_string ("@"),
12084 Fcons (intern ("system-name"),
12085 Qnil)))),
12086 Qnil)));
5992c4f7
KH
12087
12088 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
12089 "Maximum number of lines to keep in the message log buffer.\n\
12090If nil, disable message logging. If t, log messages but don't truncate\n\
12091the buffer when it becomes large.");
12092 XSETFASTINT (Vmessage_log_max, 50);
08b610e4
RS
12093
12094 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
12095 "Functions called before redisplay, if window sizes have changed.\n\
12096The value should be a list of functions that take one argument.\n\
12097Just before redisplay, for each frame, if any of its windows have changed\n\
12098size since the last redisplay, or have been split or deleted,\n\
12099all the functions in the list are called, with the frame as argument.");
12100 Vwindow_size_change_functions = Qnil;
75c43375
RS
12101
12102 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
5f5c8ee5 12103 "List of Functions to call before redisplaying a window with scrolling.\n\
75c43375 12104Each function is called with two arguments, the window\n\
8d9583b0
RS
12105and its new display-start position. Note that the value of `window-end'\n\
12106is not valid when these functions are called.");
75c43375 12107 Vwindow_scroll_functions = Qnil;
5f5c8ee5
GM
12108
12109 DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p,
12110 "*Non-nil means automatically resize toolbars.\n\
12111This increases a toolbar's height if not all toolbar items are visible.\n\
12112It decreases a toolbar's height when it would display blank lines\n\
12113otherwise.");
12114 auto_resize_toolbars_p = 1;
12115
12116 DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p,
12117 "*Non-nil means raise toolbar buttons when the mouse moves over them.");
12118 auto_raise_toolbar_buttons_p = 1;
12119
12120 DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin,
12121 "*Margin around toolbar buttons in pixels.");
12122 toolbar_button_margin = 1;
12123
12124 DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief,
12125 "Relief thickness of toolbar buttons.");
12126 toolbar_button_relief = 3;
12127
12128 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
12129 "List of functions to call to fontify regions of text.\n\
12130Each function is called with one argument POS. Functions must\n\
12131fontify a region starting at POS in the current buffer, and give\n\
12132fontified regions the property `fontified'.\n\
12133This variable automatically becomes buffer-local when set.");
12134 Vfontification_functions = Qnil;
12135 Fmake_local_variable (Qfontification_functions);
7bbe686f
AI
12136
12137 DEFVAR_BOOL ("unibyte-display-via-language-environment",
5f5c8ee5
GM
12138 &unibyte_display_via_language_environment,
12139 "*Non-nil means display unibyte text according to language environment.\n\
7bbe686f
AI
12140Specifically this means that unibyte non-ASCII characters\n\
12141are displayed by converting them to the equivalent multibyte characters\n\
12142according to the current language environment. As a result, they are\n\
12143displayed according to the current fontset.");
12144 unibyte_display_via_language_environment = 0;
a2889657
JB
12145}
12146
5f5c8ee5
GM
12147
12148/* Initialize this module when Emacs starts. */
12149
dfcf069d 12150void
a2889657
JB
12151init_xdisp ()
12152{
12153 Lisp_Object root_window;
5f5c8ee5 12154 struct window *mini_w;
a2889657 12155
5f5c8ee5 12156 CHARPOS (this_line_start_pos) = 0;
a2889657
JB
12157
12158 mini_w = XWINDOW (minibuf_window);
11e82b76 12159 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
a2889657
JB
12160
12161 echo_area_glyphs = 0;
12162 previous_echo_glyphs = 0;
5f5c8ee5 12163 echo_area_message = previous_echo_area_message = Qnil;
a2889657
JB
12164
12165 if (!noninteractive)
12166 {
5f5c8ee5
GM
12167 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
12168 int i;
12169
12170 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
12c226c5 12171 set_window_height (root_window,
5f5c8ee5 12172 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
12c226c5 12173 0);
c2213350 12174 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
a2889657
JB
12175 set_window_height (minibuf_window, 1, 0);
12176
c2213350
KH
12177 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
12178 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
5f5c8ee5
GM
12179
12180 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
12181 scratch_glyph_row.glyphs[TEXT_AREA + 1]
12182 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
12183
12184 /* The default ellipsis glyphs `...'. */
12185 for (i = 0; i < 3; ++i)
12186 XSETFASTINT (default_invis_vector[i], '.');
a2889657 12187 }
5f5c8ee5
GM
12188
12189#ifdef HAVE_WINDOW_SYSTEM
12190 {
12191 /* Allocate the buffer for frame titles. */
12192 int size = 100;
12193 frame_title_buf = (char *) xmalloc (size);
12194 frame_title_buf_end = frame_title_buf + size;
12195 frame_title_ptr = NULL;
12196 }
12197#endif /* HAVE_WINDOW_SYSTEM */
a2889657 12198}
5f5c8ee5
GM
12199
12200