]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(message_truncate_lines, Qmessage_truncate_lines): New
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
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. */
169
170 #include <config.h>
171 #include <stdio.h>
172 #include "lisp.h"
173 #include "frame.h"
174 #include "window.h"
175 #include "termchar.h"
176 #include "dispextern.h"
177 #include "buffer.h"
178 #include "charset.h"
179 #include "indent.h"
180 #include "commands.h"
181 #include "macros.h"
182 #include "disptab.h"
183 #include "termhooks.h"
184 #include "intervals.h"
185 #include "keyboard.h"
186 #include "coding.h"
187 #include "process.h"
188 #include "region-cache.h"
189 #include "fontset.h"
190
191 #ifdef HAVE_X_WINDOWS
192 #include "xterm.h"
193 #endif
194 #ifdef WINDOWSNT
195 #include "w32term.h"
196 #endif
197
198 #define min(a, b) ((a) < (b) ? (a) : (b))
199 #define max(a, b) ((a) > (b) ? (a) : (b))
200
201 #define INFINITY 10000000
202
203 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
204 extern void set_frame_menubar ();
205 extern int pending_menu_activation;
206 #endif
207
208 extern int interrupt_input;
209 extern int command_loop_level;
210
211 extern int minibuffer_auto_raise;
212
213 extern Lisp_Object Qface;
214
215 extern Lisp_Object Voverriding_local_map;
216 extern Lisp_Object Voverriding_local_map_menu_flag;
217 extern Lisp_Object Qmenu_item;
218
219 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
220 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
221 Lisp_Object Qredisplay_end_trigger_functions;
222 Lisp_Object Qinhibit_point_motion_hooks;
223 Lisp_Object QCeval, Qwhen, QCfile, QCdata;
224 Lisp_Object Qfontified;
225
226 /* Functions called to fontify regions of text. */
227
228 Lisp_Object Vfontification_functions;
229 Lisp_Object Qfontification_functions;
230
231 /* Non-zero means draw tool bar buttons raised when the mouse moves
232 over them. */
233
234 int auto_raise_tool_bar_buttons_p;
235
236 /* Margin around tool bar buttons in pixels. */
237
238 int tool_bar_button_margin;
239
240 /* Thickness of shadow to draw around tool bar buttons. */
241
242 int tool_bar_button_relief;
243
244 /* Non-zero means automatically resize tool-bars so that all tool-bar
245 items are visible, and no blank lines remain. */
246
247 int auto_resize_tool_bars_p;
248
249 /* Non-nil means don't actually do any redisplay. */
250
251 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
252
253 /* Names of text properties relevant for redisplay. */
254
255 Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
256 extern Lisp_Object Qface, Qinvisible, Qimage, Qwidth;
257
258 /* Symbols used in text property values. */
259
260 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
261 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
262 Lisp_Object Qmargin;
263 extern Lisp_Object Qheight;
264
265 /* Non-nil means highlight trailing whitespace. */
266
267 Lisp_Object Vshow_trailing_whitespace;
268
269 /* Name of the face used to highlight trailing whitespace. */
270
271 Lisp_Object Qtrailing_whitespace;
272
273 /* The symbol `image' which is the car of the lists used to represent
274 images in Lisp. */
275
276 Lisp_Object Qimage;
277
278 /* Non-zero means print newline to stdout before next mini-buffer
279 message. */
280
281 int noninteractive_need_newline;
282
283 /* Non-zero means print newline to message log before next message. */
284
285 static int message_log_need_newline;
286
287 \f
288 /* The buffer position of the first character appearing entirely or
289 partially on the line of the selected window which contains the
290 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
291 redisplay optimization in redisplay_internal. */
292
293 static struct text_pos this_line_start_pos;
294
295 /* Number of characters past the end of the line above, including the
296 terminating newline. */
297
298 static struct text_pos this_line_end_pos;
299
300 /* The vertical positions and the height of this line. */
301
302 static int this_line_vpos;
303 static int this_line_y;
304 static int this_line_pixel_height;
305
306 /* X position at which this display line starts. Usually zero;
307 negative if first character is partially visible. */
308
309 static int this_line_start_x;
310
311 /* Buffer that this_line_.* variables are referring to. */
312
313 static struct buffer *this_line_buffer;
314
315 /* Nonzero means truncate lines in all windows less wide than the
316 frame. */
317
318 int truncate_partial_width_windows;
319
320 /* A flag to control how to display unibyte 8-bit character. */
321
322 int unibyte_display_via_language_environment;
323
324 /* Nonzero means we have more than one non-mini-buffer-only frame.
325 Not guaranteed to be accurate except while parsing
326 frame-title-format. */
327
328 int multiple_frames;
329
330 Lisp_Object Vglobal_mode_string;
331
332 /* Marker for where to display an arrow on top of the buffer text. */
333
334 Lisp_Object Voverlay_arrow_position;
335
336 /* String to display for the arrow. Only used on terminal frames. */
337
338 Lisp_Object Voverlay_arrow_string;
339
340 /* Values of those variables at last redisplay. However, if
341 Voverlay_arrow_position is a marker, last_arrow_position is its
342 numerical position. */
343
344 static Lisp_Object last_arrow_position, last_arrow_string;
345
346 /* Like mode-line-format, but for the title bar on a visible frame. */
347
348 Lisp_Object Vframe_title_format;
349
350 /* Like mode-line-format, but for the title bar on an iconified frame. */
351
352 Lisp_Object Vicon_title_format;
353
354 /* List of functions to call when a window's size changes. These
355 functions get one arg, a frame on which one or more windows' sizes
356 have changed. */
357
358 static Lisp_Object Vwindow_size_change_functions;
359
360 Lisp_Object Qmenu_bar_update_hook;
361
362 /* Nonzero if overlay arrow has been displayed once in this window. */
363
364 static int overlay_arrow_seen;
365
366 /* Nonzero means highlight the region even in nonselected windows. */
367
368 int highlight_nonselected_windows;
369
370 /* If cursor motion alone moves point off frame, try scrolling this
371 many lines up or down if that will bring it back. */
372
373 static int scroll_step;
374
375 /* Non-0 means scroll just far enough to bring point back on the
376 screen, when appropriate. */
377
378 static int scroll_conservatively;
379
380 /* Recenter the window whenever point gets within this many lines of
381 the top or bottom of the window. This value is translated into a
382 pixel value by multiplying it with CANON_Y_UNIT, which means that
383 there is really a fixed pixel height scroll margin. */
384
385 int scroll_margin;
386
387 /* Number of windows showing the buffer of the selected window (or
388 another buffer with the same base buffer). keyboard.c refers to
389 this. */
390
391 int buffer_shared;
392
393 /* Vector containing glyphs for an ellipsis `...'. */
394
395 static Lisp_Object default_invis_vector[3];
396
397 /* Nonzero means display mode line highlighted. */
398
399 int mode_line_inverse_video;
400
401 /* Prompt to display in front of the mini-buffer contents. */
402
403 Lisp_Object minibuf_prompt;
404
405 /* Width of current mini-buffer prompt. Only set after display_line
406 of the line that contains the prompt. */
407
408 int minibuf_prompt_width;
409 int minibuf_prompt_pixel_width;
410
411 /* This is the window where the echo area message was displayed. It
412 is always a mini-buffer window, but it may not be the same window
413 currently active as a mini-buffer. */
414
415 Lisp_Object echo_area_window;
416
417 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
418 pushes the current message and the value of
419 message_enable_multibyte on the stack, the function restore_message
420 pops the stack and displays MESSAGE again. */
421
422 Lisp_Object Vmessage_stack;
423
424 /* Nonzero means multibyte characters were enabled when the echo area
425 message was specified. */
426
427 int message_enable_multibyte;
428
429 /* True if we should redraw the mode lines on the next redisplay. */
430
431 int update_mode_lines;
432
433 /* Nonzero if window sizes or contents have changed since last
434 redisplay that finished */
435
436 int windows_or_buffers_changed;
437
438 /* Nonzero after display_mode_line if %l was used and it displayed a
439 line number. */
440
441 int line_number_displayed;
442
443 /* Maximum buffer size for which to display line numbers. */
444
445 Lisp_Object Vline_number_display_limit;
446
447 /* line width to consider when repostioning for line number display */
448
449 static int line_number_display_limit_width;
450
451 /* Number of lines to keep in the message log buffer. t means
452 infinite. nil means don't log at all. */
453
454 Lisp_Object Vmessage_log_max;
455
456 /* Current, index 0, and last displayed echo area message. Either
457 buffers from echo_buffers, or nil to indicate no message. */
458
459 Lisp_Object echo_area_buffer[2];
460
461 /* The buffers referenced from echo_area_buffer. */
462
463 static Lisp_Object echo_buffer[2];
464
465 /* A vector saved used in with_area_buffer to reduce consing. */
466
467 static Lisp_Object Vwith_echo_area_save_vector;
468
469 /* Non-zero means display_echo_area should display the last echo area
470 message again. Set by redisplay_preserve_echo_area. */
471
472 static int display_last_displayed_message_p;
473
474 /* Nonzero if echo area is being used by print; zero if being used by
475 message. */
476
477 int message_buf_print;
478
479 /* Maximum height for resizing mini-windows. Either a float
480 specifying a fraction of the available height, or an integer
481 specifying a number of lines. */
482
483 Lisp_Object Vmax_mini_window_height;
484
485 /* Non-zero means messages should be displayed with truncated
486 lines instead of being continued. */
487
488 int message_truncate_lines;
489 Lisp_Object Qmessage_truncate_lines;
490
491 /* Non-zero means we want a hollow cursor in windows that are not
492 selected. Zero means there's no cursor in such windows. */
493
494 int cursor_in_non_selected_windows;
495
496 /* A scratch glyph row with contents used for generating truncation
497 glyphs. Also used in direct_output_for_insert. */
498
499 #define MAX_SCRATCH_GLYPHS 100
500 struct glyph_row scratch_glyph_row;
501 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
502
503 /* Ascent and height of the last line processed by move_it_to. */
504
505 static int last_max_ascent, last_height;
506
507 /* The maximum distance to look ahead for text properties. Values
508 that are too small let us call compute_char_face and similar
509 functions too often which is expensive. Values that are too large
510 let us call compute_char_face and alike too often because we
511 might not be interested in text properties that far away. */
512
513 #define TEXT_PROP_DISTANCE_LIMIT 100
514
515 /* Non-zero means print traces of redisplay if compiled with
516 GLYPH_DEBUG != 0. */
517
518 #if GLYPH_DEBUG
519 int trace_redisplay_p;
520 #endif
521
522 /* Non-zero means automatically scroll windows horizontally to make
523 point visible. */
524
525 int automatic_hscrolling_p;
526
527 /* A list of symbols, one for each supported image type. */
528
529 Lisp_Object Vimage_types;
530
531 /* Value returned from text property handlers (see below). */
532
533 enum prop_handled
534 {
535 HANDLED_NORMALLY,
536 HANDLED_RECOMPUTE_PROPS,
537 HANDLED_OVERLAY_STRING_CONSUMED,
538 HANDLED_RETURN
539 };
540
541 /* A description of text properties that redisplay is interested
542 in. */
543
544 struct props
545 {
546 /* The name of the property. */
547 Lisp_Object *name;
548
549 /* A unique index for the property. */
550 enum prop_idx idx;
551
552 /* A handler function called to set up iterator IT from the property
553 at IT's current position. Value is used to steer handle_stop. */
554 enum prop_handled (*handler) P_ ((struct it *it));
555 };
556
557 static enum prop_handled handle_face_prop P_ ((struct it *));
558 static enum prop_handled handle_invisible_prop P_ ((struct it *));
559 static enum prop_handled handle_display_prop P_ ((struct it *));
560 static enum prop_handled handle_composition_prop P_ ((struct it *));
561 static enum prop_handled handle_overlay_change P_ ((struct it *));
562 static enum prop_handled handle_fontified_prop P_ ((struct it *));
563
564 /* Properties handled by iterators. */
565
566 static struct props it_props[] =
567 {
568 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
569 /* Handle `face' before `display' because some sub-properties of
570 `display' need to know the face. */
571 {&Qface, FACE_PROP_IDX, handle_face_prop},
572 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
573 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
574 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
575 {NULL, 0, NULL}
576 };
577
578 /* Value is the position described by X. If X is a marker, value is
579 the marker_position of X. Otherwise, value is X. */
580
581 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
582
583 /* Enumeration returned by some move_it_.* functions internally. */
584
585 enum move_it_result
586 {
587 /* Not used. Undefined value. */
588 MOVE_UNDEFINED,
589
590 /* Move ended at the requested buffer position or ZV. */
591 MOVE_POS_MATCH_OR_ZV,
592
593 /* Move ended at the requested X pixel position. */
594 MOVE_X_REACHED,
595
596 /* Move within a line ended at the end of a line that must be
597 continued. */
598 MOVE_LINE_CONTINUED,
599
600 /* Move within a line ended at the end of a line that would
601 be displayed truncated. */
602 MOVE_LINE_TRUNCATED,
603
604 /* Move within a line ended at a line end. */
605 MOVE_NEWLINE_OR_CR
606 };
607
608
609 \f
610 /* Function prototypes. */
611
612 static void ensure_echo_area_buffers P_ ((void));
613 static struct glyph_row *row_containing_pos P_ ((struct window *, int,
614 struct glyph_row *,
615 struct glyph_row *));
616 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
617 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
618 static void clear_garbaged_frames P_ ((void));
619 static int current_message_1 P_ ((Lisp_Object *));
620 static int truncate_message_1 P_ ((int));
621 static int set_message_1 P_ ((char *s, Lisp_Object, int, int));
622 static int display_echo_area P_ ((struct window *));
623 static int display_echo_area_1 P_ ((struct window *));
624 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
625 static int string_char_and_length P_ ((unsigned char *, int, int *));
626 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
627 struct text_pos));
628 static int compute_window_start_on_continuation_line P_ ((struct window *));
629 static Lisp_Object eval_handler P_ ((Lisp_Object));
630 static Lisp_Object eval_form P_ ((Lisp_Object));
631 static void insert_left_trunc_glyphs P_ ((struct it *));
632 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
633 static void extend_face_to_end_of_line P_ ((struct it *));
634 static int append_space P_ ((struct it *, int));
635 static void make_cursor_line_fully_visible P_ ((struct window *));
636 static int try_scrolling P_ ((Lisp_Object, int, int, int, int));
637 static int trailing_whitespace_p P_ ((int));
638 static int message_log_check_duplicate P_ ((int, int, int, int));
639 int invisible_p P_ ((Lisp_Object, Lisp_Object));
640 int invisible_ellipsis_p P_ ((Lisp_Object, Lisp_Object));
641 static void push_it P_ ((struct it *));
642 static void pop_it P_ ((struct it *));
643 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
644 static void redisplay_internal P_ ((int));
645 static int echo_area_display P_ ((int));
646 static void redisplay_windows P_ ((Lisp_Object));
647 static void redisplay_window P_ ((Lisp_Object, int));
648 static void update_menu_bar P_ ((struct frame *, int));
649 static int try_window_reusing_current_matrix P_ ((struct window *));
650 static int try_window_id P_ ((struct window *));
651 static int display_line P_ ((struct it *));
652 static void display_mode_lines P_ ((struct window *));
653 static void display_mode_line P_ ((struct window *, enum face_id,
654 Lisp_Object));
655 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object));
656 static char *decode_mode_spec P_ ((struct window *, int, int, int));
657 static void display_menu_bar P_ ((struct window *));
658 static int display_count_lines P_ ((int, int, int, int, int *));
659 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
660 int, int, struct it *, int, int, int, int));
661 static void compute_line_metrics P_ ((struct it *));
662 static void run_redisplay_end_trigger_hook P_ ((struct it *));
663 static int get_overlay_strings P_ ((struct it *));
664 static void next_overlay_string P_ ((struct it *));
665 void set_iterator_to_next P_ ((struct it *));
666 static void reseat P_ ((struct it *, struct text_pos, int));
667 static void reseat_1 P_ ((struct it *, struct text_pos, int));
668 static void back_to_previous_visible_line_start P_ ((struct it *));
669 static void reseat_at_previous_visible_line_start P_ ((struct it *));
670 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
671 static int next_element_from_display_vector P_ ((struct it *));
672 static int next_element_from_string P_ ((struct it *));
673 static int next_element_from_c_string P_ ((struct it *));
674 static int next_element_from_buffer P_ ((struct it *));
675 static int next_element_from_composition P_ ((struct it *));
676 static int next_element_from_image P_ ((struct it *));
677 static int next_element_from_stretch P_ ((struct it *));
678 static void load_overlay_strings P_ ((struct it *));
679 static void init_from_display_pos P_ ((struct it *, struct window *,
680 struct display_pos *));
681 static void reseat_to_string P_ ((struct it *, unsigned char *,
682 Lisp_Object, int, int, int, int));
683 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
684 int, int, int));
685 void move_it_vertically_backward P_ ((struct it *, int));
686 static void init_to_row_start P_ ((struct it *, struct window *,
687 struct glyph_row *));
688 static void init_to_row_end P_ ((struct it *, struct window *,
689 struct glyph_row *));
690 static void back_to_previous_line_start P_ ((struct it *));
691 static void forward_to_next_line_start P_ ((struct it *));
692 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
693 Lisp_Object, int));
694 static struct text_pos string_pos P_ ((int, Lisp_Object));
695 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
696 static int number_of_chars P_ ((unsigned char *, int));
697 static void compute_stop_pos P_ ((struct it *));
698 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
699 Lisp_Object));
700 static int face_before_or_after_it_pos P_ ((struct it *, int));
701 static int next_overlay_change P_ ((int));
702 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
703 Lisp_Object, struct text_pos *));
704
705 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
706 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
707
708 #ifdef HAVE_WINDOW_SYSTEM
709
710 static void update_tool_bar P_ ((struct frame *, int));
711 static void build_desired_tool_bar_string P_ ((struct frame *f));
712 static int redisplay_tool_bar P_ ((struct frame *));
713 static void display_tool_bar_line P_ ((struct it *));
714
715 #endif /* HAVE_WINDOW_SYSTEM */
716
717 \f
718 /***********************************************************************
719 Window display dimensions
720 ***********************************************************************/
721
722 /* Return the window-relative maximum y + 1 for glyph rows displaying
723 text in window W. This is the height of W minus the height of a
724 mode line, if any. */
725
726 INLINE int
727 window_text_bottom_y (w)
728 struct window *w;
729 {
730 struct frame *f = XFRAME (w->frame);
731 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
732
733 if (WINDOW_WANTS_MODELINE_P (w))
734 height -= CURRENT_MODE_LINE_HEIGHT (w);
735 return height;
736 }
737
738
739 /* Return the pixel width of display area AREA of window W. AREA < 0
740 means return the total width of W, not including bitmap areas to
741 the left and right of the window. */
742
743 INLINE int
744 window_box_width (w, area)
745 struct window *w;
746 int area;
747 {
748 struct frame *f = XFRAME (w->frame);
749 int width = XFASTINT (w->width);
750
751 if (!w->pseudo_window_p)
752 {
753 width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FLAGS_AREA_COLS (f);
754
755 if (area == TEXT_AREA)
756 {
757 if (INTEGERP (w->left_margin_width))
758 width -= XFASTINT (w->left_margin_width);
759 if (INTEGERP (w->right_margin_width))
760 width -= XFASTINT (w->right_margin_width);
761 }
762 else if (area == LEFT_MARGIN_AREA)
763 width = (INTEGERP (w->left_margin_width)
764 ? XFASTINT (w->left_margin_width) : 0);
765 else if (area == RIGHT_MARGIN_AREA)
766 width = (INTEGERP (w->right_margin_width)
767 ? XFASTINT (w->right_margin_width) : 0);
768 }
769
770 return width * CANON_X_UNIT (f);
771 }
772
773
774 /* Return the pixel height of the display area of window W, not
775 including mode lines of W, if any.. */
776
777 INLINE int
778 window_box_height (w)
779 struct window *w;
780 {
781 struct frame *f = XFRAME (w->frame);
782 int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
783
784 if (WINDOW_WANTS_MODELINE_P (w))
785 height -= CURRENT_MODE_LINE_HEIGHT (w);
786
787 if (WINDOW_WANTS_HEADER_LINE_P (w))
788 height -= CURRENT_HEADER_LINE_HEIGHT (w);
789
790 return height;
791 }
792
793
794 /* Return the frame-relative coordinate of the left edge of display
795 area AREA of window W. AREA < 0 means return the left edge of the
796 whole window, to the right of any bitmap area at the left side of
797 W. */
798
799 INLINE int
800 window_box_left (w, area)
801 struct window *w;
802 int area;
803 {
804 struct frame *f = XFRAME (w->frame);
805 int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
806
807 if (!w->pseudo_window_p)
808 {
809 x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
810 + FRAME_LEFT_FLAGS_AREA_WIDTH (f));
811
812 if (area == TEXT_AREA)
813 x += window_box_width (w, LEFT_MARGIN_AREA);
814 else if (area == RIGHT_MARGIN_AREA)
815 x += (window_box_width (w, LEFT_MARGIN_AREA)
816 + window_box_width (w, TEXT_AREA));
817 }
818
819 return x;
820 }
821
822
823 /* Return the frame-relative coordinate of the right edge of display
824 area AREA of window W. AREA < 0 means return the left edge of the
825 whole window, to the left of any bitmap area at the right side of
826 W. */
827
828 INLINE int
829 window_box_right (w, area)
830 struct window *w;
831 int area;
832 {
833 return window_box_left (w, area) + window_box_width (w, area);
834 }
835
836
837 /* Get the bounding box of the display area AREA of window W, without
838 mode lines, in frame-relative coordinates. AREA < 0 means the
839 whole window, not including bitmap areas to the left and right of
840 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
841 coordinates of the upper-left corner of the box. Return in
842 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
843
844 INLINE void
845 window_box (w, area, box_x, box_y, box_width, box_height)
846 struct window *w;
847 int area;
848 int *box_x, *box_y, *box_width, *box_height;
849 {
850 struct frame *f = XFRAME (w->frame);
851
852 *box_width = window_box_width (w, area);
853 *box_height = window_box_height (w);
854 *box_x = window_box_left (w, area);
855 *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
856 + XFASTINT (w->top) * CANON_Y_UNIT (f));
857 if (WINDOW_WANTS_HEADER_LINE_P (w))
858 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
859 }
860
861
862 /* Get the bounding box of the display area AREA of window W, without
863 mode lines. AREA < 0 means the whole window, not including bitmap
864 areas to the left and right of the window. Return in *TOP_LEFT_X
865 and TOP_LEFT_Y the frame-relative pixel coordinates of the
866 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
867 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
868 box. */
869
870 INLINE void
871 window_box_edges (w, area, top_left_x, top_left_y,
872 bottom_right_x, bottom_right_y)
873 struct window *w;
874 int area;
875 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
876 {
877 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
878 bottom_right_y);
879 *bottom_right_x += *top_left_x;
880 *bottom_right_y += *top_left_y;
881 }
882
883
884 \f
885 /***********************************************************************
886 Utilities
887 ***********************************************************************/
888
889 /* Return the next character from STR which is MAXLEN bytes long.
890 Return in *LEN the length of the character. This is like
891 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
892 we find one, we return a `?', but with the length of the invalid
893 character. */
894
895 static INLINE int
896 string_char_and_length (str, maxlen, len)
897 unsigned char *str;
898 int maxlen, *len;
899 {
900 int c;
901
902 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
903 if (!CHAR_VALID_P (c, 1))
904 /* We may not change the length here because other places in Emacs
905 don't use this function, i.e. they silently accept invalid
906 characters. */
907 c = '?';
908
909 return c;
910 }
911
912
913
914 /* Given a position POS containing a valid character and byte position
915 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
916
917 static struct text_pos
918 string_pos_nchars_ahead (pos, string, nchars)
919 struct text_pos pos;
920 Lisp_Object string;
921 int nchars;
922 {
923 xassert (STRINGP (string) && nchars >= 0);
924
925 if (STRING_MULTIBYTE (string))
926 {
927 int rest = STRING_BYTES (XSTRING (string)) - BYTEPOS (pos);
928 unsigned char *p = XSTRING (string)->data + BYTEPOS (pos);
929 int len;
930
931 while (nchars--)
932 {
933 string_char_and_length (p, rest, &len);
934 p += len, rest -= len;
935 xassert (rest >= 0);
936 CHARPOS (pos) += 1;
937 BYTEPOS (pos) += len;
938 }
939 }
940 else
941 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
942
943 return pos;
944 }
945
946
947 /* Value is the text position, i.e. character and byte position,
948 for character position CHARPOS in STRING. */
949
950 static INLINE struct text_pos
951 string_pos (charpos, string)
952 int charpos;
953 Lisp_Object string;
954 {
955 struct text_pos pos;
956 xassert (STRINGP (string));
957 xassert (charpos >= 0);
958 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
959 return pos;
960 }
961
962
963 /* Value is a text position, i.e. character and byte position, for
964 character position CHARPOS in C string S. MULTIBYTE_P non-zero
965 means recognize multibyte characters. */
966
967 static struct text_pos
968 c_string_pos (charpos, s, multibyte_p)
969 int charpos;
970 unsigned char *s;
971 int multibyte_p;
972 {
973 struct text_pos pos;
974
975 xassert (s != NULL);
976 xassert (charpos >= 0);
977
978 if (multibyte_p)
979 {
980 int rest = strlen (s), len;
981
982 SET_TEXT_POS (pos, 0, 0);
983 while (charpos--)
984 {
985 string_char_and_length (s, rest, &len);
986 s += len, rest -= len;
987 xassert (rest >= 0);
988 CHARPOS (pos) += 1;
989 BYTEPOS (pos) += len;
990 }
991 }
992 else
993 SET_TEXT_POS (pos, charpos, charpos);
994
995 return pos;
996 }
997
998
999 /* Value is the number of characters in C string S. MULTIBYTE_P
1000 non-zero means recognize multibyte characters. */
1001
1002 static int
1003 number_of_chars (s, multibyte_p)
1004 unsigned char *s;
1005 int multibyte_p;
1006 {
1007 int nchars;
1008
1009 if (multibyte_p)
1010 {
1011 int rest = strlen (s), len;
1012 unsigned char *p = (unsigned char *) s;
1013
1014 for (nchars = 0; rest > 0; ++nchars)
1015 {
1016 string_char_and_length (p, rest, &len);
1017 rest -= len, p += len;
1018 }
1019 }
1020 else
1021 nchars = strlen (s);
1022
1023 return nchars;
1024 }
1025
1026
1027 /* Compute byte position NEWPOS->bytepos corresponding to
1028 NEWPOS->charpos. POS is a known position in string STRING.
1029 NEWPOS->charpos must be >= POS.charpos. */
1030
1031 static void
1032 compute_string_pos (newpos, pos, string)
1033 struct text_pos *newpos, pos;
1034 Lisp_Object string;
1035 {
1036 xassert (STRINGP (string));
1037 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1038
1039 if (STRING_MULTIBYTE (string))
1040 *newpos = string_pos_nchars_ahead (pos, string,
1041 CHARPOS (*newpos) - CHARPOS (pos));
1042 else
1043 BYTEPOS (*newpos) = CHARPOS (*newpos);
1044 }
1045
1046
1047 \f
1048 /***********************************************************************
1049 Lisp form evaluation
1050 ***********************************************************************/
1051
1052 /* Error handler for eval_form. */
1053
1054 static Lisp_Object
1055 eval_handler (arg)
1056 Lisp_Object arg;
1057 {
1058 return Qnil;
1059 }
1060
1061
1062 /* Evaluate SEXPR and return the result, or nil if something went
1063 wrong. */
1064
1065 static Lisp_Object
1066 eval_form (sexpr)
1067 Lisp_Object sexpr;
1068 {
1069 int count = specpdl_ptr - specpdl;
1070 Lisp_Object val;
1071 specbind (Qinhibit_redisplay, Qt);
1072 val = internal_condition_case_1 (Feval, sexpr, Qerror, eval_handler);
1073 return unbind_to (count, val);
1074 }
1075
1076
1077 \f
1078 /***********************************************************************
1079 Debugging
1080 ***********************************************************************/
1081
1082 #if 0
1083
1084 /* Define CHECK_IT to perform sanity checks on iterators.
1085 This is for debugging. It is too slow to do unconditionally. */
1086
1087 static void
1088 check_it (it)
1089 struct it *it;
1090 {
1091 if (it->method == next_element_from_string)
1092 {
1093 xassert (STRINGP (it->string));
1094 xassert (IT_STRING_CHARPOS (*it) >= 0);
1095 }
1096 else if (it->method == next_element_from_buffer)
1097 {
1098 /* Check that character and byte positions agree. */
1099 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1100 }
1101
1102 if (it->dpvec)
1103 xassert (it->current.dpvec_index >= 0);
1104 else
1105 xassert (it->current.dpvec_index < 0);
1106 }
1107
1108 #define CHECK_IT(IT) check_it ((IT))
1109
1110 #else /* not 0 */
1111
1112 #define CHECK_IT(IT) (void) 0
1113
1114 #endif /* not 0 */
1115
1116
1117 #if GLYPH_DEBUG
1118
1119 /* Check that the window end of window W is what we expect it
1120 to be---the last row in the current matrix displaying text. */
1121
1122 static void
1123 check_window_end (w)
1124 struct window *w;
1125 {
1126 if (!MINI_WINDOW_P (w)
1127 && !NILP (w->window_end_valid))
1128 {
1129 struct glyph_row *row;
1130 xassert ((row = MATRIX_ROW (w->current_matrix,
1131 XFASTINT (w->window_end_vpos)),
1132 !row->enabled_p
1133 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1134 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1135 }
1136 }
1137
1138 #define CHECK_WINDOW_END(W) check_window_end ((W))
1139
1140 #else /* not GLYPH_DEBUG */
1141
1142 #define CHECK_WINDOW_END(W) (void) 0
1143
1144 #endif /* not GLYPH_DEBUG */
1145
1146
1147 \f
1148 /***********************************************************************
1149 Iterator initialization
1150 ***********************************************************************/
1151
1152 /* Initialize IT for displaying current_buffer in window W, starting
1153 at character position CHARPOS. CHARPOS < 0 means that no buffer
1154 position is specified which is useful when the iterator is assigned
1155 a position later. BYTEPOS is the byte position corresponding to
1156 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1157
1158 If ROW is not null, calls to produce_glyphs with IT as parameter
1159 will produce glyphs in that row.
1160
1161 BASE_FACE_ID is the id of a base face to use. It must be one of
1162 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1163 HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
1164 displaying the tool-bar.
1165
1166 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1167 HEADER_LINE_FACE_ID, the iterator will be initialized to use the
1168 corresponding mode line glyph row of the desired matrix of W. */
1169
1170 void
1171 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1172 struct it *it;
1173 struct window *w;
1174 int charpos, bytepos;
1175 struct glyph_row *row;
1176 enum face_id base_face_id;
1177 {
1178 int highlight_region_p;
1179
1180 /* Some precondition checks. */
1181 xassert (w != NULL && it != NULL);
1182 xassert (charpos < 0 || (charpos > 0 && charpos <= ZV));
1183
1184 /* If face attributes have been changed since the last redisplay,
1185 free realized faces now because they depend on face definitions
1186 that might have changed. */
1187 if (face_change_count)
1188 {
1189 face_change_count = 0;
1190 free_all_realized_faces (Qnil);
1191 }
1192
1193 /* Use one of the mode line rows of W's desired matrix if
1194 appropriate. */
1195 if (row == NULL)
1196 {
1197 if (base_face_id == MODE_LINE_FACE_ID)
1198 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1199 else if (base_face_id == HEADER_LINE_FACE_ID)
1200 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1201 }
1202
1203 /* Clear IT. */
1204 bzero (it, sizeof *it);
1205 it->current.overlay_string_index = -1;
1206 it->current.dpvec_index = -1;
1207 it->base_face_id = base_face_id;
1208
1209 /* The window in which we iterate over current_buffer: */
1210 XSETWINDOW (it->window, w);
1211 it->w = w;
1212 it->f = XFRAME (w->frame);
1213
1214 /* Extra space between lines (on window systems only). */
1215 if (base_face_id == DEFAULT_FACE_ID
1216 && FRAME_WINDOW_P (it->f))
1217 {
1218 if (NATNUMP (current_buffer->extra_line_spacing))
1219 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1220 else if (it->f->extra_line_spacing > 0)
1221 it->extra_line_spacing = it->f->extra_line_spacing;
1222 }
1223
1224 /* If realized faces have been removed, e.g. because of face
1225 attribute changes of named faces, recompute them. */
1226 if (FRAME_FACE_CACHE (it->f)->used == 0)
1227 recompute_basic_faces (it->f);
1228
1229 /* Current value of the `space-width', and 'height' properties. */
1230 it->space_width = Qnil;
1231 it->font_height = Qnil;
1232
1233 /* Are control characters displayed as `^C'? */
1234 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
1235
1236 /* -1 means everything between a CR and the following line end
1237 is invisible. >0 means lines indented more than this value are
1238 invisible. */
1239 it->selective = (INTEGERP (current_buffer->selective_display)
1240 ? XFASTINT (current_buffer->selective_display)
1241 : (!NILP (current_buffer->selective_display)
1242 ? -1 : 0));
1243 it->selective_display_ellipsis_p
1244 = !NILP (current_buffer->selective_display_ellipses);
1245
1246 /* Display table to use. */
1247 it->dp = window_display_table (w);
1248
1249 /* Are multibyte characters enabled in current_buffer? */
1250 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
1251
1252 /* Non-zero if we should highlight the region. */
1253 highlight_region_p
1254 = (!NILP (Vtransient_mark_mode)
1255 && !NILP (current_buffer->mark_active)
1256 && XMARKER (current_buffer->mark)->buffer != 0);
1257
1258 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1259 start and end of a visible region in window IT->w. Set both to
1260 -1 to indicate no region. */
1261 if (highlight_region_p
1262 /* Maybe highlight only in selected window. */
1263 && (/* Either show region everywhere. */
1264 highlight_nonselected_windows
1265 /* Or show region in the selected window. */
1266 || w == XWINDOW (selected_window)
1267 /* Or show the region if we are in the mini-buffer and W is
1268 the window the mini-buffer refers to. */
1269 || (MINI_WINDOW_P (XWINDOW (selected_window))
1270 && w == XWINDOW (Vminibuf_scroll_window))))
1271 {
1272 int charpos = marker_position (current_buffer->mark);
1273 it->region_beg_charpos = min (PT, charpos);
1274 it->region_end_charpos = max (PT, charpos);
1275 }
1276 else
1277 it->region_beg_charpos = it->region_end_charpos = -1;
1278
1279 /* Get the position at which the redisplay_end_trigger hook should
1280 be run, if it is to be run at all. */
1281 if (MARKERP (w->redisplay_end_trigger)
1282 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
1283 it->redisplay_end_trigger_charpos
1284 = marker_position (w->redisplay_end_trigger);
1285 else if (INTEGERP (w->redisplay_end_trigger))
1286 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
1287
1288 /* Correct bogus values of tab_width. */
1289 it->tab_width = XINT (current_buffer->tab_width);
1290 if (it->tab_width <= 0 || it->tab_width > 1000)
1291 it->tab_width = 8;
1292
1293 /* Are lines in the display truncated? */
1294 it->truncate_lines_p
1295 = (base_face_id != DEFAULT_FACE_ID
1296 || XINT (it->w->hscroll)
1297 || (truncate_partial_width_windows
1298 && !WINDOW_FULL_WIDTH_P (it->w))
1299 || !NILP (current_buffer->truncate_lines));
1300
1301 /* Get dimensions of truncation and continuation glyphs. These are
1302 displayed as bitmaps under X, so we don't need them for such
1303 frames. */
1304 if (!FRAME_WINDOW_P (it->f))
1305 {
1306 if (it->truncate_lines_p)
1307 {
1308 /* We will need the truncation glyph. */
1309 xassert (it->glyph_row == NULL);
1310 produce_special_glyphs (it, IT_TRUNCATION);
1311 it->truncation_pixel_width = it->pixel_width;
1312 }
1313 else
1314 {
1315 /* We will need the continuation glyph. */
1316 xassert (it->glyph_row == NULL);
1317 produce_special_glyphs (it, IT_CONTINUATION);
1318 it->continuation_pixel_width = it->pixel_width;
1319 }
1320
1321 /* Reset these values to zero becaue the produce_special_glyphs
1322 above has changed them. */
1323 it->pixel_width = it->ascent = it->descent = 0;
1324 it->phys_ascent = it->phys_descent = 0;
1325 }
1326
1327 /* Set this after getting the dimensions of truncation and
1328 continuation glyphs, so that we don't produce glyphs when calling
1329 produce_special_glyphs, above. */
1330 it->glyph_row = row;
1331 it->area = TEXT_AREA;
1332
1333 /* Get the dimensions of the display area. The display area
1334 consists of the visible window area plus a horizontally scrolled
1335 part to the left of the window. All x-values are relative to the
1336 start of this total display area. */
1337 if (base_face_id != DEFAULT_FACE_ID)
1338 {
1339 /* Mode lines, menu bar in terminal frames. */
1340 it->first_visible_x = 0;
1341 it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
1342 }
1343 else
1344 {
1345 it->first_visible_x
1346 = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
1347 it->last_visible_x = (it->first_visible_x
1348 + window_box_width (w, TEXT_AREA));
1349
1350 /* If we truncate lines, leave room for the truncator glyph(s) at
1351 the right margin. Otherwise, leave room for the continuation
1352 glyph(s). Truncation and continuation glyphs are not inserted
1353 for window-based redisplay. */
1354 if (!FRAME_WINDOW_P (it->f))
1355 {
1356 if (it->truncate_lines_p)
1357 it->last_visible_x -= it->truncation_pixel_width;
1358 else
1359 it->last_visible_x -= it->continuation_pixel_width;
1360 }
1361
1362 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
1363 it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
1364 }
1365
1366 /* Leave room for a border glyph. */
1367 if (!FRAME_WINDOW_P (it->f)
1368 && !WINDOW_RIGHTMOST_P (it->w))
1369 it->last_visible_x -= 1;
1370
1371 it->last_visible_y = window_text_bottom_y (w);
1372
1373 /* For mode lines and alike, arrange for the first glyph having a
1374 left box line if the face specifies a box. */
1375 if (base_face_id != DEFAULT_FACE_ID)
1376 {
1377 struct face *face;
1378
1379 it->face_id = base_face_id;
1380
1381 /* If we have a boxed mode line, make the first character appear
1382 with a left box line. */
1383 face = FACE_FROM_ID (it->f, base_face_id);
1384 if (face->box != FACE_NO_BOX)
1385 it->start_of_box_run_p = 1;
1386 }
1387
1388 /* If a buffer position was specified, set the iterator there,
1389 getting overlays and face properties from that position. */
1390 if (charpos > 0)
1391 {
1392 it->end_charpos = ZV;
1393 it->face_id = -1;
1394 IT_CHARPOS (*it) = charpos;
1395
1396 /* Compute byte position if not specified. */
1397 if (bytepos <= 0)
1398 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
1399 else
1400 IT_BYTEPOS (*it) = bytepos;
1401
1402 /* Compute faces etc. */
1403 reseat (it, it->current.pos, 1);
1404 }
1405
1406 CHECK_IT (it);
1407 }
1408
1409
1410 /* Initialize IT for the display of window W with window start POS. */
1411
1412 void
1413 start_display (it, w, pos)
1414 struct it *it;
1415 struct window *w;
1416 struct text_pos pos;
1417 {
1418 int start_at_line_beg_p;
1419 struct glyph_row *row;
1420 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
1421 int first_y;
1422
1423 row = w->desired_matrix->rows + first_vpos;
1424 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
1425 first_y = it->current_y;
1426
1427 /* If window start is not at a line start, move back to the line
1428 start. This makes sure that we take continuation lines into
1429 account. */
1430 start_at_line_beg_p = (CHARPOS (pos) == BEGV
1431 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
1432 if (!start_at_line_beg_p)
1433 reseat_at_previous_visible_line_start (it);
1434
1435 /* If window start is not at a line start, skip forward to POS to
1436 get the correct continuation_lines_width and current_x. */
1437 if (!start_at_line_beg_p)
1438 {
1439 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
1440
1441 /* If lines are continued, this line may end in the middle of a
1442 multi-glyph character (e.g. a control character displayed as
1443 \003, or in the middle of an overlay string). In this case
1444 move_it_to above will not have taken us to the start of
1445 the continuation line but to the end of the continued line. */
1446 if (!it->truncate_lines_p && it->current_x > 0)
1447 {
1448 if (it->current.dpvec_index >= 0
1449 || it->current.overlay_string_index >= 0)
1450 {
1451 set_iterator_to_next (it);
1452 move_it_in_display_line_to (it, -1, -1, 0);
1453 }
1454 it->continuation_lines_width += it->current_x;
1455 }
1456
1457 it->current_y = first_y;
1458 it->vpos = 0;
1459 it->current_x = it->hpos = 0;
1460 }
1461
1462 #if 0 /* Don't assert the following because start_display is sometimes
1463 called intentionally with a window start that is not at a
1464 line start. Please leave this code in as a comment. */
1465
1466 /* Window start should be on a line start, now. */
1467 xassert (it->continuation_lines_width
1468 || IT_CHARPOS (it) == BEGV
1469 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
1470 #endif /* 0 */
1471 }
1472
1473
1474 /* Initialize IT for stepping through current_buffer in window W,
1475 starting at position POS that includes overlay string and display
1476 vector/ control character translation position information. */
1477
1478 static void
1479 init_from_display_pos (it, w, pos)
1480 struct it *it;
1481 struct window *w;
1482 struct display_pos *pos;
1483 {
1484 /* Keep in mind: the call to reseat in init_iterator skips invisible
1485 text, so we might end up at a position different from POS. This
1486 is only a problem when POS is a row start after a newline and an
1487 overlay starts there with an after-string, and the overlay has an
1488 invisible property. Since we don't skip invisible text in
1489 display_line and elsewhere immediately after consuming the
1490 newline before the row start, such a POS will not be in a string,
1491 but the call to init_iterator below will move us to the
1492 after-string. */
1493 init_iterator (it, w, CHARPOS (pos->pos), BYTEPOS (pos->pos),
1494 NULL, DEFAULT_FACE_ID);
1495
1496 /* If position is within an overlay string, set up IT to
1497 the right overlay string. */
1498 if (pos->overlay_string_index >= 0)
1499 {
1500 int relative_index;
1501
1502 /* We already have the first chunk of overlay strings in
1503 IT->overlay_strings. Load more until the one for
1504 pos->overlay_string_index is in IT->overlay_strings. */
1505 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
1506 {
1507 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
1508 it->current.overlay_string_index = 0;
1509 while (n--)
1510 {
1511 load_overlay_strings (it);
1512 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
1513 }
1514 }
1515
1516 it->current.overlay_string_index = pos->overlay_string_index;
1517 relative_index = (it->current.overlay_string_index
1518 % OVERLAY_STRING_CHUNK_SIZE);
1519 it->string = it->overlay_strings[relative_index];
1520 it->current.string_pos = pos->string_pos;
1521 it->method = next_element_from_string;
1522 }
1523 else if (CHARPOS (pos->string_pos) >= 0)
1524 {
1525 /* Recorded position is not in an overlay string, but in another
1526 string. This can only be a string from a `display' property.
1527 IT should already be filled with that string. */
1528 it->current.string_pos = pos->string_pos;
1529 xassert (STRINGP (it->string));
1530 }
1531
1532 /* Restore position in display vector translations or control
1533 character translations. */
1534 if (pos->dpvec_index >= 0)
1535 {
1536 /* This fills IT->dpvec. */
1537 get_next_display_element (it);
1538 xassert (it->dpvec && it->current.dpvec_index == 0);
1539 it->current.dpvec_index = pos->dpvec_index;
1540 }
1541
1542 CHECK_IT (it);
1543 }
1544
1545
1546 /* Initialize IT for stepping through current_buffer in window W
1547 starting at ROW->start. */
1548
1549 static void
1550 init_to_row_start (it, w, row)
1551 struct it *it;
1552 struct window *w;
1553 struct glyph_row *row;
1554 {
1555 init_from_display_pos (it, w, &row->start);
1556 it->continuation_lines_width = row->continuation_lines_width;
1557 CHECK_IT (it);
1558 }
1559
1560
1561 /* Initialize IT for stepping through current_buffer in window W
1562 starting in the line following ROW, i.e. starting at ROW->end. */
1563
1564 static void
1565 init_to_row_end (it, w, row)
1566 struct it *it;
1567 struct window *w;
1568 struct glyph_row *row;
1569 {
1570 init_from_display_pos (it, w, &row->end);
1571
1572 if (row->continued_p)
1573 it->continuation_lines_width = (row->continuation_lines_width
1574 + row->pixel_width);
1575 CHECK_IT (it);
1576 }
1577
1578
1579
1580 \f
1581 /***********************************************************************
1582 Text properties
1583 ***********************************************************************/
1584
1585 /* Called when IT reaches IT->stop_charpos. Handle text property and
1586 overlay changes. Set IT->stop_charpos to the next position where
1587 to stop. */
1588
1589 static void
1590 handle_stop (it)
1591 struct it *it;
1592 {
1593 enum prop_handled handled;
1594 int handle_overlay_change_p = 1;
1595 struct props *p;
1596
1597 it->dpvec = NULL;
1598 it->current.dpvec_index = -1;
1599
1600 do
1601 {
1602 handled = HANDLED_NORMALLY;
1603
1604 /* Call text property handlers. */
1605 for (p = it_props; p->handler; ++p)
1606 {
1607 handled = p->handler (it);
1608
1609 if (handled == HANDLED_RECOMPUTE_PROPS)
1610 break;
1611 else if (handled == HANDLED_RETURN)
1612 return;
1613 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
1614 handle_overlay_change_p = 0;
1615 }
1616
1617 if (handled != HANDLED_RECOMPUTE_PROPS)
1618 {
1619 /* Don't check for overlay strings below when set to deliver
1620 characters from a display vector. */
1621 if (it->method == next_element_from_display_vector)
1622 handle_overlay_change_p = 0;
1623
1624 /* Handle overlay changes. */
1625 if (handle_overlay_change_p)
1626 handled = handle_overlay_change (it);
1627
1628 /* Determine where to stop next. */
1629 if (handled == HANDLED_NORMALLY)
1630 compute_stop_pos (it);
1631 }
1632 }
1633 while (handled == HANDLED_RECOMPUTE_PROPS);
1634 }
1635
1636
1637 /* Compute IT->stop_charpos from text property and overlay change
1638 information for IT's current position. */
1639
1640 static void
1641 compute_stop_pos (it)
1642 struct it *it;
1643 {
1644 register INTERVAL iv, next_iv;
1645 Lisp_Object object, limit, position;
1646
1647 /* If nowhere else, stop at the end. */
1648 it->stop_charpos = it->end_charpos;
1649
1650 if (STRINGP (it->string))
1651 {
1652 /* Strings are usually short, so don't limit the search for
1653 properties. */
1654 object = it->string;
1655 limit = Qnil;
1656 XSETFASTINT (position, IT_STRING_CHARPOS (*it));
1657 }
1658 else
1659 {
1660 int charpos;
1661
1662 /* If next overlay change is in front of the current stop pos
1663 (which is IT->end_charpos), stop there. Note: value of
1664 next_overlay_change is point-max if no overlay change
1665 follows. */
1666 charpos = next_overlay_change (IT_CHARPOS (*it));
1667 if (charpos < it->stop_charpos)
1668 it->stop_charpos = charpos;
1669
1670 /* If showing the region, we have to stop at the region
1671 start or end because the face might change there. */
1672 if (it->region_beg_charpos > 0)
1673 {
1674 if (IT_CHARPOS (*it) < it->region_beg_charpos)
1675 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
1676 else if (IT_CHARPOS (*it) < it->region_end_charpos)
1677 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
1678 }
1679
1680 /* Set up variables for computing the stop position from text
1681 property changes. */
1682 XSETBUFFER (object, current_buffer);
1683 XSETFASTINT (limit, IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
1684 XSETFASTINT (position, IT_CHARPOS (*it));
1685
1686 }
1687
1688 /* Get the interval containing IT's position. Value is a null
1689 interval if there isn't such an interval. */
1690 iv = validate_interval_range (object, &position, &position, 0);
1691 if (!NULL_INTERVAL_P (iv))
1692 {
1693 Lisp_Object values_here[LAST_PROP_IDX];
1694 struct props *p;
1695
1696 /* Get properties here. */
1697 for (p = it_props; p->handler; ++p)
1698 values_here[p->idx] = textget (iv->plist, *p->name);
1699
1700 /* Look for an interval following iv that has different
1701 properties. */
1702 for (next_iv = next_interval (iv);
1703 (!NULL_INTERVAL_P (next_iv)
1704 && (NILP (limit)
1705 || XFASTINT (limit) > next_iv->position));
1706 next_iv = next_interval (next_iv))
1707 {
1708 for (p = it_props; p->handler; ++p)
1709 {
1710 Lisp_Object new_value;
1711
1712 new_value = textget (next_iv->plist, *p->name);
1713 if (!EQ (values_here[p->idx], new_value))
1714 break;
1715 }
1716
1717 if (p->handler)
1718 break;
1719 }
1720
1721 if (!NULL_INTERVAL_P (next_iv))
1722 {
1723 if (INTEGERP (limit)
1724 && next_iv->position >= XFASTINT (limit))
1725 /* No text property change up to limit. */
1726 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
1727 else
1728 /* Text properties change in next_iv. */
1729 it->stop_charpos = min (it->stop_charpos, next_iv->position);
1730 }
1731 }
1732
1733 xassert (STRINGP (it->string)
1734 || (it->stop_charpos >= BEGV
1735 && it->stop_charpos >= IT_CHARPOS (*it)));
1736 }
1737
1738
1739 /* Return the position of the next overlay change after POS in
1740 current_buffer. Value is point-max if no overlay change
1741 follows. This is like `next-overlay-change' but doesn't use
1742 xmalloc. */
1743
1744 static int
1745 next_overlay_change (pos)
1746 int pos;
1747 {
1748 int noverlays;
1749 int endpos;
1750 Lisp_Object *overlays;
1751 int len;
1752 int i;
1753
1754 /* Get all overlays at the given position. */
1755 len = 10;
1756 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1757 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1758 if (noverlays > len)
1759 {
1760 len = noverlays;
1761 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
1762 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL);
1763 }
1764
1765 /* If any of these overlays ends before endpos,
1766 use its ending point instead. */
1767 for (i = 0; i < noverlays; ++i)
1768 {
1769 Lisp_Object oend;
1770 int oendpos;
1771
1772 oend = OVERLAY_END (overlays[i]);
1773 oendpos = OVERLAY_POSITION (oend);
1774 endpos = min (endpos, oendpos);
1775 }
1776
1777 return endpos;
1778 }
1779
1780
1781 \f
1782 /***********************************************************************
1783 Fontification
1784 ***********************************************************************/
1785
1786 /* Handle changes in the `fontified' property of the current buffer by
1787 calling hook functions from Qfontification_functions to fontify
1788 regions of text. */
1789
1790 static enum prop_handled
1791 handle_fontified_prop (it)
1792 struct it *it;
1793 {
1794 Lisp_Object prop, pos;
1795 enum prop_handled handled = HANDLED_NORMALLY;
1796
1797 /* Get the value of the `fontified' property at IT's current buffer
1798 position. (The `fontified' property doesn't have a special
1799 meaning in strings.) If the value is nil, call functions from
1800 Qfontification_functions. */
1801 if (!STRINGP (it->string)
1802 && it->s == NULL
1803 && !NILP (Vfontification_functions)
1804 && (pos = make_number (IT_CHARPOS (*it)),
1805 prop = Fget_char_property (pos, Qfontified, Qnil),
1806 NILP (prop)))
1807 {
1808 Lisp_Object args[2];
1809
1810 /* Run the hook functions. */
1811 args[0] = Qfontification_functions;
1812 args[1] = pos;
1813 Frun_hook_with_args (2, args);
1814
1815 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1816 something. This avoids an endless loop if they failed to
1817 fontify the text for which reason ever. */
1818 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
1819 handled = HANDLED_RECOMPUTE_PROPS;
1820 }
1821
1822 return handled;
1823 }
1824
1825
1826 \f
1827 /***********************************************************************
1828 Faces
1829 ***********************************************************************/
1830
1831 /* Set up iterator IT from face properties at its current position.
1832 Called from handle_stop. */
1833
1834 static enum prop_handled
1835 handle_face_prop (it)
1836 struct it *it;
1837 {
1838 int new_face_id, next_stop;
1839
1840 if (!STRINGP (it->string))
1841 {
1842 new_face_id
1843 = face_at_buffer_position (it->w,
1844 IT_CHARPOS (*it),
1845 it->region_beg_charpos,
1846 it->region_end_charpos,
1847 &next_stop,
1848 (IT_CHARPOS (*it)
1849 + TEXT_PROP_DISTANCE_LIMIT),
1850 0);
1851
1852 /* Is this a start of a run of characters with box face?
1853 Caveat: this can be called for a freshly initialized
1854 iterator; face_id is -1 is this case. We know that the new
1855 face will not change until limit, i.e. if the new face has a
1856 box, all characters up to limit will have one. But, as
1857 usual, we don't know whether limit is really the end. */
1858 if (new_face_id != it->face_id)
1859 {
1860 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1861
1862 /* If new face has a box but old face has not, this is
1863 the start of a run of characters with box, i.e. it has
1864 a shadow on the left side. The value of face_id of the
1865 iterator will be -1 if this is the initial call that gets
1866 the face. In this case, we have to look in front of IT's
1867 position and see whether there is a face != new_face_id. */
1868 it->start_of_box_run_p
1869 = (new_face->box != FACE_NO_BOX
1870 && (it->face_id >= 0
1871 || IT_CHARPOS (*it) == BEG
1872 || new_face_id != face_before_it_pos (it)));
1873 it->face_box_p = new_face->box != FACE_NO_BOX;
1874 }
1875 }
1876 else
1877 {
1878 new_face_id
1879 = face_at_string_position (it->w,
1880 it->string,
1881 IT_STRING_CHARPOS (*it),
1882 (it->current.overlay_string_index >= 0
1883 ? IT_CHARPOS (*it)
1884 : 0),
1885 it->region_beg_charpos,
1886 it->region_end_charpos,
1887 &next_stop,
1888 it->base_face_id);
1889
1890 #if 0 /* This shouldn't be neccessary. Let's check it. */
1891 /* If IT is used to display a mode line we would really like to
1892 use the mode line face instead of the frame's default face. */
1893 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
1894 && new_face_id == DEFAULT_FACE_ID)
1895 new_face_id = MODE_LINE_FACE_ID;
1896 #endif
1897
1898 /* Is this a start of a run of characters with box? Caveat:
1899 this can be called for a freshly allocated iterator; face_id
1900 is -1 is this case. We know that the new face will not
1901 change until the next check pos, i.e. if the new face has a
1902 box, all characters up to that position will have a
1903 box. But, as usual, we don't know whether that position
1904 is really the end. */
1905 if (new_face_id != it->face_id)
1906 {
1907 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
1908 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
1909
1910 /* If new face has a box but old face hasn't, this is the
1911 start of a run of characters with box, i.e. it has a
1912 shadow on the left side. */
1913 it->start_of_box_run_p
1914 = new_face->box && (old_face == NULL || !old_face->box);
1915 it->face_box_p = new_face->box != FACE_NO_BOX;
1916 }
1917 }
1918
1919 it->face_id = new_face_id;
1920 return HANDLED_NORMALLY;
1921 }
1922
1923
1924 /* Compute the face one character before or after the current position
1925 of IT. BEFORE_P non-zero means get the face in front of IT's
1926 position. Value is the id of the face. */
1927
1928 static int
1929 face_before_or_after_it_pos (it, before_p)
1930 struct it *it;
1931 int before_p;
1932 {
1933 int face_id, limit;
1934 int next_check_charpos;
1935 struct text_pos pos;
1936
1937 xassert (it->s == NULL);
1938
1939 if (STRINGP (it->string))
1940 {
1941 /* No face change past the end of the string (for the case
1942 we are padding with spaces). No face change before the
1943 string start. */
1944 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size
1945 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
1946 return it->face_id;
1947
1948 /* Set pos to the position before or after IT's current position. */
1949 if (before_p)
1950 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
1951 else
1952 /* For composition, we must check the character after the
1953 composition. */
1954 pos = (it->what == IT_COMPOSITION
1955 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
1956 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
1957
1958 /* Get the face for ASCII, or unibyte. */
1959 face_id
1960 = face_at_string_position (it->w,
1961 it->string,
1962 CHARPOS (pos),
1963 (it->current.overlay_string_index >= 0
1964 ? IT_CHARPOS (*it)
1965 : 0),
1966 it->region_beg_charpos,
1967 it->region_end_charpos,
1968 &next_check_charpos,
1969 it->base_face_id);
1970
1971 /* Correct the face for charsets different from ASCII. Do it
1972 for the multibyte case only. The face returned above is
1973 suitable for unibyte text if IT->string is unibyte. */
1974 if (STRING_MULTIBYTE (it->string))
1975 {
1976 unsigned char *p = XSTRING (it->string)->data + BYTEPOS (pos);
1977 int rest = STRING_BYTES (XSTRING (it->string)) - BYTEPOS (pos);
1978 int c, len;
1979 struct face *face = FACE_FROM_ID (it->f, face_id);
1980
1981 c = string_char_and_length (p, rest, &len);
1982 face_id = FACE_FOR_CHAR (it->f, face, c);
1983 }
1984 }
1985 else
1986 {
1987 if ((IT_CHARPOS (*it) >= ZV && !before_p)
1988 || (IT_CHARPOS (*it) <= BEGV && before_p))
1989 return it->face_id;
1990
1991 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
1992 pos = it->current.pos;
1993
1994 if (before_p)
1995 DEC_TEXT_POS (pos, it->multibyte_p);
1996 else
1997 {
1998 if (it->what == IT_COMPOSITION)
1999 /* For composition, we must check the position after the
2000 composition. */
2001 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2002 else
2003 INC_TEXT_POS (pos, it->multibyte_p);
2004 }
2005 /* Determine face for CHARSET_ASCII, or unibyte. */
2006 face_id = face_at_buffer_position (it->w,
2007 CHARPOS (pos),
2008 it->region_beg_charpos,
2009 it->region_end_charpos,
2010 &next_check_charpos,
2011 limit, 0);
2012
2013 /* Correct the face for charsets different from ASCII. Do it
2014 for the multibyte case only. The face returned above is
2015 suitable for unibyte text if current_buffer is unibyte. */
2016 if (it->multibyte_p)
2017 {
2018 int c = FETCH_MULTIBYTE_CHAR (CHARPOS (pos));
2019 struct face *face = FACE_FROM_ID (it->f, face_id);
2020 face_id = FACE_FOR_CHAR (it->f, face, c);
2021 }
2022 }
2023
2024 return face_id;
2025 }
2026
2027
2028 \f
2029 /***********************************************************************
2030 Invisible text
2031 ***********************************************************************/
2032
2033 /* Set up iterator IT from invisible properties at its current
2034 position. Called from handle_stop. */
2035
2036 static enum prop_handled
2037 handle_invisible_prop (it)
2038 struct it *it;
2039 {
2040 enum prop_handled handled = HANDLED_NORMALLY;
2041
2042 if (STRINGP (it->string))
2043 {
2044 extern Lisp_Object Qinvisible;
2045 Lisp_Object prop, end_charpos, limit, charpos;
2046
2047 /* Get the value of the invisible text property at the
2048 current position. Value will be nil if there is no such
2049 property. */
2050 XSETFASTINT (charpos, IT_STRING_CHARPOS (*it));
2051 prop = Fget_text_property (charpos, Qinvisible, it->string);
2052
2053 if (!NILP (prop)
2054 && IT_STRING_CHARPOS (*it) < it->end_charpos)
2055 {
2056 handled = HANDLED_RECOMPUTE_PROPS;
2057
2058 /* Get the position at which the next change of the
2059 invisible text property can be found in IT->string.
2060 Value will be nil if the property value is the same for
2061 all the rest of IT->string. */
2062 XSETINT (limit, XSTRING (it->string)->size);
2063 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
2064 it->string, limit);
2065
2066 /* Text at current position is invisible. The next
2067 change in the property is at position end_charpos.
2068 Move IT's current position to that position. */
2069 if (INTEGERP (end_charpos)
2070 && XFASTINT (end_charpos) < XFASTINT (limit))
2071 {
2072 struct text_pos old;
2073 old = it->current.string_pos;
2074 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
2075 compute_string_pos (&it->current.string_pos, old, it->string);
2076 }
2077 else
2078 {
2079 /* The rest of the string is invisible. If this is an
2080 overlay string, proceed with the next overlay string
2081 or whatever comes and return a character from there. */
2082 if (it->current.overlay_string_index >= 0)
2083 {
2084 next_overlay_string (it);
2085 /* Don't check for overlay strings when we just
2086 finished processing them. */
2087 handled = HANDLED_OVERLAY_STRING_CONSUMED;
2088 }
2089 else
2090 {
2091 struct Lisp_String *s = XSTRING (it->string);
2092 IT_STRING_CHARPOS (*it) = s->size;
2093 IT_STRING_BYTEPOS (*it) = STRING_BYTES (s);
2094 }
2095 }
2096 }
2097 }
2098 else
2099 {
2100 int visible_p, newpos, next_stop;
2101 Lisp_Object pos, prop;
2102
2103 /* First of all, is there invisible text at this position? */
2104 XSETFASTINT (pos, IT_CHARPOS (*it));
2105 prop = Fget_char_property (pos, Qinvisible, it->window);
2106
2107 /* If we are on invisible text, skip over it. */
2108 if (TEXT_PROP_MEANS_INVISIBLE (prop)
2109 && IT_CHARPOS (*it) < it->end_charpos)
2110 {
2111 /* Record whether we have to display an ellipsis for the
2112 invisible text. */
2113 int display_ellipsis_p
2114 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
2115
2116 handled = HANDLED_RECOMPUTE_PROPS;
2117
2118 /* Loop skipping over invisible text. The loop is left at
2119 ZV or with IT on the first char being visible again. */
2120 do
2121 {
2122 /* Try to skip some invisible text. Return value is the
2123 position reached which can be equal to IT's position
2124 if there is nothing invisible here. This skips both
2125 over invisible text properties and overlays with
2126 invisible property. */
2127 newpos = skip_invisible (IT_CHARPOS (*it),
2128 &next_stop, ZV, it->window);
2129
2130 /* If we skipped nothing at all we weren't at invisible
2131 text in the first place. If everything to the end of
2132 the buffer was skipped, end the loop. */
2133 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
2134 visible_p = 1;
2135 else
2136 {
2137 /* We skipped some characters but not necessarily
2138 all there are. Check if we ended up on visible
2139 text. Fget_char_property returns the property of
2140 the char before the given position, i.e. if we
2141 get visible_p = 1, this means that the char at
2142 newpos is visible. */
2143 XSETFASTINT (pos, newpos);
2144 prop = Fget_char_property (pos, Qinvisible, it->window);
2145 visible_p = !TEXT_PROP_MEANS_INVISIBLE (prop);
2146 }
2147
2148 /* If we ended up on invisible text, proceed to
2149 skip starting with next_stop. */
2150 if (!visible_p)
2151 IT_CHARPOS (*it) = next_stop;
2152 }
2153 while (!visible_p);
2154
2155 /* The position newpos is now either ZV or on visible text. */
2156 IT_CHARPOS (*it) = newpos;
2157 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
2158
2159 /* Maybe return `...' next for the end of the invisible text. */
2160 if (display_ellipsis_p)
2161 {
2162 if (it->dp
2163 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
2164 {
2165 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
2166 it->dpvec = v->contents;
2167 it->dpend = v->contents + v->size;
2168 }
2169 else
2170 {
2171 /* Default `...'. */
2172 it->dpvec = default_invis_vector;
2173 it->dpend = default_invis_vector + 3;
2174 }
2175
2176 /* The ellipsis display does not replace the display of
2177 the character at the new position. Indicate this by
2178 setting IT->dpvec_char_len to zero. */
2179 it->dpvec_char_len = 0;
2180
2181 it->current.dpvec_index = 0;
2182 it->method = next_element_from_display_vector;
2183 }
2184 }
2185 }
2186
2187 return handled;
2188 }
2189
2190
2191 \f
2192 /***********************************************************************
2193 'display' property
2194 ***********************************************************************/
2195
2196 /* Set up iterator IT from `display' property at its current position.
2197 Called from handle_stop. */
2198
2199 static enum prop_handled
2200 handle_display_prop (it)
2201 struct it *it;
2202 {
2203 Lisp_Object prop, object;
2204 struct text_pos *position;
2205 int space_or_image_found_p;
2206
2207 if (STRINGP (it->string))
2208 {
2209 object = it->string;
2210 position = &it->current.string_pos;
2211 }
2212 else
2213 {
2214 object = Qnil;
2215 position = &it->current.pos;
2216 }
2217
2218 /* Reset those iterator values set from display property values. */
2219 it->font_height = Qnil;
2220 it->space_width = Qnil;
2221 it->voffset = 0;
2222
2223 /* We don't support recursive `display' properties, i.e. string
2224 values that have a string `display' property, that have a string
2225 `display' property etc. */
2226 if (!it->string_from_display_prop_p)
2227 it->area = TEXT_AREA;
2228
2229 prop = Fget_char_property (make_number (position->charpos),
2230 Qdisplay, object);
2231 if (NILP (prop))
2232 return HANDLED_NORMALLY;
2233
2234 space_or_image_found_p = 0;
2235 if (CONSP (prop)
2236 && CONSP (XCAR (prop))
2237 && !EQ (Qmargin, XCAR (XCAR (prop))))
2238 {
2239 /* A list of sub-properties. */
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 starting
2266 at START_POS in OBJECT. */
2267
2268 static struct text_pos
2269 display_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 end = next_single_char_property_change (make_number (CHARPOS (start_pos)),
2278 Qdisplay, object, Qnil);
2279 CHARPOS (end_pos) = XFASTINT (end);
2280 if (STRINGP (object))
2281 compute_string_pos (&end_pos, start_pos, it->string);
2282 else
2283 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
2284
2285 return end_pos;
2286 }
2287
2288
2289 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2290 is the object in which the `display' property was found. *POSITION
2291 is the position at which it was found.
2292
2293 If PROP is a `space' or `image' sub-property, set *POSITION to the
2294 end position of the `display' property.
2295
2296 Value is non-zero if a `space' or `image' property value was found. */
2297
2298 static int
2299 handle_single_display_prop (it, prop, object, position)
2300 struct it *it;
2301 Lisp_Object prop;
2302 Lisp_Object object;
2303 struct text_pos *position;
2304 {
2305 Lisp_Object value;
2306 int space_or_image_found_p = 0;
2307
2308 Lisp_Object form;
2309
2310 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
2311 evaluated. If the result is nil, VALUE is ignored. */
2312 form = Qt;
2313 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
2314 {
2315 prop = XCDR (prop);
2316 if (!CONSP (prop))
2317 return 0;
2318 form = XCAR (prop);
2319 prop = XCDR (prop);
2320 }
2321
2322 if (!NILP (form) && !EQ (form, Qt))
2323 {
2324 struct gcpro gcpro1;
2325 struct text_pos end_pos, pt;
2326
2327 GCPRO1 (form);
2328 end_pos = display_prop_end (it, object, *position);
2329
2330 /* Temporarily set point to the end position, and then evaluate
2331 the form. This makes `(eolp)' work as FORM. */
2332 if (BUFFERP (object))
2333 {
2334 CHARPOS (pt) = PT;
2335 BYTEPOS (pt) = PT_BYTE;
2336 TEMP_SET_PT_BOTH (CHARPOS (end_pos), BYTEPOS (end_pos));
2337 }
2338
2339 form = eval_form (form);
2340
2341 if (BUFFERP (object))
2342 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
2343 UNGCPRO;
2344 }
2345
2346 if (NILP (form))
2347 return 0;
2348
2349 if (CONSP (prop)
2350 && EQ (XCAR (prop), Qheight)
2351 && CONSP (XCDR (prop)))
2352 {
2353 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2354 return 0;
2355
2356 /* `(height HEIGHT)'. */
2357 it->font_height = XCAR (XCDR (prop));
2358 if (!NILP (it->font_height))
2359 {
2360 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2361 int new_height = -1;
2362
2363 if (CONSP (it->font_height)
2364 && (EQ (XCAR (it->font_height), Qplus)
2365 || EQ (XCAR (it->font_height), Qminus))
2366 && CONSP (XCDR (it->font_height))
2367 && INTEGERP (XCAR (XCDR (it->font_height))))
2368 {
2369 /* `(+ N)' or `(- N)' where N is an integer. */
2370 int steps = XINT (XCAR (XCDR (it->font_height)));
2371 if (EQ (XCAR (it->font_height), Qplus))
2372 steps = - steps;
2373 it->face_id = smaller_face (it->f, it->face_id, steps);
2374 }
2375 else if (SYMBOLP (it->font_height))
2376 {
2377 /* Call function with current height as argument.
2378 Value is the new height. */
2379 Lisp_Object form, height;
2380 struct gcpro gcpro1;
2381
2382 height = face->lface[LFACE_HEIGHT_INDEX];
2383 form = Fcons (it->font_height, Fcons (height, Qnil));
2384 GCPRO1 (form);
2385 height = eval_form (form);
2386 if (NUMBERP (height))
2387 new_height = XFLOATINT (height);
2388 UNGCPRO;
2389 }
2390 else if (NUMBERP (it->font_height))
2391 {
2392 /* Value is a multiple of the canonical char height. */
2393 struct face *face;
2394
2395 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
2396 new_height = (XFLOATINT (it->font_height)
2397 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
2398 }
2399 else
2400 {
2401 /* Evaluate IT->font_height with `height' bound to the
2402 current specified height to get the new height. */
2403 Lisp_Object value;
2404 int count = specpdl_ptr - specpdl;
2405
2406 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
2407 value = eval_form (it->font_height);
2408 unbind_to (count, Qnil);
2409
2410 if (NUMBERP (value))
2411 new_height = XFLOATINT (value);
2412 }
2413
2414 if (new_height > 0)
2415 it->face_id = face_with_height (it->f, it->face_id, new_height);
2416 }
2417 }
2418 else if (CONSP (prop)
2419 && EQ (XCAR (prop), Qspace_width)
2420 && CONSP (XCDR (prop)))
2421 {
2422 /* `(space_width WIDTH)'. */
2423 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2424 return 0;
2425
2426 value = XCAR (XCDR (prop));
2427 if (NUMBERP (value) && XFLOATINT (value) > 0)
2428 it->space_width = value;
2429 }
2430 else if (CONSP (prop)
2431 && EQ (XCAR (prop), Qraise)
2432 && CONSP (XCDR (prop)))
2433 {
2434 /* `(raise FACTOR)'. */
2435 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
2436 return 0;
2437
2438 #ifdef HAVE_WINDOW_SYSTEM
2439 value = XCAR (XCDR (prop));
2440 if (NUMBERP (value))
2441 {
2442 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2443 it->voffset = - (XFLOATINT (value)
2444 * (FONT_HEIGHT (face->font)));
2445 }
2446 #endif /* HAVE_WINDOW_SYSTEM */
2447 }
2448 else if (!it->string_from_display_prop_p)
2449 {
2450 /* `((margin left-margin) VALUE)' or `((margin right-margin)
2451 VALUE) or `((margin nil) VALUE)' or VALUE. */
2452 Lisp_Object location, value;
2453 struct text_pos start_pos;
2454 int valid_p;
2455
2456 /* Characters having this form of property are not displayed, so
2457 we have to find the end of the property. */
2458 start_pos = *position;
2459 *position = display_prop_end (it, object, start_pos);
2460 value = Qnil;
2461
2462 /* Let's stop at the new position and assume that all
2463 text properties change there. */
2464 it->stop_charpos = position->charpos;
2465
2466 location = Qunbound;
2467 if (CONSP (prop) && CONSP (XCAR (prop)))
2468 {
2469 Lisp_Object tem;
2470
2471 value = XCDR (prop);
2472 if (CONSP (value))
2473 value = XCAR (value);
2474
2475 tem = XCAR (prop);
2476 if (EQ (XCAR (tem), Qmargin)
2477 && (tem = XCDR (tem),
2478 tem = CONSP (tem) ? XCAR (tem) : Qnil,
2479 (NILP (tem)
2480 || EQ (tem, Qleft_margin)
2481 || EQ (tem, Qright_margin))))
2482 location = tem;
2483 }
2484
2485 if (EQ (location, Qunbound))
2486 {
2487 location = Qnil;
2488 value = prop;
2489 }
2490
2491 #ifdef HAVE_WINDOW_SYSTEM
2492 if (FRAME_TERMCAP_P (it->f))
2493 valid_p = STRINGP (value);
2494 else
2495 valid_p = (STRINGP (value)
2496 || (CONSP (value) && EQ (XCAR (value), Qspace))
2497 || valid_image_p (value));
2498 #else /* not HAVE_WINDOW_SYSTEM */
2499 valid_p = STRINGP (value);
2500 #endif /* not HAVE_WINDOW_SYSTEM */
2501
2502 if ((EQ (location, Qleft_margin)
2503 || EQ (location, Qright_margin)
2504 || NILP (location))
2505 && valid_p)
2506 {
2507 space_or_image_found_p = 1;
2508
2509 /* Save current settings of IT so that we can restore them
2510 when we are finished with the glyph property value. */
2511 push_it (it);
2512
2513 if (NILP (location))
2514 it->area = TEXT_AREA;
2515 else if (EQ (location, Qleft_margin))
2516 it->area = LEFT_MARGIN_AREA;
2517 else
2518 it->area = RIGHT_MARGIN_AREA;
2519
2520 if (STRINGP (value))
2521 {
2522 it->string = value;
2523 it->multibyte_p = STRING_MULTIBYTE (it->string);
2524 it->current.overlay_string_index = -1;
2525 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2526 it->end_charpos = it->string_nchars
2527 = XSTRING (it->string)->size;
2528 it->method = next_element_from_string;
2529 it->stop_charpos = 0;
2530 it->string_from_display_prop_p = 1;
2531 }
2532 else if (CONSP (value) && EQ (XCAR (value), Qspace))
2533 {
2534 it->method = next_element_from_stretch;
2535 it->object = value;
2536 it->current.pos = it->position = start_pos;
2537 }
2538 #ifdef HAVE_WINDOW_SYSTEM
2539 else
2540 {
2541 it->what = IT_IMAGE;
2542 it->image_id = lookup_image (it->f, value);
2543 it->position = start_pos;
2544 it->object = NILP (object) ? it->w->buffer : object;
2545 it->method = next_element_from_image;
2546
2547 /* Say that we haven't consumed the characters with
2548 `display' property yet. The call to pop_it in
2549 set_iterator_to_next will clean this up. */
2550 *position = start_pos;
2551 }
2552 #endif /* HAVE_WINDOW_SYSTEM */
2553 }
2554 else
2555 /* Invalid property or property not supported. Restore
2556 the position to what it was before. */
2557 *position = start_pos;
2558 }
2559
2560 return space_or_image_found_p;
2561 }
2562
2563
2564 \f
2565 /***********************************************************************
2566 `composition' property
2567 ***********************************************************************/
2568
2569 /* Set up iterator IT from `composition' property at its current
2570 position. Called from handle_stop. */
2571
2572 static enum prop_handled
2573 handle_composition_prop (it)
2574 struct it *it;
2575 {
2576 Lisp_Object prop, string;
2577 int pos, pos_byte, end;
2578 enum prop_handled handled = HANDLED_NORMALLY;
2579
2580 if (STRINGP (it->string))
2581 {
2582 pos = IT_STRING_CHARPOS (*it);
2583 pos_byte = IT_STRING_BYTEPOS (*it);
2584 string = it->string;
2585 }
2586 else
2587 {
2588 pos = IT_CHARPOS (*it);
2589 pos_byte = IT_BYTEPOS (*it);
2590 string = Qnil;
2591 }
2592
2593 /* If there's a valid composition and point is not inside of the
2594 composition (in the case that the composition is from the current
2595 buffer), draw a glyph composed from the composition components. */
2596 if (find_composition (pos, -1, &pos, &end, &prop, string)
2597 && COMPOSITION_VALID_P (pos, end, prop)
2598 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
2599 {
2600 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
2601
2602 if (id >= 0)
2603 {
2604 it->method = next_element_from_composition;
2605 it->cmp_id = id;
2606 it->cmp_len = COMPOSITION_LENGTH (prop);
2607 /* For a terminal, draw only the first character of the
2608 components. */
2609 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
2610 it->len = (STRINGP (it->string)
2611 ? string_char_to_byte (it->string, end)
2612 : CHAR_TO_BYTE (end)) - pos_byte;
2613 it->stop_charpos = end;
2614 handled = HANDLED_RETURN;
2615 }
2616 }
2617
2618 return handled;
2619 }
2620
2621
2622 \f
2623 /***********************************************************************
2624 Overlay strings
2625 ***********************************************************************/
2626
2627 /* The following structure is used to record overlay strings for
2628 later sorting in load_overlay_strings. */
2629
2630 struct overlay_entry
2631 {
2632 Lisp_Object string;
2633 int priority;
2634 int after_string_p;
2635 };
2636
2637
2638 /* Set up iterator IT from overlay strings at its current position.
2639 Called from handle_stop. */
2640
2641 static enum prop_handled
2642 handle_overlay_change (it)
2643 struct it *it;
2644 {
2645 /* Overlays are handled in current_buffer only. */
2646 if (STRINGP (it->string))
2647 return HANDLED_NORMALLY;
2648 else
2649 return (get_overlay_strings (it)
2650 ? HANDLED_RECOMPUTE_PROPS
2651 : HANDLED_NORMALLY);
2652 }
2653
2654
2655 /* Set up the next overlay string for delivery by IT, if there is an
2656 overlay string to deliver. Called by set_iterator_to_next when the
2657 end of the current overlay string is reached. If there are more
2658 overlay strings to display, IT->string and
2659 IT->current.overlay_string_index are set appropriately here.
2660 Otherwise IT->string is set to nil. */
2661
2662 static void
2663 next_overlay_string (it)
2664 struct it *it;
2665 {
2666 ++it->current.overlay_string_index;
2667 if (it->current.overlay_string_index == it->n_overlay_strings)
2668 {
2669 /* No more overlay strings. Restore IT's settings to what
2670 they were before overlay strings were processed, and
2671 continue to deliver from current_buffer. */
2672 pop_it (it);
2673 xassert (it->stop_charpos >= BEGV
2674 && it->stop_charpos <= it->end_charpos);
2675 it->string = Qnil;
2676 it->current.overlay_string_index = -1;
2677 SET_TEXT_POS (it->current.string_pos, -1, -1);
2678 it->n_overlay_strings = 0;
2679 it->method = next_element_from_buffer;
2680 }
2681 else
2682 {
2683 /* There are more overlay strings to process. If
2684 IT->current.overlay_string_index has advanced to a position
2685 where we must load IT->overlay_strings with more strings, do
2686 it. */
2687 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
2688
2689 if (it->current.overlay_string_index && i == 0)
2690 load_overlay_strings (it);
2691
2692 /* Initialize IT to deliver display elements from the overlay
2693 string. */
2694 it->string = it->overlay_strings[i];
2695 it->multibyte_p = STRING_MULTIBYTE (it->string);
2696 SET_TEXT_POS (it->current.string_pos, 0, 0);
2697 it->method = next_element_from_string;
2698 it->stop_charpos = 0;
2699 }
2700
2701 CHECK_IT (it);
2702 }
2703
2704
2705 /* Compare two overlay_entry structures E1 and E2. Used as a
2706 comparison function for qsort in load_overlay_strings. Overlay
2707 strings for the same position are sorted so that
2708
2709 1. All after-strings come in front of before-strings.
2710
2711 2. Within after-strings, strings are sorted so that overlay strings
2712 from overlays with higher priorities come first.
2713
2714 2. Within before-strings, strings are sorted so that overlay
2715 strings from overlays with higher priorities come last.
2716
2717 Value is analogous to strcmp. */
2718
2719
2720 static int
2721 compare_overlay_entries (e1, e2)
2722 void *e1, *e2;
2723 {
2724 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
2725 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
2726 int result;
2727
2728 if (entry1->after_string_p != entry2->after_string_p)
2729 /* Let after-strings appear in front of before-strings. */
2730 result = entry1->after_string_p ? -1 : 1;
2731 else if (entry1->after_string_p)
2732 /* After-strings sorted in order of decreasing priority. */
2733 result = entry2->priority - entry1->priority;
2734 else
2735 /* Before-strings sorted in order of increasing priority. */
2736 result = entry1->priority - entry2->priority;
2737
2738 return result;
2739 }
2740
2741
2742 /* Load the vector IT->overlay_strings with overlay strings from IT's
2743 current buffer position. Set IT->n_overlays to the total number of
2744 overlay strings found.
2745
2746 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2747 a time. On entry into load_overlay_strings,
2748 IT->current.overlay_string_index gives the number of overlay
2749 strings that have already been loaded by previous calls to this
2750 function.
2751
2752 Overlay strings are sorted so that after-string strings come in
2753 front of before-string strings. Within before and after-strings,
2754 strings are sorted by overlay priority. See also function
2755 compare_overlay_entries. */
2756
2757 static void
2758 load_overlay_strings (it)
2759 struct it *it;
2760 {
2761 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
2762 Lisp_Object ov, overlay, window, str;
2763 int start, end;
2764 int size = 20;
2765 int n = 0, i, j;
2766 struct overlay_entry *entries
2767 = (struct overlay_entry *) alloca (size * sizeof *entries);
2768
2769 /* Append the overlay string STRING of overlay OVERLAY to vector
2770 `entries' which has size `size' and currently contains `n'
2771 elements. AFTER_P non-zero means STRING is an after-string of
2772 OVERLAY. */
2773 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2774 do \
2775 { \
2776 Lisp_Object priority; \
2777 \
2778 if (n == size) \
2779 { \
2780 int new_size = 2 * size; \
2781 struct overlay_entry *old = entries; \
2782 entries = \
2783 (struct overlay_entry *) alloca (new_size \
2784 * sizeof *entries); \
2785 bcopy (old, entries, size * sizeof *entries); \
2786 size = new_size; \
2787 } \
2788 \
2789 entries[n].string = (STRING); \
2790 priority = Foverlay_get ((OVERLAY), Qpriority); \
2791 entries[n].priority \
2792 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2793 entries[n].after_string_p = (AFTER_P); \
2794 ++n; \
2795 } \
2796 while (0)
2797
2798 /* Process overlay before the overlay center. */
2799 for (ov = current_buffer->overlays_before;
2800 CONSP (ov);
2801 ov = XCDR (ov))
2802 {
2803 overlay = XCAR (ov);
2804 xassert (OVERLAYP (overlay));
2805 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2806 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2807
2808 if (end < IT_CHARPOS (*it))
2809 break;
2810
2811 /* Skip this overlay if it doesn't start or end at IT's current
2812 position. */
2813 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2814 continue;
2815
2816 /* Skip this overlay if it doesn't apply to IT->w. */
2817 window = Foverlay_get (overlay, Qwindow);
2818 if (WINDOWP (window) && XWINDOW (window) != it->w)
2819 continue;
2820
2821 /* If overlay has a non-empty before-string, record it. */
2822 if (start == IT_CHARPOS (*it)
2823 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2824 && XSTRING (str)->size)
2825 RECORD_OVERLAY_STRING (overlay, str, 0);
2826
2827 /* If overlay has a non-empty after-string, record it. */
2828 if (end == IT_CHARPOS (*it)
2829 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2830 && XSTRING (str)->size)
2831 RECORD_OVERLAY_STRING (overlay, str, 1);
2832 }
2833
2834 /* Process overlays after the overlay center. */
2835 for (ov = current_buffer->overlays_after;
2836 CONSP (ov);
2837 ov = XCDR (ov))
2838 {
2839 overlay = XCAR (ov);
2840 xassert (OVERLAYP (overlay));
2841 start = OVERLAY_POSITION (OVERLAY_START (overlay));
2842 end = OVERLAY_POSITION (OVERLAY_END (overlay));
2843
2844 if (start > IT_CHARPOS (*it))
2845 break;
2846
2847 /* Skip this overlay if it doesn't start or end at IT's current
2848 position. */
2849 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
2850 continue;
2851
2852 /* Skip this overlay if it doesn't apply to IT->w. */
2853 window = Foverlay_get (overlay, Qwindow);
2854 if (WINDOWP (window) && XWINDOW (window) != it->w)
2855 continue;
2856
2857 /* If overlay has a non-empty before-string, record it. */
2858 if (start == IT_CHARPOS (*it)
2859 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
2860 && XSTRING (str)->size)
2861 RECORD_OVERLAY_STRING (overlay, str, 0);
2862
2863 /* If overlay has a non-empty after-string, record it. */
2864 if (end == IT_CHARPOS (*it)
2865 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
2866 && XSTRING (str)->size)
2867 RECORD_OVERLAY_STRING (overlay, str, 1);
2868 }
2869
2870 #undef RECORD_OVERLAY_STRING
2871
2872 /* Sort entries. */
2873 qsort (entries, n, sizeof *entries, compare_overlay_entries);
2874
2875 /* Record the total number of strings to process. */
2876 it->n_overlay_strings = n;
2877
2878 /* IT->current.overlay_string_index is the number of overlay strings
2879 that have already been consumed by IT. Copy some of the
2880 remaining overlay strings to IT->overlay_strings. */
2881 i = 0;
2882 j = it->current.overlay_string_index;
2883 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
2884 it->overlay_strings[i++] = entries[j++].string;
2885
2886 CHECK_IT (it);
2887 }
2888
2889
2890 /* Get the first chunk of overlay strings at IT's current buffer
2891 position. Value is non-zero if at least one overlay string was
2892 found. */
2893
2894 static int
2895 get_overlay_strings (it)
2896 struct it *it;
2897 {
2898 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2899 process. This fills IT->overlay_strings with strings, and sets
2900 IT->n_overlay_strings to the total number of strings to process.
2901 IT->pos.overlay_string_index has to be set temporarily to zero
2902 because load_overlay_strings needs this; it must be set to -1
2903 when no overlay strings are found because a zero value would
2904 indicate a position in the first overlay string. */
2905 it->current.overlay_string_index = 0;
2906 load_overlay_strings (it);
2907
2908 /* If we found overlay strings, set up IT to deliver display
2909 elements from the first one. Otherwise set up IT to deliver
2910 from current_buffer. */
2911 if (it->n_overlay_strings)
2912 {
2913 /* Make sure we know settings in current_buffer, so that we can
2914 restore meaningful values when we're done with the overlay
2915 strings. */
2916 compute_stop_pos (it);
2917 xassert (it->face_id >= 0);
2918
2919 /* Save IT's settings. They are restored after all overlay
2920 strings have been processed. */
2921 xassert (it->sp == 0);
2922 push_it (it);
2923
2924 /* Set up IT to deliver display elements from the first overlay
2925 string. */
2926 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
2927 it->stop_charpos = 0;
2928 it->string = it->overlay_strings[0];
2929 it->multibyte_p = STRING_MULTIBYTE (it->string);
2930 xassert (STRINGP (it->string));
2931 it->method = next_element_from_string;
2932 }
2933 else
2934 {
2935 it->string = Qnil;
2936 it->current.overlay_string_index = -1;
2937 it->method = next_element_from_buffer;
2938 }
2939
2940 CHECK_IT (it);
2941
2942 /* Value is non-zero if we found at least one overlay string. */
2943 return STRINGP (it->string);
2944 }
2945
2946
2947 \f
2948 /***********************************************************************
2949 Saving and restoring state
2950 ***********************************************************************/
2951
2952 /* Save current settings of IT on IT->stack. Called, for example,
2953 before setting up IT for an overlay string, to be able to restore
2954 IT's settings to what they were after the overlay string has been
2955 processed. */
2956
2957 static void
2958 push_it (it)
2959 struct it *it;
2960 {
2961 struct iterator_stack_entry *p;
2962
2963 xassert (it->sp < 2);
2964 p = it->stack + it->sp;
2965
2966 p->stop_charpos = it->stop_charpos;
2967 xassert (it->face_id >= 0);
2968 p->face_id = it->face_id;
2969 p->string = it->string;
2970 p->pos = it->current;
2971 p->end_charpos = it->end_charpos;
2972 p->string_nchars = it->string_nchars;
2973 p->area = it->area;
2974 p->multibyte_p = it->multibyte_p;
2975 p->space_width = it->space_width;
2976 p->font_height = it->font_height;
2977 p->voffset = it->voffset;
2978 p->string_from_display_prop_p = it->string_from_display_prop_p;
2979 ++it->sp;
2980 }
2981
2982
2983 /* Restore IT's settings from IT->stack. Called, for example, when no
2984 more overlay strings must be processed, and we return to delivering
2985 display elements from a buffer, or when the end of a string from a
2986 `display' property is reached and we return to delivering display
2987 elements from an overlay string, or from a buffer. */
2988
2989 static void
2990 pop_it (it)
2991 struct it *it;
2992 {
2993 struct iterator_stack_entry *p;
2994
2995 xassert (it->sp > 0);
2996 --it->sp;
2997 p = it->stack + it->sp;
2998 it->stop_charpos = p->stop_charpos;
2999 it->face_id = p->face_id;
3000 it->string = p->string;
3001 it->current = p->pos;
3002 it->end_charpos = p->end_charpos;
3003 it->string_nchars = p->string_nchars;
3004 it->area = p->area;
3005 it->multibyte_p = p->multibyte_p;
3006 it->space_width = p->space_width;
3007 it->font_height = p->font_height;
3008 it->voffset = p->voffset;
3009 it->string_from_display_prop_p = p->string_from_display_prop_p;
3010 }
3011
3012
3013 \f
3014 /***********************************************************************
3015 Moving over lines
3016 ***********************************************************************/
3017
3018 /* Set IT's current position to the previous line start. */
3019
3020 static void
3021 back_to_previous_line_start (it)
3022 struct it *it;
3023 {
3024 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
3025 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3026 }
3027
3028
3029 /* Set IT's current position to the next line start. */
3030
3031 static void
3032 forward_to_next_line_start (it)
3033 struct it *it;
3034 {
3035 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), 1);
3036 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3037 }
3038
3039
3040 /* Set IT's current position to the previous visible line start. Skip
3041 invisible text that is so either due to text properties or due to
3042 selective display. Caution: this does not change IT->current_x and
3043 IT->hpos. */
3044
3045 static void
3046 back_to_previous_visible_line_start (it)
3047 struct it *it;
3048 {
3049 int visible_p = 0;
3050
3051 /* Go back one newline if not on BEGV already. */
3052 if (IT_CHARPOS (*it) > BEGV)
3053 back_to_previous_line_start (it);
3054
3055 /* Move over lines that are invisible because of selective display
3056 or text properties. */
3057 while (IT_CHARPOS (*it) > BEGV
3058 && !visible_p)
3059 {
3060 visible_p = 1;
3061
3062 /* If selective > 0, then lines indented more than that values
3063 are invisible. */
3064 if (it->selective > 0
3065 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3066 it->selective))
3067 visible_p = 0;
3068 else
3069 {
3070 Lisp_Object prop;
3071
3072 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
3073 Qinvisible, it->window);
3074 if (TEXT_PROP_MEANS_INVISIBLE (prop))
3075 visible_p = 0;
3076 }
3077
3078 /* Back one more newline if the current one is invisible. */
3079 if (!visible_p)
3080 back_to_previous_line_start (it);
3081 }
3082
3083 xassert (IT_CHARPOS (*it) >= BEGV);
3084 xassert (IT_CHARPOS (*it) == BEGV
3085 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3086 CHECK_IT (it);
3087 }
3088
3089
3090 /* Reseat iterator IT at the previous visible line start. Skip
3091 invisible text that is so either due to text properties or due to
3092 selective display. At the end, update IT's overlay information,
3093 face information etc. */
3094
3095 static void
3096 reseat_at_previous_visible_line_start (it)
3097 struct it *it;
3098 {
3099 back_to_previous_visible_line_start (it);
3100 reseat (it, it->current.pos, 1);
3101 CHECK_IT (it);
3102 }
3103
3104
3105 /* Reseat iterator IT on the next visible line start in the current
3106 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3107 preceding the line start. Skip over invisible text that is so
3108 because of selective display. Compute faces, overlays etc at the
3109 new position. Note that this function does not skip over text that
3110 is invisible because of text properties. */
3111
3112 static void
3113 reseat_at_next_visible_line_start (it, on_newline_p)
3114 struct it *it;
3115 int on_newline_p;
3116 {
3117 /* Restore the buffer position when currently not delivering display
3118 elements from the current buffer. This is the case, for example,
3119 when called at the end of a truncated overlay string. */
3120 while (it->sp)
3121 pop_it (it);
3122 it->method = next_element_from_buffer;
3123
3124 /* Otherwise, scan_buffer would not work. */
3125 if (IT_CHARPOS (*it) < ZV)
3126 {
3127 /* If on a newline, advance past it. Otherwise, find the next
3128 newline which automatically gives us the position following
3129 the newline. */
3130 if (FETCH_BYTE (IT_BYTEPOS (*it)) == '\n')
3131 {
3132 ++IT_CHARPOS (*it);
3133 ++IT_BYTEPOS (*it);
3134 }
3135 else
3136 forward_to_next_line_start (it);
3137
3138 /* We must either have reached the end of the buffer or end up
3139 after a newline. */
3140 xassert (IT_CHARPOS (*it) == ZV
3141 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
3142
3143 /* Skip over lines that are invisible because they are indented
3144 more than the value of IT->selective. */
3145 if (it->selective > 0)
3146 while (IT_CHARPOS (*it) < ZV
3147 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
3148 it->selective))
3149 forward_to_next_line_start (it);
3150
3151 /* Position on the newline if we should. */
3152 if (on_newline_p
3153 && IT_CHARPOS (*it) > BEGV
3154 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n')
3155 {
3156 --IT_CHARPOS (*it);
3157 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
3158 }
3159
3160 /* Set the iterator there. The 0 as the last parameter of
3161 reseat means don't force a text property lookup. The lookup
3162 is then only done if we've skipped past the iterator's
3163 check_charpos'es. This optimization is important because
3164 text property lookups tend to be expensive. */
3165 reseat (it, it->current.pos, 0);
3166 }
3167
3168 CHECK_IT (it);
3169 }
3170
3171
3172 \f
3173 /***********************************************************************
3174 Changing an iterator's position
3175 ***********************************************************************/
3176
3177 /* Change IT's current position to POS in current_buffer. If FORCE_P
3178 is non-zero, always check for text properties at the new position.
3179 Otherwise, text properties are only looked up if POS >=
3180 IT->check_charpos of a property. */
3181
3182 static void
3183 reseat (it, pos, force_p)
3184 struct it *it;
3185 struct text_pos pos;
3186 int force_p;
3187 {
3188 int original_pos = IT_CHARPOS (*it);
3189
3190 reseat_1 (it, pos, 0);
3191
3192 /* Determine where to check text properties. Avoid doing it
3193 where possible because text property lookup is very expensive. */
3194 if (force_p
3195 || CHARPOS (pos) > it->stop_charpos
3196 || CHARPOS (pos) < original_pos)
3197 handle_stop (it);
3198
3199 CHECK_IT (it);
3200 }
3201
3202
3203 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3204 IT->stop_pos to POS, also. */
3205
3206 static void
3207 reseat_1 (it, pos, set_stop_p)
3208 struct it *it;
3209 struct text_pos pos;
3210 int set_stop_p;
3211 {
3212 /* Don't call this function when scanning a C string. */
3213 xassert (it->s == NULL);
3214
3215 /* POS must be a reasonable value. */
3216 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
3217
3218 it->current.pos = it->position = pos;
3219 XSETBUFFER (it->object, current_buffer);
3220 it->dpvec = NULL;
3221 it->current.dpvec_index = -1;
3222 it->current.overlay_string_index = -1;
3223 IT_STRING_CHARPOS (*it) = -1;
3224 IT_STRING_BYTEPOS (*it) = -1;
3225 it->string = Qnil;
3226 it->method = next_element_from_buffer;
3227 it->sp = 0;
3228
3229 if (set_stop_p)
3230 it->stop_charpos = CHARPOS (pos);
3231 }
3232
3233
3234 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3235 If S is non-null, it is a C string to iterate over. Otherwise,
3236 STRING gives a Lisp string to iterate over.
3237
3238 If PRECISION > 0, don't return more then PRECISION number of
3239 characters from the string.
3240
3241 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3242 characters have been returned. FIELD_WIDTH < 0 means an infinite
3243 field width.
3244
3245 MULTIBYTE = 0 means disable processing of multibyte characters,
3246 MULTIBYTE > 0 means enable it,
3247 MULTIBYTE < 0 means use IT->multibyte_p.
3248
3249 IT must be initialized via a prior call to init_iterator before
3250 calling this function. */
3251
3252 static void
3253 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
3254 struct it *it;
3255 unsigned char *s;
3256 Lisp_Object string;
3257 int charpos;
3258 int precision, field_width, multibyte;
3259 {
3260 /* No region in strings. */
3261 it->region_beg_charpos = it->region_end_charpos = -1;
3262
3263 /* No text property checks performed by default, but see below. */
3264 it->stop_charpos = -1;
3265
3266 /* Set iterator position and end position. */
3267 bzero (&it->current, sizeof it->current);
3268 it->current.overlay_string_index = -1;
3269 it->current.dpvec_index = -1;
3270 xassert (charpos >= 0);
3271
3272 /* Use the setting of MULTIBYTE if specified. */
3273 if (multibyte >= 0)
3274 it->multibyte_p = multibyte > 0;
3275
3276 if (s == NULL)
3277 {
3278 xassert (STRINGP (string));
3279 it->string = string;
3280 it->s = NULL;
3281 it->end_charpos = it->string_nchars = XSTRING (string)->size;
3282 it->method = next_element_from_string;
3283 it->current.string_pos = string_pos (charpos, string);
3284 }
3285 else
3286 {
3287 it->s = s;
3288 it->string = Qnil;
3289
3290 /* Note that we use IT->current.pos, not it->current.string_pos,
3291 for displaying C strings. */
3292 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
3293 if (it->multibyte_p)
3294 {
3295 it->current.pos = c_string_pos (charpos, s, 1);
3296 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
3297 }
3298 else
3299 {
3300 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
3301 it->end_charpos = it->string_nchars = strlen (s);
3302 }
3303
3304 it->method = next_element_from_c_string;
3305 }
3306
3307 /* PRECISION > 0 means don't return more than PRECISION characters
3308 from the string. */
3309 if (precision > 0 && it->end_charpos - charpos > precision)
3310 it->end_charpos = it->string_nchars = charpos + precision;
3311
3312 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3313 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3314 FIELD_WIDTH < 0 means infinite field width. This is useful for
3315 padding with `-' at the end of a mode line. */
3316 if (field_width < 0)
3317 field_width = INFINITY;
3318 if (field_width > it->end_charpos - charpos)
3319 it->end_charpos = charpos + field_width;
3320
3321 /* Use the standard display table for displaying strings. */
3322 if (DISP_TABLE_P (Vstandard_display_table))
3323 it->dp = XCHAR_TABLE (Vstandard_display_table);
3324
3325 it->stop_charpos = charpos;
3326 CHECK_IT (it);
3327 }
3328
3329
3330 \f
3331 /***********************************************************************
3332 Iteration
3333 ***********************************************************************/
3334
3335 /* Load IT's display element fields with information about the next
3336 display element from the current position of IT. Value is zero if
3337 end of buffer (or C string) is reached. */
3338
3339 int
3340 get_next_display_element (it)
3341 struct it *it;
3342 {
3343 /* Non-zero means that we found an display element. Zero means that
3344 we hit the end of what we iterate over. Performance note: the
3345 function pointer `method' used here turns out to be faster than
3346 using a sequence of if-statements. */
3347 int success_p = (*it->method) (it);
3348
3349 if (it->what == IT_CHARACTER)
3350 {
3351 /* Map via display table or translate control characters.
3352 IT->c, IT->len etc. have been set to the next character by
3353 the function call above. If we have a display table, and it
3354 contains an entry for IT->c, translate it. Don't do this if
3355 IT->c itself comes from a display table, otherwise we could
3356 end up in an infinite recursion. (An alternative could be to
3357 count the recursion depth of this function and signal an
3358 error when a certain maximum depth is reached.) Is it worth
3359 it? */
3360 if (success_p && it->dpvec == NULL)
3361 {
3362 Lisp_Object dv;
3363
3364 if (it->dp
3365 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
3366 VECTORP (dv)))
3367 {
3368 struct Lisp_Vector *v = XVECTOR (dv);
3369
3370 /* Return the first character from the display table
3371 entry, if not empty. If empty, don't display the
3372 current character. */
3373 if (v->size)
3374 {
3375 it->dpvec_char_len = it->len;
3376 it->dpvec = v->contents;
3377 it->dpend = v->contents + v->size;
3378 it->current.dpvec_index = 0;
3379 it->method = next_element_from_display_vector;
3380 }
3381
3382 success_p = get_next_display_element (it);
3383 }
3384
3385 /* Translate control characters into `\003' or `^C' form.
3386 Control characters coming from a display table entry are
3387 currently not translated because we use IT->dpvec to hold
3388 the translation. This could easily be changed but I
3389 don't believe that it is worth doing.
3390
3391 Non-printable multibyte characters are also translated
3392 octal form. */
3393 else if ((it->c < ' '
3394 && (it->area != TEXT_AREA
3395 || (it->c != '\n' && it->c != '\t')))
3396 || (it->c >= 127
3397 && it->len == 1)
3398 || !CHAR_PRINTABLE_P (it->c))
3399 {
3400 /* IT->c is a control character which must be displayed
3401 either as '\003' or as `^C' where the '\\' and '^'
3402 can be defined in the display table. Fill
3403 IT->ctl_chars with glyphs for what we have to
3404 display. Then, set IT->dpvec to these glyphs. */
3405 GLYPH g;
3406
3407 if (it->c < 128 && it->ctl_arrow_p)
3408 {
3409 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3410 if (it->dp
3411 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
3412 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
3413 g = XINT (DISP_CTRL_GLYPH (it->dp));
3414 else
3415 g = FAST_MAKE_GLYPH ('^', 0);
3416 XSETINT (it->ctl_chars[0], g);
3417
3418 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
3419 XSETINT (it->ctl_chars[1], g);
3420
3421 /* Set up IT->dpvec and return first character from it. */
3422 it->dpvec_char_len = it->len;
3423 it->dpvec = it->ctl_chars;
3424 it->dpend = it->dpvec + 2;
3425 it->current.dpvec_index = 0;
3426 it->method = next_element_from_display_vector;
3427 get_next_display_element (it);
3428 }
3429 else
3430 {
3431 unsigned char str[MAX_MULTIBYTE_LENGTH];
3432 int len;
3433 int i;
3434 GLYPH escape_glyph;
3435
3436 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3437 if (it->dp
3438 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
3439 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
3440 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
3441 else
3442 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
3443
3444 if (SINGLE_BYTE_CHAR_P (it->c))
3445 str[0] = it->c, len = 1;
3446 else
3447 len = CHAR_STRING (it->c, str);
3448
3449 for (i = 0; i < len; i++)
3450 {
3451 XSETINT (it->ctl_chars[i * 4], escape_glyph);
3452 /* Insert three more glyphs into IT->ctl_chars for
3453 the octal display of the character. */
3454 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
3455 XSETINT (it->ctl_chars[i * 4 + 1], g);
3456 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
3457 XSETINT (it->ctl_chars[i * 4 + 2], g);
3458 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
3459 XSETINT (it->ctl_chars[i * 4 + 3], g);
3460 }
3461
3462 /* Set up IT->dpvec and return the first character
3463 from it. */
3464 it->dpvec_char_len = it->len;
3465 it->dpvec = it->ctl_chars;
3466 it->dpend = it->dpvec + len * 4;
3467 it->current.dpvec_index = 0;
3468 it->method = next_element_from_display_vector;
3469 get_next_display_element (it);
3470 }
3471 }
3472 }
3473
3474 /* Adjust face id for a multibyte character. There are no
3475 multibyte character in unibyte text. */
3476 if (it->multibyte_p
3477 && success_p
3478 && FRAME_WINDOW_P (it->f))
3479 {
3480 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3481 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
3482 }
3483 }
3484
3485 /* Is this character the last one of a run of characters with
3486 box? If yes, set IT->end_of_box_run_p to 1. */
3487 if (it->face_box_p
3488 && it->s == NULL)
3489 {
3490 int face_id;
3491 struct face *face;
3492
3493 it->end_of_box_run_p
3494 = ((face_id = face_after_it_pos (it),
3495 face_id != it->face_id)
3496 && (face = FACE_FROM_ID (it->f, face_id),
3497 face->box == FACE_NO_BOX));
3498 }
3499
3500 /* Value is 0 if end of buffer or string reached. */
3501 return success_p;
3502 }
3503
3504
3505 /* Move IT to the next display element.
3506
3507 Functions get_next_display_element and set_iterator_to_next are
3508 separate because I find this arrangement easier to handle than a
3509 get_next_display_element function that also increments IT's
3510 position. The way it is we can first look at an iterator's current
3511 display element, decide whether it fits on a line, and if it does,
3512 increment the iterator position. The other way around we probably
3513 would either need a flag indicating whether the iterator has to be
3514 incremented the next time, or we would have to implement a
3515 decrement position function which would not be easy to write. */
3516
3517 void
3518 set_iterator_to_next (it)
3519 struct it *it;
3520 {
3521 if (it->method == next_element_from_buffer)
3522 {
3523 /* The current display element of IT is a character from
3524 current_buffer. Advance in the buffer, and maybe skip over
3525 invisible lines that are so because of selective display. */
3526 if (ITERATOR_AT_END_OF_LINE_P (it))
3527 reseat_at_next_visible_line_start (it, 0);
3528 else
3529 {
3530 xassert (it->len != 0);
3531 IT_BYTEPOS (*it) += it->len;
3532 IT_CHARPOS (*it) += 1;
3533 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
3534 }
3535 }
3536 else if (it->method == next_element_from_composition)
3537 {
3538 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
3539 if (STRINGP (it->string))
3540 {
3541 IT_STRING_BYTEPOS (*it) += it->len;
3542 IT_STRING_CHARPOS (*it) += it->cmp_len;
3543 it->method = next_element_from_string;
3544 goto consider_string_end;
3545 }
3546 else
3547 {
3548 IT_BYTEPOS (*it) += it->len;
3549 IT_CHARPOS (*it) += it->cmp_len;
3550 it->method = next_element_from_buffer;
3551 }
3552 }
3553 else if (it->method == next_element_from_c_string)
3554 {
3555 /* Current display element of IT is from a C string. */
3556 IT_BYTEPOS (*it) += it->len;
3557 IT_CHARPOS (*it) += 1;
3558 }
3559 else if (it->method == next_element_from_display_vector)
3560 {
3561 /* Current display element of IT is from a display table entry.
3562 Advance in the display table definition. Reset it to null if
3563 end reached, and continue with characters from buffers/
3564 strings. */
3565 ++it->current.dpvec_index;
3566
3567 /* Restore face of the iterator to what they were before the
3568 display vector entry (these entries may contain faces). */
3569 it->face_id = it->saved_face_id;
3570
3571 if (it->dpvec + it->current.dpvec_index == it->dpend)
3572 {
3573 if (it->s)
3574 it->method = next_element_from_c_string;
3575 else if (STRINGP (it->string))
3576 it->method = next_element_from_string;
3577 else
3578 it->method = next_element_from_buffer;
3579
3580 it->dpvec = NULL;
3581 it->current.dpvec_index = -1;
3582
3583 /* Skip over characters which were displayed via IT->dpvec. */
3584 if (it->dpvec_char_len < 0)
3585 reseat_at_next_visible_line_start (it, 1);
3586 else if (it->dpvec_char_len > 0)
3587 {
3588 it->len = it->dpvec_char_len;
3589 set_iterator_to_next (it);
3590 }
3591 }
3592 }
3593 else if (it->method == next_element_from_string)
3594 {
3595 /* Current display element is a character from a Lisp string. */
3596 xassert (it->s == NULL && STRINGP (it->string));
3597 IT_STRING_BYTEPOS (*it) += it->len;
3598 IT_STRING_CHARPOS (*it) += 1;
3599
3600 consider_string_end:
3601
3602 if (it->current.overlay_string_index >= 0)
3603 {
3604 /* IT->string is an overlay string. Advance to the
3605 next, if there is one. */
3606 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3607 next_overlay_string (it);
3608 }
3609 else
3610 {
3611 /* IT->string is not an overlay string. If we reached
3612 its end, and there is something on IT->stack, proceed
3613 with what is on the stack. This can be either another
3614 string, this time an overlay string, or a buffer. */
3615 if (IT_STRING_CHARPOS (*it) == XSTRING (it->string)->size
3616 && it->sp > 0)
3617 {
3618 pop_it (it);
3619 if (!STRINGP (it->string))
3620 it->method = next_element_from_buffer;
3621 }
3622 }
3623 }
3624 else if (it->method == next_element_from_image
3625 || it->method == next_element_from_stretch)
3626 {
3627 /* The position etc with which we have to proceed are on
3628 the stack. The position may be at the end of a string,
3629 if the `display' property takes up the whole string. */
3630 pop_it (it);
3631 it->image_id = 0;
3632 if (STRINGP (it->string))
3633 {
3634 it->method = next_element_from_string;
3635 goto consider_string_end;
3636 }
3637 else
3638 it->method = next_element_from_buffer;
3639 }
3640 else
3641 /* There are no other methods defined, so this should be a bug. */
3642 abort ();
3643
3644 /* Reset flags indicating start and end of a sequence of
3645 characters with box. */
3646 it->start_of_box_run_p = it->end_of_box_run_p = 0;
3647
3648 xassert (it->method != next_element_from_string
3649 || (STRINGP (it->string)
3650 && IT_STRING_CHARPOS (*it) >= 0));
3651 }
3652
3653
3654 /* Load IT's display element fields with information about the next
3655 display element which comes from a display table entry or from the
3656 result of translating a control character to one of the forms `^C'
3657 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3658
3659 static int
3660 next_element_from_display_vector (it)
3661 struct it *it;
3662 {
3663 /* Precondition. */
3664 xassert (it->dpvec && it->current.dpvec_index >= 0);
3665
3666 /* Remember the current face id in case glyphs specify faces.
3667 IT's face is restored in set_iterator_to_next. */
3668 it->saved_face_id = it->face_id;
3669
3670 if (INTEGERP (*it->dpvec)
3671 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
3672 {
3673 int lface_id;
3674 GLYPH g;
3675
3676 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
3677 it->c = FAST_GLYPH_CHAR (g);
3678 it->len = CHAR_BYTES (it->c);
3679
3680 /* The entry may contain a face id to use. Such a face id is
3681 the id of a Lisp face, not a realized face. A face id of
3682 zero means no face. */
3683 lface_id = FAST_GLYPH_FACE (g);
3684 if (lface_id)
3685 {
3686 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
3687 if (face_id >= 0)
3688 {
3689 it->face_id = face_id;
3690 }
3691 }
3692 }
3693 else
3694 /* Display table entry is invalid. Return a space. */
3695 it->c = ' ', it->len = 1;
3696
3697 /* Don't change position and object of the iterator here. They are
3698 still the values of the character that had this display table
3699 entry or was translated, and that's what we want. */
3700 it->what = IT_CHARACTER;
3701 return 1;
3702 }
3703
3704
3705 /* Load IT with the next display element from Lisp string IT->string.
3706 IT->current.string_pos is the current position within the string.
3707 If IT->current.overlay_string_index >= 0, the Lisp string is an
3708 overlay string. */
3709
3710 static int
3711 next_element_from_string (it)
3712 struct it *it;
3713 {
3714 struct text_pos position;
3715
3716 xassert (STRINGP (it->string));
3717 xassert (IT_STRING_CHARPOS (*it) >= 0);
3718 position = it->current.string_pos;
3719
3720 /* Time to check for invisible text? */
3721 if (IT_STRING_CHARPOS (*it) < it->end_charpos
3722 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
3723 {
3724 handle_stop (it);
3725
3726 /* Since a handler may have changed IT->method, we must
3727 recurse here. */
3728 return get_next_display_element (it);
3729 }
3730
3731 if (it->current.overlay_string_index >= 0)
3732 {
3733 /* Get the next character from an overlay string. In overlay
3734 strings, There is no field width or padding with spaces to
3735 do. */
3736 if (IT_STRING_CHARPOS (*it) >= XSTRING (it->string)->size)
3737 {
3738 it->what = IT_EOB;
3739 return 0;
3740 }
3741 else if (STRING_MULTIBYTE (it->string))
3742 {
3743 int remaining = (STRING_BYTES (XSTRING (it->string))
3744 - IT_STRING_BYTEPOS (*it));
3745 unsigned char *s = (XSTRING (it->string)->data
3746 + IT_STRING_BYTEPOS (*it));
3747 it->c = string_char_and_length (s, remaining, &it->len);
3748 }
3749 else
3750 {
3751 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3752 it->len = 1;
3753 }
3754 }
3755 else
3756 {
3757 /* Get the next character from a Lisp string that is not an
3758 overlay string. Such strings come from the mode line, for
3759 example. We may have to pad with spaces, or truncate the
3760 string. See also next_element_from_c_string. */
3761 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
3762 {
3763 it->what = IT_EOB;
3764 return 0;
3765 }
3766 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
3767 {
3768 /* Pad with spaces. */
3769 it->c = ' ', it->len = 1;
3770 CHARPOS (position) = BYTEPOS (position) = -1;
3771 }
3772 else if (STRING_MULTIBYTE (it->string))
3773 {
3774 int maxlen = (STRING_BYTES (XSTRING (it->string))
3775 - IT_STRING_BYTEPOS (*it));
3776 unsigned char *s = (XSTRING (it->string)->data
3777 + IT_STRING_BYTEPOS (*it));
3778 it->c = string_char_and_length (s, maxlen, &it->len);
3779 }
3780 else
3781 {
3782 it->c = XSTRING (it->string)->data[IT_STRING_BYTEPOS (*it)];
3783 it->len = 1;
3784 }
3785 }
3786
3787 /* Record what we have and where it came from. Note that we store a
3788 buffer position in IT->position although it could arguably be a
3789 string position. */
3790 it->what = IT_CHARACTER;
3791 it->object = it->string;
3792 it->position = position;
3793 return 1;
3794 }
3795
3796
3797 /* Load IT with next display element from C string IT->s.
3798 IT->string_nchars is the maximum number of characters to return
3799 from the string. IT->end_charpos may be greater than
3800 IT->string_nchars when this function is called, in which case we
3801 may have to return padding spaces. Value is zero if end of string
3802 reached, including padding spaces. */
3803
3804 static int
3805 next_element_from_c_string (it)
3806 struct it *it;
3807 {
3808 int success_p = 1;
3809
3810 xassert (it->s);
3811 it->what = IT_CHARACTER;
3812 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
3813 it->object = Qnil;
3814
3815 /* IT's position can be greater IT->string_nchars in case a field
3816 width or precision has been specified when the iterator was
3817 initialized. */
3818 if (IT_CHARPOS (*it) >= it->end_charpos)
3819 {
3820 /* End of the game. */
3821 it->what = IT_EOB;
3822 success_p = 0;
3823 }
3824 else if (IT_CHARPOS (*it) >= it->string_nchars)
3825 {
3826 /* Pad with spaces. */
3827 it->c = ' ', it->len = 1;
3828 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
3829 }
3830 else if (it->multibyte_p)
3831 {
3832 /* Implementation note: The calls to strlen apparently aren't a
3833 performance problem because there is no noticeable performance
3834 difference between Emacs running in unibyte or multibyte mode. */
3835 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
3836 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
3837 maxlen, &it->len);
3838 }
3839 else
3840 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
3841
3842 return success_p;
3843 }
3844
3845
3846 /* Set up IT to return characters from an ellipsis, if appropriate.
3847 The definition of the ellipsis glyphs may come from a display table
3848 entry. This function Fills IT with the first glyph from the
3849 ellipsis if an ellipsis is to be displayed. */
3850
3851 static int
3852 next_element_from_ellipsis (it)
3853 struct it *it;
3854 {
3855 if (it->selective_display_ellipsis_p)
3856 {
3857 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3858 {
3859 /* Use the display table definition for `...'. Invalid glyphs
3860 will be handled by the method returning elements from dpvec. */
3861 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3862 it->dpvec_char_len = it->len;
3863 it->dpvec = v->contents;
3864 it->dpend = v->contents + v->size;
3865 it->current.dpvec_index = 0;
3866 it->method = next_element_from_display_vector;
3867 }
3868 else
3869 {
3870 /* Use default `...' which is stored in default_invis_vector. */
3871 it->dpvec_char_len = it->len;
3872 it->dpvec = default_invis_vector;
3873 it->dpend = default_invis_vector + 3;
3874 it->current.dpvec_index = 0;
3875 it->method = next_element_from_display_vector;
3876 }
3877 }
3878 else
3879 reseat_at_next_visible_line_start (it, 1);
3880
3881 return get_next_display_element (it);
3882 }
3883
3884
3885 /* Deliver an image display element. The iterator IT is already
3886 filled with image information (done in handle_display_prop). Value
3887 is always 1. */
3888
3889
3890 static int
3891 next_element_from_image (it)
3892 struct it *it;
3893 {
3894 it->what = IT_IMAGE;
3895 return 1;
3896 }
3897
3898
3899 /* Fill iterator IT with next display element from a stretch glyph
3900 property. IT->object is the value of the text property. Value is
3901 always 1. */
3902
3903 static int
3904 next_element_from_stretch (it)
3905 struct it *it;
3906 {
3907 it->what = IT_STRETCH;
3908 return 1;
3909 }
3910
3911
3912 /* Load IT with the next display element from current_buffer. Value
3913 is zero if end of buffer reached. IT->stop_charpos is the next
3914 position at which to stop and check for text properties or buffer
3915 end. */
3916
3917 static int
3918 next_element_from_buffer (it)
3919 struct it *it;
3920 {
3921 int success_p = 1;
3922
3923 /* Check this assumption, otherwise, we would never enter the
3924 if-statement, below. */
3925 xassert (IT_CHARPOS (*it) >= BEGV
3926 && IT_CHARPOS (*it) <= it->stop_charpos);
3927
3928 if (IT_CHARPOS (*it) >= it->stop_charpos)
3929 {
3930 if (IT_CHARPOS (*it) >= it->end_charpos)
3931 {
3932 int overlay_strings_follow_p;
3933
3934 /* End of the game, except when overlay strings follow that
3935 haven't been returned yet. */
3936 if (it->overlay_strings_at_end_processed_p)
3937 overlay_strings_follow_p = 0;
3938 else
3939 {
3940 it->overlay_strings_at_end_processed_p = 1;
3941 overlay_strings_follow_p = get_overlay_strings (it);
3942 }
3943
3944 if (overlay_strings_follow_p)
3945 success_p = get_next_display_element (it);
3946 else
3947 {
3948 it->what = IT_EOB;
3949 it->position = it->current.pos;
3950 success_p = 0;
3951 }
3952 }
3953 else
3954 {
3955 handle_stop (it);
3956 return get_next_display_element (it);
3957 }
3958 }
3959 else
3960 {
3961 /* No face changes, overlays etc. in sight, so just return a
3962 character from current_buffer. */
3963 unsigned char *p;
3964
3965 /* Maybe run the redisplay end trigger hook. Performance note:
3966 This doesn't seem to cost measurable time. */
3967 if (it->redisplay_end_trigger_charpos
3968 && it->glyph_row
3969 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
3970 run_redisplay_end_trigger_hook (it);
3971
3972 /* Get the next character, maybe multibyte. */
3973 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
3974 if (it->multibyte_p && !ASCII_BYTE_P (*p))
3975 {
3976 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
3977 - IT_BYTEPOS (*it));
3978 it->c = string_char_and_length (p, maxlen, &it->len);
3979 }
3980 else
3981 it->c = *p, it->len = 1;
3982
3983 /* Record what we have and where it came from. */
3984 it->what = IT_CHARACTER;;
3985 it->object = it->w->buffer;
3986 it->position = it->current.pos;
3987
3988 /* Normally we return the character found above, except when we
3989 really want to return an ellipsis for selective display. */
3990 if (it->selective)
3991 {
3992 if (it->c == '\n')
3993 {
3994 /* A value of selective > 0 means hide lines indented more
3995 than that number of columns. */
3996 if (it->selective > 0
3997 && IT_CHARPOS (*it) + 1 < ZV
3998 && indented_beyond_p (IT_CHARPOS (*it) + 1,
3999 IT_BYTEPOS (*it) + 1,
4000 it->selective))
4001 {
4002 success_p = next_element_from_ellipsis (it);
4003 it->dpvec_char_len = -1;
4004 }
4005 }
4006 else if (it->c == '\r' && it->selective == -1)
4007 {
4008 /* A value of selective == -1 means that everything from the
4009 CR to the end of the line is invisible, with maybe an
4010 ellipsis displayed for it. */
4011 success_p = next_element_from_ellipsis (it);
4012 it->dpvec_char_len = -1;
4013 }
4014 }
4015 }
4016
4017 /* Value is zero if end of buffer reached. */
4018 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
4019 return success_p;
4020 }
4021
4022
4023 /* Run the redisplay end trigger hook for IT. */
4024
4025 static void
4026 run_redisplay_end_trigger_hook (it)
4027 struct it *it;
4028 {
4029 Lisp_Object args[3];
4030
4031 /* IT->glyph_row should be non-null, i.e. we should be actually
4032 displaying something, or otherwise we should not run the hook. */
4033 xassert (it->glyph_row);
4034
4035 /* Set up hook arguments. */
4036 args[0] = Qredisplay_end_trigger_functions;
4037 args[1] = it->window;
4038 XSETINT (args[2], it->redisplay_end_trigger_charpos);
4039 it->redisplay_end_trigger_charpos = 0;
4040
4041 /* Since we are *trying* to run these functions, don't try to run
4042 them again, even if they get an error. */
4043 it->w->redisplay_end_trigger = Qnil;
4044 Frun_hook_with_args (3, args);
4045
4046 /* Notice if it changed the face of the character we are on. */
4047 handle_face_prop (it);
4048 }
4049
4050
4051 /* Deliver a composition display element. The iterator IT is already
4052 filled with composition information (done in
4053 handle_composition_prop). Value is always 1. */
4054
4055 static int
4056 next_element_from_composition (it)
4057 struct it *it;
4058 {
4059 it->what = IT_COMPOSITION;
4060 it->position = (STRINGP (it->string)
4061 ? it->current.string_pos
4062 : it->current.pos);
4063 return 1;
4064 }
4065
4066
4067 \f
4068 /***********************************************************************
4069 Moving an iterator without producing glyphs
4070 ***********************************************************************/
4071
4072 /* Move iterator IT to a specified buffer or X position within one
4073 line on the display without producing glyphs.
4074
4075 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
4076 whichever is reached first.
4077
4078 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
4079
4080 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
4081 0 <= TO_X <= IT->last_visible_x. This means in particular, that
4082 TO_X includes the amount by which a window is horizontally
4083 scrolled.
4084
4085 Value is
4086
4087 MOVE_POS_MATCH_OR_ZV
4088 - when TO_POS or ZV was reached.
4089
4090 MOVE_X_REACHED
4091 -when TO_X was reached before TO_POS or ZV were reached.
4092
4093 MOVE_LINE_CONTINUED
4094 - when we reached the end of the display area and the line must
4095 be continued.
4096
4097 MOVE_LINE_TRUNCATED
4098 - when we reached the end of the display area and the line is
4099 truncated.
4100
4101 MOVE_NEWLINE_OR_CR
4102 - when we stopped at a line end, i.e. a newline or a CR and selective
4103 display is on. */
4104
4105 static enum move_it_result
4106 move_it_in_display_line_to (it, to_charpos, to_x, op)
4107 struct it *it;
4108 int to_charpos, to_x, op;
4109 {
4110 enum move_it_result result = MOVE_UNDEFINED;
4111 struct glyph_row *saved_glyph_row;
4112
4113 /* Don't produce glyphs in produce_glyphs. */
4114 saved_glyph_row = it->glyph_row;
4115 it->glyph_row = NULL;
4116
4117 while (1)
4118 {
4119 int x, i;
4120
4121 /* Stop when ZV or TO_CHARPOS reached. */
4122 if (!get_next_display_element (it)
4123 || ((op & MOVE_TO_POS) != 0
4124 && BUFFERP (it->object)
4125 && IT_CHARPOS (*it) >= to_charpos))
4126 {
4127 result = MOVE_POS_MATCH_OR_ZV;
4128 break;
4129 }
4130
4131 /* The call to produce_glyphs will get the metrics of the
4132 display element IT is loaded with. We record in x the
4133 x-position before this display element in case it does not
4134 fit on the line. */
4135 x = it->current_x;
4136 PRODUCE_GLYPHS (it);
4137
4138 if (it->area != TEXT_AREA)
4139 {
4140 set_iterator_to_next (it);
4141 continue;
4142 }
4143
4144 /* The number of glyphs we get back in IT->nglyphs will normally
4145 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4146 character on a terminal frame, or (iii) a line end. For the
4147 second case, IT->nglyphs - 1 padding glyphs will be present
4148 (on X frames, there is only one glyph produced for a
4149 composite character.
4150
4151 The behavior implemented below means, for continuation lines,
4152 that as many spaces of a TAB as fit on the current line are
4153 displayed there. For terminal frames, as many glyphs of a
4154 multi-glyph character are displayed in the current line, too.
4155 This is what the old redisplay code did, and we keep it that
4156 way. Under X, the whole shape of a complex character must
4157 fit on the line or it will be completely displayed in the
4158 next line.
4159
4160 Note that both for tabs and padding glyphs, all glyphs have
4161 the same width. */
4162 if (it->nglyphs)
4163 {
4164 /* More than one glyph or glyph doesn't fit on line. All
4165 glyphs have the same width. */
4166 int single_glyph_width = it->pixel_width / it->nglyphs;
4167 int new_x;
4168
4169 for (i = 0; i < it->nglyphs; ++i, x = new_x)
4170 {
4171 new_x = x + single_glyph_width;
4172
4173 /* We want to leave anything reaching TO_X to the caller. */
4174 if ((op & MOVE_TO_X) && new_x > to_x)
4175 {
4176 it->current_x = x;
4177 result = MOVE_X_REACHED;
4178 break;
4179 }
4180 else if (/* Lines are continued. */
4181 !it->truncate_lines_p
4182 && (/* And glyph doesn't fit on the line. */
4183 new_x > it->last_visible_x
4184 /* Or it fits exactly and we're on a window
4185 system frame. */
4186 || (new_x == it->last_visible_x
4187 && FRAME_WINDOW_P (it->f))))
4188 {
4189 if (/* IT->hpos == 0 means the very first glyph
4190 doesn't fit on the line, e.g. a wide image. */
4191 it->hpos == 0
4192 || (new_x == it->last_visible_x
4193 && FRAME_WINDOW_P (it->f)))
4194 {
4195 ++it->hpos;
4196 it->current_x = new_x;
4197 if (i == it->nglyphs - 1)
4198 set_iterator_to_next (it);
4199 }
4200 else
4201 it->current_x = x;
4202
4203 result = MOVE_LINE_CONTINUED;
4204 break;
4205 }
4206 else if (new_x > it->first_visible_x)
4207 {
4208 /* Glyph is visible. Increment number of glyphs that
4209 would be displayed. */
4210 ++it->hpos;
4211 }
4212 else
4213 {
4214 /* Glyph is completely off the left margin of the display
4215 area. Nothing to do. */
4216 }
4217 }
4218
4219 if (result != MOVE_UNDEFINED)
4220 break;
4221 }
4222 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
4223 {
4224 /* Stop when TO_X specified and reached. This check is
4225 necessary here because of lines consisting of a line end,
4226 only. The line end will not produce any glyphs and we
4227 would never get MOVE_X_REACHED. */
4228 xassert (it->nglyphs == 0);
4229 result = MOVE_X_REACHED;
4230 break;
4231 }
4232
4233 /* Is this a line end? If yes, we're done. */
4234 if (ITERATOR_AT_END_OF_LINE_P (it))
4235 {
4236 result = MOVE_NEWLINE_OR_CR;
4237 break;
4238 }
4239
4240 /* The current display element has been consumed. Advance
4241 to the next. */
4242 set_iterator_to_next (it);
4243
4244 /* Stop if lines are truncated and IT's current x-position is
4245 past the right edge of the window now. */
4246 if (it->truncate_lines_p
4247 && it->current_x >= it->last_visible_x)
4248 {
4249 result = MOVE_LINE_TRUNCATED;
4250 break;
4251 }
4252 }
4253
4254 /* Restore the iterator settings altered at the beginning of this
4255 function. */
4256 it->glyph_row = saved_glyph_row;
4257 return result;
4258 }
4259
4260
4261 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4262 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4263 the description of enum move_operation_enum.
4264
4265 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4266 screen line, this function will set IT to the next position >
4267 TO_CHARPOS. */
4268
4269 void
4270 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
4271 struct it *it;
4272 int to_charpos, to_x, to_y, to_vpos;
4273 int op;
4274 {
4275 enum move_it_result skip, skip2 = MOVE_X_REACHED;
4276 int line_height;
4277
4278 while (1)
4279 {
4280 if (op & MOVE_TO_VPOS)
4281 {
4282 /* If no TO_CHARPOS and no TO_X specified, stop at the
4283 start of the line TO_VPOS. */
4284 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
4285 {
4286 if (it->vpos == to_vpos)
4287 break;
4288 skip = move_it_in_display_line_to (it, -1, -1, 0);
4289 }
4290 else
4291 {
4292 /* TO_VPOS >= 0 means stop at TO_X in the line at
4293 TO_VPOS, or at TO_POS, whichever comes first. */
4294 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
4295
4296 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
4297 break;
4298 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
4299 {
4300 /* We have reached TO_X but not in the line we want. */
4301 skip = move_it_in_display_line_to (it, to_charpos,
4302 -1, MOVE_TO_POS);
4303 if (skip == MOVE_POS_MATCH_OR_ZV)
4304 break;
4305 }
4306 }
4307 }
4308 else if (op & MOVE_TO_Y)
4309 {
4310 struct it it_backup;
4311 int done_p;
4312
4313 /* TO_Y specified means stop at TO_X in the line containing
4314 TO_Y---or at TO_CHARPOS if this is reached first. The
4315 problem is that we can't really tell whether the line
4316 contains TO_Y before we have completely scanned it, and
4317 this may skip past TO_X. What we do is to first scan to
4318 TO_X.
4319
4320 If TO_X is not specified, use a TO_X of zero. The reason
4321 is to make the outcome of this function more predictable.
4322 If we didn't use TO_X == 0, we would stop at the end of
4323 the line which is probably not what a caller would expect
4324 to happen. */
4325 skip = move_it_in_display_line_to (it, to_charpos,
4326 ((op & MOVE_TO_X)
4327 ? to_x : 0),
4328 (MOVE_TO_X
4329 | (op & MOVE_TO_POS)));
4330
4331 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4332 if (skip == MOVE_POS_MATCH_OR_ZV)
4333 break;
4334
4335 /* If TO_X was reached, we would like to know whether TO_Y
4336 is in the line. This can only be said if we know the
4337 total line height which requires us to scan the rest of
4338 the line. */
4339 done_p = 0;
4340 if (skip == MOVE_X_REACHED)
4341 {
4342 it_backup = *it;
4343 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
4344 op & MOVE_TO_POS);
4345 }
4346
4347 /* Now, decide whether TO_Y is in this line. */
4348 line_height = it->max_ascent + it->max_descent;
4349
4350 if (to_y >= it->current_y
4351 && to_y < it->current_y + line_height)
4352 {
4353 if (skip == MOVE_X_REACHED)
4354 /* If TO_Y is in this line and TO_X was reached above,
4355 we scanned too far. We have to restore IT's settings
4356 to the ones before skipping. */
4357 *it = it_backup;
4358 done_p = 1;
4359 }
4360 else if (skip == MOVE_X_REACHED)
4361 {
4362 skip = skip2;
4363 if (skip == MOVE_POS_MATCH_OR_ZV)
4364 done_p = 1;
4365 }
4366
4367 if (done_p)
4368 break;
4369 }
4370 else
4371 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
4372
4373 switch (skip)
4374 {
4375 case MOVE_POS_MATCH_OR_ZV:
4376 return;
4377
4378 case MOVE_NEWLINE_OR_CR:
4379 set_iterator_to_next (it);
4380 it->continuation_lines_width = 0;
4381 break;
4382
4383 case MOVE_LINE_TRUNCATED:
4384 it->continuation_lines_width = 0;
4385 reseat_at_next_visible_line_start (it, 0);
4386 if ((op & MOVE_TO_POS) != 0
4387 && IT_CHARPOS (*it) > to_charpos)
4388 goto out;
4389 break;
4390
4391 case MOVE_LINE_CONTINUED:
4392 it->continuation_lines_width += it->current_x;
4393 break;
4394
4395 default:
4396 abort ();
4397 }
4398
4399 /* Reset/increment for the next run. */
4400 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
4401 it->current_x = it->hpos = 0;
4402 it->current_y += it->max_ascent + it->max_descent;
4403 ++it->vpos;
4404 last_height = it->max_ascent + it->max_descent;
4405 last_max_ascent = it->max_ascent;
4406 it->max_ascent = it->max_descent = 0;
4407 }
4408 out:;
4409 }
4410
4411
4412 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4413
4414 If DY > 0, move IT backward at least that many pixels. DY = 0
4415 means move IT backward to the preceding line start or BEGV. This
4416 function may move over more than DY pixels if IT->current_y - DY
4417 ends up in the middle of a line; in this case IT->current_y will be
4418 set to the top of the line moved to. */
4419
4420 void
4421 move_it_vertically_backward (it, dy)
4422 struct it *it;
4423 int dy;
4424 {
4425 int nlines, h, line_height;
4426 struct it it2;
4427 int start_pos = IT_CHARPOS (*it);
4428
4429 xassert (dy >= 0);
4430
4431 /* Estimate how many newlines we must move back. */
4432 nlines = max (1, dy / CANON_Y_UNIT (it->f));
4433
4434 /* Set the iterator's position that many lines back. */
4435 while (nlines-- && IT_CHARPOS (*it) > BEGV)
4436 back_to_previous_visible_line_start (it);
4437
4438 /* Reseat the iterator here. When moving backward, we don't want
4439 reseat to skip forward over invisible text, set up the iterator
4440 to deliver from overlay strings at the new position etc. So,
4441 use reseat_1 here. */
4442 reseat_1 (it, it->current.pos, 1);
4443
4444 /* We are now surely at a line start. */
4445 it->current_x = it->hpos = 0;
4446
4447 /* Move forward and see what y-distance we moved. First move to the
4448 start of the next line so that we get its height. We need this
4449 height to be able to tell whether we reached the specified
4450 y-distance. */
4451 it2 = *it;
4452 it2.max_ascent = it2.max_descent = 0;
4453 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
4454 MOVE_TO_POS | MOVE_TO_VPOS);
4455 xassert (IT_CHARPOS (*it) >= BEGV);
4456 line_height = it2.max_ascent + it2.max_descent;
4457 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
4458 xassert (IT_CHARPOS (*it) >= BEGV);
4459 h = it2.current_y - it->current_y;
4460 nlines = it2.vpos - it->vpos;
4461
4462 /* Correct IT's y and vpos position. */
4463 it->vpos -= nlines;
4464 it->current_y -= h;
4465
4466 if (dy == 0)
4467 {
4468 /* DY == 0 means move to the start of the screen line. The
4469 value of nlines is > 0 if continuation lines were involved. */
4470 if (nlines > 0)
4471 move_it_by_lines (it, nlines, 1);
4472 xassert (IT_CHARPOS (*it) <= start_pos);
4473 }
4474 else if (nlines)
4475 {
4476 /* The y-position we try to reach. Note that h has been
4477 subtracted in front of the if-statement. */
4478 int target_y = it->current_y + h - dy;
4479
4480 /* If we did not reach target_y, try to move further backward if
4481 we can. If we moved too far backward, try to move forward. */
4482 if (target_y < it->current_y
4483 && IT_CHARPOS (*it) > BEGV)
4484 {
4485 move_it_vertically (it, target_y - it->current_y);
4486 xassert (IT_CHARPOS (*it) >= BEGV);
4487 }
4488 else if (target_y >= it->current_y + line_height
4489 && IT_CHARPOS (*it) < ZV)
4490 {
4491 move_it_vertically (it, target_y - (it->current_y + line_height));
4492 xassert (IT_CHARPOS (*it) >= BEGV);
4493 }
4494 }
4495 }
4496
4497
4498 /* Move IT by a specified amount of pixel lines DY. DY negative means
4499 move backwards. DY = 0 means move to start of screen line. At the
4500 end, IT will be on the start of a screen line. */
4501
4502 void
4503 move_it_vertically (it, dy)
4504 struct it *it;
4505 int dy;
4506 {
4507 if (dy <= 0)
4508 move_it_vertically_backward (it, -dy);
4509 else if (dy > 0)
4510 {
4511 move_it_to (it, ZV, -1, it->current_y + dy, -1,
4512 MOVE_TO_POS | MOVE_TO_Y);
4513
4514 /* If buffer ends in ZV without a newline, move to the start of
4515 the line to satisfy the post-condition. */
4516 if (IT_CHARPOS (*it) == ZV
4517 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
4518 move_it_by_lines (it, 0, 0);
4519 }
4520 }
4521
4522
4523 /* Return non-zero if some text between buffer positions START_CHARPOS
4524 and END_CHARPOS is invisible. IT->window is the window for text
4525 property lookup. */
4526
4527 static int
4528 invisible_text_between_p (it, start_charpos, end_charpos)
4529 struct it *it;
4530 int start_charpos, end_charpos;
4531 {
4532 Lisp_Object prop, limit;
4533 int invisible_found_p;
4534
4535 xassert (it != NULL && start_charpos <= end_charpos);
4536
4537 /* Is text at START invisible? */
4538 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
4539 it->window);
4540 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4541 invisible_found_p = 1;
4542 else
4543 {
4544 limit = next_single_char_property_change (make_number (start_charpos),
4545 Qinvisible, Qnil,
4546 make_number (end_charpos));
4547 invisible_found_p = XFASTINT (limit) < end_charpos;
4548 }
4549
4550 return invisible_found_p;
4551 }
4552
4553
4554 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
4555 negative means move up. DVPOS == 0 means move to the start of the
4556 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4557 NEED_Y_P is zero, IT->current_y will be left unchanged.
4558
4559 Further optimization ideas: If we would know that IT->f doesn't use
4560 a face with proportional font, we could be faster for
4561 truncate-lines nil. */
4562
4563 void
4564 move_it_by_lines (it, dvpos, need_y_p)
4565 struct it *it;
4566 int dvpos, need_y_p;
4567 {
4568 struct position pos;
4569
4570 if (!FRAME_WINDOW_P (it->f))
4571 {
4572 struct text_pos textpos;
4573
4574 /* We can use vmotion on frames without proportional fonts. */
4575 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
4576 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
4577 reseat (it, textpos, 1);
4578 it->vpos += pos.vpos;
4579 it->current_y += pos.vpos;
4580 }
4581 else if (dvpos == 0)
4582 {
4583 /* DVPOS == 0 means move to the start of the screen line. */
4584 move_it_vertically_backward (it, 0);
4585 xassert (it->current_x == 0 && it->hpos == 0);
4586 }
4587 else if (dvpos > 0)
4588 {
4589 /* If there are no continuation lines, and if there is no
4590 selective display, try the simple method of moving forward
4591 DVPOS newlines, then see where we are. */
4592 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4593 {
4594 int shortage = 0, charpos;
4595
4596 if (FETCH_BYTE (IT_BYTEPOS (*it) == '\n'))
4597 charpos = IT_CHARPOS (*it) + 1;
4598 else
4599 charpos = scan_buffer ('\n', IT_CHARPOS (*it), 0, dvpos,
4600 &shortage, 0);
4601
4602 if (!invisible_text_between_p (it, IT_CHARPOS (*it), charpos))
4603 {
4604 struct text_pos pos;
4605 CHARPOS (pos) = charpos;
4606 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4607 reseat (it, pos, 1);
4608 it->vpos += dvpos - shortage;
4609 it->hpos = it->current_x = 0;
4610 return;
4611 }
4612 }
4613
4614 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
4615 }
4616 else
4617 {
4618 struct it it2;
4619 int start_charpos, i;
4620
4621 /* If there are no continuation lines, and if there is no
4622 selective display, try the simple method of moving backward
4623 -DVPOS newlines. */
4624 if (!need_y_p && it->truncate_lines_p && it->selective == 0)
4625 {
4626 int shortage;
4627 int charpos = IT_CHARPOS (*it);
4628 int bytepos = IT_BYTEPOS (*it);
4629
4630 /* If in the middle of a line, go to its start. */
4631 if (charpos > BEGV && FETCH_BYTE (bytepos - 1) != '\n')
4632 {
4633 charpos = find_next_newline_no_quit (charpos, -1);
4634 bytepos = CHAR_TO_BYTE (charpos);
4635 }
4636
4637 if (charpos == BEGV)
4638 {
4639 struct text_pos pos;
4640 CHARPOS (pos) = charpos;
4641 BYTEPOS (pos) = bytepos;
4642 reseat (it, pos, 1);
4643 it->hpos = it->current_x = 0;
4644 return;
4645 }
4646 else
4647 {
4648 charpos = scan_buffer ('\n', charpos - 1, 0, dvpos, &shortage, 0);
4649 if (!invisible_text_between_p (it, charpos, IT_CHARPOS (*it)))
4650 {
4651 struct text_pos pos;
4652 CHARPOS (pos) = charpos;
4653 BYTEPOS (pos) = CHAR_TO_BYTE (charpos);
4654 reseat (it, pos, 1);
4655 it->vpos += dvpos + (shortage ? shortage - 1 : 0);
4656 it->hpos = it->current_x = 0;
4657 return;
4658 }
4659 }
4660 }
4661
4662 /* Go back -DVPOS visible lines and reseat the iterator there. */
4663 start_charpos = IT_CHARPOS (*it);
4664 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
4665 back_to_previous_visible_line_start (it);
4666 reseat (it, it->current.pos, 1);
4667 it->current_x = it->hpos = 0;
4668
4669 /* Above call may have moved too far if continuation lines
4670 are involved. Scan forward and see if it did. */
4671 it2 = *it;
4672 it2.vpos = it2.current_y = 0;
4673 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
4674 it->vpos -= it2.vpos;
4675 it->current_y -= it2.current_y;
4676 it->current_x = it->hpos = 0;
4677
4678 /* If we moved too far, move IT some lines forward. */
4679 if (it2.vpos > -dvpos)
4680 {
4681 int delta = it2.vpos + dvpos;
4682 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
4683 }
4684 }
4685 }
4686
4687
4688 \f
4689 /***********************************************************************
4690 Messages
4691 ***********************************************************************/
4692
4693
4694 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
4695 to *Messages*. */
4696
4697 void
4698 add_to_log (format, arg1, arg2)
4699 char *format;
4700 Lisp_Object arg1, arg2;
4701 {
4702 Lisp_Object args[3];
4703 Lisp_Object msg, fmt;
4704 char *buffer;
4705 int len;
4706 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4707
4708 fmt = msg = Qnil;
4709 GCPRO4 (fmt, msg, arg1, arg2);
4710
4711 args[0] = fmt = build_string (format);
4712 args[1] = arg1;
4713 args[2] = arg2;
4714 msg = Fformat (3, args);
4715
4716 len = STRING_BYTES (XSTRING (msg)) + 1;
4717 buffer = (char *) alloca (len);
4718 strcpy (buffer, XSTRING (msg)->data);
4719
4720 message_dolog (buffer, len - 1, 1, 0);
4721 UNGCPRO;
4722 }
4723
4724
4725 /* Output a newline in the *Messages* buffer if "needs" one. */
4726
4727 void
4728 message_log_maybe_newline ()
4729 {
4730 if (message_log_need_newline)
4731 message_dolog ("", 0, 1, 0);
4732 }
4733
4734
4735 /* Add a string M of length LEN to the message log, optionally
4736 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4737 nonzero, means interpret the contents of M as multibyte. This
4738 function calls low-level routines in order to bypass text property
4739 hooks, etc. which might not be safe to run. */
4740
4741 void
4742 message_dolog (m, len, nlflag, multibyte)
4743 char *m;
4744 int len, nlflag, multibyte;
4745 {
4746 if (!NILP (Vmessage_log_max))
4747 {
4748 struct buffer *oldbuf;
4749 Lisp_Object oldpoint, oldbegv, oldzv;
4750 int old_windows_or_buffers_changed = windows_or_buffers_changed;
4751 int point_at_end = 0;
4752 int zv_at_end = 0;
4753 Lisp_Object old_deactivate_mark, tem;
4754 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4755
4756 old_deactivate_mark = Vdeactivate_mark;
4757 oldbuf = current_buffer;
4758 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4759 current_buffer->undo_list = Qt;
4760
4761 oldpoint = Fpoint_marker ();
4762 oldbegv = Fpoint_min_marker ();
4763 oldzv = Fpoint_max_marker ();
4764 GCPRO4 (oldpoint, oldbegv, oldzv, old_deactivate_mark);
4765
4766 if (PT == Z)
4767 point_at_end = 1;
4768 if (ZV == Z)
4769 zv_at_end = 1;
4770
4771 BEGV = BEG;
4772 BEGV_BYTE = BEG_BYTE;
4773 ZV = Z;
4774 ZV_BYTE = Z_BYTE;
4775 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4776
4777 /* Insert the string--maybe converting multibyte to single byte
4778 or vice versa, so that all the text fits the buffer. */
4779 if (multibyte
4780 && NILP (current_buffer->enable_multibyte_characters))
4781 {
4782 int i, c, nbytes;
4783 unsigned char work[1];
4784
4785 /* Convert a multibyte string to single-byte
4786 for the *Message* buffer. */
4787 for (i = 0; i < len; i += nbytes)
4788 {
4789 c = string_char_and_length (m + i, len - i, &nbytes);
4790 work[0] = (SINGLE_BYTE_CHAR_P (c)
4791 ? c
4792 : multibyte_char_to_unibyte (c, Qnil));
4793 insert_1_both (work, 1, 1, 1, 0, 0);
4794 }
4795 }
4796 else if (! multibyte
4797 && ! NILP (current_buffer->enable_multibyte_characters))
4798 {
4799 int i, c, nbytes;
4800 unsigned char *msg = (unsigned char *) m;
4801 unsigned char str[MAX_MULTIBYTE_LENGTH];
4802 /* Convert a single-byte string to multibyte
4803 for the *Message* buffer. */
4804 for (i = 0; i < len; i++)
4805 {
4806 c = unibyte_char_to_multibyte (msg[i]);
4807 nbytes = CHAR_STRING (c, str);
4808 insert_1_both (str, 1, nbytes, 1, 0, 0);
4809 }
4810 }
4811 else if (len)
4812 insert_1 (m, len, 1, 0, 0);
4813
4814 if (nlflag)
4815 {
4816 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
4817 insert_1 ("\n", 1, 1, 0, 0);
4818
4819 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
4820 this_bol = PT;
4821 this_bol_byte = PT_BYTE;
4822
4823 if (this_bol > BEG)
4824 {
4825 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
4826 prev_bol = PT;
4827 prev_bol_byte = PT_BYTE;
4828
4829 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
4830 this_bol, this_bol_byte);
4831 if (dup)
4832 {
4833 del_range_both (prev_bol, prev_bol_byte,
4834 this_bol, this_bol_byte, 0);
4835 if (dup > 1)
4836 {
4837 char dupstr[40];
4838 int duplen;
4839
4840 /* If you change this format, don't forget to also
4841 change message_log_check_duplicate. */
4842 sprintf (dupstr, " [%d times]", dup);
4843 duplen = strlen (dupstr);
4844 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
4845 insert_1 (dupstr, duplen, 1, 0, 1);
4846 }
4847 }
4848 }
4849
4850 if (NATNUMP (Vmessage_log_max))
4851 {
4852 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
4853 -XFASTINT (Vmessage_log_max) - 1, 0);
4854 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
4855 }
4856 }
4857 BEGV = XMARKER (oldbegv)->charpos;
4858 BEGV_BYTE = marker_byte_position (oldbegv);
4859
4860 if (zv_at_end)
4861 {
4862 ZV = Z;
4863 ZV_BYTE = Z_BYTE;
4864 }
4865 else
4866 {
4867 ZV = XMARKER (oldzv)->charpos;
4868 ZV_BYTE = marker_byte_position (oldzv);
4869 }
4870
4871 if (point_at_end)
4872 TEMP_SET_PT_BOTH (Z, Z_BYTE);
4873 else
4874 /* We can't do Fgoto_char (oldpoint) because it will run some
4875 Lisp code. */
4876 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
4877 XMARKER (oldpoint)->bytepos);
4878
4879 UNGCPRO;
4880 free_marker (oldpoint);
4881 free_marker (oldbegv);
4882 free_marker (oldzv);
4883
4884 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
4885 set_buffer_internal (oldbuf);
4886 if (NILP (tem))
4887 windows_or_buffers_changed = old_windows_or_buffers_changed;
4888 message_log_need_newline = !nlflag;
4889 Vdeactivate_mark = old_deactivate_mark;
4890 }
4891 }
4892
4893
4894 /* We are at the end of the buffer after just having inserted a newline.
4895 (Note: We depend on the fact we won't be crossing the gap.)
4896 Check to see if the most recent message looks a lot like the previous one.
4897 Return 0 if different, 1 if the new one should just replace it, or a
4898 value N > 1 if we should also append " [N times]". */
4899
4900 static int
4901 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
4902 int prev_bol, this_bol;
4903 int prev_bol_byte, this_bol_byte;
4904 {
4905 int i;
4906 int len = Z_BYTE - 1 - this_bol_byte;
4907 int seen_dots = 0;
4908 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
4909 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
4910
4911 for (i = 0; i < len; i++)
4912 {
4913 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
4914 && p1[i] != '\n')
4915 seen_dots = 1;
4916 if (p1[i] != p2[i])
4917 return seen_dots;
4918 }
4919 p1 += len;
4920 if (*p1 == '\n')
4921 return 2;
4922 if (*p1++ == ' ' && *p1++ == '[')
4923 {
4924 int n = 0;
4925 while (*p1 >= '0' && *p1 <= '9')
4926 n = n * 10 + *p1++ - '0';
4927 if (strncmp (p1, " times]\n", 8) == 0)
4928 return n+1;
4929 }
4930 return 0;
4931 }
4932
4933
4934 /* Display an echo area message M with a specified length of LEN
4935 chars. The string may include null characters. If M is 0, clear
4936 out any existing message, and let the mini-buffer text show through.
4937
4938 The buffer M must continue to exist until after the echo area gets
4939 cleared or some other message gets displayed there. This means do
4940 not pass text that is stored in a Lisp string; do not pass text in
4941 a buffer that was alloca'd. */
4942
4943 void
4944 message2 (m, len, multibyte)
4945 char *m;
4946 int len;
4947 int multibyte;
4948 {
4949 /* First flush out any partial line written with print. */
4950 message_log_maybe_newline ();
4951 if (m)
4952 message_dolog (m, len, 1, multibyte);
4953 message2_nolog (m, len, multibyte);
4954 }
4955
4956
4957 /* The non-logging counterpart of message2. */
4958
4959 void
4960 message2_nolog (m, len, multibyte)
4961 char *m;
4962 int len;
4963 {
4964 struct frame *sf = SELECTED_FRAME ();
4965 message_enable_multibyte = multibyte;
4966
4967 if (noninteractive)
4968 {
4969 if (noninteractive_need_newline)
4970 putc ('\n', stderr);
4971 noninteractive_need_newline = 0;
4972 if (m)
4973 fwrite (m, len, 1, stderr);
4974 if (cursor_in_echo_area == 0)
4975 fprintf (stderr, "\n");
4976 fflush (stderr);
4977 }
4978 /* A null message buffer means that the frame hasn't really been
4979 initialized yet. Error messages get reported properly by
4980 cmd_error, so this must be just an informative message; toss it. */
4981 else if (INTERACTIVE
4982 && sf->glyphs_initialized_p
4983 && FRAME_MESSAGE_BUF (sf))
4984 {
4985 Lisp_Object mini_window;
4986 struct frame *f;
4987
4988 /* Get the frame containing the mini-buffer
4989 that the selected frame is using. */
4990 mini_window = FRAME_MINIBUF_WINDOW (sf);
4991 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
4992
4993 FRAME_SAMPLE_VISIBILITY (f);
4994 if (FRAME_VISIBLE_P (sf)
4995 && ! FRAME_VISIBLE_P (f))
4996 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
4997
4998 if (m)
4999 {
5000 set_message (m, Qnil, len, multibyte);
5001 if (minibuffer_auto_raise)
5002 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5003 }
5004 else
5005 clear_message (1, 1);
5006
5007 do_pending_window_change (0);
5008 echo_area_display (1);
5009 do_pending_window_change (0);
5010 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5011 (*frame_up_to_date_hook) (f);
5012 }
5013 }
5014
5015
5016 /* Display an echo area message M with a specified length of NBYTES
5017 bytes. The string may include null characters. If M is not a
5018 string, clear out any existing message, and let the mini-buffer
5019 text show through. */
5020
5021 void
5022 message3 (m, nbytes, multibyte)
5023 Lisp_Object m;
5024 int nbytes;
5025 int multibyte;
5026 {
5027 struct gcpro gcpro1;
5028
5029 GCPRO1 (m);
5030
5031 /* First flush out any partial line written with print. */
5032 message_log_maybe_newline ();
5033 if (STRINGP (m))
5034 message_dolog (XSTRING (m)->data, nbytes, 1, multibyte);
5035 message3_nolog (m, nbytes, multibyte);
5036
5037 UNGCPRO;
5038 }
5039
5040
5041 /* The non-logging version of message3. */
5042
5043 void
5044 message3_nolog (m, nbytes, multibyte)
5045 Lisp_Object m;
5046 int nbytes, multibyte;
5047 {
5048 struct frame *sf = SELECTED_FRAME ();
5049 message_enable_multibyte = multibyte;
5050
5051 if (noninteractive)
5052 {
5053 if (noninteractive_need_newline)
5054 putc ('\n', stderr);
5055 noninteractive_need_newline = 0;
5056 if (STRINGP (m))
5057 fwrite (XSTRING (m)->data, nbytes, 1, stderr);
5058 if (cursor_in_echo_area == 0)
5059 fprintf (stderr, "\n");
5060 fflush (stderr);
5061 }
5062 /* A null message buffer means that the frame hasn't really been
5063 initialized yet. Error messages get reported properly by
5064 cmd_error, so this must be just an informative message; toss it. */
5065 else if (INTERACTIVE
5066 && sf->glyphs_initialized_p
5067 && FRAME_MESSAGE_BUF (sf))
5068 {
5069 Lisp_Object mini_window;
5070 Lisp_Object frame;
5071 struct frame *f;
5072
5073 /* Get the frame containing the mini-buffer
5074 that the selected frame is using. */
5075 mini_window = FRAME_MINIBUF_WINDOW (sf);
5076 frame = XWINDOW (mini_window)->frame;
5077 f = XFRAME (frame);
5078
5079 FRAME_SAMPLE_VISIBILITY (f);
5080 if (FRAME_VISIBLE_P (sf)
5081 && !FRAME_VISIBLE_P (f))
5082 Fmake_frame_visible (frame);
5083
5084 if (STRINGP (m) && XSTRING (m)->size)
5085 {
5086 set_message (NULL, m, nbytes, multibyte);
5087 if (minibuffer_auto_raise)
5088 Fraise_frame (frame);
5089 }
5090 else
5091 clear_message (1, 1);
5092
5093 do_pending_window_change (0);
5094 echo_area_display (1);
5095 do_pending_window_change (0);
5096 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
5097 (*frame_up_to_date_hook) (f);
5098 }
5099 }
5100
5101
5102 /* Display a null-terminated echo area message M. If M is 0, clear
5103 out any existing message, and let the mini-buffer text show through.
5104
5105 The buffer M must continue to exist until after the echo area gets
5106 cleared or some other message gets displayed there. Do not pass
5107 text that is stored in a Lisp string. Do not pass text in a buffer
5108 that was alloca'd. */
5109
5110 void
5111 message1 (m)
5112 char *m;
5113 {
5114 message2 (m, (m ? strlen (m) : 0), 0);
5115 }
5116
5117
5118 /* The non-logging counterpart of message1. */
5119
5120 void
5121 message1_nolog (m)
5122 char *m;
5123 {
5124 message2_nolog (m, (m ? strlen (m) : 0), 0);
5125 }
5126
5127 /* Display a message M which contains a single %s
5128 which gets replaced with STRING. */
5129
5130 void
5131 message_with_string (m, string, log)
5132 char *m;
5133 Lisp_Object string;
5134 int log;
5135 {
5136 if (noninteractive)
5137 {
5138 if (m)
5139 {
5140 if (noninteractive_need_newline)
5141 putc ('\n', stderr);
5142 noninteractive_need_newline = 0;
5143 fprintf (stderr, m, XSTRING (string)->data);
5144 if (cursor_in_echo_area == 0)
5145 fprintf (stderr, "\n");
5146 fflush (stderr);
5147 }
5148 }
5149 else if (INTERACTIVE)
5150 {
5151 /* The frame whose minibuffer we're going to display the message on.
5152 It may be larger than the selected frame, so we need
5153 to use its buffer, not the selected frame's buffer. */
5154 Lisp_Object mini_window;
5155 struct frame *f, *sf = SELECTED_FRAME ();
5156
5157 /* Get the frame containing the minibuffer
5158 that the selected frame is using. */
5159 mini_window = FRAME_MINIBUF_WINDOW (sf);
5160 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5161
5162 /* A null message buffer means that the frame hasn't really been
5163 initialized yet. Error messages get reported properly by
5164 cmd_error, so this must be just an informative message; toss it. */
5165 if (FRAME_MESSAGE_BUF (f))
5166 {
5167 int len;
5168 char *a[1];
5169 a[0] = (char *) XSTRING (string)->data;
5170
5171 len = doprnt (FRAME_MESSAGE_BUF (f),
5172 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5173
5174 if (log)
5175 message2 (FRAME_MESSAGE_BUF (f), len,
5176 STRING_MULTIBYTE (string));
5177 else
5178 message2_nolog (FRAME_MESSAGE_BUF (f), len,
5179 STRING_MULTIBYTE (string));
5180
5181 /* Print should start at the beginning of the message
5182 buffer next time. */
5183 message_buf_print = 0;
5184 }
5185 }
5186 }
5187
5188
5189 /* Dump an informative message to the minibuf. If M is 0, clear out
5190 any existing message, and let the mini-buffer text show through. */
5191
5192 /* VARARGS 1 */
5193 void
5194 message (m, a1, a2, a3)
5195 char *m;
5196 EMACS_INT a1, a2, a3;
5197 {
5198 if (noninteractive)
5199 {
5200 if (m)
5201 {
5202 if (noninteractive_need_newline)
5203 putc ('\n', stderr);
5204 noninteractive_need_newline = 0;
5205 fprintf (stderr, m, a1, a2, a3);
5206 if (cursor_in_echo_area == 0)
5207 fprintf (stderr, "\n");
5208 fflush (stderr);
5209 }
5210 }
5211 else if (INTERACTIVE)
5212 {
5213 /* The frame whose mini-buffer we're going to display the message
5214 on. It may be larger than the selected frame, so we need to
5215 use its buffer, not the selected frame's buffer. */
5216 Lisp_Object mini_window;
5217 struct frame *f, *sf = SELECTED_FRAME ();
5218
5219 /* Get the frame containing the mini-buffer
5220 that the selected frame is using. */
5221 mini_window = FRAME_MINIBUF_WINDOW (sf);
5222 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
5223
5224 /* A null message buffer means that the frame hasn't really been
5225 initialized yet. Error messages get reported properly by
5226 cmd_error, so this must be just an informative message; toss
5227 it. */
5228 if (FRAME_MESSAGE_BUF (f))
5229 {
5230 if (m)
5231 {
5232 int len;
5233 #ifdef NO_ARG_ARRAY
5234 char *a[3];
5235 a[0] = (char *) a1;
5236 a[1] = (char *) a2;
5237 a[2] = (char *) a3;
5238
5239 len = doprnt (FRAME_MESSAGE_BUF (f),
5240 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
5241 #else
5242 len = doprnt (FRAME_MESSAGE_BUF (f),
5243 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
5244 (char **) &a1);
5245 #endif /* NO_ARG_ARRAY */
5246
5247 message2 (FRAME_MESSAGE_BUF (f), len, 0);
5248 }
5249 else
5250 message1 (0);
5251
5252 /* Print should start at the beginning of the message
5253 buffer next time. */
5254 message_buf_print = 0;
5255 }
5256 }
5257 }
5258
5259
5260 /* The non-logging version of message. */
5261
5262 void
5263 message_nolog (m, a1, a2, a3)
5264 char *m;
5265 EMACS_INT a1, a2, a3;
5266 {
5267 Lisp_Object old_log_max;
5268 old_log_max = Vmessage_log_max;
5269 Vmessage_log_max = Qnil;
5270 message (m, a1, a2, a3);
5271 Vmessage_log_max = old_log_max;
5272 }
5273
5274
5275 /* Display the current message in the current mini-buffer. This is
5276 only called from error handlers in process.c, and is not time
5277 critical. */
5278
5279 void
5280 update_echo_area ()
5281 {
5282 if (!NILP (echo_area_buffer[0]))
5283 {
5284 Lisp_Object string;
5285 string = Fcurrent_message ();
5286 message3 (string, XSTRING (string)->size,
5287 !NILP (current_buffer->enable_multibyte_characters));
5288 }
5289 }
5290
5291
5292 /* Make sure echo area buffers in echo_buffers[] are life. If they
5293 aren't, make new ones. */
5294
5295 static void
5296 ensure_echo_area_buffers ()
5297 {
5298 int i;
5299
5300 for (i = 0; i < 2; ++i)
5301 if (!BUFFERP (echo_buffer[i])
5302 || NILP (XBUFFER (echo_buffer[i])->name))
5303 {
5304 char name[30];
5305 sprintf (name, " *Echo Area %d*", i);
5306 echo_buffer[i] = Fget_buffer_create (build_string (name));
5307 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
5308 }
5309 }
5310
5311
5312 /* Call FN with args A1..A5 with either the current or last displayed
5313 echo_area_buffer as current buffer.
5314
5315 WHICH zero means use the current message buffer
5316 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5317 from echo_buffer[] and clear it.
5318
5319 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5320 suitable buffer from echo_buffer[] and clear it.
5321
5322 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5323 that the current message becomes the last displayed one, make
5324 choose a suitable buffer for echo_area_buffer[0], and clear it.
5325
5326 Value is what FN returns. */
5327
5328 static int
5329 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
5330 struct window *w;
5331 int which;
5332 int (*fn) ();
5333 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
5334 {
5335 Lisp_Object buffer;
5336 int this_one, the_other, clear_buffer_p, rc;
5337 int count = specpdl_ptr - specpdl;
5338
5339 /* If buffers aren't life, make new ones. */
5340 ensure_echo_area_buffers ();
5341
5342 clear_buffer_p = 0;
5343
5344 if (which == 0)
5345 this_one = 0, the_other = 1;
5346 else if (which > 0)
5347 this_one = 1, the_other = 0;
5348 else
5349 {
5350 this_one = 0, the_other = 1;
5351 clear_buffer_p = 1;
5352
5353 /* We need a fresh one in case the current echo buffer equals
5354 the one containing the last displayed echo area message. */
5355 if (!NILP (echo_area_buffer[this_one])
5356 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
5357 echo_area_buffer[this_one] = Qnil;
5358 }
5359
5360 /* Choose a suitable buffer from echo_buffer[] is we don't
5361 have one. */
5362 if (NILP (echo_area_buffer[this_one]))
5363 {
5364 echo_area_buffer[this_one]
5365 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
5366 ? echo_buffer[the_other]
5367 : echo_buffer[this_one]);
5368 clear_buffer_p = 1;
5369 }
5370
5371 buffer = echo_area_buffer[this_one];
5372
5373 record_unwind_protect (unwind_with_echo_area_buffer,
5374 with_echo_area_buffer_unwind_data (w));
5375
5376 /* Make the echo area buffer current. Note that for display
5377 purposes, it is not necessary that the displayed window's buffer
5378 == current_buffer, except for text property lookup. So, let's
5379 only set that buffer temporarily here without doing a full
5380 Fset_window_buffer. We must also change w->pointm, though,
5381 because otherwise an assertions in unshow_buffer fails, and Emacs
5382 aborts. */
5383 set_buffer_internal_1 (XBUFFER (buffer));
5384 if (w)
5385 {
5386 w->buffer = buffer;
5387 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
5388 }
5389
5390 current_buffer->undo_list = Qt;
5391 current_buffer->read_only = Qnil;
5392
5393 if (clear_buffer_p && Z > BEG)
5394 del_range (BEG, Z);
5395
5396 xassert (BEGV >= BEG);
5397 xassert (ZV <= Z && ZV >= BEGV);
5398
5399 rc = fn (a1, a2, a3, a4, a5);
5400
5401 xassert (BEGV >= BEG);
5402 xassert (ZV <= Z && ZV >= BEGV);
5403
5404 unbind_to (count, Qnil);
5405 return rc;
5406 }
5407
5408
5409 /* Save state that should be preserved around the call to the function
5410 FN called in with_echo_area_buffer. */
5411
5412 static Lisp_Object
5413 with_echo_area_buffer_unwind_data (w)
5414 struct window *w;
5415 {
5416 int i = 0;
5417 Lisp_Object vector;
5418
5419 /* Reduce consing by keeping one vector in
5420 Vwith_echo_area_save_vector. */
5421 vector = Vwith_echo_area_save_vector;
5422 Vwith_echo_area_save_vector = Qnil;
5423
5424 if (NILP (vector))
5425 vector = Fmake_vector (make_number (7), Qnil);
5426
5427 XSETBUFFER (XVECTOR (vector)->contents[i], current_buffer); ++i;
5428 XVECTOR (vector)->contents[i++] = Vdeactivate_mark;
5429 XVECTOR (vector)->contents[i++] = make_number (windows_or_buffers_changed);
5430
5431 if (w)
5432 {
5433 XSETWINDOW (XVECTOR (vector)->contents[i], w); ++i;
5434 XVECTOR (vector)->contents[i++] = w->buffer;
5435 XVECTOR (vector)->contents[i++]
5436 = make_number (XMARKER (w->pointm)->charpos);
5437 XVECTOR (vector)->contents[i++]
5438 = make_number (XMARKER (w->pointm)->bytepos);
5439 }
5440 else
5441 {
5442 int end = i + 4;
5443 while (i < end)
5444 XVECTOR (vector)->contents[i++] = Qnil;
5445 }
5446
5447 xassert (i == XVECTOR (vector)->size);
5448 return vector;
5449 }
5450
5451
5452 /* Restore global state from VECTOR which was created by
5453 with_echo_area_buffer_unwind_data. */
5454
5455 static Lisp_Object
5456 unwind_with_echo_area_buffer (vector)
5457 Lisp_Object vector;
5458 {
5459 int i = 0;
5460
5461 set_buffer_internal_1 (XBUFFER (XVECTOR (vector)->contents[i])); ++i;
5462 Vdeactivate_mark = XVECTOR (vector)->contents[i]; ++i;
5463 windows_or_buffers_changed = XFASTINT (XVECTOR (vector)->contents[i]); ++i;
5464
5465 if (WINDOWP (XVECTOR (vector)->contents[i]))
5466 {
5467 struct window *w;
5468 Lisp_Object buffer, charpos, bytepos;
5469
5470 w = XWINDOW (XVECTOR (vector)->contents[i]); ++i;
5471 buffer = XVECTOR (vector)->contents[i]; ++i;
5472 charpos = XVECTOR (vector)->contents[i]; ++i;
5473 bytepos = XVECTOR (vector)->contents[i]; ++i;
5474
5475 w->buffer = buffer;
5476 set_marker_both (w->pointm, buffer,
5477 XFASTINT (charpos), XFASTINT (bytepos));
5478 }
5479
5480 Vwith_echo_area_save_vector = vector;
5481 return Qnil;
5482 }
5483
5484
5485 /* Set up the echo area for use by print functions. MULTIBYTE_P
5486 non-zero means we will print multibyte. */
5487
5488 void
5489 setup_echo_area_for_printing (multibyte_p)
5490 int multibyte_p;
5491 {
5492 ensure_echo_area_buffers ();
5493
5494 if (!message_buf_print)
5495 {
5496 /* A message has been output since the last time we printed.
5497 Choose a fresh echo area buffer. */
5498 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5499 echo_area_buffer[0] = echo_buffer[1];
5500 else
5501 echo_area_buffer[0] = echo_buffer[0];
5502
5503 /* Switch to that buffer and clear it. */
5504 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5505 if (Z > BEG)
5506 del_range (BEG, Z);
5507 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5508
5509 /* Set up the buffer for the multibyteness we need. */
5510 if (multibyte_p
5511 != !NILP (current_buffer->enable_multibyte_characters))
5512 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
5513
5514 /* Raise the frame containing the echo area. */
5515 if (minibuffer_auto_raise)
5516 {
5517 struct frame *sf = SELECTED_FRAME ();
5518 Lisp_Object mini_window;
5519 mini_window = FRAME_MINIBUF_WINDOW (sf);
5520 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
5521 }
5522
5523 message_buf_print = 1;
5524 }
5525 else
5526 {
5527 if (NILP (echo_area_buffer[0]))
5528 {
5529 if (EQ (echo_area_buffer[1], echo_buffer[0]))
5530 echo_area_buffer[0] = echo_buffer[1];
5531 else
5532 echo_area_buffer[0] = echo_buffer[0];
5533 }
5534
5535 if (current_buffer != XBUFFER (echo_area_buffer[0]))
5536 /* Someone switched buffers between print requests. */
5537 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
5538 }
5539 }
5540
5541
5542 /* Display an echo area message in window W. Value is non-zero if W's
5543 height is changed. If display_last_displayed_message_p is
5544 non-zero, display the message that was last displayed, otherwise
5545 display the current message. */
5546
5547 static int
5548 display_echo_area (w)
5549 struct window *w;
5550 {
5551 int i, no_message_p, window_height_changed_p, count;
5552
5553 /* Temporarily disable garbage collections while displaying the echo
5554 area. This is done because a GC can print a message itself.
5555 That message would modify the echo area buffer's contents while a
5556 redisplay of the buffer is going on, and seriously confuse
5557 redisplay. */
5558 count = inhibit_garbage_collection ();
5559
5560 /* If there is no message, we must call display_echo_area_1
5561 nevertheless because it resizes the window. But we will have to
5562 reset the echo_area_buffer in question to nil at the end because
5563 with_echo_area_buffer will sets it to an empty buffer. */
5564 i = display_last_displayed_message_p ? 1 : 0;
5565 no_message_p = NILP (echo_area_buffer[i]);
5566
5567 window_height_changed_p
5568 = with_echo_area_buffer (w, display_last_displayed_message_p,
5569 (int (*) ()) display_echo_area_1, w);
5570
5571 if (no_message_p)
5572 echo_area_buffer[i] = Qnil;
5573
5574 unbind_to (count, Qnil);
5575 return window_height_changed_p;
5576 }
5577
5578
5579 /* Helper for display_echo_area. Display the current buffer which
5580 contains the current echo area message in window W, a mini-window.
5581 Change the height of W so that all of the message is displayed.
5582 Value is non-zero if height of W was changed. */
5583
5584 static int
5585 display_echo_area_1 (w)
5586 struct window *w;
5587 {
5588 Lisp_Object window;
5589 struct text_pos start;
5590 int window_height_changed_p = 0;
5591
5592 /* Do this before displaying, so that we have a large enough glyph
5593 matrix for the display. */
5594 window_height_changed_p = resize_mini_window (w, 0);
5595
5596 /* Display. */
5597 clear_glyph_matrix (w->desired_matrix);
5598 XSETWINDOW (window, w);
5599 SET_TEXT_POS (start, BEG, BEG_BYTE);
5600 try_window (window, start);
5601
5602 return window_height_changed_p;
5603 }
5604
5605
5606 /* Resize the echo area window to exactly the size needed for the
5607 currently displayed message, if there is one. */
5608
5609 void
5610 resize_echo_area_axactly ()
5611 {
5612 if (BUFFERP (echo_area_buffer[0])
5613 && WINDOWP (echo_area_window))
5614 {
5615 struct window *w = XWINDOW (echo_area_window);
5616 int resized_p;
5617
5618 resized_p = with_echo_area_buffer (w, 0,
5619 (int (*) ()) resize_mini_window,
5620 w, 1);
5621 if (resized_p)
5622 {
5623 ++windows_or_buffers_changed;
5624 ++update_mode_lines;
5625 redisplay_internal (0);
5626 }
5627 }
5628 }
5629
5630
5631 /* Resize mini-window W to fit the size of its contents. EXACT:P
5632 means size the window exactly to the size needed. Otherwise, it's
5633 only enlarged until W's buffer is empty. Value is non-zero if
5634 the window height has been changed. */
5635
5636 int
5637 resize_mini_window (w, exact_p)
5638 struct window *w;
5639 int exact_p;
5640 {
5641 struct frame *f = XFRAME (w->frame);
5642 int window_height_changed_p = 0;
5643
5644 xassert (MINI_WINDOW_P (w));
5645
5646 /* Nil means don't try to resize. */
5647 if (NILP (Vmax_mini_window_height)
5648 || (FRAME_X_P (f) && f->output_data.x == NULL))
5649 return 0;
5650
5651 if (!FRAME_MINIBUF_ONLY_P (f))
5652 {
5653 struct it it;
5654 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
5655 int total_height = XFASTINT (root->height) + XFASTINT (w->height);
5656 int height, max_height;
5657 int unit = CANON_Y_UNIT (f);
5658 struct text_pos start;
5659
5660 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
5661
5662 /* Compute the max. number of lines specified by the user. */
5663 if (FLOATP (Vmax_mini_window_height))
5664 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
5665 else if (INTEGERP (Vmax_mini_window_height))
5666 max_height = XINT (Vmax_mini_window_height);
5667 else
5668 max_height = total_height / 4;
5669
5670 /* Correct that max. height if it's bogus. */
5671 max_height = max (1, max_height);
5672 max_height = min (total_height, max_height);
5673
5674 /* Find out the height of the text in the window. */
5675 if (it.truncate_lines_p)
5676 height = 1;
5677 else
5678 {
5679 last_height = 0;
5680 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
5681 if (it.max_ascent == 0 && it.max_descent == 0)
5682 height = it.current_y + last_height;
5683 else
5684 height = it.current_y + it.max_ascent + it.max_descent;
5685 height = (height + unit - 1) / unit;
5686 }
5687
5688 /* Compute a suitable window start. */
5689 if (height > max_height)
5690 {
5691 height = max_height;
5692 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5693 move_it_vertically_backward (&it, (height - 1) * unit);
5694 start = it.current.pos;
5695 }
5696 else
5697 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5698 SET_MARKER_FROM_TEXT_POS (w->start, start);
5699
5700 /* Let it grow only, until we display an empty message, in which
5701 case the window shrinks again. */
5702 if (height > XFASTINT (w->height))
5703 {
5704 int old_height = XFASTINT (w->height);
5705 freeze_window_starts (f, 1);
5706 grow_mini_window (w, height - XFASTINT (w->height));
5707 window_height_changed_p = XFASTINT (w->height) != old_height;
5708 }
5709 else if (height < XFASTINT (w->height)
5710 && (exact_p || BEGV == ZV))
5711 {
5712 int old_height = XFASTINT (w->height);
5713 freeze_window_starts (f, 0);
5714 shrink_mini_window (w);
5715 window_height_changed_p = XFASTINT (w->height) != old_height;
5716 }
5717 }
5718
5719 return window_height_changed_p;
5720 }
5721
5722
5723 /* Value is the current message, a string, or nil if there is no
5724 current message. */
5725
5726 Lisp_Object
5727 current_message ()
5728 {
5729 Lisp_Object msg;
5730
5731 if (NILP (echo_area_buffer[0]))
5732 msg = Qnil;
5733 else
5734 {
5735 with_echo_area_buffer (0, 0, (int (*) ()) current_message_1, &msg);
5736 if (NILP (msg))
5737 echo_area_buffer[0] = Qnil;
5738 }
5739
5740 return msg;
5741 }
5742
5743
5744 static int
5745 current_message_1 (msg)
5746 Lisp_Object *msg;
5747 {
5748 if (Z > BEG)
5749 *msg = make_buffer_string (BEG, Z, 1);
5750 else
5751 *msg = Qnil;
5752 return 0;
5753 }
5754
5755
5756 /* Push the current message on Vmessage_stack for later restauration
5757 by restore_message. Value is non-zero if the current message isn't
5758 empty. This is a relatively infrequent operation, so it's not
5759 worth optimizing. */
5760
5761 int
5762 push_message ()
5763 {
5764 Lisp_Object msg;
5765 msg = current_message ();
5766 Vmessage_stack = Fcons (msg, Vmessage_stack);
5767 return STRINGP (msg);
5768 }
5769
5770
5771 /* Restore message display from the top of Vmessage_stack. */
5772
5773 void
5774 restore_message ()
5775 {
5776 Lisp_Object msg;
5777
5778 xassert (CONSP (Vmessage_stack));
5779 msg = XCAR (Vmessage_stack);
5780 if (STRINGP (msg))
5781 message3_nolog (msg, STRING_BYTES (XSTRING (msg)), STRING_MULTIBYTE (msg));
5782 else
5783 message3_nolog (msg, 0, 0);
5784 }
5785
5786
5787 /* Pop the top-most entry off Vmessage_stack. */
5788
5789 void
5790 pop_message ()
5791 {
5792 xassert (CONSP (Vmessage_stack));
5793 Vmessage_stack = XCDR (Vmessage_stack);
5794 }
5795
5796
5797 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
5798 exits. If the stack is not empty, we have a missing pop_message
5799 somewhere. */
5800
5801 void
5802 check_message_stack ()
5803 {
5804 if (!NILP (Vmessage_stack))
5805 abort ();
5806 }
5807
5808
5809 /* Truncate to NCHARS what will be displayed in the echo area the next
5810 time we display it---but don't redisplay it now. */
5811
5812 void
5813 truncate_echo_area (nchars)
5814 int nchars;
5815 {
5816 if (nchars == 0)
5817 echo_area_buffer[0] = Qnil;
5818 /* A null message buffer means that the frame hasn't really been
5819 initialized yet. Error messages get reported properly by
5820 cmd_error, so this must be just an informative message; toss it. */
5821 else if (!noninteractive
5822 && INTERACTIVE
5823 && !NILP (echo_area_buffer[0]))
5824 {
5825 struct frame *sf = SELECTED_FRAME ();
5826 if (FRAME_MESSAGE_BUF (sf))
5827 with_echo_area_buffer (0, 0, (int (*) ()) truncate_message_1, nchars);
5828 }
5829 }
5830
5831
5832 /* Helper function for truncate_echo_area. Truncate the current
5833 message to at most NCHARS characters. */
5834
5835 static int
5836 truncate_message_1 (nchars)
5837 int nchars;
5838 {
5839 if (BEG + nchars < Z)
5840 del_range (BEG + nchars, Z);
5841 if (Z == BEG)
5842 echo_area_buffer[0] = Qnil;
5843 return 0;
5844 }
5845
5846
5847 /* Set the current message to a substring of S or STRING.
5848
5849 If STRING is a Lisp string, set the message to the first NBYTES
5850 bytes from STRING. NBYTES zero means use the whole string. If
5851 STRING is multibyte, the message will be displayed multibyte.
5852
5853 If S is not null, set the message to the first LEN bytes of S. LEN
5854 zero means use the whole string. MULTIBYTE_P non-zero means S is
5855 multibyte. Display the message multibyte in that case. */
5856
5857 void
5858 set_message (s, string, nbytes, multibyte_p)
5859 char *s;
5860 Lisp_Object string;
5861 int nbytes;
5862 {
5863 message_enable_multibyte
5864 = ((s && multibyte_p)
5865 || (STRINGP (string) && STRING_MULTIBYTE (string)));
5866
5867 with_echo_area_buffer (0, -1, (int (*) ()) set_message_1,
5868 s, string, nbytes, multibyte_p);
5869 message_buf_print = 0;
5870 }
5871
5872
5873 /* Helper function for set_message. Arguments have the same meaning
5874 as there. This function is called with the echo area buffer being
5875 current. */
5876
5877 static int
5878 set_message_1 (s, string, nbytes, multibyte_p)
5879 char *s;
5880 Lisp_Object string;
5881 int nbytes, multibyte_p;
5882 {
5883 xassert (BEG == Z);
5884
5885 /* Change multibyteness of the echo buffer appropriately. */
5886 if (message_enable_multibyte
5887 != !NILP (current_buffer->enable_multibyte_characters))
5888 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
5889
5890 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
5891
5892 /* Insert new message at BEG. */
5893 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
5894
5895 if (STRINGP (string))
5896 {
5897 int nchars;
5898
5899 if (nbytes == 0)
5900 nbytes = XSTRING (string)->size_byte;
5901 nchars = string_byte_to_char (string, nbytes);
5902
5903 /* This function takes care of single/multibyte conversion. We
5904 just have to ensure that the echo area buffer has the right
5905 setting of enable_multibyte_characters. */
5906 insert_from_string (string, 0, 0, nchars, nbytes, 1);
5907 }
5908 else if (s)
5909 {
5910 if (nbytes == 0)
5911 nbytes = strlen (s);
5912
5913 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
5914 {
5915 /* Convert from multi-byte to single-byte. */
5916 int i, c, n;
5917 unsigned char work[1];
5918
5919 /* Convert a multibyte string to single-byte. */
5920 for (i = 0; i < nbytes; i += n)
5921 {
5922 c = string_char_and_length (s + i, nbytes - i, &n);
5923 work[0] = (SINGLE_BYTE_CHAR_P (c)
5924 ? c
5925 : multibyte_char_to_unibyte (c, Qnil));
5926 insert_1_both (work, 1, 1, 1, 0, 0);
5927 }
5928 }
5929 else if (!multibyte_p
5930 && !NILP (current_buffer->enable_multibyte_characters))
5931 {
5932 /* Convert from single-byte to multi-byte. */
5933 int i, c, n;
5934 unsigned char *msg = (unsigned char *) s;
5935 unsigned char str[MAX_MULTIBYTE_LENGTH];
5936
5937 /* Convert a single-byte string to multibyte. */
5938 for (i = 0; i < nbytes; i++)
5939 {
5940 c = unibyte_char_to_multibyte (msg[i]);
5941 n = CHAR_STRING (c, str);
5942 insert_1_both (str, 1, n, 1, 0, 0);
5943 }
5944 }
5945 else
5946 insert_1 (s, nbytes, 1, 0, 0);
5947 }
5948
5949 return 0;
5950 }
5951
5952
5953 /* Clear messages. CURRENT_P non-zero means clear the current
5954 message. LAST_DISPLAYED_P non-zero means clear the message
5955 last displayed. */
5956
5957 void
5958 clear_message (current_p, last_displayed_p)
5959 int current_p, last_displayed_p;
5960 {
5961 if (current_p)
5962 echo_area_buffer[0] = Qnil;
5963
5964 if (last_displayed_p)
5965 echo_area_buffer[1] = Qnil;
5966
5967 message_buf_print = 0;
5968 }
5969
5970 /* Clear garbaged frames.
5971
5972 This function is used where the old redisplay called
5973 redraw_garbaged_frames which in turn called redraw_frame which in
5974 turn called clear_frame. The call to clear_frame was a source of
5975 flickering. I believe a clear_frame is not necessary. It should
5976 suffice in the new redisplay to invalidate all current matrices,
5977 and ensure a complete redisplay of all windows. */
5978
5979 static void
5980 clear_garbaged_frames ()
5981 {
5982 if (frame_garbaged)
5983 {
5984 Lisp_Object tail, frame;
5985
5986 FOR_EACH_FRAME (tail, frame)
5987 {
5988 struct frame *f = XFRAME (frame);
5989
5990 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
5991 {
5992 clear_current_matrices (f);
5993 f->garbaged = 0;
5994 }
5995 }
5996
5997 frame_garbaged = 0;
5998 ++windows_or_buffers_changed;
5999 }
6000 }
6001
6002
6003 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
6004 is non-zero update selected_frame. Value is non-zero if the
6005 mini-windows height has been changed. */
6006
6007 static int
6008 echo_area_display (update_frame_p)
6009 int update_frame_p;
6010 {
6011 Lisp_Object mini_window;
6012 struct window *w;
6013 struct frame *f;
6014 int window_height_changed_p = 0;
6015 struct frame *sf = SELECTED_FRAME ();
6016
6017 mini_window = FRAME_MINIBUF_WINDOW (sf);
6018 w = XWINDOW (mini_window);
6019 f = XFRAME (WINDOW_FRAME (w));
6020
6021 /* Don't display if frame is invisible or not yet initialized. */
6022 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
6023 return 0;
6024
6025 #ifdef HAVE_WINDOW_SYSTEM
6026 /* When Emacs starts, selected_frame may be a visible terminal
6027 frame, even if we run under a window system. If we let this
6028 through, a message would be displayed on the terminal. */
6029 if (EQ (selected_frame, Vterminal_frame)
6030 && !NILP (Vwindow_system))
6031 return 0;
6032 #endif /* HAVE_WINDOW_SYSTEM */
6033
6034 /* Redraw garbaged frames. */
6035 if (frame_garbaged)
6036 clear_garbaged_frames ();
6037
6038 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
6039 {
6040 echo_area_window = mini_window;
6041 window_height_changed_p = display_echo_area (w);
6042 w->must_be_updated_p = 1;
6043
6044 if (update_frame_p)
6045 {
6046 /* Not called from redisplay_internal. If we changed
6047 window configuration, we must redisplay thoroughly.
6048 Otherwise, we can do with updating what we displayed
6049 above. */
6050 if (window_height_changed_p)
6051 {
6052 ++windows_or_buffers_changed;
6053 ++update_mode_lines;
6054 redisplay_internal (0);
6055 }
6056 else if (FRAME_WINDOW_P (f))
6057 {
6058 update_single_window (w, 1);
6059 rif->flush_display (f);
6060 }
6061 else
6062 update_frame (f, 1, 1);
6063 }
6064 }
6065 else if (!EQ (mini_window, selected_window))
6066 windows_or_buffers_changed++;
6067
6068 /* Last displayed message is now the current message. */
6069 echo_area_buffer[1] = echo_area_buffer[0];
6070
6071 /* Prevent redisplay optimization in redisplay_internal by resetting
6072 this_line_start_pos. This is done because the mini-buffer now
6073 displays the message instead of its buffer text. */
6074 if (EQ (mini_window, selected_window))
6075 CHARPOS (this_line_start_pos) = 0;
6076
6077 return window_height_changed_p;
6078 }
6079
6080
6081 \f
6082 /***********************************************************************
6083 Frame Titles
6084 ***********************************************************************/
6085
6086
6087 #ifdef HAVE_WINDOW_SYSTEM
6088
6089 /* A buffer for constructing frame titles in it; allocated from the
6090 heap in init_xdisp and resized as needed in store_frame_title_char. */
6091
6092 static char *frame_title_buf;
6093
6094 /* The buffer's end, and a current output position in it. */
6095
6096 static char *frame_title_buf_end;
6097 static char *frame_title_ptr;
6098
6099
6100 /* Store a single character C for the frame title in frame_title_buf.
6101 Re-allocate frame_title_buf if necessary. */
6102
6103 static void
6104 store_frame_title_char (c)
6105 char c;
6106 {
6107 /* If output position has reached the end of the allocated buffer,
6108 double the buffer's size. */
6109 if (frame_title_ptr == frame_title_buf_end)
6110 {
6111 int len = frame_title_ptr - frame_title_buf;
6112 int new_size = 2 * len * sizeof *frame_title_buf;
6113 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
6114 frame_title_buf_end = frame_title_buf + new_size;
6115 frame_title_ptr = frame_title_buf + len;
6116 }
6117
6118 *frame_title_ptr++ = c;
6119 }
6120
6121
6122 /* Store part of a frame title in frame_title_buf, beginning at
6123 frame_title_ptr. STR is the string to store. Do not copy more
6124 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
6125 the whole string. Pad with spaces until FIELD_WIDTH number of
6126 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
6127 Called from display_mode_element when it is used to build a frame
6128 title. */
6129
6130 static int
6131 store_frame_title (str, field_width, precision)
6132 unsigned char *str;
6133 int field_width, precision;
6134 {
6135 int n = 0;
6136
6137 /* Copy at most PRECISION chars from STR. */
6138 while ((precision <= 0 || n < precision)
6139 && *str)
6140 {
6141 store_frame_title_char (*str++);
6142 ++n;
6143 }
6144
6145 /* Fill up with spaces until FIELD_WIDTH reached. */
6146 while (field_width > 0
6147 && n < field_width)
6148 {
6149 store_frame_title_char (' ');
6150 ++n;
6151 }
6152
6153 return n;
6154 }
6155
6156
6157 /* Set the title of FRAME, if it has changed. The title format is
6158 Vicon_title_format if FRAME is iconified, otherwise it is
6159 frame_title_format. */
6160
6161 static void
6162 x_consider_frame_title (frame)
6163 Lisp_Object frame;
6164 {
6165 struct frame *f = XFRAME (frame);
6166
6167 if (FRAME_WINDOW_P (f)
6168 || FRAME_MINIBUF_ONLY_P (f)
6169 || f->explicit_name)
6170 {
6171 /* Do we have more than one visible frame on this X display? */
6172 Lisp_Object tail;
6173 Lisp_Object fmt;
6174 struct buffer *obuf;
6175 int len;
6176 struct it it;
6177
6178 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
6179 {
6180 struct frame *tf = XFRAME (XCAR (tail));
6181
6182 if (tf != f
6183 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
6184 && !FRAME_MINIBUF_ONLY_P (tf)
6185 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
6186 break;
6187 }
6188
6189 /* Set global variable indicating that multiple frames exist. */
6190 multiple_frames = CONSP (tail);
6191
6192 /* Switch to the buffer of selected window of the frame. Set up
6193 frame_title_ptr so that display_mode_element will output into it;
6194 then display the title. */
6195 obuf = current_buffer;
6196 Fset_buffer (XWINDOW (f->selected_window)->buffer);
6197 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
6198 frame_title_ptr = frame_title_buf;
6199 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
6200 NULL, DEFAULT_FACE_ID);
6201 len = display_mode_element (&it, 0, -1, -1, fmt);
6202 frame_title_ptr = NULL;
6203 set_buffer_internal (obuf);
6204
6205 /* Set the title only if it's changed. This avoids consing in
6206 the common case where it hasn't. (If it turns out that we've
6207 already wasted too much time by walking through the list with
6208 display_mode_element, then we might need to optimize at a
6209 higher level than this.) */
6210 if (! STRINGP (f->name)
6211 || STRING_BYTES (XSTRING (f->name)) != len
6212 || bcmp (frame_title_buf, XSTRING (f->name)->data, len) != 0)
6213 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
6214 }
6215 }
6216
6217 #else /* not HAVE_WINDOW_SYSTEM */
6218
6219 #define frame_title_ptr ((char *)0)
6220 #define store_frame_title(str, mincol, maxcol) 0
6221
6222 #endif /* not HAVE_WINDOW_SYSTEM */
6223
6224
6225
6226 \f
6227 /***********************************************************************
6228 Menu Bars
6229 ***********************************************************************/
6230
6231
6232 /* Prepare for redisplay by updating menu-bar item lists when
6233 appropriate. This can call eval. */
6234
6235 void
6236 prepare_menu_bars ()
6237 {
6238 int all_windows;
6239 struct gcpro gcpro1, gcpro2;
6240 struct frame *f;
6241 struct frame *tooltip_frame;
6242
6243 #ifdef HAVE_X_WINDOWS
6244 tooltip_frame = tip_frame;
6245 #else
6246 tooltip_frame = NULL;
6247 #endif
6248
6249 /* Update all frame titles based on their buffer names, etc. We do
6250 this before the menu bars so that the buffer-menu will show the
6251 up-to-date frame titles. */
6252 #ifdef HAVE_WINDOW_SYSTEM
6253 if (windows_or_buffers_changed || update_mode_lines)
6254 {
6255 Lisp_Object tail, frame;
6256
6257 FOR_EACH_FRAME (tail, frame)
6258 {
6259 f = XFRAME (frame);
6260 if (f != tooltip_frame
6261 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
6262 x_consider_frame_title (frame);
6263 }
6264 }
6265 #endif /* HAVE_WINDOW_SYSTEM */
6266
6267 /* Update the menu bar item lists, if appropriate. This has to be
6268 done before any actual redisplay or generation of display lines. */
6269 all_windows = (update_mode_lines
6270 || buffer_shared > 1
6271 || windows_or_buffers_changed);
6272 if (all_windows)
6273 {
6274 Lisp_Object tail, frame;
6275 int count = specpdl_ptr - specpdl;
6276
6277 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6278
6279 FOR_EACH_FRAME (tail, frame)
6280 {
6281 f = XFRAME (frame);
6282
6283 /* Ignore tooltip frame. */
6284 if (f == tooltip_frame)
6285 continue;
6286
6287 /* If a window on this frame changed size, report that to
6288 the user and clear the size-change flag. */
6289 if (FRAME_WINDOW_SIZES_CHANGED (f))
6290 {
6291 Lisp_Object functions;
6292
6293 /* Clear flag first in case we get an error below. */
6294 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
6295 functions = Vwindow_size_change_functions;
6296 GCPRO2 (tail, functions);
6297
6298 while (CONSP (functions))
6299 {
6300 call1 (XCAR (functions), frame);
6301 functions = XCDR (functions);
6302 }
6303 UNGCPRO;
6304 }
6305
6306 GCPRO1 (tail);
6307 update_menu_bar (f, 0);
6308 #ifdef HAVE_WINDOW_SYSTEM
6309 update_tool_bar (f, 0);
6310 #endif
6311 UNGCPRO;
6312 }
6313
6314 unbind_to (count, Qnil);
6315 }
6316 else
6317 {
6318 struct frame *sf = SELECTED_FRAME ();
6319 update_menu_bar (sf, 1);
6320 #ifdef HAVE_WINDOW_SYSTEM
6321 update_tool_bar (sf, 1);
6322 #endif
6323 }
6324
6325 /* Motif needs this. See comment in xmenu.c. Turn it off when
6326 pending_menu_activation is not defined. */
6327 #ifdef USE_X_TOOLKIT
6328 pending_menu_activation = 0;
6329 #endif
6330 }
6331
6332
6333 /* Update the menu bar item list for frame F. This has to be done
6334 before we start to fill in any display lines, because it can call
6335 eval.
6336
6337 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6338
6339 static void
6340 update_menu_bar (f, save_match_data)
6341 struct frame *f;
6342 int save_match_data;
6343 {
6344 Lisp_Object window;
6345 register struct window *w;
6346
6347 window = FRAME_SELECTED_WINDOW (f);
6348 w = XWINDOW (window);
6349
6350 if (update_mode_lines)
6351 w->update_mode_line = Qt;
6352
6353 if (FRAME_WINDOW_P (f)
6354 ?
6355 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6356 FRAME_EXTERNAL_MENU_BAR (f)
6357 #else
6358 FRAME_MENU_BAR_LINES (f) > 0
6359 #endif
6360 : FRAME_MENU_BAR_LINES (f) > 0)
6361 {
6362 /* If the user has switched buffers or windows, we need to
6363 recompute to reflect the new bindings. But we'll
6364 recompute when update_mode_lines is set too; that means
6365 that people can use force-mode-line-update to request
6366 that the menu bar be recomputed. The adverse effect on
6367 the rest of the redisplay algorithm is about the same as
6368 windows_or_buffers_changed anyway. */
6369 if (windows_or_buffers_changed
6370 || !NILP (w->update_mode_line)
6371 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6372 < BUF_MODIFF (XBUFFER (w->buffer)))
6373 != !NILP (w->last_had_star))
6374 || ((!NILP (Vtransient_mark_mode)
6375 && !NILP (XBUFFER (w->buffer)->mark_active))
6376 != !NILP (w->region_showing)))
6377 {
6378 struct buffer *prev = current_buffer;
6379 int count = specpdl_ptr - specpdl;
6380
6381 set_buffer_internal_1 (XBUFFER (w->buffer));
6382 if (save_match_data)
6383 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6384 if (NILP (Voverriding_local_map_menu_flag))
6385 {
6386 specbind (Qoverriding_terminal_local_map, Qnil);
6387 specbind (Qoverriding_local_map, Qnil);
6388 }
6389
6390 /* Run the Lucid hook. */
6391 call1 (Vrun_hooks, Qactivate_menubar_hook);
6392
6393 /* If it has changed current-menubar from previous value,
6394 really recompute the menu-bar from the value. */
6395 if (! NILP (Vlucid_menu_bar_dirty_flag))
6396 call0 (Qrecompute_lucid_menubar);
6397
6398 safe_run_hooks (Qmenu_bar_update_hook);
6399 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
6400
6401 /* Redisplay the menu bar in case we changed it. */
6402 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
6403 if (FRAME_WINDOW_P (f))
6404 set_frame_menubar (f, 0, 0);
6405 else
6406 /* On a terminal screen, the menu bar is an ordinary screen
6407 line, and this makes it get updated. */
6408 w->update_mode_line = Qt;
6409 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6410 /* In the non-toolkit version, the menu bar is an ordinary screen
6411 line, and this makes it get updated. */
6412 w->update_mode_line = Qt;
6413 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6414
6415 unbind_to (count, Qnil);
6416 set_buffer_internal_1 (prev);
6417 }
6418 }
6419 }
6420
6421
6422 \f
6423 /***********************************************************************
6424 Tool-bars
6425 ***********************************************************************/
6426
6427 #ifdef HAVE_WINDOW_SYSTEM
6428
6429 /* Update the tool-bar item list for frame F. This has to be done
6430 before we start to fill in any display lines. Called from
6431 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
6432 and restore it here. */
6433
6434 static void
6435 update_tool_bar (f, save_match_data)
6436 struct frame *f;
6437 int save_match_data;
6438 {
6439 if (WINDOWP (f->tool_bar_window)
6440 && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0)
6441 {
6442 Lisp_Object window;
6443 struct window *w;
6444
6445 window = FRAME_SELECTED_WINDOW (f);
6446 w = XWINDOW (window);
6447
6448 /* If the user has switched buffers or windows, we need to
6449 recompute to reflect the new bindings. But we'll
6450 recompute when update_mode_lines is set too; that means
6451 that people can use force-mode-line-update to request
6452 that the menu bar be recomputed. The adverse effect on
6453 the rest of the redisplay algorithm is about the same as
6454 windows_or_buffers_changed anyway. */
6455 if (windows_or_buffers_changed
6456 || !NILP (w->update_mode_line)
6457 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
6458 < BUF_MODIFF (XBUFFER (w->buffer)))
6459 != !NILP (w->last_had_star))
6460 || ((!NILP (Vtransient_mark_mode)
6461 && !NILP (XBUFFER (w->buffer)->mark_active))
6462 != !NILP (w->region_showing)))
6463 {
6464 struct buffer *prev = current_buffer;
6465 int count = specpdl_ptr - specpdl;
6466
6467 /* Set current_buffer to the buffer of the selected
6468 window of the frame, so that we get the right local
6469 keymaps. */
6470 set_buffer_internal_1 (XBUFFER (w->buffer));
6471
6472 /* Save match data, if we must. */
6473 if (save_match_data)
6474 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
6475
6476 /* Make sure that we don't accidentally use bogus keymaps. */
6477 if (NILP (Voverriding_local_map_menu_flag))
6478 {
6479 specbind (Qoverriding_terminal_local_map, Qnil);
6480 specbind (Qoverriding_local_map, Qnil);
6481 }
6482
6483 /* Build desired tool-bar items from keymaps. */
6484 f->desired_tool_bar_items
6485 = tool_bar_items (f->desired_tool_bar_items,
6486 &f->n_desired_tool_bar_items);
6487
6488 /* Redisplay the tool-bar in case we changed it. */
6489 w->update_mode_line = Qt;
6490
6491 unbind_to (count, Qnil);
6492 set_buffer_internal_1 (prev);
6493 }
6494 }
6495 }
6496
6497
6498 /* Set F->desired_tool_bar_string to a Lisp string representing frame
6499 F's desired tool-bar contents. F->desired_tool_bar_items must have
6500 been set up previously by calling prepare_menu_bars. */
6501
6502 static void
6503 build_desired_tool_bar_string (f)
6504 struct frame *f;
6505 {
6506 int i, size, size_needed, string_idx;
6507 struct gcpro gcpro1, gcpro2, gcpro3;
6508 Lisp_Object image, plist, props;
6509
6510 image = plist = props = Qnil;
6511 GCPRO3 (image, plist, props);
6512
6513 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
6514 Otherwise, make a new string. */
6515
6516 /* The size of the string we might be able to reuse. */
6517 size = (STRINGP (f->desired_tool_bar_string)
6518 ? XSTRING (f->desired_tool_bar_string)->size
6519 : 0);
6520
6521 /* Each image in the string we build is preceded by a space,
6522 and there is a space at the end. */
6523 size_needed = f->n_desired_tool_bar_items + 1;
6524
6525 /* Reuse f->desired_tool_bar_string, if possible. */
6526 if (size < size_needed)
6527 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
6528 make_number (' '));
6529 else
6530 {
6531 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
6532 Fremove_text_properties (make_number (0), make_number (size),
6533 props, f->desired_tool_bar_string);
6534 }
6535
6536 /* Put a `display' property on the string for the images to display,
6537 put a `menu_item' property on tool-bar items with a value that
6538 is the index of the item in F's tool-bar item vector. */
6539 for (i = 0, string_idx = 0;
6540 i < f->n_desired_tool_bar_items;
6541 ++i, string_idx += 1)
6542 {
6543 #define PROP(IDX) \
6544 (XVECTOR (f->desired_tool_bar_items) \
6545 ->contents[i * TOOL_BAR_ITEM_NSLOTS + (IDX)])
6546
6547 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
6548 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
6549 int margin, relief;
6550 extern Lisp_Object QCrelief, QCmargin, QCalgorithm, Qimage;
6551 extern Lisp_Object Qlaplace;
6552
6553 /* If image is a vector, choose the image according to the
6554 button state. */
6555 image = PROP (TOOL_BAR_ITEM_IMAGES);
6556 if (VECTORP (image))
6557 {
6558 enum tool_bar_item_image idx;
6559
6560 if (enabled_p)
6561 idx = (selected_p
6562 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
6563 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
6564 else
6565 idx = (selected_p
6566 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
6567 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
6568
6569 xassert (XVECTOR (image)->size >= idx);
6570 image = XVECTOR (image)->contents[idx];
6571 }
6572
6573 /* Ignore invalid image specifications. */
6574 if (!valid_image_p (image))
6575 continue;
6576
6577 /* Display the tool-bar button pressed, or depressed. */
6578 plist = Fcopy_sequence (XCDR (image));
6579
6580 /* Compute margin and relief to draw. */
6581 relief = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
6582 margin = relief + max (0, tool_bar_button_margin);
6583
6584 if (auto_raise_tool_bar_buttons_p)
6585 {
6586 /* Add a `:relief' property to the image spec if the item is
6587 selected. */
6588 if (selected_p)
6589 {
6590 plist = Fplist_put (plist, QCrelief, make_number (-relief));
6591 margin -= relief;
6592 }
6593 }
6594 else
6595 {
6596 /* If image is selected, display it pressed, i.e. with a
6597 negative relief. If it's not selected, display it with a
6598 raised relief. */
6599 plist = Fplist_put (plist, QCrelief,
6600 (selected_p
6601 ? make_number (-relief)
6602 : make_number (relief)));
6603 margin -= relief;
6604 }
6605
6606 /* Put a margin around the image. */
6607 if (margin)
6608 plist = Fplist_put (plist, QCmargin, make_number (margin));
6609
6610 /* If button is not enabled, make the image appear disabled by
6611 applying an appropriate algorithm to it. */
6612 if (!enabled_p)
6613 plist = Fplist_put (plist, QCalgorithm, Qlaplace);
6614
6615 /* Put a `display' text property on the string for the image to
6616 display. Put a `menu-item' property on the string that gives
6617 the start of this item's properties in the tool-bar items
6618 vector. */
6619 image = Fcons (Qimage, plist);
6620 props = list4 (Qdisplay, image,
6621 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)),
6622 Fadd_text_properties (make_number (string_idx),
6623 make_number (string_idx + 1),
6624 props, f->desired_tool_bar_string);
6625 #undef PROP
6626 }
6627
6628 UNGCPRO;
6629 }
6630
6631
6632 /* Display one line of the tool-bar of frame IT->f. */
6633
6634 static void
6635 display_tool_bar_line (it)
6636 struct it *it;
6637 {
6638 struct glyph_row *row = it->glyph_row;
6639 int max_x = it->last_visible_x;
6640 struct glyph *last;
6641
6642 prepare_desired_row (row);
6643 row->y = it->current_y;
6644
6645 while (it->current_x < max_x)
6646 {
6647 int x_before, x, n_glyphs_before, i, nglyphs;
6648
6649 /* Get the next display element. */
6650 if (!get_next_display_element (it))
6651 break;
6652
6653 /* Produce glyphs. */
6654 x_before = it->current_x;
6655 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
6656 PRODUCE_GLYPHS (it);
6657
6658 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
6659 i = 0;
6660 x = x_before;
6661 while (i < nglyphs)
6662 {
6663 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
6664
6665 if (x + glyph->pixel_width > max_x)
6666 {
6667 /* Glyph doesn't fit on line. */
6668 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
6669 it->current_x = x;
6670 goto out;
6671 }
6672
6673 ++it->hpos;
6674 x += glyph->pixel_width;
6675 ++i;
6676 }
6677
6678 /* Stop at line ends. */
6679 if (ITERATOR_AT_END_OF_LINE_P (it))
6680 break;
6681
6682 set_iterator_to_next (it);
6683 }
6684
6685 out:;
6686
6687 row->displays_text_p = row->used[TEXT_AREA] != 0;
6688 extend_face_to_end_of_line (it);
6689 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
6690 last->right_box_line_p = 1;
6691 compute_line_metrics (it);
6692
6693 /* If line is empty, make it occupy the rest of the tool-bar. */
6694 if (!row->displays_text_p)
6695 {
6696 row->height = row->phys_height = it->last_visible_y - row->y;
6697 row->ascent = row->phys_ascent = 0;
6698 }
6699
6700 row->full_width_p = 1;
6701 row->continued_p = 0;
6702 row->truncated_on_left_p = 0;
6703 row->truncated_on_right_p = 0;
6704
6705 it->current_x = it->hpos = 0;
6706 it->current_y += row->height;
6707 ++it->vpos;
6708 ++it->glyph_row;
6709 }
6710
6711
6712 /* Value is the number of screen lines needed to make all tool-bar
6713 items of frame F visible. */
6714
6715 static int
6716 tool_bar_lines_needed (f)
6717 struct frame *f;
6718 {
6719 struct window *w = XWINDOW (f->tool_bar_window);
6720 struct it it;
6721
6722 /* Initialize an iterator for iteration over
6723 F->desired_tool_bar_string in the tool-bar window of frame F. */
6724 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6725 it.first_visible_x = 0;
6726 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6727 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6728
6729 while (!ITERATOR_AT_END_P (&it))
6730 {
6731 it.glyph_row = w->desired_matrix->rows;
6732 clear_glyph_row (it.glyph_row);
6733 display_tool_bar_line (&it);
6734 }
6735
6736 return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
6737 }
6738
6739
6740 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
6741 height should be changed. */
6742
6743 static int
6744 redisplay_tool_bar (f)
6745 struct frame *f;
6746 {
6747 struct window *w;
6748 struct it it;
6749 struct glyph_row *row;
6750 int change_height_p = 0;
6751
6752 /* If frame hasn't a tool-bar window or if it is zero-height, don't
6753 do anything. This means you must start with tool-bar-lines
6754 non-zero to get the auto-sizing effect. Or in other words, you
6755 can turn off tool-bars by specifying tool-bar-lines zero. */
6756 if (!WINDOWP (f->tool_bar_window)
6757 || (w = XWINDOW (f->tool_bar_window),
6758 XFASTINT (w->height) == 0))
6759 return 0;
6760
6761 /* Set up an iterator for the tool-bar window. */
6762 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
6763 it.first_visible_x = 0;
6764 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
6765 row = it.glyph_row;
6766
6767 /* Build a string that represents the contents of the tool-bar. */
6768 build_desired_tool_bar_string (f);
6769 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
6770
6771 /* Display as many lines as needed to display all tool-bar items. */
6772 while (it.current_y < it.last_visible_y)
6773 display_tool_bar_line (&it);
6774
6775 /* It doesn't make much sense to try scrolling in the tool-bar
6776 window, so don't do it. */
6777 w->desired_matrix->no_scrolling_p = 1;
6778 w->must_be_updated_p = 1;
6779
6780 if (auto_resize_tool_bars_p)
6781 {
6782 int nlines;
6783
6784 /* If there are blank lines at the end, except for a partially
6785 visible blank line at the end that is smaller than
6786 CANON_Y_UNIT, change the tool-bar's height. */
6787 row = it.glyph_row - 1;
6788 if (!row->displays_text_p
6789 && row->height >= CANON_Y_UNIT (f))
6790 change_height_p = 1;
6791
6792 /* If row displays tool-bar items, but is partially visible,
6793 change the tool-bar's height. */
6794 if (row->displays_text_p
6795 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
6796 change_height_p = 1;
6797
6798 /* Resize windows as needed by changing the `tool-bar-lines'
6799 frame parameter. */
6800 if (change_height_p
6801 && (nlines = tool_bar_lines_needed (f),
6802 nlines != XFASTINT (w->height)))
6803 {
6804 extern Lisp_Object Qtool_bar_lines;
6805 Lisp_Object frame;
6806
6807 XSETFRAME (frame, f);
6808 clear_glyph_matrix (w->desired_matrix);
6809 Fmodify_frame_parameters (frame,
6810 Fcons (Fcons (Qtool_bar_lines,
6811 make_number (nlines)),
6812 Qnil));
6813 fonts_changed_p = 1;
6814 }
6815 }
6816
6817 return change_height_p;
6818 }
6819
6820
6821 /* Get information about the tool-bar item which is displayed in GLYPH
6822 on frame F. Return in *PROP_IDX the index where tool-bar item
6823 properties start in F->current_tool_bar_items. Value is zero if
6824 GLYPH doesn't display a tool-bar item. */
6825
6826 int
6827 tool_bar_item_info (f, glyph, prop_idx)
6828 struct frame *f;
6829 struct glyph *glyph;
6830 int *prop_idx;
6831 {
6832 Lisp_Object prop;
6833 int success_p;
6834
6835 /* Get the text property `menu-item' at pos. The value of that
6836 property is the start index of this item's properties in
6837 F->current_tool_bar_items. */
6838 prop = Fget_text_property (make_number (glyph->charpos),
6839 Qmenu_item, f->current_tool_bar_string);
6840 if (INTEGERP (prop))
6841 {
6842 *prop_idx = XINT (prop);
6843 success_p = 1;
6844 }
6845 else
6846 success_p = 0;
6847
6848 return success_p;
6849 }
6850
6851 #endif /* HAVE_WINDOW_SYSTEM */
6852
6853
6854 \f
6855 /************************************************************************
6856 Horizontal scrolling
6857 ************************************************************************/
6858
6859 static int hscroll_window_tree P_ ((Lisp_Object));
6860 static int hscroll_windows P_ ((Lisp_Object));
6861
6862 /* For all leaf windows in the window tree rooted at WINDOW, set their
6863 hscroll value so that PT is (i) visible in the window, and (ii) so
6864 that it is not within a certain margin at the window's left and
6865 right border. Value is non-zero if any window's hscroll has been
6866 changed. */
6867
6868 static int
6869 hscroll_window_tree (window)
6870 Lisp_Object window;
6871 {
6872 int hscrolled_p = 0;
6873
6874 while (WINDOWP (window))
6875 {
6876 struct window *w = XWINDOW (window);
6877
6878 if (WINDOWP (w->hchild))
6879 hscrolled_p |= hscroll_window_tree (w->hchild);
6880 else if (WINDOWP (w->vchild))
6881 hscrolled_p |= hscroll_window_tree (w->vchild);
6882 else if (w->cursor.vpos >= 0)
6883 {
6884 int hscroll_margin, text_area_x, text_area_y;
6885 int text_area_width, text_area_height;
6886 struct glyph_row *current_cursor_row
6887 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
6888 struct glyph_row *desired_cursor_row
6889 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
6890 struct glyph_row *cursor_row
6891 = (desired_cursor_row->enabled_p
6892 ? desired_cursor_row
6893 : current_cursor_row);
6894
6895 window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
6896 &text_area_width, &text_area_height);
6897
6898 /* Scroll when cursor is inside this scroll margin. */
6899 hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame));
6900
6901 if ((XFASTINT (w->hscroll)
6902 && w->cursor.x < hscroll_margin)
6903 || (cursor_row->enabled_p
6904 && cursor_row->truncated_on_right_p
6905 && (w->cursor.x > text_area_width - hscroll_margin)))
6906 {
6907 struct it it;
6908 int hscroll;
6909 struct buffer *saved_current_buffer;
6910 int pt;
6911
6912 /* Find point in a display of infinite width. */
6913 saved_current_buffer = current_buffer;
6914 current_buffer = XBUFFER (w->buffer);
6915
6916 if (w == XWINDOW (selected_window))
6917 pt = BUF_PT (current_buffer);
6918 else
6919 {
6920 pt = marker_position (w->pointm);
6921 pt = max (BEGV, pt);
6922 pt = min (ZV, pt);
6923 }
6924
6925 /* Move iterator to pt starting at cursor_row->start in
6926 a line with infinite width. */
6927 init_to_row_start (&it, w, cursor_row);
6928 it.last_visible_x = INFINITY;
6929 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
6930 current_buffer = saved_current_buffer;
6931
6932 /* Center cursor in window. */
6933 hscroll = (max (0, it.current_x - text_area_width / 2)
6934 / CANON_X_UNIT (it.f));
6935
6936 /* Don't call Fset_window_hscroll if value hasn't
6937 changed because it will prevent redisplay
6938 optimizations. */
6939 if (XFASTINT (w->hscroll) != hscroll)
6940 {
6941 Fset_window_hscroll (window, make_number (hscroll));
6942 hscrolled_p = 1;
6943 }
6944 }
6945 }
6946
6947 window = w->next;
6948 }
6949
6950 /* Value is non-zero if hscroll of any leaf window has been changed. */
6951 return hscrolled_p;
6952 }
6953
6954
6955 /* Set hscroll so that cursor is visible and not inside horizontal
6956 scroll margins for all windows in the tree rooted at WINDOW. See
6957 also hscroll_window_tree above. Value is non-zero if any window's
6958 hscroll has been changed. If it has, desired matrices on the frame
6959 of WINDOW are cleared. */
6960
6961 static int
6962 hscroll_windows (window)
6963 Lisp_Object window;
6964 {
6965 int hscrolled_p;
6966
6967 if (automatic_hscrolling_p)
6968 {
6969 hscrolled_p = hscroll_window_tree (window);
6970 if (hscrolled_p)
6971 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
6972 }
6973 else
6974 hscrolled_p = 0;
6975 return hscrolled_p;
6976 }
6977
6978
6979 \f
6980 /************************************************************************
6981 Redisplay
6982 ************************************************************************/
6983
6984 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6985 to a non-zero value. This is sometimes handy to have in a debugger
6986 session. */
6987
6988 #if GLYPH_DEBUG
6989
6990 /* First and last unchanged row for try_window_id. */
6991
6992 int debug_first_unchanged_at_end_vpos;
6993 int debug_last_unchanged_at_beg_vpos;
6994
6995 /* Delta vpos and y. */
6996
6997 int debug_dvpos, debug_dy;
6998
6999 /* Delta in characters and bytes for try_window_id. */
7000
7001 int debug_delta, debug_delta_bytes;
7002
7003 /* Values of window_end_pos and window_end_vpos at the end of
7004 try_window_id. */
7005
7006 int debug_end_pos, debug_end_vpos;
7007
7008 /* Append a string to W->desired_matrix->method. FMT is a printf
7009 format string. A1...A9 are a supplement for a variable-length
7010 argument list. If trace_redisplay_p is non-zero also printf the
7011 resulting string to stderr. */
7012
7013 static void
7014 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
7015 struct window *w;
7016 char *fmt;
7017 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
7018 {
7019 char buffer[512];
7020 char *method = w->desired_matrix->method;
7021 int len = strlen (method);
7022 int size = sizeof w->desired_matrix->method;
7023 int remaining = size - len - 1;
7024
7025 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
7026 if (len && remaining)
7027 {
7028 method[len] = '|';
7029 --remaining, ++len;
7030 }
7031
7032 strncpy (method + len, buffer, remaining);
7033
7034 if (trace_redisplay_p)
7035 fprintf (stderr, "%p (%s): %s\n",
7036 w,
7037 ((BUFFERP (w->buffer)
7038 && STRINGP (XBUFFER (w->buffer)->name))
7039 ? (char *) XSTRING (XBUFFER (w->buffer)->name)->data
7040 : "no buffer"),
7041 buffer);
7042 }
7043
7044 #endif /* GLYPH_DEBUG */
7045
7046
7047 /* This counter is used to clear the face cache every once in a while
7048 in redisplay_internal. It is incremented for each redisplay.
7049 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
7050 cleared. */
7051
7052 #define CLEAR_FACE_CACHE_COUNT 10000
7053 static int clear_face_cache_count;
7054
7055 /* Record the previous terminal frame we displayed. */
7056
7057 static struct frame *previous_terminal_frame;
7058
7059 /* Non-zero while redisplay_internal is in progress. */
7060
7061 int redisplaying_p;
7062
7063
7064 /* Value is non-zero if all changes in window W, which displays
7065 current_buffer, are in the text between START and END. START is a
7066 buffer position, END is given as a distance from Z. Used in
7067 redisplay_internal for display optimization. */
7068
7069 static INLINE int
7070 text_outside_line_unchanged_p (w, start, end)
7071 struct window *w;
7072 int start, end;
7073 {
7074 int unchanged_p = 1;
7075
7076 /* If text or overlays have changed, see where. */
7077 if (XFASTINT (w->last_modified) < MODIFF
7078 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7079 {
7080 /* Gap in the line? */
7081 if (GPT < start || Z - GPT < end)
7082 unchanged_p = 0;
7083
7084 /* Changes start in front of the line, or end after it? */
7085 if (unchanged_p
7086 && (BEG_UNCHANGED < start - 1
7087 || END_UNCHANGED < end))
7088 unchanged_p = 0;
7089
7090 /* If selective display, can't optimize if changes start at the
7091 beginning of the line. */
7092 if (unchanged_p
7093 && INTEGERP (current_buffer->selective_display)
7094 && XINT (current_buffer->selective_display) > 0
7095 && (BEG_UNCHANGED < start || GPT <= start))
7096 unchanged_p = 0;
7097 }
7098
7099 return unchanged_p;
7100 }
7101
7102
7103 /* Do a frame update, taking possible shortcuts into account. This is
7104 the main external entry point for redisplay.
7105
7106 If the last redisplay displayed an echo area message and that message
7107 is no longer requested, we clear the echo area or bring back the
7108 mini-buffer if that is in use. */
7109
7110 void
7111 redisplay ()
7112 {
7113 redisplay_internal (0);
7114 }
7115
7116 /* Return 1 if point moved out of or into a composition. Otherwise
7117 return 0. PREV_BUF and PREV_PT are the last point buffer and
7118 position. BUF and PT are the current point buffer and position. */
7119
7120 int
7121 check_point_in_composition (prev_buf, prev_pt, buf, pt)
7122 struct buffer *prev_buf, *buf;
7123 int prev_pt, pt;
7124 {
7125 int start, end;
7126 Lisp_Object prop;
7127 Lisp_Object buffer;
7128
7129 XSETBUFFER (buffer, buf);
7130 /* Check a composition at the last point if point moved within the
7131 same buffer. */
7132 if (prev_buf == buf)
7133 {
7134 if (prev_pt == pt)
7135 /* Point didn't move. */
7136 return 0;
7137
7138 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
7139 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
7140 && COMPOSITION_VALID_P (start, end, prop)
7141 && start < prev_pt && end > prev_pt)
7142 /* The last point was within the composition. Return 1 iff
7143 point moved out of the composition. */
7144 return (pt <= start || pt >= end);
7145 }
7146
7147 /* Check a composition at the current point. */
7148 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
7149 && find_composition (pt, -1, &start, &end, &prop, buffer)
7150 && COMPOSITION_VALID_P (start, end, prop)
7151 && start < pt && end > pt);
7152 }
7153
7154 /* Reconsider the setting of B->clip_changed which is displayed
7155 in window W. */
7156
7157 static INLINE void
7158 reconsider_clip_changes (w, b)
7159 struct window *w;
7160 struct buffer *b;
7161 {
7162 if (b->prevent_redisplay_optimizations_p)
7163 b->clip_changed = 1;
7164 else if (b->clip_changed
7165 && !NILP (w->window_end_valid)
7166 && w->current_matrix->buffer == b
7167 && w->current_matrix->zv == BUF_ZV (b)
7168 && w->current_matrix->begv == BUF_BEGV (b))
7169 b->clip_changed = 0;
7170
7171 /* If display wasn't paused, and W is not a tool bar window, see if
7172 point has been moved into or out of a composition. In that case,
7173 we set b->clip_changed to 1 to force updating the screen. If
7174 b->clip_changed has already been set to 1, we can skip this
7175 check. */
7176 if (!b->clip_changed
7177 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
7178 {
7179 int pt;
7180
7181 if (w == XWINDOW (selected_window))
7182 pt = BUF_PT (current_buffer);
7183 else
7184 pt = marker_position (w->pointm);
7185
7186 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
7187 || pt != XINT (w->last_point))
7188 && check_point_in_composition (w->current_matrix->buffer,
7189 XINT (w->last_point),
7190 XBUFFER (w->buffer), pt))
7191 b->clip_changed = 1;
7192 }
7193 }
7194
7195
7196 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
7197 response to any user action; therefore, we should preserve the echo
7198 area. (Actually, our caller does that job.) Perhaps in the future
7199 avoid recentering windows if it is not necessary; currently that
7200 causes some problems. */
7201
7202 static void
7203 redisplay_internal (preserve_echo_area)
7204 int preserve_echo_area;
7205 {
7206 struct window *w = XWINDOW (selected_window);
7207 struct frame *f = XFRAME (w->frame);
7208 int pause;
7209 int must_finish = 0;
7210 struct text_pos tlbufpos, tlendpos;
7211 int number_of_visible_frames;
7212 int count;
7213 struct frame *sf = SELECTED_FRAME ();
7214
7215 /* Non-zero means redisplay has to consider all windows on all
7216 frames. Zero means, only selected_window is considered. */
7217 int consider_all_windows_p;
7218
7219 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
7220
7221 /* No redisplay if running in batch mode or frame is not yet fully
7222 initialized, or redisplay is explicitly turned off by setting
7223 Vinhibit_redisplay. */
7224 if (noninteractive
7225 || !NILP (Vinhibit_redisplay)
7226 || !f->glyphs_initialized_p)
7227 return;
7228
7229 /* The flag redisplay_performed_directly_p is set by
7230 direct_output_for_insert when it already did the whole screen
7231 update necessary. */
7232 if (redisplay_performed_directly_p)
7233 {
7234 redisplay_performed_directly_p = 0;
7235 if (!hscroll_windows (selected_window))
7236 return;
7237 }
7238
7239 #ifdef USE_X_TOOLKIT
7240 if (popup_activated ())
7241 return;
7242 #endif
7243
7244 /* I don't think this happens but let's be paranoid. */
7245 if (redisplaying_p)
7246 return;
7247
7248 /* Record a function that resets redisplaying_p to its old value
7249 when we leave this function. */
7250 count = specpdl_ptr - specpdl;
7251 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
7252 ++redisplaying_p;
7253
7254 retry:
7255
7256 reconsider_clip_changes (w, current_buffer);
7257
7258 /* If new fonts have been loaded that make a glyph matrix adjustment
7259 necessary, do it. */
7260 if (fonts_changed_p)
7261 {
7262 adjust_glyphs (NULL);
7263 ++windows_or_buffers_changed;
7264 fonts_changed_p = 0;
7265 }
7266
7267 if (! FRAME_WINDOW_P (sf)
7268 && previous_terminal_frame != sf)
7269 {
7270 /* Since frames on an ASCII terminal share the same display
7271 area, displaying a different frame means redisplay the whole
7272 thing. */
7273 windows_or_buffers_changed++;
7274 SET_FRAME_GARBAGED (sf);
7275 XSETFRAME (Vterminal_frame, sf);
7276 }
7277 previous_terminal_frame = sf;
7278
7279 /* Set the visible flags for all frames. Do this before checking
7280 for resized or garbaged frames; they want to know if their frames
7281 are visible. See the comment in frame.h for
7282 FRAME_SAMPLE_VISIBILITY. */
7283 {
7284 Lisp_Object tail, frame;
7285
7286 number_of_visible_frames = 0;
7287
7288 FOR_EACH_FRAME (tail, frame)
7289 {
7290 struct frame *f = XFRAME (frame);
7291
7292 FRAME_SAMPLE_VISIBILITY (f);
7293 if (FRAME_VISIBLE_P (f))
7294 ++number_of_visible_frames;
7295 clear_desired_matrices (f);
7296 }
7297 }
7298
7299 /* Notice any pending interrupt request to change frame size. */
7300 do_pending_window_change (1);
7301
7302 /* Clear frames marked as garbaged. */
7303 if (frame_garbaged)
7304 clear_garbaged_frames ();
7305
7306 /* Build menubar and tool-bar items. */
7307 prepare_menu_bars ();
7308
7309 if (windows_or_buffers_changed)
7310 update_mode_lines++;
7311
7312 /* Detect case that we need to write or remove a star in the mode line. */
7313 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
7314 {
7315 w->update_mode_line = Qt;
7316 if (buffer_shared > 1)
7317 update_mode_lines++;
7318 }
7319
7320 /* If %c is in the mode line, update it if needed. */
7321 if (!NILP (w->column_number_displayed)
7322 /* This alternative quickly identifies a common case
7323 where no change is needed. */
7324 && !(PT == XFASTINT (w->last_point)
7325 && XFASTINT (w->last_modified) >= MODIFF
7326 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
7327 && XFASTINT (w->column_number_displayed) != current_column ())
7328 w->update_mode_line = Qt;
7329
7330 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
7331
7332 /* The variable buffer_shared is set in redisplay_window and
7333 indicates that we redisplay a buffer in different windows. See
7334 there. */
7335 consider_all_windows_p = update_mode_lines || buffer_shared > 1;
7336
7337 /* If specs for an arrow have changed, do thorough redisplay
7338 to ensure we remove any arrow that should no longer exist. */
7339 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
7340 || ! EQ (Voverlay_arrow_string, last_arrow_string))
7341 consider_all_windows_p = windows_or_buffers_changed = 1;
7342
7343 /* Normally the message* functions will have already displayed and
7344 updated the echo area, but the frame may have been trashed, or
7345 the update may have been preempted, so display the echo area
7346 again here. Checking both message buffers captures the case that
7347 the echo area should be cleared. */
7348 if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
7349 {
7350 int window_height_changed_p = echo_area_display (0);
7351 must_finish = 1;
7352
7353 if (fonts_changed_p)
7354 goto retry;
7355 else if (window_height_changed_p)
7356 {
7357 consider_all_windows_p = 1;
7358 ++update_mode_lines;
7359 ++windows_or_buffers_changed;
7360
7361 /* If window configuration was changed, frames may have been
7362 marked garbaged. Clear them or we will experience
7363 surprises wrt scrolling. */
7364 if (frame_garbaged)
7365 clear_garbaged_frames ();
7366 }
7367 }
7368 else if (w == XWINDOW (minibuf_window)
7369 && (current_buffer->clip_changed
7370 || XFASTINT (w->last_modified) < MODIFF
7371 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
7372 && resize_mini_window (w, 0))
7373 {
7374 /* Resized active mini-window to fit the size of what it is
7375 showing if its contents might have changed. */
7376 must_finish = 1;
7377 consider_all_windows_p = 1;
7378 ++windows_or_buffers_changed;
7379 ++update_mode_lines;
7380
7381 /* If window configuration was changed, frames may have been
7382 marked garbaged. Clear them or we will experience
7383 surprises wrt scrolling. */
7384 if (frame_garbaged)
7385 clear_garbaged_frames ();
7386 }
7387
7388
7389 /* If showing the region, and mark has changed, we must redisplay
7390 the whole window. The assignment to this_line_start_pos prevents
7391 the optimization directly below this if-statement. */
7392 if (((!NILP (Vtransient_mark_mode)
7393 && !NILP (XBUFFER (w->buffer)->mark_active))
7394 != !NILP (w->region_showing))
7395 || (!NILP (w->region_showing)
7396 && !EQ (w->region_showing,
7397 Fmarker_position (XBUFFER (w->buffer)->mark))))
7398 CHARPOS (this_line_start_pos) = 0;
7399
7400 /* Optimize the case that only the line containing the cursor in the
7401 selected window has changed. Variables starting with this_ are
7402 set in display_line and record information about the line
7403 containing the cursor. */
7404 tlbufpos = this_line_start_pos;
7405 tlendpos = this_line_end_pos;
7406 if (!consider_all_windows_p
7407 && CHARPOS (tlbufpos) > 0
7408 && NILP (w->update_mode_line)
7409 && !current_buffer->clip_changed
7410 && FRAME_VISIBLE_P (XFRAME (w->frame))
7411 && !FRAME_OBSCURED_P (XFRAME (w->frame))
7412 /* Make sure recorded data applies to current buffer, etc. */
7413 && this_line_buffer == current_buffer
7414 && current_buffer == XBUFFER (w->buffer)
7415 && NILP (w->force_start)
7416 /* Point must be on the line that we have info recorded about. */
7417 && PT >= CHARPOS (tlbufpos)
7418 && PT <= Z - CHARPOS (tlendpos)
7419 /* All text outside that line, including its final newline,
7420 must be unchanged */
7421 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
7422 CHARPOS (tlendpos)))
7423 {
7424 if (CHARPOS (tlbufpos) > BEGV
7425 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
7426 && (CHARPOS (tlbufpos) == ZV
7427 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
7428 /* Former continuation line has disappeared by becoming empty */
7429 goto cancel;
7430 else if (XFASTINT (w->last_modified) < MODIFF
7431 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
7432 || MINI_WINDOW_P (w))
7433 {
7434 /* We have to handle the case of continuation around a
7435 wide-column character (See the comment in indent.c around
7436 line 885).
7437
7438 For instance, in the following case:
7439
7440 -------- Insert --------
7441 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
7442 J_I_ ==> J_I_ `^^' are cursors.
7443 ^^ ^^
7444 -------- --------
7445
7446 As we have to redraw the line above, we should goto cancel. */
7447
7448 struct it it;
7449 int line_height_before = this_line_pixel_height;
7450
7451 /* Note that start_display will handle the case that the
7452 line starting at tlbufpos is a continuation lines. */
7453 start_display (&it, w, tlbufpos);
7454
7455 /* Implementation note: It this still necessary? */
7456 if (it.current_x != this_line_start_x)
7457 goto cancel;
7458
7459 TRACE ((stderr, "trying display optimization 1\n"));
7460 w->cursor.vpos = -1;
7461 overlay_arrow_seen = 0;
7462 it.vpos = this_line_vpos;
7463 it.current_y = this_line_y;
7464 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
7465 display_line (&it);
7466
7467 /* If line contains point, is not continued,
7468 and ends at same distance from eob as before, we win */
7469 if (w->cursor.vpos >= 0
7470 /* Line is not continued, otherwise this_line_start_pos
7471 would have been set to 0 in display_line. */
7472 && CHARPOS (this_line_start_pos)
7473 /* Line ends as before. */
7474 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
7475 /* Line has same height as before. Otherwise other lines
7476 would have to be shifted up or down. */
7477 && this_line_pixel_height == line_height_before)
7478 {
7479 /* If this is not the window's last line, we must adjust
7480 the charstarts of the lines below. */
7481 if (it.current_y < it.last_visible_y)
7482 {
7483 struct glyph_row *row
7484 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
7485 int delta, delta_bytes;
7486
7487 if (Z - CHARPOS (tlendpos) == ZV)
7488 {
7489 /* This line ends at end of (accessible part of)
7490 buffer. There is no newline to count. */
7491 delta = (Z
7492 - CHARPOS (tlendpos)
7493 - MATRIX_ROW_START_CHARPOS (row));
7494 delta_bytes = (Z_BYTE
7495 - BYTEPOS (tlendpos)
7496 - MATRIX_ROW_START_BYTEPOS (row));
7497 }
7498 else
7499 {
7500 /* This line ends in a newline. Must take
7501 account of the newline and the rest of the
7502 text that follows. */
7503 delta = (Z
7504 - CHARPOS (tlendpos)
7505 - MATRIX_ROW_START_CHARPOS (row));
7506 delta_bytes = (Z_BYTE
7507 - BYTEPOS (tlendpos)
7508 - MATRIX_ROW_START_BYTEPOS (row));
7509 }
7510
7511 increment_matrix_positions (w->current_matrix,
7512 this_line_vpos + 1,
7513 w->current_matrix->nrows,
7514 delta, delta_bytes);
7515 }
7516
7517 /* If this row displays text now but previously didn't,
7518 or vice versa, w->window_end_vpos may have to be
7519 adjusted. */
7520 if ((it.glyph_row - 1)->displays_text_p)
7521 {
7522 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
7523 XSETINT (w->window_end_vpos, this_line_vpos);
7524 }
7525 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
7526 && this_line_vpos > 0)
7527 XSETINT (w->window_end_vpos, this_line_vpos - 1);
7528 w->window_end_valid = Qnil;
7529
7530 /* Update hint: No need to try to scroll in update_window. */
7531 w->desired_matrix->no_scrolling_p = 1;
7532
7533 #if GLYPH_DEBUG
7534 *w->desired_matrix->method = 0;
7535 debug_method_add (w, "optimization 1");
7536 #endif
7537 goto update;
7538 }
7539 else
7540 goto cancel;
7541 }
7542 else if (/* Cursor position hasn't changed. */
7543 PT == XFASTINT (w->last_point)
7544 /* Make sure the cursor was last displayed
7545 in this window. Otherwise we have to reposition it. */
7546 && 0 <= w->cursor.vpos
7547 && XINT (w->height) > w->cursor.vpos)
7548 {
7549 if (!must_finish)
7550 {
7551 do_pending_window_change (1);
7552
7553 /* We used to always goto end_of_redisplay here, but this
7554 isn't enough if we have a blinking cursor. */
7555 if (w->cursor_off_p == w->last_cursor_off_p)
7556 goto end_of_redisplay;
7557 }
7558 goto update;
7559 }
7560 /* If highlighting the region, or if the cursor is in the echo area,
7561 then we can't just move the cursor. */
7562 else if (! (!NILP (Vtransient_mark_mode)
7563 && !NILP (current_buffer->mark_active))
7564 && (w == XWINDOW (current_buffer->last_selected_window)
7565 || highlight_nonselected_windows)
7566 && NILP (w->region_showing)
7567 && NILP (Vshow_trailing_whitespace)
7568 && !cursor_in_echo_area)
7569 {
7570 struct it it;
7571 struct glyph_row *row;
7572
7573 /* Skip from tlbufpos to PT and see where it is. Note that
7574 PT may be in invisible text. If so, we will end at the
7575 next visible position. */
7576 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
7577 NULL, DEFAULT_FACE_ID);
7578 it.current_x = this_line_start_x;
7579 it.current_y = this_line_y;
7580 it.vpos = this_line_vpos;
7581
7582 /* The call to move_it_to stops in front of PT, but
7583 moves over before-strings. */
7584 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
7585
7586 if (it.vpos == this_line_vpos
7587 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
7588 row->enabled_p))
7589 {
7590 xassert (this_line_vpos == it.vpos);
7591 xassert (this_line_y == it.current_y);
7592 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
7593 goto update;
7594 }
7595 else
7596 goto cancel;
7597 }
7598
7599 cancel:
7600 /* Text changed drastically or point moved off of line. */
7601 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
7602 }
7603
7604 CHARPOS (this_line_start_pos) = 0;
7605 consider_all_windows_p |= buffer_shared > 1;
7606 ++clear_face_cache_count;
7607
7608
7609 /* Build desired matrices. If consider_all_windows_p is non-zero,
7610 do it for all windows on all frames. Otherwise do it for
7611 selected_window, only. */
7612
7613 if (consider_all_windows_p)
7614 {
7615 Lisp_Object tail, frame;
7616
7617 /* Clear the face cache eventually. */
7618 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
7619 {
7620 clear_face_cache (0);
7621 clear_face_cache_count = 0;
7622 }
7623
7624 /* Recompute # windows showing selected buffer. This will be
7625 incremented each time such a window is displayed. */
7626 buffer_shared = 0;
7627
7628 FOR_EACH_FRAME (tail, frame)
7629 {
7630 struct frame *f = XFRAME (frame);
7631 if (FRAME_WINDOW_P (f) || f == sf)
7632 {
7633 /* Mark all the scroll bars to be removed; we'll redeem
7634 the ones we want when we redisplay their windows. */
7635 if (condemn_scroll_bars_hook)
7636 (*condemn_scroll_bars_hook) (f);
7637
7638 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7639 redisplay_windows (FRAME_ROOT_WINDOW (f));
7640
7641 /* Any scroll bars which redisplay_windows should have
7642 nuked should now go away. */
7643 if (judge_scroll_bars_hook)
7644 (*judge_scroll_bars_hook) (f);
7645 }
7646 }
7647 }
7648 else if (FRAME_VISIBLE_P (sf)
7649 && !FRAME_OBSCURED_P (sf))
7650 redisplay_window (selected_window, 1);
7651
7652
7653 /* Compare desired and current matrices, perform output. */
7654
7655 update:
7656
7657 /* If fonts changed, display again. */
7658 if (fonts_changed_p)
7659 goto retry;
7660
7661 /* Prevent various kinds of signals during display update.
7662 stdio is not robust about handling signals,
7663 which can cause an apparent I/O error. */
7664 if (interrupt_input)
7665 unrequest_sigio ();
7666 stop_polling ();
7667
7668 if (consider_all_windows_p)
7669 {
7670 Lisp_Object tail;
7671 struct frame *f;
7672 int hscrolled_p;
7673
7674 pause = 0;
7675 hscrolled_p = 0;
7676
7677 /* See if we have to hscroll. */
7678 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7679 if (FRAMEP (XCAR (tail)))
7680 {
7681 f = XFRAME (XCAR (tail));
7682
7683 if ((FRAME_WINDOW_P (f)
7684 || f == sf)
7685 && FRAME_VISIBLE_P (f)
7686 && !FRAME_OBSCURED_P (f)
7687 && hscroll_windows (f->root_window))
7688 hscrolled_p = 1;
7689 }
7690
7691 if (hscrolled_p)
7692 goto retry;
7693
7694 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7695 {
7696 if (!FRAMEP (XCAR (tail)))
7697 continue;
7698
7699 f = XFRAME (XCAR (tail));
7700
7701 if ((FRAME_WINDOW_P (f) || f == sf)
7702 && FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
7703 {
7704 /* Mark all windows as to be updated. */
7705 set_window_update_flags (XWINDOW (f->root_window), 1);
7706 pause |= update_frame (f, 0, 0);
7707 if (!pause)
7708 {
7709 mark_window_display_accurate (f->root_window, 1);
7710 if (frame_up_to_date_hook != 0)
7711 (*frame_up_to_date_hook) (f);
7712 }
7713 }
7714 }
7715 }
7716 else
7717 {
7718 if (FRAME_VISIBLE_P (sf)
7719 && !FRAME_OBSCURED_P (sf))
7720 {
7721 if (hscroll_windows (selected_window))
7722 goto retry;
7723
7724 XWINDOW (selected_window)->must_be_updated_p = 1;
7725 pause = update_frame (sf, 0, 0);
7726 }
7727 else
7728 pause = 0;
7729
7730 /* We may have called echo_area_display at the top of this
7731 function. If the echo area is on another frame, that may
7732 have put text on a frame other than the selected one, so the
7733 above call to update_frame would not have caught it. Catch
7734 it here. */
7735 {
7736 Lisp_Object mini_window;
7737 struct frame *mini_frame;
7738
7739 mini_window = FRAME_MINIBUF_WINDOW (sf);
7740 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7741
7742 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
7743 {
7744 XWINDOW (mini_window)->must_be_updated_p = 1;
7745 pause |= update_frame (mini_frame, 0, 0);
7746 if (!pause && hscroll_windows (mini_window))
7747 goto retry;
7748 }
7749 }
7750 }
7751
7752 /* If display was paused because of pending input, make sure we do a
7753 thorough update the next time. */
7754 if (pause)
7755 {
7756 /* Prevent the optimization at the beginning of
7757 redisplay_internal that tries a single-line update of the
7758 line containing the cursor in the selected window. */
7759 CHARPOS (this_line_start_pos) = 0;
7760
7761 /* Let the overlay arrow be updated the next time. */
7762 if (!NILP (last_arrow_position))
7763 {
7764 last_arrow_position = Qt;
7765 last_arrow_string = Qt;
7766 }
7767
7768 /* If we pause after scrolling, some rows in the current
7769 matrices of some windows are not valid. */
7770 if (!WINDOW_FULL_WIDTH_P (w)
7771 && !FRAME_WINDOW_P (XFRAME (w->frame)))
7772 update_mode_lines = 1;
7773 }
7774
7775 /* Now text on frame agrees with windows, so put info into the
7776 windows for partial redisplay to follow. */
7777 if (!pause)
7778 {
7779 register struct buffer *b = XBUFFER (w->buffer);
7780
7781 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
7782 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
7783 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
7784 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
7785
7786 if (consider_all_windows_p)
7787 mark_window_display_accurate (FRAME_ROOT_WINDOW (sf), 1);
7788 else
7789 {
7790 XSETFASTINT (w->last_point, BUF_PT (b));
7791 w->last_cursor = w->cursor;
7792 w->last_cursor_off_p = w->cursor_off_p;
7793
7794 b->clip_changed = 0;
7795 b->prevent_redisplay_optimizations_p = 0;
7796 w->update_mode_line = Qnil;
7797 XSETFASTINT (w->last_modified, BUF_MODIFF (b));
7798 XSETFASTINT (w->last_overlay_modified, BUF_OVERLAY_MODIFF (b));
7799 w->last_had_star
7800 = (BUF_MODIFF (XBUFFER (w->buffer)) > BUF_SAVE_MODIFF (XBUFFER (w->buffer))
7801 ? Qt : Qnil);
7802
7803 /* Record if we are showing a region, so can make sure to
7804 update it fully at next redisplay. */
7805 w->region_showing = (!NILP (Vtransient_mark_mode)
7806 && (w == XWINDOW (current_buffer->last_selected_window)
7807 || highlight_nonselected_windows)
7808 && !NILP (XBUFFER (w->buffer)->mark_active)
7809 ? Fmarker_position (XBUFFER (w->buffer)->mark)
7810 : Qnil);
7811
7812 w->window_end_valid = w->buffer;
7813 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7814 last_arrow_string = Voverlay_arrow_string;
7815 if (frame_up_to_date_hook != 0)
7816 (*frame_up_to_date_hook) (sf);
7817
7818 w->current_matrix->buffer = b;
7819 w->current_matrix->begv = BUF_BEGV (b);
7820 w->current_matrix->zv = BUF_ZV (b);
7821 }
7822
7823 update_mode_lines = 0;
7824 windows_or_buffers_changed = 0;
7825 }
7826
7827 /* Start SIGIO interrupts coming again. Having them off during the
7828 code above makes it less likely one will discard output, but not
7829 impossible, since there might be stuff in the system buffer here.
7830 But it is much hairier to try to do anything about that. */
7831 if (interrupt_input)
7832 request_sigio ();
7833 start_polling ();
7834
7835 /* If a frame has become visible which was not before, redisplay
7836 again, so that we display it. Expose events for such a frame
7837 (which it gets when becoming visible) don't call the parts of
7838 redisplay constructing glyphs, so simply exposing a frame won't
7839 display anything in this case. So, we have to display these
7840 frames here explicitly. */
7841 if (!pause)
7842 {
7843 Lisp_Object tail, frame;
7844 int new_count = 0;
7845
7846 FOR_EACH_FRAME (tail, frame)
7847 {
7848 int this_is_visible = 0;
7849
7850 if (XFRAME (frame)->visible)
7851 this_is_visible = 1;
7852 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
7853 if (XFRAME (frame)->visible)
7854 this_is_visible = 1;
7855
7856 if (this_is_visible)
7857 new_count++;
7858 }
7859
7860 if (new_count != number_of_visible_frames)
7861 windows_or_buffers_changed++;
7862 }
7863
7864 /* Change frame size now if a change is pending. */
7865 do_pending_window_change (1);
7866
7867 /* If we just did a pending size change, or have additional
7868 visible frames, redisplay again. */
7869 if (windows_or_buffers_changed && !pause)
7870 goto retry;
7871
7872 end_of_redisplay:;
7873
7874 unbind_to (count, Qnil);
7875 }
7876
7877
7878 /* Redisplay, but leave alone any recent echo area message unless
7879 another message has been requested in its place.
7880
7881 This is useful in situations where you need to redisplay but no
7882 user action has occurred, making it inappropriate for the message
7883 area to be cleared. See tracking_off and
7884 wait_reading_process_input for examples of these situations. */
7885
7886 void
7887 redisplay_preserve_echo_area ()
7888 {
7889 if (!NILP (echo_area_buffer[1]))
7890 {
7891 /* We have a previously displayed message, but no current
7892 message. Redisplay the previous message. */
7893 display_last_displayed_message_p = 1;
7894 redisplay_internal (1);
7895 display_last_displayed_message_p = 0;
7896 }
7897 else
7898 redisplay_internal (1);
7899 }
7900
7901
7902 /* Function registered with record_unwind_protect in
7903 redisplay_internal. Clears the flag indicating that a redisplay is
7904 in progress. */
7905
7906 static Lisp_Object
7907 unwind_redisplay (old_redisplaying_p)
7908 Lisp_Object old_redisplaying_p;
7909 {
7910 redisplaying_p = XFASTINT (old_redisplaying_p);
7911 return Qnil;
7912 }
7913
7914
7915 /* Mark the display of windows in the window tree rooted at WINDOW as
7916 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7917 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7918 the next time redisplay_internal is called. */
7919
7920 void
7921 mark_window_display_accurate (window, accurate_p)
7922 Lisp_Object window;
7923 int accurate_p;
7924 {
7925 struct window *w;
7926
7927 for (; !NILP (window); window = w->next)
7928 {
7929 w = XWINDOW (window);
7930
7931 if (BUFFERP (w->buffer))
7932 {
7933 struct buffer *b = XBUFFER (w->buffer);
7934
7935 XSETFASTINT (w->last_modified,
7936 accurate_p ? BUF_MODIFF (b) : 0);
7937 XSETFASTINT (w->last_overlay_modified,
7938 accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
7939 w->last_had_star = (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)
7940 ? Qt : Qnil);
7941
7942 #if 0 /* I don't think this is necessary because display_line does it.
7943 Let's check it. */
7944 /* Record if we are showing a region, so can make sure to
7945 update it fully at next redisplay. */
7946 w->region_showing
7947 = (!NILP (Vtransient_mark_mode)
7948 && (w == XWINDOW (current_buffer->last_selected_window)
7949 || highlight_nonselected_windows)
7950 && (!NILP (b->mark_active)
7951 ? Fmarker_position (b->mark)
7952 : Qnil));
7953 #endif
7954
7955 if (accurate_p)
7956 {
7957 b->clip_changed = 0;
7958 b->prevent_redisplay_optimizations_p = 0;
7959 w->current_matrix->buffer = b;
7960 w->current_matrix->begv = BUF_BEGV (b);
7961 w->current_matrix->zv = BUF_ZV (b);
7962 w->last_cursor = w->cursor;
7963 w->last_cursor_off_p = w->cursor_off_p;
7964 if (w == XWINDOW (selected_window))
7965 w->last_point = make_number (BUF_PT (b));
7966 else
7967 w->last_point = make_number (XMARKER (w->pointm)->charpos);
7968 }
7969 }
7970
7971 w->window_end_valid = w->buffer;
7972 w->update_mode_line = Qnil;
7973
7974 if (!NILP (w->vchild))
7975 mark_window_display_accurate (w->vchild, accurate_p);
7976 if (!NILP (w->hchild))
7977 mark_window_display_accurate (w->hchild, accurate_p);
7978 }
7979
7980 if (accurate_p)
7981 {
7982 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
7983 last_arrow_string = Voverlay_arrow_string;
7984 }
7985 else
7986 {
7987 /* Force a thorough redisplay the next time by setting
7988 last_arrow_position and last_arrow_string to t, which is
7989 unequal to any useful value of Voverlay_arrow_... */
7990 last_arrow_position = Qt;
7991 last_arrow_string = Qt;
7992 }
7993 }
7994
7995
7996 /* Return value in display table DP (Lisp_Char_Table *) for character
7997 C. Since a display table doesn't have any parent, we don't have to
7998 follow parent. Do not call this function directly but use the
7999 macro DISP_CHAR_VECTOR. */
8000
8001 Lisp_Object
8002 disp_char_vector (dp, c)
8003 struct Lisp_Char_Table *dp;
8004 int c;
8005 {
8006 int code[4], i;
8007 Lisp_Object val;
8008
8009 if (SINGLE_BYTE_CHAR_P (c))
8010 return (dp->contents[c]);
8011
8012 SPLIT_CHAR (c, code[0], code[1], code[2]);
8013 if (code[1] < 32)
8014 code[1] = -1;
8015 else if (code[2] < 32)
8016 code[2] = -1;
8017
8018 /* Here, the possible range of code[0] (== charset ID) is
8019 128..max_charset. Since the top level char table contains data
8020 for multibyte characters after 256th element, we must increment
8021 code[0] by 128 to get a correct index. */
8022 code[0] += 128;
8023 code[3] = -1; /* anchor */
8024
8025 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
8026 {
8027 val = dp->contents[code[i]];
8028 if (!SUB_CHAR_TABLE_P (val))
8029 return (NILP (val) ? dp->defalt : val);
8030 }
8031
8032 /* Here, val is a sub char table. We return the default value of
8033 it. */
8034 return (dp->defalt);
8035 }
8036
8037
8038 \f
8039 /***********************************************************************
8040 Window Redisplay
8041 ***********************************************************************/
8042
8043 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
8044
8045 static void
8046 redisplay_windows (window)
8047 Lisp_Object window;
8048 {
8049 while (!NILP (window))
8050 {
8051 struct window *w = XWINDOW (window);
8052
8053 if (!NILP (w->hchild))
8054 redisplay_windows (w->hchild);
8055 else if (!NILP (w->vchild))
8056 redisplay_windows (w->vchild);
8057 else
8058 redisplay_window (window, 0);
8059
8060 window = w->next;
8061 }
8062 }
8063
8064
8065 /* Set cursor position of W. PT is assumed to be displayed in ROW.
8066 DELTA is the number of bytes by which positions recorded in ROW
8067 differ from current buffer positions. */
8068
8069 void
8070 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
8071 struct window *w;
8072 struct glyph_row *row;
8073 struct glyph_matrix *matrix;
8074 int delta, delta_bytes, dy, dvpos;
8075 {
8076 struct glyph *glyph = row->glyphs[TEXT_AREA];
8077 struct glyph *end = glyph + row->used[TEXT_AREA];
8078 int x = row->x;
8079 int pt_old = PT - delta;
8080
8081 /* Skip over glyphs not having an object at the start of the row.
8082 These are special glyphs like truncation marks on terminal
8083 frames. */
8084 if (row->displays_text_p)
8085 while (glyph < end
8086 && INTEGERP (glyph->object)
8087 && glyph->charpos < 0)
8088 {
8089 x += glyph->pixel_width;
8090 ++glyph;
8091 }
8092
8093 while (glyph < end
8094 && !INTEGERP (glyph->object)
8095 && (!BUFFERP (glyph->object)
8096 || glyph->charpos < pt_old))
8097 {
8098 x += glyph->pixel_width;
8099 ++glyph;
8100 }
8101
8102 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
8103 w->cursor.x = x;
8104 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
8105 w->cursor.y = row->y + dy;
8106
8107 if (w == XWINDOW (selected_window))
8108 {
8109 if (!row->continued_p
8110 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
8111 && row->x == 0)
8112 {
8113 this_line_buffer = XBUFFER (w->buffer);
8114
8115 CHARPOS (this_line_start_pos)
8116 = MATRIX_ROW_START_CHARPOS (row) + delta;
8117 BYTEPOS (this_line_start_pos)
8118 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
8119
8120 CHARPOS (this_line_end_pos)
8121 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
8122 BYTEPOS (this_line_end_pos)
8123 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
8124
8125 this_line_y = w->cursor.y;
8126 this_line_pixel_height = row->height;
8127 this_line_vpos = w->cursor.vpos;
8128 this_line_start_x = row->x;
8129 }
8130 else
8131 CHARPOS (this_line_start_pos) = 0;
8132 }
8133 }
8134
8135
8136 /* Run window scroll functions, if any, for WINDOW with new window
8137 start STARTP. Sets the window start of WINDOW to that position.
8138
8139 We assume that the window's buffer is really current. */
8140
8141 static INLINE struct text_pos
8142 run_window_scroll_functions (window, startp)
8143 Lisp_Object window;
8144 struct text_pos startp;
8145 {
8146 struct window *w = XWINDOW (window);
8147 SET_MARKER_FROM_TEXT_POS (w->start, startp);
8148
8149 if (current_buffer != XBUFFER (w->buffer))
8150 abort ();
8151
8152 if (!NILP (Vwindow_scroll_functions))
8153 {
8154 run_hook_with_args_2 (Qwindow_scroll_functions, window,
8155 make_number (CHARPOS (startp)));
8156 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8157 /* In case the hook functions switch buffers. */
8158 if (current_buffer != XBUFFER (w->buffer))
8159 set_buffer_internal_1 (XBUFFER (w->buffer));
8160 }
8161
8162 return startp;
8163 }
8164
8165
8166 /* Modify the desired matrix of window W and W->vscroll so that the
8167 line containing the cursor is fully visible. */
8168
8169 static void
8170 make_cursor_line_fully_visible (w)
8171 struct window *w;
8172 {
8173 struct glyph_matrix *matrix;
8174 struct glyph_row *row;
8175 int header_line_height;
8176
8177 /* It's not always possible to find the cursor, e.g, when a window
8178 is full of overlay strings. Don't do anything in that case. */
8179 if (w->cursor.vpos < 0)
8180 return;
8181
8182 matrix = w->desired_matrix;
8183 row = MATRIX_ROW (matrix, w->cursor.vpos);
8184
8185 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row)
8186 /* The row may be partially visible at the top because we
8187 already have chosen a vscroll to align the bottom of the
8188 row with the bottom of the window. This happens for rows
8189 taller than the window. */
8190 && row->y + row->height < window_box_height (w))
8191 {
8192 int dy = row->height - row->visible_height;
8193 w->vscroll = 0;
8194 w->cursor.y += dy;
8195 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8196 }
8197 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)
8198 /* The row may be partially visible at the bottom because
8199 we chose a vscroll to align the row's top with the
8200 window's top. This happens for rows taller than the
8201 window. */
8202 && row->y > WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w))
8203 {
8204 int dy = - (row->height - row->visible_height);
8205 w->vscroll = dy;
8206 w->cursor.y += dy;
8207 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
8208 }
8209
8210 /* When we change the cursor y-position of the selected window,
8211 change this_line_y as well so that the display optimization for
8212 the cursor line of the selected window in redisplay_internal uses
8213 the correct y-position. */
8214 if (w == XWINDOW (selected_window))
8215 this_line_y = w->cursor.y;
8216 }
8217
8218
8219 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
8220 non-zero means only WINDOW is redisplayed in redisplay_internal.
8221 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
8222 in redisplay_window to bring a partially visible line into view in
8223 the case that only the cursor has moved.
8224
8225 Value is
8226
8227 1 if scrolling succeeded
8228
8229 0 if scrolling didn't find point.
8230
8231 -1 if new fonts have been loaded so that we must interrupt
8232 redisplay, adjust glyph matrices, and try again. */
8233
8234 static int
8235 try_scrolling (window, just_this_one_p, scroll_conservatively,
8236 scroll_step, temp_scroll_step)
8237 Lisp_Object window;
8238 int just_this_one_p;
8239 int scroll_conservatively, scroll_step;
8240 int temp_scroll_step;
8241 {
8242 struct window *w = XWINDOW (window);
8243 struct frame *f = XFRAME (w->frame);
8244 struct text_pos scroll_margin_pos;
8245 struct text_pos pos;
8246 struct text_pos startp;
8247 struct it it;
8248 Lisp_Object window_end;
8249 int this_scroll_margin;
8250 int dy = 0;
8251 int scroll_max;
8252 int line_height, rc;
8253 int amount_to_scroll = 0;
8254 Lisp_Object aggressive;
8255 int height;
8256
8257 #if GLYPH_DEBUG
8258 debug_method_add (w, "try_scrolling");
8259 #endif
8260
8261 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8262
8263 /* Compute scroll margin height in pixels. We scroll when point is
8264 within this distance from the top or bottom of the window. */
8265 if (scroll_margin > 0)
8266 {
8267 this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
8268 this_scroll_margin *= CANON_Y_UNIT (f);
8269 }
8270 else
8271 this_scroll_margin = 0;
8272
8273 /* Compute how much we should try to scroll maximally to bring point
8274 into view. */
8275 if (scroll_step)
8276 scroll_max = scroll_step;
8277 else if (scroll_conservatively)
8278 scroll_max = scroll_conservatively;
8279 else if (temp_scroll_step)
8280 scroll_max = temp_scroll_step;
8281 else if (NUMBERP (current_buffer->scroll_down_aggressively)
8282 || NUMBERP (current_buffer->scroll_up_aggressively))
8283 /* We're trying to scroll because of aggressive scrolling
8284 but no scroll_step is set. Choose an arbitrary one. Maybe
8285 there should be a variable for this. */
8286 scroll_max = 10;
8287 else
8288 scroll_max = 0;
8289 scroll_max *= CANON_Y_UNIT (f);
8290
8291 /* Decide whether we have to scroll down. Start at the window end
8292 and move this_scroll_margin up to find the position of the scroll
8293 margin. */
8294 window_end = Fwindow_end (window, Qt);
8295 CHARPOS (scroll_margin_pos) = XINT (window_end);
8296 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
8297 if (this_scroll_margin)
8298 {
8299 start_display (&it, w, scroll_margin_pos);
8300 move_it_vertically (&it, - this_scroll_margin);
8301 scroll_margin_pos = it.current.pos;
8302 }
8303
8304 if (PT >= CHARPOS (scroll_margin_pos))
8305 {
8306 int y0;
8307
8308 /* Point is in the scroll margin at the bottom of the window, or
8309 below. Compute a new window start that makes point visible. */
8310
8311 /* Compute the distance from the scroll margin to PT.
8312 Give up if the distance is greater than scroll_max. */
8313 start_display (&it, w, scroll_margin_pos);
8314 y0 = it.current_y;
8315 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8316 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8317 line_height = (it.max_ascent + it.max_descent
8318 ? it.max_ascent + it.max_descent
8319 : last_height);
8320 dy = it.current_y + line_height - y0;
8321 if (dy > scroll_max)
8322 return 0;
8323
8324 /* Move the window start down. If scrolling conservatively,
8325 move it just enough down to make point visible. If
8326 scroll_step is set, move it down by scroll_step. */
8327 start_display (&it, w, startp);
8328
8329 if (scroll_conservatively)
8330 amount_to_scroll = dy;
8331 else if (scroll_step || temp_scroll_step)
8332 amount_to_scroll = scroll_max;
8333 else
8334 {
8335 aggressive = current_buffer->scroll_down_aggressively;
8336 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8337 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8338 if (NUMBERP (aggressive))
8339 amount_to_scroll = XFLOATINT (aggressive) * height;
8340 }
8341
8342 if (amount_to_scroll <= 0)
8343 return 0;
8344
8345 move_it_vertically (&it, amount_to_scroll);
8346 startp = it.current.pos;
8347 }
8348 else
8349 {
8350 /* See if point is inside the scroll margin at the top of the
8351 window. */
8352 scroll_margin_pos = startp;
8353 if (this_scroll_margin)
8354 {
8355 start_display (&it, w, startp);
8356 move_it_vertically (&it, this_scroll_margin);
8357 scroll_margin_pos = it.current.pos;
8358 }
8359
8360 if (PT < CHARPOS (scroll_margin_pos))
8361 {
8362 /* Point is in the scroll margin at the top of the window or
8363 above what is displayed in the window. */
8364 int y0;
8365
8366 /* Compute the vertical distance from PT to the scroll
8367 margin position. Give up if distance is greater than
8368 scroll_max. */
8369 SET_TEXT_POS (pos, PT, PT_BYTE);
8370 start_display (&it, w, pos);
8371 y0 = it.current_y;
8372 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
8373 it.last_visible_y, -1,
8374 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8375 dy = it.current_y - y0;
8376 if (dy > scroll_max)
8377 return 0;
8378
8379 /* Compute new window start. */
8380 start_display (&it, w, startp);
8381
8382 if (scroll_conservatively)
8383 amount_to_scroll = dy;
8384 else if (scroll_step || temp_scroll_step)
8385 amount_to_scroll = scroll_max;
8386 else
8387 {
8388 aggressive = current_buffer->scroll_up_aggressively;
8389 height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
8390 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
8391 if (NUMBERP (aggressive))
8392 amount_to_scroll = XFLOATINT (aggressive) * height;
8393 }
8394
8395 if (amount_to_scroll <= 0)
8396 return 0;
8397
8398 move_it_vertically (&it, - amount_to_scroll);
8399 startp = it.current.pos;
8400 }
8401 }
8402
8403 /* Run window scroll functions. */
8404 startp = run_window_scroll_functions (window, startp);
8405
8406 /* Display the window. Give up if new fonts are loaded, or if point
8407 doesn't appear. */
8408 if (!try_window (window, startp))
8409 rc = -1;
8410 else if (w->cursor.vpos < 0)
8411 {
8412 clear_glyph_matrix (w->desired_matrix);
8413 rc = 0;
8414 }
8415 else
8416 {
8417 /* Maybe forget recorded base line for line number display. */
8418 if (!just_this_one_p
8419 || current_buffer->clip_changed
8420 || BEG_UNCHANGED < CHARPOS (startp))
8421 w->base_line_number = Qnil;
8422
8423 /* If cursor ends up on a partially visible line, shift display
8424 lines up or down. */
8425 make_cursor_line_fully_visible (w);
8426 rc = 1;
8427 }
8428
8429 return rc;
8430 }
8431
8432
8433 /* Compute a suitable window start for window W if display of W starts
8434 on a continuation line. Value is non-zero if a new window start
8435 was computed.
8436
8437 The new window start will be computed, based on W's width, starting
8438 from the start of the continued line. It is the start of the
8439 screen line with the minimum distance from the old start W->start. */
8440
8441 static int
8442 compute_window_start_on_continuation_line (w)
8443 struct window *w;
8444 {
8445 struct text_pos pos, start_pos;
8446 int window_start_changed_p = 0;
8447
8448 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
8449
8450 /* If window start is on a continuation line... Window start may be
8451 < BEGV in case there's invisible text at the start of the
8452 buffer (M-x rmail, for example). */
8453 if (CHARPOS (start_pos) > BEGV
8454 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
8455 {
8456 struct it it;
8457 struct glyph_row *row;
8458
8459 /* Handle the case that the window start is out of range. */
8460 if (CHARPOS (start_pos) < BEGV)
8461 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
8462 else if (CHARPOS (start_pos) > ZV)
8463 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
8464
8465 /* Find the start of the continued line. This should be fast
8466 because scan_buffer is fast (newline cache). */
8467 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
8468 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
8469 row, DEFAULT_FACE_ID);
8470 reseat_at_previous_visible_line_start (&it);
8471
8472 /* If the line start is "too far" away from the window start,
8473 say it takes too much time to compute a new window start. */
8474 if (CHARPOS (start_pos) - IT_CHARPOS (it)
8475 < XFASTINT (w->height) * XFASTINT (w->width))
8476 {
8477 int min_distance, distance;
8478
8479 /* Move forward by display lines to find the new window
8480 start. If window width was enlarged, the new start can
8481 be expected to be > the old start. If window width was
8482 decreased, the new window start will be < the old start.
8483 So, we're looking for the display line start with the
8484 minimum distance from the old window start. */
8485 pos = it.current.pos;
8486 min_distance = INFINITY;
8487 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
8488 distance < min_distance)
8489 {
8490 min_distance = distance;
8491 pos = it.current.pos;
8492 move_it_by_lines (&it, 1, 0);
8493 }
8494
8495 /* Set the window start there. */
8496 SET_MARKER_FROM_TEXT_POS (w->start, pos);
8497 window_start_changed_p = 1;
8498 }
8499 }
8500
8501 return window_start_changed_p;
8502 }
8503
8504
8505 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
8506 selected_window is redisplayed. */
8507
8508 static void
8509 redisplay_window (window, just_this_one_p)
8510 Lisp_Object window;
8511 int just_this_one_p;
8512 {
8513 struct window *w = XWINDOW (window);
8514 struct frame *f = XFRAME (w->frame);
8515 struct buffer *buffer = XBUFFER (w->buffer);
8516 struct buffer *old = current_buffer;
8517 struct text_pos lpoint, opoint, startp;
8518 int update_mode_line;
8519 int tem;
8520 struct it it;
8521 /* Record it now because it's overwritten. */
8522 int current_matrix_up_to_date_p = 0;
8523 int temp_scroll_step = 0;
8524 int count = specpdl_ptr - specpdl;
8525
8526 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8527 opoint = lpoint;
8528
8529 /* W must be a leaf window here. */
8530 xassert (!NILP (w->buffer));
8531 #if GLYPH_DEBUG
8532 *w->desired_matrix->method = 0;
8533 #endif
8534
8535 specbind (Qinhibit_point_motion_hooks, Qt);
8536
8537 reconsider_clip_changes (w, buffer);
8538
8539 /* Has the mode line to be updated? */
8540 update_mode_line = (!NILP (w->update_mode_line)
8541 || update_mode_lines
8542 || buffer->clip_changed);
8543
8544 if (MINI_WINDOW_P (w))
8545 {
8546 if (w == XWINDOW (echo_area_window)
8547 && !NILP (echo_area_buffer[0]))
8548 {
8549 if (update_mode_line)
8550 /* We may have to update a tty frame's menu bar or a
8551 tool-bar. Example `M-x C-h C-h C-g'. */
8552 goto finish_menu_bars;
8553 else
8554 /* We've already displayed the echo area glyphs in this window. */
8555 goto finish_scroll_bars;
8556 }
8557 else if (w != XWINDOW (minibuf_window))
8558 {
8559 /* W is a mini-buffer window, but it's not the currently
8560 active one, so clear it. */
8561 int yb = window_text_bottom_y (w);
8562 struct glyph_row *row;
8563 int y;
8564
8565 for (y = 0, row = w->desired_matrix->rows;
8566 y < yb;
8567 y += row->height, ++row)
8568 blank_row (w, row, y);
8569 goto finish_scroll_bars;
8570 }
8571 }
8572
8573 /* Otherwise set up data on this window; select its buffer and point
8574 value. */
8575 /* Really select the buffer, for the sake of buffer-local
8576 variables. */
8577 set_buffer_internal_1 (XBUFFER (w->buffer));
8578 SET_TEXT_POS (opoint, PT, PT_BYTE);
8579
8580 current_matrix_up_to_date_p
8581 = (!NILP (w->window_end_valid)
8582 && !current_buffer->clip_changed
8583 && XFASTINT (w->last_modified) >= MODIFF
8584 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
8585
8586 /* When windows_or_buffers_changed is non-zero, we can't rely on
8587 the window end being valid, so set it to nil there. */
8588 if (windows_or_buffers_changed)
8589 {
8590 /* If window starts on a continuation line, maybe adjust the
8591 window start in case the window's width changed. */
8592 if (XMARKER (w->start)->buffer == current_buffer)
8593 compute_window_start_on_continuation_line (w);
8594
8595 w->window_end_valid = Qnil;
8596 }
8597
8598 /* Some sanity checks. */
8599 CHECK_WINDOW_END (w);
8600 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
8601 abort ();
8602 if (BYTEPOS (opoint) < CHARPOS (opoint))
8603 abort ();
8604
8605 /* If %c is in mode line, update it if needed. */
8606 if (!NILP (w->column_number_displayed)
8607 /* This alternative quickly identifies a common case
8608 where no change is needed. */
8609 && !(PT == XFASTINT (w->last_point)
8610 && XFASTINT (w->last_modified) >= MODIFF
8611 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
8612 && XFASTINT (w->column_number_displayed) != current_column ())
8613 update_mode_line = 1;
8614
8615 /* Count number of windows showing the selected buffer. An indirect
8616 buffer counts as its base buffer. */
8617 if (!just_this_one_p)
8618 {
8619 struct buffer *current_base, *window_base;
8620 current_base = current_buffer;
8621 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
8622 if (current_base->base_buffer)
8623 current_base = current_base->base_buffer;
8624 if (window_base->base_buffer)
8625 window_base = window_base->base_buffer;
8626 if (current_base == window_base)
8627 buffer_shared++;
8628 }
8629
8630 /* Point refers normally to the selected window. For any other
8631 window, set up appropriate value. */
8632 if (!EQ (window, selected_window))
8633 {
8634 int new_pt = XMARKER (w->pointm)->charpos;
8635 int new_pt_byte = marker_byte_position (w->pointm);
8636 if (new_pt < BEGV)
8637 {
8638 new_pt = BEGV;
8639 new_pt_byte = BEGV_BYTE;
8640 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
8641 }
8642 else if (new_pt > (ZV - 1))
8643 {
8644 new_pt = ZV;
8645 new_pt_byte = ZV_BYTE;
8646 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
8647 }
8648
8649 /* We don't use SET_PT so that the point-motion hooks don't run. */
8650 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
8651 }
8652
8653 /* If any of the character widths specified in the display table
8654 have changed, invalidate the width run cache. It's true that
8655 this may be a bit late to catch such changes, but the rest of
8656 redisplay goes (non-fatally) haywire when the display table is
8657 changed, so why should we worry about doing any better? */
8658 if (current_buffer->width_run_cache)
8659 {
8660 struct Lisp_Char_Table *disptab = buffer_display_table ();
8661
8662 if (! disptab_matches_widthtab (disptab,
8663 XVECTOR (current_buffer->width_table)))
8664 {
8665 invalidate_region_cache (current_buffer,
8666 current_buffer->width_run_cache,
8667 BEG, Z);
8668 recompute_width_table (current_buffer, disptab);
8669 }
8670 }
8671
8672 /* If window-start is screwed up, choose a new one. */
8673 if (XMARKER (w->start)->buffer != current_buffer)
8674 goto recenter;
8675
8676 SET_TEXT_POS_FROM_MARKER (startp, w->start);
8677
8678 /* If someone specified a new starting point but did not insist,
8679 check whether it can be used. */
8680 if (!NILP (w->optional_new_start)
8681 && CHARPOS (startp) >= BEGV
8682 && CHARPOS (startp) <= ZV)
8683 {
8684 w->optional_new_start = Qnil;
8685 /* This takes a mini-buffer prompt into account. */
8686 start_display (&it, w, startp);
8687 move_it_to (&it, PT, 0, it.last_visible_y, -1,
8688 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
8689 if (IT_CHARPOS (it) == PT)
8690 w->force_start = Qt;
8691 }
8692
8693 /* Handle case where place to start displaying has been specified,
8694 unless the specified location is outside the accessible range. */
8695 if (!NILP (w->force_start)
8696 || w->frozen_window_start_p)
8697 {
8698 w->force_start = Qnil;
8699 w->vscroll = 0;
8700 w->window_end_valid = Qnil;
8701
8702 /* Forget any recorded base line for line number display. */
8703 if (!current_matrix_up_to_date_p
8704 || current_buffer->clip_changed)
8705 w->base_line_number = Qnil;
8706
8707 /* Redisplay the mode line. Select the buffer properly for that.
8708 Also, run the hook window-scroll-functions
8709 because we have scrolled. */
8710 /* Note, we do this after clearing force_start because
8711 if there's an error, it is better to forget about force_start
8712 than to get into an infinite loop calling the hook functions
8713 and having them get more errors. */
8714 if (!update_mode_line
8715 || ! NILP (Vwindow_scroll_functions))
8716 {
8717 update_mode_line = 1;
8718 w->update_mode_line = Qt;
8719 startp = run_window_scroll_functions (window, startp);
8720 }
8721
8722 XSETFASTINT (w->last_modified, 0);
8723 XSETFASTINT (w->last_overlay_modified, 0);
8724 if (CHARPOS (startp) < BEGV)
8725 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
8726 else if (CHARPOS (startp) > ZV)
8727 SET_TEXT_POS (startp, ZV, ZV_BYTE);
8728
8729 /* Redisplay, then check if cursor has been set during the
8730 redisplay. Give up if new fonts were loaded. */
8731 if (!try_window (window, startp))
8732 {
8733 w->force_start = Qt;
8734 clear_glyph_matrix (w->desired_matrix);
8735 goto restore_buffers;
8736 }
8737
8738 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
8739 {
8740 /* If point does not appear, or on a line that is not fully
8741 visible, move point so it does appear. The desired
8742 matrix has been built above, so we can use it. */
8743 int height = window_box_height (w) / 2;
8744 struct glyph_row *row = MATRIX_ROW (w->desired_matrix, 0);
8745
8746 while (row->y < height)
8747 ++row;
8748
8749 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
8750 MATRIX_ROW_START_BYTEPOS (row));
8751
8752 if (w != XWINDOW (selected_window))
8753 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
8754 else if (current_buffer == old)
8755 SET_TEXT_POS (lpoint, PT, PT_BYTE);
8756
8757 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
8758
8759 /* If we are highlighting the region, then we just changed
8760 the region, so redisplay to show it. */
8761 if (!NILP (Vtransient_mark_mode)
8762 && !NILP (current_buffer->mark_active))
8763 {
8764 clear_glyph_matrix (w->desired_matrix);
8765 if (!try_window (window, startp))
8766 goto restore_buffers;
8767 }
8768 }
8769
8770 make_cursor_line_fully_visible (w);
8771 #if GLYPH_DEBUG
8772 debug_method_add (w, "forced window start");
8773 #endif
8774 goto done;
8775 }
8776
8777 /* Handle case where text has not changed, only point, and it has
8778 not moved off the frame. */
8779 if (current_matrix_up_to_date_p
8780 /* Point may be in this window. */
8781 && PT >= CHARPOS (startp)
8782 /* If we don't check this, we are called to move the cursor in a
8783 horizontally split window with a current matrix that doesn't
8784 fit the display. */
8785 && !windows_or_buffers_changed
8786 /* Selective display hasn't changed. */
8787 && !current_buffer->clip_changed
8788 /* If force-mode-line-update was called, really redisplay;
8789 that's how redisplay is forced after e.g. changing
8790 buffer-invisibility-spec. */
8791 && NILP (w->update_mode_line)
8792 /* Can't use this case if highlighting a region. When a
8793 region exists, cursor movement has to do more than just
8794 set the cursor. */
8795 && !(!NILP (Vtransient_mark_mode)
8796 && !NILP (current_buffer->mark_active))
8797 && NILP (w->region_showing)
8798 && NILP (Vshow_trailing_whitespace)
8799 /* Right after splitting windows, last_point may be nil. */
8800 && INTEGERP (w->last_point)
8801 /* This code is not used for mini-buffer for the sake of the case
8802 of redisplaying to replace an echo area message; since in
8803 that case the mini-buffer contents per se are usually
8804 unchanged. This code is of no real use in the mini-buffer
8805 since the handling of this_line_start_pos, etc., in redisplay
8806 handles the same cases. */
8807 && !EQ (window, minibuf_window)
8808 /* When splitting windows or for new windows, it happens that
8809 redisplay is called with a nil window_end_vpos or one being
8810 larger than the window. This should really be fixed in
8811 window.c. I don't have this on my list, now, so we do
8812 approximately the same as the old redisplay code. --gerd. */
8813 && INTEGERP (w->window_end_vpos)
8814 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
8815 && (FRAME_WINDOW_P (f)
8816 || !MARKERP (Voverlay_arrow_position)
8817 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
8818 {
8819 int this_scroll_margin;
8820 struct glyph_row *row;
8821 int scroll_p;
8822
8823 #if GLYPH_DEBUG
8824 debug_method_add (w, "cursor movement");
8825 #endif
8826
8827 /* Scroll if point within this distance from the top or bottom
8828 of the window. This is a pixel value. */
8829 this_scroll_margin = max (0, scroll_margin);
8830 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
8831 this_scroll_margin *= CANON_Y_UNIT (f);
8832
8833 /* Start with the row the cursor was displayed during the last
8834 not paused redisplay. Give up if that row is not valid. */
8835 if (w->last_cursor.vpos >= w->current_matrix->nrows)
8836 goto try_to_scroll;
8837 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
8838 if (row->mode_line_p)
8839 ++row;
8840 if (!row->enabled_p)
8841 goto try_to_scroll;
8842
8843 scroll_p = 0;
8844 if (PT > XFASTINT (w->last_point))
8845 {
8846 /* Point has moved forward. */
8847 int last_y = window_text_bottom_y (w) - this_scroll_margin;
8848
8849 while (MATRIX_ROW_END_CHARPOS (row) < PT
8850 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
8851 {
8852 xassert (row->enabled_p);
8853 ++row;
8854 }
8855
8856 /* The end position of a row equals the start position of
8857 the next row. If PT is there, we would rather display it
8858 in the next line. Exceptions are when the row ends in
8859 the middle of a character, or ends in ZV. */
8860 if (MATRIX_ROW_BOTTOM_Y (row) < last_y
8861 && MATRIX_ROW_END_CHARPOS (row) == PT
8862 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
8863 && !row->ends_at_zv_p)
8864 {
8865 xassert (row->enabled_p);
8866 ++row;
8867 }
8868
8869 /* If within the scroll margin, scroll. Note that
8870 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
8871 next line would be drawn, and that this_scroll_margin can
8872 be zero. */
8873 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
8874 || PT > MATRIX_ROW_END_CHARPOS (row)
8875 /* Line is completely visible last line in window and PT
8876 is to be set in the next line. */
8877 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
8878 && PT == MATRIX_ROW_END_CHARPOS (row)
8879 && !row->ends_at_zv_p
8880 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
8881 scroll_p = 1;
8882 }
8883 else if (PT < XFASTINT (w->last_point))
8884 {
8885 /* Cursor has to be moved backward. Note that PT >=
8886 CHARPOS (startp) because of the outer if-statement. */
8887 while (!row->mode_line_p
8888 && (MATRIX_ROW_START_CHARPOS (row) > PT
8889 || (MATRIX_ROW_START_CHARPOS (row) == PT
8890 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
8891 && (row->y > this_scroll_margin
8892 || CHARPOS (startp) == BEGV))
8893 {
8894 xassert (row->enabled_p);
8895 --row;
8896 }
8897
8898 /* Consider the following case: Window starts at BEGV, there
8899 is invisible, intangible text at BEGV, so that display
8900 starts at some point START > BEGV. It can happen that
8901 we are called with PT somewhere between BEGV and START.
8902 Try to handle that case. */
8903 if (row < w->current_matrix->rows
8904 || row->mode_line_p)
8905 {
8906 row = w->current_matrix->rows;
8907 if (row->mode_line_p)
8908 ++row;
8909 }
8910
8911 /* Due to newlines in overlay strings, we may have to skip
8912 forward over overlay strings. */
8913 while (MATRIX_ROW_END_CHARPOS (row) == PT
8914 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row)
8915 && !row->ends_at_zv_p)
8916 ++row;
8917
8918 /* If within the scroll margin, scroll. */
8919 if (row->y < this_scroll_margin
8920 && CHARPOS (startp) != BEGV)
8921 scroll_p = 1;
8922 }
8923
8924 /* if PT is not in the glyph row, give up. */
8925 if (PT < MATRIX_ROW_START_CHARPOS (row)
8926 || PT > MATRIX_ROW_END_CHARPOS (row))
8927 goto try_to_scroll;
8928
8929 /* If we end up in a partially visible line, let's make it fully
8930 visible. This can be done most easily by using the existing
8931 scrolling code. */
8932 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
8933 {
8934 temp_scroll_step = 1;
8935 goto try_to_scroll;
8936 }
8937 else if (scroll_p)
8938 goto try_to_scroll;
8939
8940 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
8941 goto done;
8942 }
8943
8944 /* If current starting point was originally the beginning of a line
8945 but no longer is, find a new starting point. */
8946 else if (!NILP (w->start_at_line_beg)
8947 && !(CHARPOS (startp) <= BEGV
8948 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
8949 {
8950 #if GLYPH_DEBUG
8951 debug_method_add (w, "recenter 1");
8952 #endif
8953 goto recenter;
8954 }
8955
8956 /* Try scrolling with try_window_id. */
8957 else if (/* Windows and buffers haven't changed. */
8958 !windows_or_buffers_changed
8959 /* Window must be either use window-based redisplay or
8960 be full width. */
8961 && (FRAME_WINDOW_P (f)
8962 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)))
8963 && !MINI_WINDOW_P (w)
8964 /* Point is not known NOT to appear in window. */
8965 && PT >= CHARPOS (startp)
8966 && XFASTINT (w->last_modified)
8967 /* Window is not hscrolled. */
8968 && XFASTINT (w->hscroll) == 0
8969 /* Selective display has not changed. */
8970 && !current_buffer->clip_changed
8971 /* Current matrix is up to date. */
8972 && !NILP (w->window_end_valid)
8973 /* Can't use this case if highlighting a region because
8974 a cursor movement will do more than just set the cursor. */
8975 && !(!NILP (Vtransient_mark_mode)
8976 && !NILP (current_buffer->mark_active))
8977 && NILP (w->region_showing)
8978 && NILP (Vshow_trailing_whitespace)
8979 /* Overlay arrow position and string not changed. */
8980 && EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
8981 && EQ (last_arrow_string, Voverlay_arrow_string)
8982 /* Value is > 0 if update has been done, it is -1 if we
8983 know that the same window start will not work. It is 0
8984 if unsuccessful for some other reason. */
8985 && (tem = try_window_id (w)) != 0)
8986 {
8987 #if GLYPH_DEBUG
8988 debug_method_add (w, "try_window_id");
8989 #endif
8990
8991 if (fonts_changed_p)
8992 goto restore_buffers;
8993 if (tem > 0)
8994 goto done;
8995 /* Otherwise try_window_id has returned -1 which means that we
8996 don't want the alternative below this comment to execute. */
8997 }
8998 else if (CHARPOS (startp) >= BEGV
8999 && CHARPOS (startp) <= ZV
9000 && PT >= CHARPOS (startp)
9001 && (CHARPOS (startp) < ZV
9002 /* Avoid starting at end of buffer. */
9003 || CHARPOS (startp) == BEGV
9004 || (XFASTINT (w->last_modified) >= MODIFF
9005 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
9006 {
9007 #if GLYPH_DEBUG
9008 debug_method_add (w, "same window start");
9009 #endif
9010
9011 /* Try to redisplay starting at same place as before.
9012 If point has not moved off frame, accept the results. */
9013 if (!current_matrix_up_to_date_p
9014 /* Don't use try_window_reusing_current_matrix in this case
9015 because a window scroll function can have changed the
9016 buffer. */
9017 || !NILP (Vwindow_scroll_functions)
9018 || MINI_WINDOW_P (w)
9019 || !try_window_reusing_current_matrix (w))
9020 {
9021 IF_DEBUG (debug_method_add (w, "1"));
9022 try_window (window, startp);
9023 }
9024
9025 if (fonts_changed_p)
9026 goto restore_buffers;
9027
9028 if (w->cursor.vpos >= 0)
9029 {
9030 if (!just_this_one_p
9031 || current_buffer->clip_changed
9032 || BEG_UNCHANGED < CHARPOS (startp))
9033 /* Forget any recorded base line for line number display. */
9034 w->base_line_number = Qnil;
9035
9036 make_cursor_line_fully_visible (w);
9037 goto done;
9038 }
9039 else
9040 clear_glyph_matrix (w->desired_matrix);
9041 }
9042
9043 try_to_scroll:
9044
9045 XSETFASTINT (w->last_modified, 0);
9046 XSETFASTINT (w->last_overlay_modified, 0);
9047
9048 /* Redisplay the mode line. Select the buffer properly for that. */
9049 if (!update_mode_line)
9050 {
9051 update_mode_line = 1;
9052 w->update_mode_line = Qt;
9053 }
9054
9055 /* Try to scroll by specified few lines. */
9056 if ((scroll_conservatively
9057 || scroll_step
9058 || temp_scroll_step
9059 || NUMBERP (current_buffer->scroll_up_aggressively)
9060 || NUMBERP (current_buffer->scroll_down_aggressively))
9061 && !current_buffer->clip_changed
9062 && CHARPOS (startp) >= BEGV
9063 && CHARPOS (startp) <= ZV)
9064 {
9065 /* The function returns -1 if new fonts were loaded, 1 if
9066 successful, 0 if not successful. */
9067 int rc = try_scrolling (window, just_this_one_p,
9068 scroll_conservatively,
9069 scroll_step,
9070 temp_scroll_step);
9071 if (rc > 0)
9072 goto done;
9073 else if (rc < 0)
9074 goto restore_buffers;
9075 }
9076
9077 /* Finally, just choose place to start which centers point */
9078
9079 recenter:
9080
9081 #if GLYPH_DEBUG
9082 debug_method_add (w, "recenter");
9083 #endif
9084
9085 /* w->vscroll = 0; */
9086
9087 /* Forget any previously recorded base line for line number display. */
9088 if (!current_matrix_up_to_date_p
9089 || current_buffer->clip_changed)
9090 w->base_line_number = Qnil;
9091
9092 /* Move backward half the height of the window. */
9093 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9094 it.current_y = it.last_visible_y;
9095 move_it_vertically_backward (&it, it.last_visible_y / 2);
9096 xassert (IT_CHARPOS (it) >= BEGV);
9097
9098 /* The function move_it_vertically_backward may move over more
9099 than the specified y-distance. If it->w is small, e.g. a
9100 mini-buffer window, we may end up in front of the window's
9101 display area. Start displaying at the start of the line
9102 containing PT in this case. */
9103 if (it.current_y <= 0)
9104 {
9105 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
9106 move_it_vertically (&it, 0);
9107 xassert (IT_CHARPOS (it) <= PT);
9108 it.current_y = 0;
9109 }
9110
9111 it.current_x = it.hpos = 0;
9112
9113 /* Set startp here explicitly in case that helps avoid an infinite loop
9114 in case the window-scroll-functions functions get errors. */
9115 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
9116
9117 /* Run scroll hooks. */
9118 startp = run_window_scroll_functions (window, it.current.pos);
9119
9120 /* Redisplay the window. */
9121 if (!current_matrix_up_to_date_p
9122 || windows_or_buffers_changed
9123 /* Don't use try_window_reusing_current_matrix in this case
9124 because it can have changed the buffer. */
9125 || !NILP (Vwindow_scroll_functions)
9126 || !just_this_one_p
9127 || MINI_WINDOW_P (w)
9128 || !try_window_reusing_current_matrix (w))
9129 try_window (window, startp);
9130
9131 /* If new fonts have been loaded (due to fontsets), give up. We
9132 have to start a new redisplay since we need to re-adjust glyph
9133 matrices. */
9134 if (fonts_changed_p)
9135 goto restore_buffers;
9136
9137 /* If cursor did not appear assume that the middle of the window is
9138 in the first line of the window. Do it again with the next line.
9139 (Imagine a window of height 100, displaying two lines of height
9140 60. Moving back 50 from it->last_visible_y will end in the first
9141 line.) */
9142 if (w->cursor.vpos < 0)
9143 {
9144 if (!NILP (w->window_end_valid)
9145 && PT >= Z - XFASTINT (w->window_end_pos))
9146 {
9147 clear_glyph_matrix (w->desired_matrix);
9148 move_it_by_lines (&it, 1, 0);
9149 try_window (window, it.current.pos);
9150 }
9151 else if (PT < IT_CHARPOS (it))
9152 {
9153 clear_glyph_matrix (w->desired_matrix);
9154 move_it_by_lines (&it, -1, 0);
9155 try_window (window, it.current.pos);
9156 }
9157 else
9158 {
9159 /* Not much we can do about it. */
9160 }
9161 }
9162
9163 /* Consider the following case: Window starts at BEGV, there is
9164 invisible, intangible text at BEGV, so that display starts at
9165 some point START > BEGV. It can happen that we are called with
9166 PT somewhere between BEGV and START. Try to handle that case. */
9167 if (w->cursor.vpos < 0)
9168 {
9169 struct glyph_row *row = w->current_matrix->rows;
9170 if (row->mode_line_p)
9171 ++row;
9172 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9173 }
9174
9175 make_cursor_line_fully_visible (w);
9176
9177 done:
9178
9179 SET_TEXT_POS_FROM_MARKER (startp, w->start);
9180 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
9181 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
9182 ? Qt : Qnil);
9183
9184 /* Display the mode line, if we must. */
9185 if ((update_mode_line
9186 /* If window not full width, must redo its mode line
9187 if (a) the window to its side is being redone and
9188 (b) we do a frame-based redisplay. This is a consequence
9189 of how inverted lines are drawn in frame-based redisplay. */
9190 || (!just_this_one_p
9191 && !FRAME_WINDOW_P (f)
9192 && !WINDOW_FULL_WIDTH_P (w))
9193 /* Line number to display. */
9194 || INTEGERP (w->base_line_pos)
9195 /* Column number is displayed and different from the one displayed. */
9196 || (!NILP (w->column_number_displayed)
9197 && XFASTINT (w->column_number_displayed) != current_column ()))
9198 /* This means that the window has a mode line. */
9199 && (WINDOW_WANTS_MODELINE_P (w)
9200 || WINDOW_WANTS_HEADER_LINE_P (w)))
9201 {
9202 Lisp_Object old_selected_frame;
9203
9204 old_selected_frame = selected_frame;
9205
9206 XSETFRAME (selected_frame, f);
9207 display_mode_lines (w);
9208 selected_frame = old_selected_frame;
9209
9210 /* If mode line height has changed, arrange for a thorough
9211 immediate redisplay using the correct mode line height. */
9212 if (WINDOW_WANTS_MODELINE_P (w)
9213 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
9214 {
9215 fonts_changed_p = 1;
9216 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
9217 = DESIRED_MODE_LINE_HEIGHT (w);
9218 }
9219
9220 /* If top line height has changed, arrange for a thorough
9221 immediate redisplay using the correct mode line height. */
9222 if (WINDOW_WANTS_HEADER_LINE_P (w)
9223 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
9224 {
9225 fonts_changed_p = 1;
9226 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
9227 = DESIRED_HEADER_LINE_HEIGHT (w);
9228 }
9229
9230 if (fonts_changed_p)
9231 goto restore_buffers;
9232 }
9233
9234 if (!line_number_displayed
9235 && !BUFFERP (w->base_line_pos))
9236 {
9237 w->base_line_pos = Qnil;
9238 w->base_line_number = Qnil;
9239 }
9240
9241 finish_menu_bars:
9242
9243 /* When we reach a frame's selected window, redo the frame's menu bar. */
9244 if (update_mode_line
9245 && EQ (FRAME_SELECTED_WINDOW (f), window))
9246 {
9247 int redisplay_menu_p = 0;
9248
9249 if (FRAME_WINDOW_P (f))
9250 {
9251 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
9252 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
9253 #else
9254 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9255 #endif
9256 }
9257 else
9258 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
9259
9260 if (redisplay_menu_p)
9261 display_menu_bar (w);
9262
9263 #ifdef HAVE_WINDOW_SYSTEM
9264 if (WINDOWP (f->tool_bar_window)
9265 && (FRAME_TOOL_BAR_LINES (f) > 0
9266 || auto_resize_tool_bars_p))
9267 redisplay_tool_bar (f);
9268 #endif
9269 }
9270
9271 finish_scroll_bars:
9272
9273 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
9274 {
9275 int start, end, whole;
9276
9277 /* Calculate the start and end positions for the current window.
9278 At some point, it would be nice to choose between scrollbars
9279 which reflect the whole buffer size, with special markers
9280 indicating narrowing, and scrollbars which reflect only the
9281 visible region.
9282
9283 Note that mini-buffers sometimes aren't displaying any text. */
9284 if (!MINI_WINDOW_P (w)
9285 || (w == XWINDOW (minibuf_window)
9286 && NILP (echo_area_buffer[0])))
9287 {
9288 whole = ZV - BEGV;
9289 start = marker_position (w->start) - BEGV;
9290 /* I don't think this is guaranteed to be right. For the
9291 moment, we'll pretend it is. */
9292 end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
9293
9294 if (end < start)
9295 end = start;
9296 if (whole < (end - start))
9297 whole = end - start;
9298 }
9299 else
9300 start = end = whole = 0;
9301
9302 /* Indicate what this scroll bar ought to be displaying now. */
9303 (*set_vertical_scroll_bar_hook) (w, end - start, whole, start);
9304
9305 /* Note that we actually used the scroll bar attached to this
9306 window, so it shouldn't be deleted at the end of redisplay. */
9307 (*redeem_scroll_bar_hook) (w);
9308 }
9309
9310 restore_buffers:
9311
9312 /* Restore current_buffer and value of point in it. */
9313 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
9314 set_buffer_internal_1 (old);
9315 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
9316
9317 unbind_to (count, Qnil);
9318 }
9319
9320
9321 /* Build the complete desired matrix of WINDOW with a window start
9322 buffer position POS. Value is non-zero if successful. It is zero
9323 if fonts were loaded during redisplay which makes re-adjusting
9324 glyph matrices necessary. */
9325
9326 int
9327 try_window (window, pos)
9328 Lisp_Object window;
9329 struct text_pos pos;
9330 {
9331 struct window *w = XWINDOW (window);
9332 struct it it;
9333 struct glyph_row *last_text_row = NULL;
9334
9335 /* Make POS the new window start. */
9336 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
9337
9338 /* Mark cursor position as unknown. No overlay arrow seen. */
9339 w->cursor.vpos = -1;
9340 overlay_arrow_seen = 0;
9341
9342 /* Initialize iterator and info to start at POS. */
9343 start_display (&it, w, pos);
9344
9345 /* Display all lines of W. */
9346 while (it.current_y < it.last_visible_y)
9347 {
9348 if (display_line (&it))
9349 last_text_row = it.glyph_row - 1;
9350 if (fonts_changed_p)
9351 return 0;
9352 }
9353
9354 /* If bottom moved off end of frame, change mode line percentage. */
9355 if (XFASTINT (w->window_end_pos) <= 0
9356 && Z != IT_CHARPOS (it))
9357 w->update_mode_line = Qt;
9358
9359 /* Set window_end_pos to the offset of the last character displayed
9360 on the window from the end of current_buffer. Set
9361 window_end_vpos to its row number. */
9362 if (last_text_row)
9363 {
9364 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
9365 w->window_end_bytepos
9366 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9367 XSETFASTINT (w->window_end_pos,
9368 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9369 XSETFASTINT (w->window_end_vpos,
9370 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9371 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
9372 ->displays_text_p);
9373 }
9374 else
9375 {
9376 w->window_end_bytepos = 0;
9377 XSETFASTINT (w->window_end_pos, 0);
9378 XSETFASTINT (w->window_end_vpos, 0);
9379 }
9380
9381 /* But that is not valid info until redisplay finishes. */
9382 w->window_end_valid = Qnil;
9383 return 1;
9384 }
9385
9386
9387 \f
9388 /************************************************************************
9389 Window redisplay reusing current matrix when buffer has not changed
9390 ************************************************************************/
9391
9392 /* Try redisplay of window W showing an unchanged buffer with a
9393 different window start than the last time it was displayed by
9394 reusing its current matrix. Value is non-zero if successful.
9395 W->start is the new window start. */
9396
9397 static int
9398 try_window_reusing_current_matrix (w)
9399 struct window *w;
9400 {
9401 struct frame *f = XFRAME (w->frame);
9402 struct glyph_row *row, *bottom_row;
9403 struct it it;
9404 struct run run;
9405 struct text_pos start, new_start;
9406 int nrows_scrolled, i;
9407 struct glyph_row *last_text_row;
9408 struct glyph_row *last_reused_text_row;
9409 struct glyph_row *start_row;
9410 int start_vpos, min_y, max_y;
9411
9412 /* Right now this function doesn't handle terminal frames. */
9413 if (!FRAME_WINDOW_P (f))
9414 return 0;
9415
9416 /* Can't do this if region may have changed. */
9417 if ((!NILP (Vtransient_mark_mode)
9418 && !NILP (current_buffer->mark_active))
9419 || !NILP (w->region_showing)
9420 || !NILP (Vshow_trailing_whitespace))
9421 return 0;
9422
9423 /* If top-line visibility has changed, give up. */
9424 if (WINDOW_WANTS_HEADER_LINE_P (w)
9425 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
9426 return 0;
9427
9428 /* Give up if old or new display is scrolled vertically. We could
9429 make this function handle this, but right now it doesn't. */
9430 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9431 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
9432 return 0;
9433
9434 /* The variable new_start now holds the new window start. The old
9435 start `start' can be determined from the current matrix. */
9436 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
9437 start = start_row->start.pos;
9438 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
9439
9440 /* Clear the desired matrix for the display below. */
9441 clear_glyph_matrix (w->desired_matrix);
9442
9443 if (CHARPOS (new_start) <= CHARPOS (start))
9444 {
9445 int first_row_y;
9446
9447 IF_DEBUG (debug_method_add (w, "twu1"));
9448
9449 /* Display up to a row that can be reused. The variable
9450 last_text_row is set to the last row displayed that displays
9451 text. */
9452 start_display (&it, w, new_start);
9453 first_row_y = it.current_y;
9454 w->cursor.vpos = -1;
9455 last_text_row = last_reused_text_row = NULL;
9456 while (it.current_y < it.last_visible_y
9457 && IT_CHARPOS (it) < CHARPOS (start)
9458 && !fonts_changed_p)
9459 if (display_line (&it))
9460 last_text_row = it.glyph_row - 1;
9461
9462 /* A value of current_y < last_visible_y means that we stopped
9463 at the previous window start, which in turn means that we
9464 have at least one reusable row. */
9465 if (it.current_y < it.last_visible_y)
9466 {
9467 nrows_scrolled = it.vpos;
9468
9469 /* Find PT if not already found in the lines displayed. */
9470 if (w->cursor.vpos < 0)
9471 {
9472 int dy = it.current_y - first_row_y;
9473
9474 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9475 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9476 {
9477 if (PT >= MATRIX_ROW_START_CHARPOS (row)
9478 && PT < MATRIX_ROW_END_CHARPOS (row))
9479 {
9480 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
9481 dy, nrows_scrolled);
9482 break;
9483 }
9484
9485 if (MATRIX_ROW_BOTTOM_Y (row) + dy >= it.last_visible_y)
9486 break;
9487
9488 ++row;
9489 }
9490
9491 /* Give up if point was not found. This shouldn't
9492 happen often; not more often than with try_window
9493 itself. */
9494 if (w->cursor.vpos < 0)
9495 {
9496 clear_glyph_matrix (w->desired_matrix);
9497 return 0;
9498 }
9499 }
9500
9501 /* Scroll the display. Do it before the current matrix is
9502 changed. The problem here is that update has not yet
9503 run, i.e. part of the current matrix is not up to date.
9504 scroll_run_hook will clear the cursor, and use the
9505 current matrix to get the height of the row the cursor is
9506 in. */
9507 run.current_y = first_row_y;
9508 run.desired_y = it.current_y;
9509 run.height = it.last_visible_y - it.current_y;
9510 if (run.height > 0
9511 && run.current_y != run.desired_y)
9512 {
9513 update_begin (f);
9514 rif->update_window_begin_hook (w);
9515 rif->scroll_run_hook (w, &run);
9516 rif->update_window_end_hook (w, 0);
9517 update_end (f);
9518 }
9519
9520 /* Shift current matrix down by nrows_scrolled lines. */
9521 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9522 rotate_matrix (w->current_matrix,
9523 start_vpos,
9524 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9525 nrows_scrolled);
9526
9527 /* Disable lines not reused. */
9528 for (i = 0; i < it.vpos; ++i)
9529 MATRIX_ROW (w->current_matrix, i)->enabled_p = 0;
9530
9531 /* Re-compute Y positions. */
9532 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix) + nrows_scrolled;
9533 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9534 max_y = it.last_visible_y;
9535 while (row < bottom_row)
9536 {
9537 row->y = it.current_y;
9538
9539 if (row->y < min_y)
9540 row->visible_height = row->height - (min_y - row->y);
9541 else if (row->y + row->height > max_y)
9542 row->visible_height
9543 = row->height - (row->y + row->height - max_y);
9544 else
9545 row->visible_height = row->height;
9546
9547 it.current_y += row->height;
9548 ++it.vpos;
9549
9550 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9551 last_reused_text_row = row;
9552 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
9553 break;
9554 ++row;
9555 }
9556 }
9557
9558 /* Update window_end_pos etc.; last_reused_text_row is the last
9559 reused row from the current matrix containing text, if any.
9560 The value of last_text_row is the last displayed line
9561 containing text. */
9562 if (last_reused_text_row)
9563 {
9564 w->window_end_bytepos
9565 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
9566 XSETFASTINT (w->window_end_pos,
9567 Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
9568 XSETFASTINT (w->window_end_vpos,
9569 MATRIX_ROW_VPOS (last_reused_text_row,
9570 w->current_matrix));
9571 }
9572 else if (last_text_row)
9573 {
9574 w->window_end_bytepos
9575 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9576 XSETFASTINT (w->window_end_pos,
9577 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9578 XSETFASTINT (w->window_end_vpos,
9579 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9580 }
9581 else
9582 {
9583 /* This window must be completely empty. */
9584 w->window_end_bytepos = 0;
9585 XSETFASTINT (w->window_end_pos, 0);
9586 XSETFASTINT (w->window_end_vpos, 0);
9587 }
9588 w->window_end_valid = Qnil;
9589
9590 /* Update hint: don't try scrolling again in update_window. */
9591 w->desired_matrix->no_scrolling_p = 1;
9592
9593 #if GLYPH_DEBUG
9594 debug_method_add (w, "try_window_reusing_current_matrix 1");
9595 #endif
9596 return 1;
9597 }
9598 else if (CHARPOS (new_start) > CHARPOS (start))
9599 {
9600 struct glyph_row *pt_row, *row;
9601 struct glyph_row *first_reusable_row;
9602 struct glyph_row *first_row_to_display;
9603 int dy;
9604 int yb = window_text_bottom_y (w);
9605
9606 IF_DEBUG (debug_method_add (w, "twu2"));
9607
9608 /* Find the row starting at new_start, if there is one. Don't
9609 reuse a partially visible line at the end. */
9610 first_reusable_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9611 while (first_reusable_row->enabled_p
9612 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
9613 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9614 < CHARPOS (new_start)))
9615 ++first_reusable_row;
9616
9617 /* Give up if there is no row to reuse. */
9618 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
9619 || !first_reusable_row->enabled_p
9620 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
9621 != CHARPOS (new_start)))
9622 return 0;
9623
9624 /* We can reuse fully visible rows beginning with
9625 first_reusable_row to the end of the window. Set
9626 first_row_to_display to the first row that cannot be reused.
9627 Set pt_row to the row containing point, if there is any. */
9628 first_row_to_display = first_reusable_row;
9629 pt_row = NULL;
9630 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb)
9631 {
9632 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
9633 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
9634 pt_row = first_row_to_display;
9635
9636 ++first_row_to_display;
9637 }
9638
9639 /* Start displaying at the start of first_row_to_display. */
9640 xassert (first_row_to_display->y < yb);
9641 init_to_row_start (&it, w, first_row_to_display);
9642 nrows_scrolled = MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix);
9643 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
9644 - nrows_scrolled);
9645 it.current_y = first_row_to_display->y - first_reusable_row->y;
9646
9647 /* Display lines beginning with first_row_to_display in the
9648 desired matrix. Set last_text_row to the last row displayed
9649 that displays text. */
9650 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
9651 if (pt_row == NULL)
9652 w->cursor.vpos = -1;
9653 last_text_row = NULL;
9654 while (it.current_y < it.last_visible_y && !fonts_changed_p)
9655 if (display_line (&it))
9656 last_text_row = it.glyph_row - 1;
9657
9658 /* Give up If point isn't in a row displayed or reused. */
9659 if (w->cursor.vpos < 0)
9660 {
9661 clear_glyph_matrix (w->desired_matrix);
9662 return 0;
9663 }
9664
9665 /* If point is in a reused row, adjust y and vpos of the cursor
9666 position. */
9667 if (pt_row)
9668 {
9669 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
9670 w->current_matrix);
9671 w->cursor.y -= first_reusable_row->y;
9672 }
9673
9674 /* Scroll the display. */
9675 run.current_y = first_reusable_row->y;
9676 run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9677 run.height = it.last_visible_y - run.current_y;
9678 if (run.height)
9679 {
9680 struct frame *f = XFRAME (WINDOW_FRAME (w));
9681 update_begin (f);
9682 rif->update_window_begin_hook (w);
9683 rif->scroll_run_hook (w, &run);
9684 rif->update_window_end_hook (w, 0);
9685 update_end (f);
9686 }
9687
9688 /* Adjust Y positions of reused rows. */
9689 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
9690 row = first_reusable_row;
9691 dy = first_reusable_row->y;
9692 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9693 max_y = it.last_visible_y;
9694 while (row < first_row_to_display)
9695 {
9696 row->y -= dy;
9697 if (row->y < min_y)
9698 row->visible_height = row->height - (min_y - row->y);
9699 else if (row->y + row->height > max_y)
9700 row->visible_height
9701 = row->height - (row->y + row->height - max_y);
9702 else
9703 row->visible_height = row->height;
9704 ++row;
9705 }
9706
9707 /* Disable rows not reused. */
9708 while (row < bottom_row)
9709 {
9710 row->enabled_p = 0;
9711 ++row;
9712 }
9713
9714 /* Scroll the current matrix. */
9715 xassert (nrows_scrolled > 0);
9716 rotate_matrix (w->current_matrix,
9717 start_vpos,
9718 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
9719 -nrows_scrolled);
9720
9721 /* Adjust window end. A null value of last_text_row means that
9722 the window end is in reused rows which in turn means that
9723 only its vpos can have changed. */
9724 if (last_text_row)
9725 {
9726 w->window_end_bytepos
9727 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
9728 XSETFASTINT (w->window_end_pos,
9729 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
9730 XSETFASTINT (w->window_end_vpos,
9731 MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
9732 }
9733 else
9734 {
9735 XSETFASTINT (w->window_end_vpos,
9736 XFASTINT (w->window_end_vpos) - nrows_scrolled);
9737 }
9738
9739 w->window_end_valid = Qnil;
9740 w->desired_matrix->no_scrolling_p = 1;
9741
9742 #if GLYPH_DEBUG
9743 debug_method_add (w, "try_window_reusing_current_matrix 2");
9744 #endif
9745 return 1;
9746 }
9747
9748 return 0;
9749 }
9750
9751
9752 \f
9753 /************************************************************************
9754 Window redisplay reusing current matrix when buffer has changed
9755 ************************************************************************/
9756
9757 static struct glyph_row *get_last_unchanged_at_beg_row P_ ((struct window *));
9758 static struct glyph_row *get_first_unchanged_at_end_row P_ ((struct window *,
9759 int *, int *));
9760 static struct glyph_row *
9761 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
9762 struct glyph_row *));
9763
9764
9765 /* Return the last row in MATRIX displaying text. If row START is
9766 non-null, start searching with that row. IT gives the dimensions
9767 of the display. Value is null if matrix is empty; otherwise it is
9768 a pointer to the row found. */
9769
9770 static struct glyph_row *
9771 find_last_row_displaying_text (matrix, it, start)
9772 struct glyph_matrix *matrix;
9773 struct it *it;
9774 struct glyph_row *start;
9775 {
9776 struct glyph_row *row, *row_found;
9777
9778 /* Set row_found to the last row in IT->w's current matrix
9779 displaying text. The loop looks funny but think of partially
9780 visible lines. */
9781 row_found = NULL;
9782 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
9783 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9784 {
9785 xassert (row->enabled_p);
9786 row_found = row;
9787 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
9788 break;
9789 ++row;
9790 }
9791
9792 return row_found;
9793 }
9794
9795
9796 /* Return the last row in the current matrix of W that is not affected
9797 by changes at the start of current_buffer that occurred since the
9798 last time W was redisplayed. Value is null if no such row exists.
9799
9800 The global variable beg_unchanged has to contain the number of
9801 bytes unchanged at the start of current_buffer. BEG +
9802 beg_unchanged is the buffer position of the first changed byte in
9803 current_buffer. Characters at positions < BEG + beg_unchanged are
9804 at the same buffer positions as they were when the current matrix
9805 was built. */
9806
9807 static struct glyph_row *
9808 get_last_unchanged_at_beg_row (w)
9809 struct window *w;
9810 {
9811 int first_changed_pos = BEG + BEG_UNCHANGED;
9812 struct glyph_row *row;
9813 struct glyph_row *row_found = NULL;
9814 int yb = window_text_bottom_y (w);
9815
9816 /* Find the last row displaying unchanged text. */
9817 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9818 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
9819 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
9820 {
9821 if (/* If row ends before first_changed_pos, it is unchanged,
9822 except in some case. */
9823 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
9824 /* When row ends in ZV and we write at ZV it is not
9825 unchanged. */
9826 && !row->ends_at_zv_p
9827 /* When first_changed_pos is the end of a continued line,
9828 row is not unchanged because it may be no longer
9829 continued. */
9830 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
9831 && row->continued_p))
9832 row_found = row;
9833
9834 /* Stop if last visible row. */
9835 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
9836 break;
9837
9838 ++row;
9839 }
9840
9841 return row_found;
9842 }
9843
9844
9845 /* Find the first glyph row in the current matrix of W that is not
9846 affected by changes at the end of current_buffer since the last
9847 time the window was redisplayed. Return in *DELTA the number of
9848 chars by which buffer positions in unchanged text at the end of
9849 current_buffer must be adjusted. Return in *DELTA_BYTES the
9850 corresponding number of bytes. Value is null if no such row
9851 exists, i.e. all rows are affected by changes. */
9852
9853 static struct glyph_row *
9854 get_first_unchanged_at_end_row (w, delta, delta_bytes)
9855 struct window *w;
9856 int *delta, *delta_bytes;
9857 {
9858 struct glyph_row *row;
9859 struct glyph_row *row_found = NULL;
9860
9861 *delta = *delta_bytes = 0;
9862
9863 /* A value of window_end_pos >= end_unchanged means that the window
9864 end is in the range of changed text. If so, there is no
9865 unchanged row at the end of W's current matrix. */
9866 xassert (!NILP (w->window_end_valid));
9867 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
9868 return NULL;
9869
9870 /* Set row to the last row in W's current matrix displaying text. */
9871 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
9872
9873 /* If matrix is entirely empty, no unchanged row exists. */
9874 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
9875 {
9876 /* The value of row is the last glyph row in the matrix having a
9877 meaningful buffer position in it. The end position of row
9878 corresponds to window_end_pos. This allows us to translate
9879 buffer positions in the current matrix to current buffer
9880 positions for characters not in changed text. */
9881 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
9882 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
9883 int last_unchanged_pos, last_unchanged_pos_old;
9884 struct glyph_row *first_text_row
9885 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
9886
9887 *delta = Z - Z_old;
9888 *delta_bytes = Z_BYTE - Z_BYTE_old;
9889
9890 /* Set last_unchanged_pos to the buffer position of the last
9891 character in the buffer that has not been changed. Z is the
9892 index + 1 of the last byte in current_buffer, i.e. by
9893 subtracting end_unchanged we get the index of the last
9894 unchanged character, and we have to add BEG to get its buffer
9895 position. */
9896 last_unchanged_pos = Z - END_UNCHANGED + BEG;
9897 last_unchanged_pos_old = last_unchanged_pos - *delta;
9898
9899 /* Search backward from ROW for a row displaying a line that
9900 starts at a minimum position >= last_unchanged_pos_old. */
9901 while (row >= first_text_row)
9902 {
9903 xassert (row->enabled_p);
9904 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row));
9905
9906 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
9907 row_found = row;
9908 --row;
9909 }
9910 }
9911
9912 xassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
9913 return row_found;
9914 }
9915
9916
9917 /* Make sure that glyph rows in the current matrix of window W
9918 reference the same glyph memory as corresponding rows in the
9919 frame's frame matrix. This function is called after scrolling W's
9920 current matrix on a terminal frame in try_window_id and
9921 try_window_reusing_current_matrix. */
9922
9923 static void
9924 sync_frame_with_window_matrix_rows (w)
9925 struct window *w;
9926 {
9927 struct frame *f = XFRAME (w->frame);
9928 struct glyph_row *window_row, *window_row_end, *frame_row;
9929
9930 /* Preconditions: W must be a leaf window and full-width. Its frame
9931 must have a frame matrix. */
9932 xassert (NILP (w->hchild) && NILP (w->vchild));
9933 xassert (WINDOW_FULL_WIDTH_P (w));
9934 xassert (!FRAME_WINDOW_P (f));
9935
9936 /* If W is a full-width window, glyph pointers in W's current matrix
9937 have, by definition, to be the same as glyph pointers in the
9938 corresponding frame matrix. */
9939 window_row = w->current_matrix->rows;
9940 window_row_end = window_row + w->current_matrix->nrows;
9941 frame_row = f->current_matrix->rows + XFASTINT (w->top);
9942 while (window_row < window_row_end)
9943 {
9944 int area;
9945
9946 for (area = LEFT_MARGIN_AREA; area <= LAST_AREA; ++area)
9947 frame_row->glyphs[area] = window_row->glyphs[area];
9948
9949 /* Disable frame rows whose corresponding window rows have
9950 been disabled in try_window_id. */
9951 if (!window_row->enabled_p)
9952 frame_row->enabled_p = 0;
9953
9954 ++window_row, ++frame_row;
9955 }
9956 }
9957
9958
9959 /* Find the glyph row in window W containing CHARPOS. Consider all
9960 rows between START and END (not inclusive). END null means search
9961 all rows to the end of the display area of W. Value is the row
9962 containing CHARPOS or null. */
9963
9964 static struct glyph_row *
9965 row_containing_pos (w, charpos, start, end)
9966 struct window *w;
9967 int charpos;
9968 struct glyph_row *start, *end;
9969 {
9970 struct glyph_row *row = start;
9971 int last_y;
9972
9973 /* If we happen to start on a header-line, skip that. */
9974 if (row->mode_line_p)
9975 ++row;
9976
9977 if ((end && row >= end) || !row->enabled_p)
9978 return NULL;
9979
9980 last_y = window_text_bottom_y (w);
9981
9982 while ((end == NULL || row < end)
9983 && (MATRIX_ROW_END_CHARPOS (row) < charpos
9984 /* The end position of a row equals the start
9985 position of the next row. If CHARPOS is there, we
9986 would rather display it in the next line, except
9987 when this line ends in ZV. */
9988 || (MATRIX_ROW_END_CHARPOS (row) == charpos
9989 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
9990 || !row->ends_at_zv_p)))
9991 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
9992 ++row;
9993
9994 /* Give up if CHARPOS not found. */
9995 if ((end && row >= end)
9996 || charpos < MATRIX_ROW_START_CHARPOS (row)
9997 || charpos > MATRIX_ROW_END_CHARPOS (row))
9998 row = NULL;
9999
10000 return row;
10001 }
10002
10003
10004 /* Try to redisplay window W by reusing its existing display. W's
10005 current matrix must be up to date when this function is called,
10006 i.e. window_end_valid must not be nil.
10007
10008 Value is
10009
10010 1 if display has been updated
10011 0 if otherwise unsuccessful
10012 -1 if redisplay with same window start is known not to succeed
10013
10014 The following steps are performed:
10015
10016 1. Find the last row in the current matrix of W that is not
10017 affected by changes at the start of current_buffer. If no such row
10018 is found, give up.
10019
10020 2. Find the first row in W's current matrix that is not affected by
10021 changes at the end of current_buffer. Maybe there is no such row.
10022
10023 3. Display lines beginning with the row + 1 found in step 1 to the
10024 row found in step 2 or, if step 2 didn't find a row, to the end of
10025 the window.
10026
10027 4. If cursor is not known to appear on the window, give up.
10028
10029 5. If display stopped at the row found in step 2, scroll the
10030 display and current matrix as needed.
10031
10032 6. Maybe display some lines at the end of W, if we must. This can
10033 happen under various circumstances, like a partially visible line
10034 becoming fully visible, or because newly displayed lines are displayed
10035 in smaller font sizes.
10036
10037 7. Update W's window end information. */
10038
10039 /* Check that window end is what we expect it to be. */
10040
10041 static int
10042 try_window_id (w)
10043 struct window *w;
10044 {
10045 struct frame *f = XFRAME (w->frame);
10046 struct glyph_matrix *current_matrix = w->current_matrix;
10047 struct glyph_matrix *desired_matrix = w->desired_matrix;
10048 struct glyph_row *last_unchanged_at_beg_row;
10049 struct glyph_row *first_unchanged_at_end_row;
10050 struct glyph_row *row;
10051 struct glyph_row *bottom_row;
10052 int bottom_vpos;
10053 struct it it;
10054 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
10055 struct text_pos start_pos;
10056 struct run run;
10057 int first_unchanged_at_end_vpos = 0;
10058 struct glyph_row *last_text_row, *last_text_row_at_end;
10059 struct text_pos start;
10060
10061 SET_TEXT_POS_FROM_MARKER (start, w->start);
10062
10063 /* Check pre-conditions. Window end must be valid, otherwise
10064 the current matrix would not be up to date. */
10065 xassert (!NILP (w->window_end_valid));
10066 xassert (FRAME_WINDOW_P (XFRAME (w->frame))
10067 || (line_ins_del_ok && WINDOW_FULL_WIDTH_P (w)));
10068
10069 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
10070 only if buffer has really changed. The reason is that the gap is
10071 initially at Z for freshly visited files. The code below would
10072 set end_unchanged to 0 in that case. */
10073 if (MODIFF > SAVE_MODIFF
10074 /* This seems to happen sometimes after saving a buffer. */
10075 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
10076 {
10077 if (GPT - BEG < BEG_UNCHANGED)
10078 BEG_UNCHANGED = GPT - BEG;
10079 if (Z - GPT < END_UNCHANGED)
10080 END_UNCHANGED = Z - GPT;
10081 }
10082
10083 /* If window starts after a line end, and the last change is in
10084 front of that newline, then changes don't affect the display.
10085 This case happens with stealth-fontification. Note that although
10086 the display is unchanged, glyph positions in the matrix have to
10087 be adjusted, of course. */
10088 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
10089 if (CHARPOS (start) > BEGV
10090 && Z - END_UNCHANGED < CHARPOS (start) - 1
10091 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n'
10092 && PT < MATRIX_ROW_END_CHARPOS (row))
10093 {
10094 struct glyph_row *r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
10095 int delta = CHARPOS (start) - MATRIX_ROW_START_CHARPOS (r0);
10096
10097 if (delta)
10098 {
10099 struct glyph_row *r1 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10100 int delta_bytes = BYTEPOS (start) - MATRIX_ROW_START_BYTEPOS (r0);
10101
10102 increment_matrix_positions (w->current_matrix,
10103 MATRIX_ROW_VPOS (r0, current_matrix),
10104 MATRIX_ROW_VPOS (r1, current_matrix),
10105 delta, delta_bytes);
10106 }
10107
10108 #if 0 /* If changes are all in front of the window start, the
10109 distance of the last displayed glyph from Z hasn't
10110 changed. */
10111 w->window_end_pos
10112 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10113 w->window_end_bytepos
10114 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10115 #endif
10116
10117 return 1;
10118 }
10119
10120 /* Return quickly if changes are all below what is displayed in the
10121 window, and if PT is in the window. */
10122 if (BEG_UNCHANGED > MATRIX_ROW_END_CHARPOS (row)
10123 && PT < MATRIX_ROW_END_CHARPOS (row))
10124 {
10125 /* We have to update window end positions because the buffer's
10126 size has changed. */
10127 w->window_end_pos
10128 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
10129 w->window_end_bytepos
10130 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10131 return 1;
10132 }
10133
10134 /* Check that window start agrees with the start of the first glyph
10135 row in its current matrix. Check this after we know the window
10136 start is not in changed text, otherwise positions would not be
10137 comparable. */
10138 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
10139 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
10140 return 0;
10141
10142 /* Compute the position at which we have to start displaying new
10143 lines. Some of the lines at the top of the window might be
10144 reusable because they are not displaying changed text. Find the
10145 last row in W's current matrix not affected by changes at the
10146 start of current_buffer. Value is null if changes start in the
10147 first line of window. */
10148 last_unchanged_at_beg_row = get_last_unchanged_at_beg_row (w);
10149 if (last_unchanged_at_beg_row)
10150 {
10151 init_to_row_end (&it, w, last_unchanged_at_beg_row);
10152 start_pos = it.current.pos;
10153
10154 /* Start displaying new lines in the desired matrix at the same
10155 vpos we would use in the current matrix, i.e. below
10156 last_unchanged_at_beg_row. */
10157 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
10158 current_matrix);
10159 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10160 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
10161
10162 xassert (it.hpos == 0 && it.current_x == 0);
10163 }
10164 else
10165 {
10166 /* There are no reusable lines at the start of the window.
10167 Start displaying in the first line. */
10168 start_display (&it, w, start);
10169 start_pos = it.current.pos;
10170 }
10171
10172 /* Find the first row that is not affected by changes at the end of
10173 the buffer. Value will be null if there is no unchanged row, in
10174 which case we must redisplay to the end of the window. delta
10175 will be set to the value by which buffer positions beginning with
10176 first_unchanged_at_end_row have to be adjusted due to text
10177 changes. */
10178 first_unchanged_at_end_row
10179 = get_first_unchanged_at_end_row (w, &delta, &delta_bytes);
10180 IF_DEBUG (debug_delta = delta);
10181 IF_DEBUG (debug_delta_bytes = delta_bytes);
10182
10183 /* Set stop_pos to the buffer position up to which we will have to
10184 display new lines. If first_unchanged_at_end_row != NULL, this
10185 is the buffer position of the start of the line displayed in that
10186 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
10187 that we don't stop at a buffer position. */
10188 stop_pos = 0;
10189 if (first_unchanged_at_end_row)
10190 {
10191 xassert (last_unchanged_at_beg_row == NULL
10192 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
10193
10194 /* If this is a continuation line, move forward to the next one
10195 that isn't. Changes in lines above affect this line.
10196 Caution: this may move first_unchanged_at_end_row to a row
10197 not displaying text. */
10198 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
10199 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10200 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10201 < it.last_visible_y))
10202 ++first_unchanged_at_end_row;
10203
10204 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
10205 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
10206 >= it.last_visible_y))
10207 first_unchanged_at_end_row = NULL;
10208 else
10209 {
10210 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
10211 + delta);
10212 first_unchanged_at_end_vpos
10213 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
10214 xassert (stop_pos >= Z - END_UNCHANGED);
10215 }
10216 }
10217 else if (last_unchanged_at_beg_row == NULL)
10218 return 0;
10219
10220
10221 #if GLYPH_DEBUG
10222
10223 /* Either there is no unchanged row at the end, or the one we have
10224 now displays text. This is a necessary condition for the window
10225 end pos calculation at the end of this function. */
10226 xassert (first_unchanged_at_end_row == NULL
10227 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
10228
10229 debug_last_unchanged_at_beg_vpos
10230 = (last_unchanged_at_beg_row
10231 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
10232 : -1);
10233 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
10234
10235 #endif /* GLYPH_DEBUG != 0 */
10236
10237
10238 /* Display new lines. Set last_text_row to the last new line
10239 displayed which has text on it, i.e. might end up as being the
10240 line where the window_end_vpos is. */
10241 w->cursor.vpos = -1;
10242 last_text_row = NULL;
10243 overlay_arrow_seen = 0;
10244 while (it.current_y < it.last_visible_y
10245 && !fonts_changed_p
10246 && (first_unchanged_at_end_row == NULL
10247 || IT_CHARPOS (it) < stop_pos))
10248 {
10249 if (display_line (&it))
10250 last_text_row = it.glyph_row - 1;
10251 }
10252
10253 if (fonts_changed_p)
10254 return -1;
10255
10256
10257 /* Compute differences in buffer positions, y-positions etc. for
10258 lines reused at the bottom of the window. Compute what we can
10259 scroll. */
10260 if (first_unchanged_at_end_row
10261 /* No lines reused because we displayed everything up to the
10262 bottom of the window. */
10263 && it.current_y < it.last_visible_y)
10264 {
10265 dvpos = (it.vpos
10266 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
10267 current_matrix));
10268 dy = it.current_y - first_unchanged_at_end_row->y;
10269 run.current_y = first_unchanged_at_end_row->y;
10270 run.desired_y = run.current_y + dy;
10271 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
10272 }
10273 else
10274 {
10275 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
10276 first_unchanged_at_end_row = NULL;
10277 }
10278 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
10279
10280
10281 /* Find the cursor if not already found. We have to decide whether
10282 PT will appear on this window (it sometimes doesn't, but this is
10283 not a very frequent case.) This decision has to be made before
10284 the current matrix is altered. A value of cursor.vpos < 0 means
10285 that PT is either in one of the lines beginning at
10286 first_unchanged_at_end_row or below the window. Don't care for
10287 lines that might be displayed later at the window end; as
10288 mentioned, this is not a frequent case. */
10289 if (w->cursor.vpos < 0)
10290 {
10291 /* Cursor in unchanged rows at the top? */
10292 if (PT < CHARPOS (start_pos)
10293 && last_unchanged_at_beg_row)
10294 {
10295 row = row_containing_pos (w, PT,
10296 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
10297 last_unchanged_at_beg_row + 1);
10298 xassert (row && row <= last_unchanged_at_beg_row);
10299 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10300 }
10301
10302 /* Start from first_unchanged_at_end_row looking for PT. */
10303 else if (first_unchanged_at_end_row)
10304 {
10305 row = row_containing_pos (w, PT - delta,
10306 first_unchanged_at_end_row, NULL);
10307 if (row)
10308 set_cursor_from_row (w, row, w->current_matrix, delta,
10309 delta_bytes, dy, dvpos);
10310 }
10311
10312 /* Give up if cursor was not found. */
10313 if (w->cursor.vpos < 0)
10314 {
10315 clear_glyph_matrix (w->desired_matrix);
10316 return -1;
10317 }
10318 }
10319
10320 /* Don't let the cursor end in the scroll margins. */
10321 {
10322 int this_scroll_margin, cursor_height;
10323
10324 this_scroll_margin = max (0, scroll_margin);
10325 this_scroll_margin = min (this_scroll_margin,
10326 XFASTINT (w->height) / 4);
10327 this_scroll_margin *= CANON_Y_UNIT (it.f);
10328 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
10329
10330 if ((w->cursor.y < this_scroll_margin
10331 && CHARPOS (start) > BEGV)
10332 /* Don't take scroll margin into account at the bottom because
10333 old redisplay didn't do it either. */
10334 || w->cursor.y + cursor_height > it.last_visible_y)
10335 {
10336 w->cursor.vpos = -1;
10337 clear_glyph_matrix (w->desired_matrix);
10338 return -1;
10339 }
10340 }
10341
10342 /* Scroll the display. Do it before changing the current matrix so
10343 that xterm.c doesn't get confused about where the cursor glyph is
10344 found. */
10345 if (dy && run.height)
10346 {
10347 update_begin (f);
10348
10349 if (FRAME_WINDOW_P (f))
10350 {
10351 rif->update_window_begin_hook (w);
10352 rif->scroll_run_hook (w, &run);
10353 rif->update_window_end_hook (w, 0);
10354 }
10355 else
10356 {
10357 /* Terminal frame. In this case, dvpos gives the number of
10358 lines to scroll by; dvpos < 0 means scroll up. */
10359 int first_unchanged_at_end_vpos
10360 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
10361 int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
10362 int end = XFASTINT (w->top) + window_internal_height (w);
10363
10364 /* Perform the operation on the screen. */
10365 if (dvpos > 0)
10366 {
10367 /* Scroll last_unchanged_at_beg_row to the end of the
10368 window down dvpos lines. */
10369 set_terminal_window (end);
10370
10371 /* On dumb terminals delete dvpos lines at the end
10372 before inserting dvpos empty lines. */
10373 if (!scroll_region_ok)
10374 ins_del_lines (end - dvpos, -dvpos);
10375
10376 /* Insert dvpos empty lines in front of
10377 last_unchanged_at_beg_row. */
10378 ins_del_lines (from, dvpos);
10379 }
10380 else if (dvpos < 0)
10381 {
10382 /* Scroll up last_unchanged_at_beg_vpos to the end of
10383 the window to last_unchanged_at_beg_vpos - |dvpos|. */
10384 set_terminal_window (end);
10385
10386 /* Delete dvpos lines in front of
10387 last_unchanged_at_beg_vpos. ins_del_lines will set
10388 the cursor to the given vpos and emit |dvpos| delete
10389 line sequences. */
10390 ins_del_lines (from + dvpos, dvpos);
10391
10392 /* On a dumb terminal insert dvpos empty lines at the
10393 end. */
10394 if (!scroll_region_ok)
10395 ins_del_lines (end + dvpos, -dvpos);
10396 }
10397
10398 set_terminal_window (0);
10399 }
10400
10401 update_end (f);
10402 }
10403
10404 /* Shift reused rows of the current matrix to the right position.
10405 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
10406 text. */
10407 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
10408 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
10409 if (dvpos < 0)
10410 {
10411 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
10412 bottom_vpos, dvpos);
10413 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
10414 bottom_vpos, 0);
10415 }
10416 else if (dvpos > 0)
10417 {
10418 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
10419 bottom_vpos, dvpos);
10420 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
10421 first_unchanged_at_end_vpos + dvpos, 0);
10422 }
10423
10424 /* For frame-based redisplay, make sure that current frame and window
10425 matrix are in sync with respect to glyph memory. */
10426 if (!FRAME_WINDOW_P (f))
10427 sync_frame_with_window_matrix_rows (w);
10428
10429 /* Adjust buffer positions in reused rows. */
10430 if (delta)
10431 increment_matrix_positions (current_matrix,
10432 first_unchanged_at_end_vpos + dvpos,
10433 bottom_vpos, delta, delta_bytes);
10434
10435 /* Adjust Y positions. */
10436 if (dy)
10437 shift_glyph_matrix (w, current_matrix,
10438 first_unchanged_at_end_vpos + dvpos,
10439 bottom_vpos, dy);
10440
10441 if (first_unchanged_at_end_row)
10442 first_unchanged_at_end_row += dvpos;
10443
10444 /* If scrolling up, there may be some lines to display at the end of
10445 the window. */
10446 last_text_row_at_end = NULL;
10447 if (dy < 0)
10448 {
10449 /* Set last_row to the glyph row in the current matrix where the
10450 window end line is found. It has been moved up or down in
10451 the matrix by dvpos. */
10452 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
10453 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
10454
10455 /* If last_row is the window end line, it should display text. */
10456 xassert (last_row->displays_text_p);
10457
10458 /* If window end line was partially visible before, begin
10459 displaying at that line. Otherwise begin displaying with the
10460 line following it. */
10461 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
10462 {
10463 init_to_row_start (&it, w, last_row);
10464 it.vpos = last_vpos;
10465 it.current_y = last_row->y;
10466 }
10467 else
10468 {
10469 init_to_row_end (&it, w, last_row);
10470 it.vpos = 1 + last_vpos;
10471 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
10472 ++last_row;
10473 }
10474
10475 /* We may start in a continuation line. If so, we have to get
10476 the right continuation_lines_width and current_x. */
10477 it.continuation_lines_width = last_row->continuation_lines_width;
10478 it.hpos = it.current_x = 0;
10479
10480 /* Display the rest of the lines at the window end. */
10481 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
10482 while (it.current_y < it.last_visible_y
10483 && !fonts_changed_p)
10484 {
10485 /* Is it always sure that the display agrees with lines in
10486 the current matrix? I don't think so, so we mark rows
10487 displayed invalid in the current matrix by setting their
10488 enabled_p flag to zero. */
10489 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
10490 if (display_line (&it))
10491 last_text_row_at_end = it.glyph_row - 1;
10492 }
10493 }
10494
10495 /* Update window_end_pos and window_end_vpos. */
10496 if (first_unchanged_at_end_row
10497 && first_unchanged_at_end_row->y < it.last_visible_y
10498 && !last_text_row_at_end)
10499 {
10500 /* Window end line if one of the preserved rows from the current
10501 matrix. Set row to the last row displaying text in current
10502 matrix starting at first_unchanged_at_end_row, after
10503 scrolling. */
10504 xassert (first_unchanged_at_end_row->displays_text_p);
10505 row = find_last_row_displaying_text (w->current_matrix, &it,
10506 first_unchanged_at_end_row);
10507 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
10508
10509 XSETFASTINT (w->window_end_pos, Z - MATRIX_ROW_END_CHARPOS (row));
10510 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
10511 XSETFASTINT (w->window_end_vpos,
10512 MATRIX_ROW_VPOS (row, w->current_matrix));
10513 }
10514 else if (last_text_row_at_end)
10515 {
10516 XSETFASTINT (w->window_end_pos,
10517 Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
10518 w->window_end_bytepos
10519 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
10520 XSETFASTINT (w->window_end_vpos,
10521 MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
10522 }
10523 else if (last_text_row)
10524 {
10525 /* We have displayed either to the end of the window or at the
10526 end of the window, i.e. the last row with text is to be found
10527 in the desired matrix. */
10528 XSETFASTINT (w->window_end_pos,
10529 Z - MATRIX_ROW_END_CHARPOS (last_text_row));
10530 w->window_end_bytepos
10531 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
10532 XSETFASTINT (w->window_end_vpos,
10533 MATRIX_ROW_VPOS (last_text_row, desired_matrix));
10534 }
10535 else if (first_unchanged_at_end_row == NULL
10536 && last_text_row == NULL
10537 && last_text_row_at_end == NULL)
10538 {
10539 /* Displayed to end of window, but no line containing text was
10540 displayed. Lines were deleted at the end of the window. */
10541 int vpos;
10542 int header_line_p = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
10543
10544 for (vpos = XFASTINT (w->window_end_vpos); vpos > 0; --vpos)
10545 if ((w->desired_matrix->rows[vpos + header_line_p].enabled_p
10546 && w->desired_matrix->rows[vpos + header_line_p].displays_text_p)
10547 || (!w->desired_matrix->rows[vpos + header_line_p].enabled_p
10548 && w->current_matrix->rows[vpos + header_line_p].displays_text_p))
10549 break;
10550
10551 w->window_end_vpos = make_number (vpos);
10552 }
10553 else
10554 abort ();
10555
10556 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
10557 debug_end_vpos = XFASTINT (w->window_end_vpos));
10558
10559 /* Record that display has not been completed. */
10560 w->window_end_valid = Qnil;
10561 w->desired_matrix->no_scrolling_p = 1;
10562 return 1;
10563 }
10564
10565
10566 \f
10567 /***********************************************************************
10568 More debugging support
10569 ***********************************************************************/
10570
10571 #if GLYPH_DEBUG
10572
10573 void dump_glyph_row P_ ((struct glyph_matrix *, int, int));
10574 static void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
10575
10576
10577 /* Dump the contents of glyph matrix MATRIX on stderr. If
10578 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
10579
10580 void
10581 dump_glyph_matrix (matrix, with_glyphs_p)
10582 struct glyph_matrix *matrix;
10583 int with_glyphs_p;
10584 {
10585 int i;
10586 for (i = 0; i < matrix->nrows; ++i)
10587 dump_glyph_row (matrix, i, with_glyphs_p);
10588 }
10589
10590
10591 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
10592 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
10593
10594 void
10595 dump_glyph_row (matrix, vpos, with_glyphs_p)
10596 struct glyph_matrix *matrix;
10597 int vpos, with_glyphs_p;
10598 {
10599 struct glyph_row *row;
10600
10601 if (vpos < 0 || vpos >= matrix->nrows)
10602 return;
10603
10604 row = MATRIX_ROW (matrix, vpos);
10605
10606 fprintf (stderr, "Row Start End Used oEI><O\\CTZFes X Y W\n");
10607 fprintf (stderr, "=============================================\n");
10608
10609 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%1.1d%1.1d %4d %4d %4d\n",
10610 row - matrix->rows,
10611 MATRIX_ROW_START_CHARPOS (row),
10612 MATRIX_ROW_END_CHARPOS (row),
10613 row->used[TEXT_AREA],
10614 row->contains_overlapping_glyphs_p,
10615 row->enabled_p,
10616 row->inverse_p,
10617 row->truncated_on_left_p,
10618 row->truncated_on_right_p,
10619 row->overlay_arrow_p,
10620 row->continued_p,
10621 MATRIX_ROW_CONTINUATION_LINE_P (row),
10622 row->displays_text_p,
10623 row->ends_at_zv_p,
10624 row->fill_line_p,
10625 row->ends_in_middle_of_char_p,
10626 row->starts_in_middle_of_char_p,
10627 row->x,
10628 row->y,
10629 row->pixel_width);
10630 fprintf (stderr, "%9d %5d\n", row->start.overlay_string_index,
10631 row->end.overlay_string_index);
10632 fprintf (stderr, "%9d %5d\n",
10633 CHARPOS (row->start.string_pos),
10634 CHARPOS (row->end.string_pos));
10635 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
10636 row->end.dpvec_index);
10637
10638 if (with_glyphs_p)
10639 {
10640 struct glyph *glyph, *glyph_end;
10641 int prev_had_glyphs_p;
10642
10643 glyph = row->glyphs[TEXT_AREA];
10644 glyph_end = glyph + row->used[TEXT_AREA];
10645
10646 /* Glyph for a line end in text. */
10647 if (glyph == glyph_end && glyph->charpos > 0)
10648 ++glyph_end;
10649
10650 if (glyph < glyph_end)
10651 {
10652 fprintf (stderr, " Glyph Type Pos W Code C Face LR\n");
10653 prev_had_glyphs_p = 1;
10654 }
10655 else
10656 prev_had_glyphs_p = 0;
10657
10658 while (glyph < glyph_end)
10659 {
10660 if (glyph->type == CHAR_GLYPH)
10661 {
10662 fprintf (stderr,
10663 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10664 glyph - row->glyphs[TEXT_AREA],
10665 'C',
10666 glyph->charpos,
10667 glyph->pixel_width,
10668 glyph->u.ch,
10669 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
10670 ? glyph->u.ch
10671 : '.'),
10672 glyph->face_id,
10673 glyph->left_box_line_p,
10674 glyph->right_box_line_p);
10675 }
10676 else if (glyph->type == STRETCH_GLYPH)
10677 {
10678 fprintf (stderr,
10679 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10680 glyph - row->glyphs[TEXT_AREA],
10681 'S',
10682 glyph->charpos,
10683 glyph->pixel_width,
10684 0,
10685 '.',
10686 glyph->face_id,
10687 glyph->left_box_line_p,
10688 glyph->right_box_line_p);
10689 }
10690 else if (glyph->type == IMAGE_GLYPH)
10691 {
10692 fprintf (stderr,
10693 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
10694 glyph - row->glyphs[TEXT_AREA],
10695 'I',
10696 glyph->charpos,
10697 glyph->pixel_width,
10698 glyph->u.img_id,
10699 '.',
10700 glyph->face_id,
10701 glyph->left_box_line_p,
10702 glyph->right_box_line_p);
10703 }
10704 ++glyph;
10705 }
10706 }
10707 }
10708
10709
10710 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
10711 Sdump_glyph_matrix, 0, 1, "p",
10712 "Dump the current matrix of the selected window to stderr.\n\
10713 Shows contents of glyph row structures. With non-nil optional\n\
10714 parameter WITH-GLYPHS-P, dump glyphs as well.")
10715 (with_glyphs_p)
10716 Lisp_Object with_glyphs_p;
10717 {
10718 struct window *w = XWINDOW (selected_window);
10719 struct buffer *buffer = XBUFFER (w->buffer);
10720
10721 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
10722 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
10723 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
10724 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
10725 fprintf (stderr, "=============================================\n");
10726 dump_glyph_matrix (w->current_matrix, !NILP (with_glyphs_p));
10727 return Qnil;
10728 }
10729
10730
10731 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 1, "",
10732 "Dump glyph row ROW to stderr.")
10733 (row)
10734 Lisp_Object row;
10735 {
10736 CHECK_NUMBER (row, 0);
10737 dump_glyph_row (XWINDOW (selected_window)->current_matrix, XINT (row), 1);
10738 return Qnil;
10739 }
10740
10741
10742 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row,
10743 0, 0, "", "")
10744 ()
10745 {
10746 struct frame *sf = SELECTED_FRAME ();
10747 struct glyph_matrix *m = (XWINDOW (sf->tool_bar_window)
10748 ->current_matrix);
10749 dump_glyph_row (m, 0, 1);
10750 return Qnil;
10751 }
10752
10753
10754 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle,
10755 Strace_redisplay_toggle, 0, 0, "",
10756 "Toggle tracing of redisplay.")
10757 ()
10758 {
10759 trace_redisplay_p = !trace_redisplay_p;
10760 return Qnil;
10761 }
10762
10763
10764 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, 1, "",
10765 "Print STRING to stderr.")
10766 (string)
10767 Lisp_Object string;
10768 {
10769 CHECK_STRING (string, 0);
10770 fprintf (stderr, "%s", XSTRING (string)->data);
10771 return Qnil;
10772 }
10773
10774 #endif /* GLYPH_DEBUG */
10775
10776
10777 \f
10778 /***********************************************************************
10779 Building Desired Matrix Rows
10780 ***********************************************************************/
10781
10782 /* Return a temporary glyph row holding the glyphs of an overlay
10783 arrow. Only used for non-window-redisplay windows. */
10784
10785 static struct glyph_row *
10786 get_overlay_arrow_glyph_row (w)
10787 struct window *w;
10788 {
10789 struct frame *f = XFRAME (WINDOW_FRAME (w));
10790 struct buffer *buffer = XBUFFER (w->buffer);
10791 struct buffer *old = current_buffer;
10792 unsigned char *arrow_string = XSTRING (Voverlay_arrow_string)->data;
10793 int arrow_len = XSTRING (Voverlay_arrow_string)->size;
10794 unsigned char *arrow_end = arrow_string + arrow_len;
10795 unsigned char *p;
10796 struct it it;
10797 int multibyte_p;
10798 int n_glyphs_before;
10799
10800 set_buffer_temp (buffer);
10801 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
10802 it.glyph_row->used[TEXT_AREA] = 0;
10803 SET_TEXT_POS (it.position, 0, 0);
10804
10805 multibyte_p = !NILP (buffer->enable_multibyte_characters);
10806 p = arrow_string;
10807 while (p < arrow_end)
10808 {
10809 Lisp_Object face, ilisp;
10810
10811 /* Get the next character. */
10812 if (multibyte_p)
10813 it.c = string_char_and_length (p, arrow_len, &it.len);
10814 else
10815 it.c = *p, it.len = 1;
10816 p += it.len;
10817
10818 /* Get its face. */
10819 XSETFASTINT (ilisp, p - arrow_string);
10820 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
10821 it.face_id = compute_char_face (f, it.c, face);
10822
10823 /* Compute its width, get its glyphs. */
10824 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
10825 SET_TEXT_POS (it.position, -1, -1);
10826 PRODUCE_GLYPHS (&it);
10827
10828 /* If this character doesn't fit any more in the line, we have
10829 to remove some glyphs. */
10830 if (it.current_x > it.last_visible_x)
10831 {
10832 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
10833 break;
10834 }
10835 }
10836
10837 set_buffer_temp (old);
10838 return it.glyph_row;
10839 }
10840
10841
10842 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
10843 glyphs are only inserted for terminal frames since we can't really
10844 win with truncation glyphs when partially visible glyphs are
10845 involved. Which glyphs to insert is determined by
10846 produce_special_glyphs. */
10847
10848 static void
10849 insert_left_trunc_glyphs (it)
10850 struct it *it;
10851 {
10852 struct it truncate_it;
10853 struct glyph *from, *end, *to, *toend;
10854
10855 xassert (!FRAME_WINDOW_P (it->f));
10856
10857 /* Get the truncation glyphs. */
10858 truncate_it = *it;
10859 truncate_it.current_x = 0;
10860 truncate_it.face_id = DEFAULT_FACE_ID;
10861 truncate_it.glyph_row = &scratch_glyph_row;
10862 truncate_it.glyph_row->used[TEXT_AREA] = 0;
10863 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
10864 truncate_it.object = make_number (0);
10865 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
10866
10867 /* Overwrite glyphs from IT with truncation glyphs. */
10868 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
10869 end = from + truncate_it.glyph_row->used[TEXT_AREA];
10870 to = it->glyph_row->glyphs[TEXT_AREA];
10871 toend = to + it->glyph_row->used[TEXT_AREA];
10872
10873 while (from < end)
10874 *to++ = *from++;
10875
10876 /* There may be padding glyphs left over. Remove them. */
10877 from = to;
10878 while (from < toend && CHAR_GLYPH_PADDING_P (*from))
10879 ++from;
10880 while (from < toend)
10881 *to++ = *from++;
10882
10883 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
10884 }
10885
10886
10887 /* Compute the pixel height and width of IT->glyph_row.
10888
10889 Most of the time, ascent and height of a display line will be equal
10890 to the max_ascent and max_height values of the display iterator
10891 structure. This is not the case if
10892
10893 1. We hit ZV without displaying anything. In this case, max_ascent
10894 and max_height will be zero.
10895
10896 2. We have some glyphs that don't contribute to the line height.
10897 (The glyph row flag contributes_to_line_height_p is for future
10898 pixmap extensions).
10899
10900 The first case is easily covered by using default values because in
10901 these cases, the line height does not really matter, except that it
10902 must not be zero. */
10903
10904 static void
10905 compute_line_metrics (it)
10906 struct it *it;
10907 {
10908 struct glyph_row *row = it->glyph_row;
10909 int area, i;
10910
10911 if (FRAME_WINDOW_P (it->f))
10912 {
10913 int i, header_line_height;
10914
10915 /* The line may consist of one space only, that was added to
10916 place the cursor on it. If so, the row's height hasn't been
10917 computed yet. */
10918 if (row->height == 0)
10919 {
10920 if (it->max_ascent + it->max_descent == 0)
10921 it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
10922 row->ascent = it->max_ascent;
10923 row->height = it->max_ascent + it->max_descent;
10924 row->phys_ascent = it->max_phys_ascent;
10925 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
10926 }
10927
10928 /* Compute the width of this line. */
10929 row->pixel_width = row->x;
10930 for (i = 0; i < row->used[TEXT_AREA]; ++i)
10931 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
10932
10933 xassert (row->pixel_width >= 0);
10934 xassert (row->ascent >= 0 && row->height > 0);
10935
10936 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
10937 || MATRIX_ROW_OVERLAPS_PRED_P (row));
10938
10939 /* If first line's physical ascent is larger than its logical
10940 ascent, use the physical ascent, and make the row taller.
10941 This makes accented characters fully visible. */
10942 if (row == it->w->desired_matrix->rows
10943 && row->phys_ascent > row->ascent)
10944 {
10945 row->height += row->phys_ascent - row->ascent;
10946 row->ascent = row->phys_ascent;
10947 }
10948
10949 /* Compute how much of the line is visible. */
10950 row->visible_height = row->height;
10951
10952 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
10953 if (row->y < header_line_height)
10954 row->visible_height -= header_line_height - row->y;
10955 else
10956 {
10957 int max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
10958 if (row->y + row->height > max_y)
10959 row->visible_height -= row->y + row->height - max_y;
10960 }
10961 }
10962 else
10963 {
10964 row->pixel_width = row->used[TEXT_AREA];
10965 row->ascent = row->phys_ascent = 0;
10966 row->height = row->phys_height = row->visible_height = 1;
10967 }
10968
10969 /* Compute a hash code for this row. */
10970 row->hash = 0;
10971 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
10972 for (i = 0; i < row->used[area]; ++i)
10973 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
10974 + row->glyphs[area][i].u.val
10975 + row->glyphs[area][i].face_id
10976 + row->glyphs[area][i].padding_p
10977 + (row->glyphs[area][i].type << 2));
10978
10979 it->max_ascent = it->max_descent = 0;
10980 it->max_phys_ascent = it->max_phys_descent = 0;
10981 }
10982
10983
10984 /* Append one space to the glyph row of iterator IT if doing a
10985 window-based redisplay. DEFAULT_FACE_P non-zero means let the
10986 space have the default face, otherwise let it have the same face as
10987 IT->face_id. Value is non-zero if a space was added.
10988
10989 This function is called to make sure that there is always one glyph
10990 at the end of a glyph row that the cursor can be set on under
10991 window-systems. (If there weren't such a glyph we would not know
10992 how wide and tall a box cursor should be displayed).
10993
10994 At the same time this space let's a nicely handle clearing to the
10995 end of the line if the row ends in italic text. */
10996
10997 static int
10998 append_space (it, default_face_p)
10999 struct it *it;
11000 int default_face_p;
11001 {
11002 if (FRAME_WINDOW_P (it->f))
11003 {
11004 int n = it->glyph_row->used[TEXT_AREA];
11005
11006 if (it->glyph_row->glyphs[TEXT_AREA] + n
11007 < it->glyph_row->glyphs[1 + TEXT_AREA])
11008 {
11009 /* Save some values that must not be changed. */
11010 int saved_x = it->current_x;
11011 struct text_pos saved_pos;
11012 int saved_what = it->what;
11013 int saved_face_id = it->face_id;
11014 Lisp_Object saved_object;
11015 struct face *face;
11016
11017 saved_object = it->object;
11018 saved_pos = it->position;
11019
11020 it->what = IT_CHARACTER;
11021 bzero (&it->position, sizeof it->position);
11022 it->object = make_number (0);
11023 it->c = ' ';
11024 it->len = 1;
11025
11026 if (default_face_p)
11027 it->face_id = DEFAULT_FACE_ID;
11028 face = FACE_FROM_ID (it->f, it->face_id);
11029 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
11030
11031 PRODUCE_GLYPHS (it);
11032
11033 it->current_x = saved_x;
11034 it->object = saved_object;
11035 it->position = saved_pos;
11036 it->what = saved_what;
11037 it->face_id = saved_face_id;
11038 return 1;
11039 }
11040 }
11041
11042 return 0;
11043 }
11044
11045
11046 /* Extend the face of the last glyph in the text area of IT->glyph_row
11047 to the end of the display line. Called from display_line.
11048 If the glyph row is empty, add a space glyph to it so that we
11049 know the face to draw. Set the glyph row flag fill_line_p. */
11050
11051 static void
11052 extend_face_to_end_of_line (it)
11053 struct it *it;
11054 {
11055 struct face *face;
11056 struct frame *f = it->f;
11057
11058 /* If line is already filled, do nothing. */
11059 if (it->current_x >= it->last_visible_x)
11060 return;
11061
11062 /* Face extension extends the background and box of IT->face_id
11063 to the end of the line. If the background equals the background
11064 of the frame, we haven't to do anything. */
11065 face = FACE_FROM_ID (f, it->face_id);
11066 if (FRAME_WINDOW_P (f)
11067 && face->box == FACE_NO_BOX
11068 && face->background == FRAME_BACKGROUND_PIXEL (f)
11069 && !face->stipple)
11070 return;
11071
11072 /* Set the glyph row flag indicating that the face of the last glyph
11073 in the text area has to be drawn to the end of the text area. */
11074 it->glyph_row->fill_line_p = 1;
11075
11076 /* If current character of IT is not ASCII, make sure we have the
11077 ASCII face. This will be automatically undone the next time
11078 get_next_display_element returns a multibyte character. Note
11079 that the character will always be single byte in unibyte text. */
11080 if (!SINGLE_BYTE_CHAR_P (it->c))
11081 {
11082 it->face_id = FACE_FOR_CHAR (f, face, 0);
11083 }
11084
11085 if (FRAME_WINDOW_P (f))
11086 {
11087 /* If the row is empty, add a space with the current face of IT,
11088 so that we know which face to draw. */
11089 if (it->glyph_row->used[TEXT_AREA] == 0)
11090 {
11091 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
11092 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
11093 it->glyph_row->used[TEXT_AREA] = 1;
11094 }
11095 }
11096 else
11097 {
11098 /* Save some values that must not be changed. */
11099 int saved_x = it->current_x;
11100 struct text_pos saved_pos;
11101 Lisp_Object saved_object;
11102 int saved_what = it->what;
11103
11104 saved_object = it->object;
11105 saved_pos = it->position;
11106
11107 it->what = IT_CHARACTER;
11108 bzero (&it->position, sizeof it->position);
11109 it->object = make_number (0);
11110 it->c = ' ';
11111 it->len = 1;
11112
11113 PRODUCE_GLYPHS (it);
11114
11115 while (it->current_x <= it->last_visible_x)
11116 PRODUCE_GLYPHS (it);
11117
11118 /* Don't count these blanks really. It would let us insert a left
11119 truncation glyph below and make us set the cursor on them, maybe. */
11120 it->current_x = saved_x;
11121 it->object = saved_object;
11122 it->position = saved_pos;
11123 it->what = saved_what;
11124 }
11125 }
11126
11127
11128 /* Value is non-zero if text starting at CHARPOS in current_buffer is
11129 trailing whitespace. */
11130
11131 static int
11132 trailing_whitespace_p (charpos)
11133 int charpos;
11134 {
11135 int bytepos = CHAR_TO_BYTE (charpos);
11136 int c = 0;
11137
11138 while (bytepos < ZV_BYTE
11139 && (c = FETCH_CHAR (bytepos),
11140 c == ' ' || c == '\t'))
11141 ++bytepos;
11142
11143 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
11144 {
11145 if (bytepos != PT_BYTE)
11146 return 1;
11147 }
11148 return 0;
11149 }
11150
11151
11152 /* Highlight trailing whitespace, if any, in ROW. */
11153
11154 void
11155 highlight_trailing_whitespace (f, row)
11156 struct frame *f;
11157 struct glyph_row *row;
11158 {
11159 int used = row->used[TEXT_AREA];
11160
11161 if (used)
11162 {
11163 struct glyph *start = row->glyphs[TEXT_AREA];
11164 struct glyph *glyph = start + used - 1;
11165
11166 /* Skip over the space glyph inserted to display the
11167 cursor at the end of a line. */
11168 if (glyph->type == CHAR_GLYPH
11169 && glyph->u.ch == ' '
11170 && INTEGERP (glyph->object))
11171 --glyph;
11172
11173 /* If last glyph is a space or stretch, and it's trailing
11174 whitespace, set the face of all trailing whitespace glyphs in
11175 IT->glyph_row to `trailing-whitespace'. */
11176 if (glyph >= start
11177 && BUFFERP (glyph->object)
11178 && (glyph->type == STRETCH_GLYPH
11179 || (glyph->type == CHAR_GLYPH
11180 && glyph->u.ch == ' '))
11181 && trailing_whitespace_p (glyph->charpos))
11182 {
11183 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
11184
11185 while (glyph >= start
11186 && BUFFERP (glyph->object)
11187 && (glyph->type == STRETCH_GLYPH
11188 || (glyph->type == CHAR_GLYPH
11189 && glyph->u.ch == ' ')))
11190 (glyph--)->face_id = face_id;
11191 }
11192 }
11193 }
11194
11195
11196 /* Construct the glyph row IT->glyph_row in the desired matrix of
11197 IT->w from text at the current position of IT. See dispextern.h
11198 for an overview of struct it. Value is non-zero if
11199 IT->glyph_row displays text, as opposed to a line displaying ZV
11200 only. */
11201
11202 static int
11203 display_line (it)
11204 struct it *it;
11205 {
11206 struct glyph_row *row = it->glyph_row;
11207
11208 /* We always start displaying at hpos zero even if hscrolled. */
11209 xassert (it->hpos == 0 && it->current_x == 0);
11210
11211 /* We must not display in a row that's not a text row. */
11212 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
11213 < it->w->desired_matrix->nrows);
11214
11215 /* Is IT->w showing the region? */
11216 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
11217
11218 /* Clear the result glyph row and enable it. */
11219 prepare_desired_row (row);
11220
11221 row->y = it->current_y;
11222 row->start = it->current;
11223 row->continuation_lines_width = it->continuation_lines_width;
11224 row->displays_text_p = 1;
11225 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
11226 it->starts_in_middle_of_char_p = 0;
11227
11228 /* Arrange the overlays nicely for our purposes. Usually, we call
11229 display_line on only one line at a time, in which case this
11230 can't really hurt too much, or we call it on lines which appear
11231 one after another in the buffer, in which case all calls to
11232 recenter_overlay_lists but the first will be pretty cheap. */
11233 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
11234
11235 /* Move over display elements that are not visible because we are
11236 hscrolled. This may stop at an x-position < IT->first_visible_x
11237 if the first glyph is partially visible or if we hit a line end. */
11238 if (it->current_x < it->first_visible_x)
11239 move_it_in_display_line_to (it, ZV, it->first_visible_x,
11240 MOVE_TO_POS | MOVE_TO_X);
11241
11242 /* Get the initial row height. This is either the height of the
11243 text hscrolled, if there is any, or zero. */
11244 row->ascent = it->max_ascent;
11245 row->height = it->max_ascent + it->max_descent;
11246 row->phys_ascent = it->max_phys_ascent;
11247 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
11248
11249 /* Loop generating characters. The loop is left with IT on the next
11250 character to display. */
11251 while (1)
11252 {
11253 int n_glyphs_before, hpos_before, x_before;
11254 int x, i, nglyphs;
11255 int ascent, descent, phys_ascent, phys_descent;
11256
11257 /* Retrieve the next thing to display. Value is zero if end of
11258 buffer reached. */
11259 if (!get_next_display_element (it))
11260 {
11261 /* Maybe add a space at the end of this line that is used to
11262 display the cursor there under X. Set the charpos of the
11263 first glyph of blank lines not corresponding to any text
11264 to -1. */
11265 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
11266 || row->used[TEXT_AREA] == 0)
11267 {
11268 row->glyphs[TEXT_AREA]->charpos = -1;
11269 row->displays_text_p = 0;
11270
11271 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines))
11272 row->indicate_empty_line_p = 1;
11273 }
11274
11275 it->continuation_lines_width = 0;
11276 row->ends_at_zv_p = 1;
11277 break;
11278 }
11279
11280 /* Now, get the metrics of what we want to display. This also
11281 generates glyphs in `row' (which is IT->glyph_row). */
11282 n_glyphs_before = row->used[TEXT_AREA];
11283 x = it->current_x;
11284
11285 /* Remember the line height so far in case the next element doesn't
11286 fit on the line. */
11287 if (!it->truncate_lines_p)
11288 {
11289 ascent = it->max_ascent;
11290 descent = it->max_descent;
11291 phys_ascent = it->max_phys_ascent;
11292 phys_descent = it->max_phys_descent;
11293 }
11294
11295 PRODUCE_GLYPHS (it);
11296
11297 /* If this display element was in marginal areas, continue with
11298 the next one. */
11299 if (it->area != TEXT_AREA)
11300 {
11301 row->ascent = max (row->ascent, it->max_ascent);
11302 row->height = max (row->height, it->max_ascent + it->max_descent);
11303 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11304 row->phys_height = max (row->phys_height,
11305 it->max_phys_ascent + it->max_phys_descent);
11306 set_iterator_to_next (it);
11307 continue;
11308 }
11309
11310 /* Does the display element fit on the line? If we truncate
11311 lines, we should draw past the right edge of the window. If
11312 we don't truncate, we want to stop so that we can display the
11313 continuation glyph before the right margin. If lines are
11314 continued, there are two possible strategies for characters
11315 resulting in more than 1 glyph (e.g. tabs): Display as many
11316 glyphs as possible in this line and leave the rest for the
11317 continuation line, or display the whole element in the next
11318 line. Original redisplay did the former, so we do it also. */
11319 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11320 hpos_before = it->hpos;
11321 x_before = x;
11322
11323 if (nglyphs == 1
11324 && it->current_x < it->last_visible_x)
11325 {
11326 ++it->hpos;
11327 row->ascent = max (row->ascent, it->max_ascent);
11328 row->height = max (row->height, it->max_ascent + it->max_descent);
11329 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11330 row->phys_height = max (row->phys_height,
11331 it->max_phys_ascent + it->max_phys_descent);
11332 if (it->current_x - it->pixel_width < it->first_visible_x)
11333 row->x = x - it->first_visible_x;
11334 }
11335 else
11336 {
11337 int new_x;
11338 struct glyph *glyph;
11339
11340 for (i = 0; i < nglyphs; ++i, x = new_x)
11341 {
11342 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11343 new_x = x + glyph->pixel_width;
11344
11345 if (/* Lines are continued. */
11346 !it->truncate_lines_p
11347 && (/* Glyph doesn't fit on the line. */
11348 new_x > it->last_visible_x
11349 /* Or it fits exactly on a window system frame. */
11350 || (new_x == it->last_visible_x
11351 && FRAME_WINDOW_P (it->f))))
11352 {
11353 /* End of a continued line. */
11354
11355 if (it->hpos == 0
11356 || (new_x == it->last_visible_x
11357 && FRAME_WINDOW_P (it->f)))
11358 {
11359 /* Current glyph is the only one on the line or
11360 fits exactly on the line. We must continue
11361 the line because we can't draw the cursor
11362 after the glyph. */
11363 row->continued_p = 1;
11364 it->current_x = new_x;
11365 it->continuation_lines_width += new_x;
11366 ++it->hpos;
11367 if (i == nglyphs - 1)
11368 set_iterator_to_next (it);
11369 }
11370 else if (CHAR_GLYPH_PADDING_P (*glyph)
11371 && !FRAME_WINDOW_P (it->f))
11372 {
11373 /* A padding glyph that doesn't fit on this line.
11374 This means the whole character doesn't fit
11375 on the line. */
11376 row->used[TEXT_AREA] = n_glyphs_before;
11377
11378 /* Fill the rest of the row with continuation
11379 glyphs like in 20.x. */
11380 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
11381 < row->glyphs[1 + TEXT_AREA])
11382 produce_special_glyphs (it, IT_CONTINUATION);
11383
11384 row->continued_p = 1;
11385 it->current_x = x_before;
11386 it->continuation_lines_width += x_before;
11387
11388 /* Restore the height to what it was before the
11389 element not fitting on the line. */
11390 it->max_ascent = ascent;
11391 it->max_descent = descent;
11392 it->max_phys_ascent = phys_ascent;
11393 it->max_phys_descent = phys_descent;
11394 }
11395 else
11396 {
11397 /* Display element draws past the right edge of
11398 the window. Restore positions to values
11399 before the element. The next line starts
11400 with current_x before the glyph that could
11401 not be displayed, so that TAB works right. */
11402 row->used[TEXT_AREA] = n_glyphs_before + i;
11403
11404 /* Display continuation glyphs. */
11405 if (!FRAME_WINDOW_P (it->f))
11406 produce_special_glyphs (it, IT_CONTINUATION);
11407 row->continued_p = 1;
11408
11409 it->current_x = x;
11410 it->continuation_lines_width += x;
11411 if (nglyphs > 1 && i > 0)
11412 {
11413 row->ends_in_middle_of_char_p = 1;
11414 it->starts_in_middle_of_char_p = 1;
11415 }
11416
11417 /* Restore the height to what it was before the
11418 element not fitting on the line. */
11419 it->max_ascent = ascent;
11420 it->max_descent = descent;
11421 it->max_phys_ascent = phys_ascent;
11422 it->max_phys_descent = phys_descent;
11423 }
11424
11425 break;
11426 }
11427 else if (new_x > it->first_visible_x)
11428 {
11429 /* Increment number of glyphs actually displayed. */
11430 ++it->hpos;
11431
11432 if (x < it->first_visible_x)
11433 /* Glyph is partially visible, i.e. row starts at
11434 negative X position. */
11435 row->x = x - it->first_visible_x;
11436 }
11437 else
11438 {
11439 /* Glyph is completely off the left margin of the
11440 window. This should not happen because of the
11441 move_it_in_display_line at the start of
11442 this function. */
11443 abort ();
11444 }
11445 }
11446
11447 row->ascent = max (row->ascent, it->max_ascent);
11448 row->height = max (row->height, it->max_ascent + it->max_descent);
11449 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
11450 row->phys_height = max (row->phys_height,
11451 it->max_phys_ascent + it->max_phys_descent);
11452
11453 /* End of this display line if row is continued. */
11454 if (row->continued_p)
11455 break;
11456 }
11457
11458 /* Is this a line end? If yes, we're also done, after making
11459 sure that a non-default face is extended up to the right
11460 margin of the window. */
11461 if (ITERATOR_AT_END_OF_LINE_P (it))
11462 {
11463 int used_before = row->used[TEXT_AREA];
11464
11465 /* Add a space at the end of the line that is used to
11466 display the cursor there. */
11467 append_space (it, 0);
11468
11469 /* Extend the face to the end of the line. */
11470 extend_face_to_end_of_line (it);
11471
11472 /* Make sure we have the position. */
11473 if (used_before == 0)
11474 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
11475
11476 /* Consume the line end. This skips over invisible lines. */
11477 set_iterator_to_next (it);
11478 it->continuation_lines_width = 0;
11479 break;
11480 }
11481
11482 /* Proceed with next display element. Note that this skips
11483 over lines invisible because of selective display. */
11484 set_iterator_to_next (it);
11485
11486 /* If we truncate lines, we are done when the last displayed
11487 glyphs reach past the right margin of the window. */
11488 if (it->truncate_lines_p
11489 && (FRAME_WINDOW_P (it->f)
11490 ? (it->current_x >= it->last_visible_x)
11491 : (it->current_x > it->last_visible_x)))
11492 {
11493 /* Maybe add truncation glyphs. */
11494 if (!FRAME_WINDOW_P (it->f))
11495 {
11496 --it->glyph_row->used[TEXT_AREA];
11497 produce_special_glyphs (it, IT_TRUNCATION);
11498 }
11499
11500 row->truncated_on_right_p = 1;
11501 it->continuation_lines_width = 0;
11502 reseat_at_next_visible_line_start (it, 0);
11503 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
11504 it->hpos = hpos_before;
11505 it->current_x = x_before;
11506 break;
11507 }
11508 }
11509
11510 /* If line is not empty and hscrolled, maybe insert truncation glyphs
11511 at the left window margin. */
11512 if (it->first_visible_x
11513 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
11514 {
11515 if (!FRAME_WINDOW_P (it->f))
11516 insert_left_trunc_glyphs (it);
11517 row->truncated_on_left_p = 1;
11518 }
11519
11520 /* If the start of this line is the overlay arrow-position, then
11521 mark this glyph row as the one containing the overlay arrow.
11522 This is clearly a mess with variable size fonts. It would be
11523 better to let it be displayed like cursors under X. */
11524 if (MARKERP (Voverlay_arrow_position)
11525 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
11526 && (MATRIX_ROW_START_CHARPOS (row)
11527 == marker_position (Voverlay_arrow_position))
11528 && STRINGP (Voverlay_arrow_string)
11529 && ! overlay_arrow_seen)
11530 {
11531 /* Overlay arrow in window redisplay is a bitmap. */
11532 if (!FRAME_WINDOW_P (it->f))
11533 {
11534 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
11535 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
11536 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
11537 struct glyph *p = row->glyphs[TEXT_AREA];
11538 struct glyph *p2, *end;
11539
11540 /* Copy the arrow glyphs. */
11541 while (glyph < arrow_end)
11542 *p++ = *glyph++;
11543
11544 /* Throw away padding glyphs. */
11545 p2 = p;
11546 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
11547 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
11548 ++p2;
11549 if (p2 > p)
11550 {
11551 while (p2 < end)
11552 *p++ = *p2++;
11553 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
11554 }
11555 }
11556
11557 overlay_arrow_seen = 1;
11558 row->overlay_arrow_p = 1;
11559 }
11560
11561 /* Compute pixel dimensions of this line. */
11562 compute_line_metrics (it);
11563
11564 /* Remember the position at which this line ends. */
11565 row->end = it->current;
11566
11567 /* Maybe set the cursor. */
11568 if (it->w->cursor.vpos < 0
11569 && PT >= MATRIX_ROW_START_CHARPOS (row)
11570 && PT <= MATRIX_ROW_END_CHARPOS (row))
11571 {
11572 /* Also see redisplay_window, case cursor movement in unchanged
11573 window. */
11574 if (MATRIX_ROW_END_CHARPOS (row) == PT
11575 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)
11576 && !row->ends_at_zv_p)
11577 ;
11578 else
11579 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
11580 }
11581
11582 /* Highlight trailing whitespace. */
11583 if (!NILP (Vshow_trailing_whitespace))
11584 highlight_trailing_whitespace (it->f, it->glyph_row);
11585
11586 /* Prepare for the next line. This line starts horizontally at (X
11587 HPOS) = (0 0). Vertical positions are incremented. As a
11588 convenience for the caller, IT->glyph_row is set to the next
11589 row to be used. */
11590 it->current_x = it->hpos = 0;
11591 it->current_y += row->height;
11592 ++it->vpos;
11593 ++it->glyph_row;
11594 return row->displays_text_p;
11595 }
11596
11597
11598 \f
11599 /***********************************************************************
11600 Menu Bar
11601 ***********************************************************************/
11602
11603 /* Redisplay the menu bar in the frame for window W.
11604
11605 The menu bar of X frames that don't have X toolkit support is
11606 displayed in a special window W->frame->menu_bar_window.
11607
11608 The menu bar of terminal frames is treated specially as far as
11609 glyph matrices are concerned. Menu bar lines are not part of
11610 windows, so the update is done directly on the frame matrix rows
11611 for the menu bar. */
11612
11613 static void
11614 display_menu_bar (w)
11615 struct window *w;
11616 {
11617 struct frame *f = XFRAME (WINDOW_FRAME (w));
11618 struct it it;
11619 Lisp_Object items;
11620 int i;
11621
11622 /* Don't do all this for graphical frames. */
11623 #ifdef HAVE_NTGUI
11624 if (!NILP (Vwindow_system))
11625 return;
11626 #endif
11627 #ifdef USE_X_TOOLKIT
11628 if (FRAME_X_P (f))
11629 return;
11630 #endif
11631
11632 #ifdef USE_X_TOOLKIT
11633 xassert (!FRAME_WINDOW_P (f));
11634 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
11635 it.first_visible_x = 0;
11636 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11637 #else /* not USE_X_TOOLKIT */
11638 if (FRAME_WINDOW_P (f))
11639 {
11640 /* Menu bar lines are displayed in the desired matrix of the
11641 dummy window menu_bar_window. */
11642 struct window *menu_w;
11643 xassert (WINDOWP (f->menu_bar_window));
11644 menu_w = XWINDOW (f->menu_bar_window);
11645 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
11646 MENU_FACE_ID);
11647 it.first_visible_x = 0;
11648 it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
11649 }
11650 else
11651 {
11652 /* This is a TTY frame, i.e. character hpos/vpos are used as
11653 pixel x/y. */
11654 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
11655 MENU_FACE_ID);
11656 it.first_visible_x = 0;
11657 it.last_visible_x = FRAME_WIDTH (f);
11658 }
11659 #endif /* not USE_X_TOOLKIT */
11660
11661 /* Clear all rows of the menu bar. */
11662 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
11663 {
11664 struct glyph_row *row = it.glyph_row + i;
11665 clear_glyph_row (row);
11666 row->enabled_p = 1;
11667 row->full_width_p = 1;
11668 }
11669
11670 /* Make the first line of the menu bar appear in reverse video. */
11671 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11672
11673 /* Display all items of the menu bar. */
11674 items = FRAME_MENU_BAR_ITEMS (it.f);
11675 for (i = 0; i < XVECTOR (items)->size; i += 4)
11676 {
11677 Lisp_Object string;
11678
11679 /* Stop at nil string. */
11680 string = XVECTOR (items)->contents[i + 1];
11681 if (NILP (string))
11682 break;
11683
11684 /* Remember where item was displayed. */
11685 XSETFASTINT (XVECTOR (items)->contents[i + 3], it.hpos);
11686
11687 /* Display the item, pad with one space. */
11688 if (it.current_x < it.last_visible_x)
11689 display_string (NULL, string, Qnil, 0, 0, &it,
11690 XSTRING (string)->size + 1, 0, 0, -1);
11691 }
11692
11693 /* Fill out the line with spaces. */
11694 if (it.current_x < it.last_visible_x)
11695 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
11696
11697 /* Compute the total height of the lines. */
11698 compute_line_metrics (&it);
11699 }
11700
11701
11702 \f
11703 /***********************************************************************
11704 Mode Line
11705 ***********************************************************************/
11706
11707 /* Display the mode and/or top line of window W. */
11708
11709 static void
11710 display_mode_lines (w)
11711 struct window *w;
11712 {
11713 /* These will be set while the mode line specs are processed. */
11714 line_number_displayed = 0;
11715 w->column_number_displayed = Qnil;
11716
11717 if (WINDOW_WANTS_MODELINE_P (w))
11718 display_mode_line (w, MODE_LINE_FACE_ID,
11719 current_buffer->mode_line_format);
11720
11721 if (WINDOW_WANTS_HEADER_LINE_P (w))
11722 display_mode_line (w, HEADER_LINE_FACE_ID,
11723 current_buffer->header_line_format);
11724 }
11725
11726
11727 /* Display mode or top line of window W. FACE_ID specifies which line
11728 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
11729 FORMAT is the mode line format to display. */
11730
11731 static void
11732 display_mode_line (w, face_id, format)
11733 struct window *w;
11734 enum face_id face_id;
11735 Lisp_Object format;
11736 {
11737 struct it it;
11738 struct face *face;
11739
11740 init_iterator (&it, w, -1, -1, NULL, face_id);
11741 prepare_desired_row (it.glyph_row);
11742
11743 /* Temporarily make frame's keyboard the current kboard so that
11744 kboard-local variables in the mode_line_format will get the right
11745 values. */
11746 push_frame_kboard (it.f);
11747 display_mode_element (&it, 0, 0, 0, format);
11748 pop_frame_kboard ();
11749
11750 /* Fill up with spaces. */
11751 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
11752
11753 compute_line_metrics (&it);
11754 it.glyph_row->full_width_p = 1;
11755 it.glyph_row->mode_line_p = 1;
11756 it.glyph_row->inverse_p = mode_line_inverse_video != 0;
11757 it.glyph_row->continued_p = 0;
11758 it.glyph_row->truncated_on_left_p = 0;
11759 it.glyph_row->truncated_on_right_p = 0;
11760
11761 /* Make a 3D mode-line have a shadow at its right end. */
11762 face = FACE_FROM_ID (it.f, face_id);
11763 extend_face_to_end_of_line (&it);
11764 if (face->box != FACE_NO_BOX)
11765 {
11766 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
11767 + it.glyph_row->used[TEXT_AREA] - 1);
11768 last->right_box_line_p = 1;
11769 }
11770 }
11771
11772
11773 /* Contribute ELT to the mode line for window IT->w. How it
11774 translates into text depends on its data type.
11775
11776 IT describes the display environment in which we display, as usual.
11777
11778 DEPTH is the depth in recursion. It is used to prevent
11779 infinite recursion here.
11780
11781 FIELD_WIDTH is the number of characters the display of ELT should
11782 occupy in the mode line, and PRECISION is the maximum number of
11783 characters to display from ELT's representation. See
11784 display_string for details. *
11785
11786 Returns the hpos of the end of the text generated by ELT. */
11787
11788 static int
11789 display_mode_element (it, depth, field_width, precision, elt)
11790 struct it *it;
11791 int depth;
11792 int field_width, precision;
11793 Lisp_Object elt;
11794 {
11795 int n = 0, field, prec;
11796
11797 tail_recurse:
11798 if (depth > 10)
11799 goto invalid;
11800
11801 depth++;
11802
11803 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
11804 {
11805 case Lisp_String:
11806 {
11807 /* A string: output it and check for %-constructs within it. */
11808 unsigned char c;
11809 unsigned char *this = XSTRING (elt)->data;
11810 unsigned char *lisp_string = this;
11811
11812 while ((precision <= 0 || n < precision)
11813 && *this
11814 && (frame_title_ptr
11815 || it->current_x < it->last_visible_x))
11816 {
11817 unsigned char *last = this;
11818
11819 /* Advance to end of string or next format specifier. */
11820 while ((c = *this++) != '\0' && c != '%')
11821 ;
11822
11823 if (this - 1 != last)
11824 {
11825 /* Output to end of string or up to '%'. Field width
11826 is length of string. Don't output more than
11827 PRECISION allows us. */
11828 prec = --this - last;
11829 if (precision > 0 && prec > precision - n)
11830 prec = precision - n;
11831
11832 if (frame_title_ptr)
11833 n += store_frame_title (last, prec, prec);
11834 else
11835 n += display_string (NULL, elt, Qnil, 0, last - lisp_string,
11836 it, 0, prec, 0, -1);
11837 }
11838 else /* c == '%' */
11839 {
11840 unsigned char *percent_position = this;
11841
11842 /* Get the specified minimum width. Zero means
11843 don't pad. */
11844 field = 0;
11845 while ((c = *this++) >= '0' && c <= '9')
11846 field = field * 10 + c - '0';
11847
11848 /* Don't pad beyond the total padding allowed. */
11849 if (field_width - n > 0 && field > field_width - n)
11850 field = field_width - n;
11851
11852 /* Note that either PRECISION <= 0 or N < PRECISION. */
11853 prec = precision - n;
11854
11855 if (c == 'M')
11856 n += display_mode_element (it, depth, field, prec,
11857 Vglobal_mode_string);
11858 else if (c != 0)
11859 {
11860 unsigned char *spec
11861 = decode_mode_spec (it->w, c, field, prec);
11862
11863 if (frame_title_ptr)
11864 n += store_frame_title (spec, field, prec);
11865 else
11866 {
11867 int nglyphs_before
11868 = it->glyph_row->used[TEXT_AREA];
11869 int charpos
11870 = percent_position - XSTRING (elt)->data;
11871 int nwritten
11872 = display_string (spec, Qnil, elt, charpos, 0, it,
11873 field, prec, 0, -1);
11874
11875 /* Assign to the glyphs written above the
11876 string where the `%x' came from, position
11877 of the `%'. */
11878 if (nwritten > 0)
11879 {
11880 struct glyph *glyph
11881 = (it->glyph_row->glyphs[TEXT_AREA]
11882 + nglyphs_before);
11883 int i;
11884
11885 for (i = 0; i < nwritten; ++i)
11886 {
11887 glyph[i].object = elt;
11888 glyph[i].charpos = charpos;
11889 }
11890
11891 n += nwritten;
11892 }
11893 }
11894 }
11895 }
11896 }
11897 }
11898 break;
11899
11900 case Lisp_Symbol:
11901 /* A symbol: process the value of the symbol recursively
11902 as if it appeared here directly. Avoid error if symbol void.
11903 Special case: if value of symbol is a string, output the string
11904 literally. */
11905 {
11906 register Lisp_Object tem;
11907 tem = Fboundp (elt);
11908 if (!NILP (tem))
11909 {
11910 tem = Fsymbol_value (elt);
11911 /* If value is a string, output that string literally:
11912 don't check for % within it. */
11913 if (STRINGP (tem))
11914 {
11915 prec = XSTRING (tem)->size;
11916 if (precision > 0 && prec > precision - n)
11917 prec = precision - n;
11918 if (frame_title_ptr)
11919 n += store_frame_title (XSTRING (tem)->data, -1, prec);
11920 else
11921 n += display_string (NULL, tem, Qnil, 0, 0, it,
11922 0, prec, 0, -1);
11923 }
11924 else if (!EQ (tem, elt))
11925 {
11926 /* Give up right away for nil or t. */
11927 elt = tem;
11928 goto tail_recurse;
11929 }
11930 }
11931 }
11932 break;
11933
11934 case Lisp_Cons:
11935 {
11936 register Lisp_Object car, tem;
11937
11938 /* A cons cell: three distinct cases.
11939 If first element is a string or a cons, process all the elements
11940 and effectively concatenate them.
11941 If first element is a negative number, truncate displaying cdr to
11942 at most that many characters. If positive, pad (with spaces)
11943 to at least that many characters.
11944 If first element is a symbol, process the cadr or caddr recursively
11945 according to whether the symbol's value is non-nil or nil. */
11946 car = XCAR (elt);
11947 if (EQ (car, QCeval) && CONSP (XCDR (elt)))
11948 {
11949 /* An element of the form (:eval FORM) means evaluate FORM
11950 and use the result as mode line elements. */
11951 struct gcpro gcpro1;
11952 Lisp_Object spec;
11953
11954 spec = eval_form (XCAR (XCDR (elt)));
11955 GCPRO1 (spec);
11956 n += display_mode_element (it, depth, field_width - n,
11957 precision - n, spec);
11958 UNGCPRO;
11959 }
11960 else if (SYMBOLP (car))
11961 {
11962 tem = Fboundp (car);
11963 elt = XCDR (elt);
11964 if (!CONSP (elt))
11965 goto invalid;
11966 /* elt is now the cdr, and we know it is a cons cell.
11967 Use its car if CAR has a non-nil value. */
11968 if (!NILP (tem))
11969 {
11970 tem = Fsymbol_value (car);
11971 if (!NILP (tem))
11972 {
11973 elt = XCAR (elt);
11974 goto tail_recurse;
11975 }
11976 }
11977 /* Symbol's value is nil (or symbol is unbound)
11978 Get the cddr of the original list
11979 and if possible find the caddr and use that. */
11980 elt = XCDR (elt);
11981 if (NILP (elt))
11982 break;
11983 else if (!CONSP (elt))
11984 goto invalid;
11985 elt = XCAR (elt);
11986 goto tail_recurse;
11987 }
11988 else if (INTEGERP (car))
11989 {
11990 register int lim = XINT (car);
11991 elt = XCDR (elt);
11992 if (lim < 0)
11993 {
11994 /* Negative int means reduce maximum width. */
11995 if (precision <= 0)
11996 precision = -lim;
11997 else
11998 precision = min (precision, -lim);
11999 }
12000 else if (lim > 0)
12001 {
12002 /* Padding specified. Don't let it be more than
12003 current maximum. */
12004 if (precision > 0)
12005 lim = min (precision, lim);
12006
12007 /* If that's more padding than already wanted, queue it.
12008 But don't reduce padding already specified even if
12009 that is beyond the current truncation point. */
12010 field_width = max (lim, field_width);
12011 }
12012 goto tail_recurse;
12013 }
12014 else if (STRINGP (car) || CONSP (car))
12015 {
12016 register int limit = 50;
12017 /* Limit is to protect against circular lists. */
12018 while (CONSP (elt)
12019 && --limit > 0
12020 && (precision <= 0 || n < precision))
12021 {
12022 n += display_mode_element (it, depth, field_width - n,
12023 precision - n, XCAR (elt));
12024 elt = XCDR (elt);
12025 }
12026 }
12027 }
12028 break;
12029
12030 default:
12031 invalid:
12032 if (frame_title_ptr)
12033 n += store_frame_title ("*invalid*", 0, precision - n);
12034 else
12035 n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
12036 precision - n, 0, 0);
12037 return n;
12038 }
12039
12040 /* Pad to FIELD_WIDTH. */
12041 if (field_width > 0 && n < field_width)
12042 {
12043 if (frame_title_ptr)
12044 n += store_frame_title ("", field_width - n, 0);
12045 else
12046 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
12047 0, 0, 0);
12048 }
12049
12050 return n;
12051 }
12052
12053
12054 /* Write a null-terminated, right justified decimal representation of
12055 the positive integer D to BUF using a minimal field width WIDTH. */
12056
12057 static void
12058 pint2str (buf, width, d)
12059 register char *buf;
12060 register int width;
12061 register int d;
12062 {
12063 register char *p = buf;
12064
12065 if (d <= 0)
12066 *p++ = '0';
12067 else
12068 {
12069 while (d > 0)
12070 {
12071 *p++ = d % 10 + '0';
12072 d /= 10;
12073 }
12074 }
12075
12076 for (width -= (int) (p - buf); width > 0; --width)
12077 *p++ = ' ';
12078 *p-- = '\0';
12079 while (p > buf)
12080 {
12081 d = *buf;
12082 *buf++ = *p;
12083 *p-- = d;
12084 }
12085 }
12086
12087 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
12088 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
12089 type of CODING_SYSTEM. Return updated pointer into BUF. */
12090
12091 static unsigned char invalid_eol_type[] = "(*invalid*)";
12092
12093 static char *
12094 decode_mode_spec_coding (coding_system, buf, eol_flag)
12095 Lisp_Object coding_system;
12096 register char *buf;
12097 int eol_flag;
12098 {
12099 Lisp_Object val;
12100 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
12101 unsigned char *eol_str;
12102 int eol_str_len;
12103 /* The EOL conversion we are using. */
12104 Lisp_Object eoltype;
12105
12106 val = Fget (coding_system, Qcoding_system);
12107
12108 if (!VECTORP (val)) /* Not yet decided. */
12109 {
12110 if (multibyte)
12111 *buf++ = '-';
12112 if (eol_flag)
12113 eoltype = eol_mnemonic_undecided;
12114 /* Don't mention EOL conversion if it isn't decided. */
12115 }
12116 else
12117 {
12118 Lisp_Object eolvalue;
12119
12120 eolvalue = Fget (coding_system, Qeol_type);
12121
12122 if (multibyte)
12123 *buf++ = XFASTINT (XVECTOR (val)->contents[1]);
12124
12125 if (eol_flag)
12126 {
12127 /* The EOL conversion that is normal on this system. */
12128
12129 if (NILP (eolvalue)) /* Not yet decided. */
12130 eoltype = eol_mnemonic_undecided;
12131 else if (VECTORP (eolvalue)) /* Not yet decided. */
12132 eoltype = eol_mnemonic_undecided;
12133 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
12134 eoltype = (XFASTINT (eolvalue) == 0
12135 ? eol_mnemonic_unix
12136 : (XFASTINT (eolvalue) == 1
12137 ? eol_mnemonic_dos : eol_mnemonic_mac));
12138 }
12139 }
12140
12141 if (eol_flag)
12142 {
12143 /* Mention the EOL conversion if it is not the usual one. */
12144 if (STRINGP (eoltype))
12145 {
12146 eol_str = XSTRING (eoltype)->data;
12147 eol_str_len = XSTRING (eoltype)->size;
12148 }
12149 else if (INTEGERP (eoltype)
12150 && CHAR_VALID_P (XINT (eoltype), 0))
12151 {
12152 eol_str = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
12153 eol_str_len = CHAR_STRING (XINT (eoltype), eol_str);
12154 }
12155 else
12156 {
12157 eol_str = invalid_eol_type;
12158 eol_str_len = sizeof (invalid_eol_type) - 1;
12159 }
12160 bcopy (eol_str, buf, eol_str_len);
12161 buf += eol_str_len;
12162 }
12163
12164 return buf;
12165 }
12166
12167 /* Return a string for the output of a mode line %-spec for window W,
12168 generated by character C. PRECISION >= 0 means don't return a
12169 string longer than that value. FIELD_WIDTH > 0 means pad the
12170 string returned with spaces to that value. */
12171
12172 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
12173
12174 static char *
12175 decode_mode_spec (w, c, field_width, precision)
12176 struct window *w;
12177 register int c;
12178 int field_width, precision;
12179 {
12180 Lisp_Object obj;
12181 struct frame *f = XFRAME (WINDOW_FRAME (w));
12182 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
12183 struct buffer *b = XBUFFER (w->buffer);
12184
12185 obj = Qnil;
12186
12187 switch (c)
12188 {
12189 case '*':
12190 if (!NILP (b->read_only))
12191 return "%";
12192 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12193 return "*";
12194 return "-";
12195
12196 case '+':
12197 /* This differs from %* only for a modified read-only buffer. */
12198 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12199 return "*";
12200 if (!NILP (b->read_only))
12201 return "%";
12202 return "-";
12203
12204 case '&':
12205 /* This differs from %* in ignoring read-only-ness. */
12206 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
12207 return "*";
12208 return "-";
12209
12210 case '%':
12211 return "%";
12212
12213 case '[':
12214 {
12215 int i;
12216 char *p;
12217
12218 if (command_loop_level > 5)
12219 return "[[[... ";
12220 p = decode_mode_spec_buf;
12221 for (i = 0; i < command_loop_level; i++)
12222 *p++ = '[';
12223 *p = 0;
12224 return decode_mode_spec_buf;
12225 }
12226
12227 case ']':
12228 {
12229 int i;
12230 char *p;
12231
12232 if (command_loop_level > 5)
12233 return " ...]]]";
12234 p = decode_mode_spec_buf;
12235 for (i = 0; i < command_loop_level; i++)
12236 *p++ = ']';
12237 *p = 0;
12238 return decode_mode_spec_buf;
12239 }
12240
12241 case '-':
12242 {
12243 register int i;
12244
12245 /* Let lots_of_dashes be a string of infinite length. */
12246 if (field_width <= 0
12247 || field_width > sizeof (lots_of_dashes))
12248 {
12249 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
12250 decode_mode_spec_buf[i] = '-';
12251 decode_mode_spec_buf[i] = '\0';
12252 return decode_mode_spec_buf;
12253 }
12254 else
12255 return lots_of_dashes;
12256 }
12257
12258 case 'b':
12259 obj = b->name;
12260 break;
12261
12262 case 'c':
12263 {
12264 int col = current_column ();
12265 XSETFASTINT (w->column_number_displayed, col);
12266 pint2str (decode_mode_spec_buf, field_width, col);
12267 return decode_mode_spec_buf;
12268 }
12269
12270 case 'F':
12271 /* %F displays the frame name. */
12272 if (!NILP (f->title))
12273 return (char *) XSTRING (f->title)->data;
12274 if (f->explicit_name || ! FRAME_WINDOW_P (f))
12275 return (char *) XSTRING (f->name)->data;
12276 return "Emacs";
12277
12278 case 'f':
12279 obj = b->filename;
12280 break;
12281
12282 case 'l':
12283 {
12284 int startpos = XMARKER (w->start)->charpos;
12285 int startpos_byte = marker_byte_position (w->start);
12286 int line, linepos, linepos_byte, topline;
12287 int nlines, junk;
12288 int height = XFASTINT (w->height);
12289
12290 /* If we decided that this buffer isn't suitable for line numbers,
12291 don't forget that too fast. */
12292 if (EQ (w->base_line_pos, w->buffer))
12293 goto no_value;
12294 /* But do forget it, if the window shows a different buffer now. */
12295 else if (BUFFERP (w->base_line_pos))
12296 w->base_line_pos = Qnil;
12297
12298 /* If the buffer is very big, don't waste time. */
12299 if (!INTEGERP (Vline_number_display_limit)
12300 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
12301 {
12302 w->base_line_pos = Qnil;
12303 w->base_line_number = Qnil;
12304 goto no_value;
12305 }
12306
12307 if (!NILP (w->base_line_number)
12308 && !NILP (w->base_line_pos)
12309 && XFASTINT (w->base_line_pos) <= startpos)
12310 {
12311 line = XFASTINT (w->base_line_number);
12312 linepos = XFASTINT (w->base_line_pos);
12313 linepos_byte = buf_charpos_to_bytepos (b, linepos);
12314 }
12315 else
12316 {
12317 line = 1;
12318 linepos = BUF_BEGV (b);
12319 linepos_byte = BUF_BEGV_BYTE (b);
12320 }
12321
12322 /* Count lines from base line to window start position. */
12323 nlines = display_count_lines (linepos, linepos_byte,
12324 startpos_byte,
12325 startpos, &junk);
12326
12327 topline = nlines + line;
12328
12329 /* Determine a new base line, if the old one is too close
12330 or too far away, or if we did not have one.
12331 "Too close" means it's plausible a scroll-down would
12332 go back past it. */
12333 if (startpos == BUF_BEGV (b))
12334 {
12335 XSETFASTINT (w->base_line_number, topline);
12336 XSETFASTINT (w->base_line_pos, BUF_BEGV (b));
12337 }
12338 else if (nlines < height + 25 || nlines > height * 3 + 50
12339 || linepos == BUF_BEGV (b))
12340 {
12341 int limit = BUF_BEGV (b);
12342 int limit_byte = BUF_BEGV_BYTE (b);
12343 int position;
12344 int distance = (height * 2 + 30) * line_number_display_limit_width;
12345
12346 if (startpos - distance > limit)
12347 {
12348 limit = startpos - distance;
12349 limit_byte = CHAR_TO_BYTE (limit);
12350 }
12351
12352 nlines = display_count_lines (startpos, startpos_byte,
12353 limit_byte,
12354 - (height * 2 + 30),
12355 &position);
12356 /* If we couldn't find the lines we wanted within
12357 line_number_display_limit_width chars per line,
12358 give up on line numbers for this window. */
12359 if (position == limit_byte && limit == startpos - distance)
12360 {
12361 w->base_line_pos = w->buffer;
12362 w->base_line_number = Qnil;
12363 goto no_value;
12364 }
12365
12366 XSETFASTINT (w->base_line_number, topline - nlines);
12367 XSETFASTINT (w->base_line_pos, BYTE_TO_CHAR (position));
12368 }
12369
12370 /* Now count lines from the start pos to point. */
12371 nlines = display_count_lines (startpos, startpos_byte,
12372 PT_BYTE, PT, &junk);
12373
12374 /* Record that we did display the line number. */
12375 line_number_displayed = 1;
12376
12377 /* Make the string to show. */
12378 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
12379 return decode_mode_spec_buf;
12380 no_value:
12381 {
12382 char* p = decode_mode_spec_buf;
12383 int pad = field_width - 2;
12384 while (pad-- > 0)
12385 *p++ = ' ';
12386 *p++ = '?';
12387 *p = '?';
12388 return decode_mode_spec_buf;
12389 }
12390 }
12391 break;
12392
12393 case 'm':
12394 obj = b->mode_name;
12395 break;
12396
12397 case 'n':
12398 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
12399 return " Narrow";
12400 break;
12401
12402 case 'p':
12403 {
12404 int pos = marker_position (w->start);
12405 int total = BUF_ZV (b) - BUF_BEGV (b);
12406
12407 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
12408 {
12409 if (pos <= BUF_BEGV (b))
12410 return "All";
12411 else
12412 return "Bottom";
12413 }
12414 else if (pos <= BUF_BEGV (b))
12415 return "Top";
12416 else
12417 {
12418 if (total > 1000000)
12419 /* Do it differently for a large value, to avoid overflow. */
12420 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12421 else
12422 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
12423 /* We can't normally display a 3-digit number,
12424 so get us a 2-digit number that is close. */
12425 if (total == 100)
12426 total = 99;
12427 sprintf (decode_mode_spec_buf, "%2d%%", total);
12428 return decode_mode_spec_buf;
12429 }
12430 }
12431
12432 /* Display percentage of size above the bottom of the screen. */
12433 case 'P':
12434 {
12435 int toppos = marker_position (w->start);
12436 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
12437 int total = BUF_ZV (b) - BUF_BEGV (b);
12438
12439 if (botpos >= BUF_ZV (b))
12440 {
12441 if (toppos <= BUF_BEGV (b))
12442 return "All";
12443 else
12444 return "Bottom";
12445 }
12446 else
12447 {
12448 if (total > 1000000)
12449 /* Do it differently for a large value, to avoid overflow. */
12450 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
12451 else
12452 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
12453 /* We can't normally display a 3-digit number,
12454 so get us a 2-digit number that is close. */
12455 if (total == 100)
12456 total = 99;
12457 if (toppos <= BUF_BEGV (b))
12458 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
12459 else
12460 sprintf (decode_mode_spec_buf, "%2d%%", total);
12461 return decode_mode_spec_buf;
12462 }
12463 }
12464
12465 case 's':
12466 /* status of process */
12467 obj = Fget_buffer_process (w->buffer);
12468 if (NILP (obj))
12469 return "no process";
12470 #ifdef subprocesses
12471 obj = Fsymbol_name (Fprocess_status (obj));
12472 #endif
12473 break;
12474
12475 case 't': /* indicate TEXT or BINARY */
12476 #ifdef MODE_LINE_BINARY_TEXT
12477 return MODE_LINE_BINARY_TEXT (b);
12478 #else
12479 return "T";
12480 #endif
12481
12482 case 'z':
12483 /* coding-system (not including end-of-line format) */
12484 case 'Z':
12485 /* coding-system (including end-of-line type) */
12486 {
12487 int eol_flag = (c == 'Z');
12488 char *p = decode_mode_spec_buf;
12489
12490 if (! FRAME_WINDOW_P (f))
12491 {
12492 /* No need to mention EOL here--the terminal never needs
12493 to do EOL conversion. */
12494 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
12495 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
12496 }
12497 p = decode_mode_spec_coding (b->buffer_file_coding_system,
12498 p, eol_flag);
12499
12500 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
12501 #ifdef subprocesses
12502 obj = Fget_buffer_process (Fcurrent_buffer ());
12503 if (PROCESSP (obj))
12504 {
12505 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
12506 p, eol_flag);
12507 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
12508 p, eol_flag);
12509 }
12510 #endif /* subprocesses */
12511 #endif /* 0 */
12512 *p = 0;
12513 return decode_mode_spec_buf;
12514 }
12515 }
12516
12517 if (STRINGP (obj))
12518 return (char *) XSTRING (obj)->data;
12519 else
12520 return "";
12521 }
12522
12523
12524 /* Count up to COUNT lines starting from START / START_BYTE.
12525 But don't go beyond LIMIT_BYTE.
12526 Return the number of lines thus found (always nonnegative).
12527
12528 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
12529
12530 static int
12531 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
12532 int start, start_byte, limit_byte, count;
12533 int *byte_pos_ptr;
12534 {
12535 register unsigned char *cursor;
12536 unsigned char *base;
12537
12538 register int ceiling;
12539 register unsigned char *ceiling_addr;
12540 int orig_count = count;
12541
12542 /* If we are not in selective display mode,
12543 check only for newlines. */
12544 int selective_display = (!NILP (current_buffer->selective_display)
12545 && !INTEGERP (current_buffer->selective_display));
12546
12547 if (count > 0)
12548 {
12549 while (start_byte < limit_byte)
12550 {
12551 ceiling = BUFFER_CEILING_OF (start_byte);
12552 ceiling = min (limit_byte - 1, ceiling);
12553 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
12554 base = (cursor = BYTE_POS_ADDR (start_byte));
12555 while (1)
12556 {
12557 if (selective_display)
12558 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
12559 ;
12560 else
12561 while (*cursor != '\n' && ++cursor != ceiling_addr)
12562 ;
12563
12564 if (cursor != ceiling_addr)
12565 {
12566 if (--count == 0)
12567 {
12568 start_byte += cursor - base + 1;
12569 *byte_pos_ptr = start_byte;
12570 return orig_count;
12571 }
12572 else
12573 if (++cursor == ceiling_addr)
12574 break;
12575 }
12576 else
12577 break;
12578 }
12579 start_byte += cursor - base;
12580 }
12581 }
12582 else
12583 {
12584 while (start_byte > limit_byte)
12585 {
12586 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
12587 ceiling = max (limit_byte, ceiling);
12588 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
12589 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
12590 while (1)
12591 {
12592 if (selective_display)
12593 while (--cursor != ceiling_addr
12594 && *cursor != '\n' && *cursor != 015)
12595 ;
12596 else
12597 while (--cursor != ceiling_addr && *cursor != '\n')
12598 ;
12599
12600 if (cursor != ceiling_addr)
12601 {
12602 if (++count == 0)
12603 {
12604 start_byte += cursor - base + 1;
12605 *byte_pos_ptr = start_byte;
12606 /* When scanning backwards, we should
12607 not count the newline posterior to which we stop. */
12608 return - orig_count - 1;
12609 }
12610 }
12611 else
12612 break;
12613 }
12614 /* Here we add 1 to compensate for the last decrement
12615 of CURSOR, which took it past the valid range. */
12616 start_byte += cursor - base + 1;
12617 }
12618 }
12619
12620 *byte_pos_ptr = limit_byte;
12621
12622 if (count < 0)
12623 return - orig_count + count;
12624 return orig_count - count;
12625
12626 }
12627
12628
12629 \f
12630 /***********************************************************************
12631 Displaying strings
12632 ***********************************************************************/
12633
12634 /* Display a NUL-terminated string, starting with index START.
12635
12636 If STRING is non-null, display that C string. Otherwise, the Lisp
12637 string LISP_STRING is displayed.
12638
12639 If FACE_STRING is not nil, FACE_STRING_POS is a position in
12640 FACE_STRING. Display STRING or LISP_STRING with the face at
12641 FACE_STRING_POS in FACE_STRING:
12642
12643 Display the string in the environment given by IT, but use the
12644 standard display table, temporarily.
12645
12646 FIELD_WIDTH is the minimum number of output glyphs to produce.
12647 If STRING has fewer characters than FIELD_WIDTH, pad to the right
12648 with spaces. If STRING has more characters, more than FIELD_WIDTH
12649 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
12650
12651 PRECISION is the maximum number of characters to output from
12652 STRING. PRECISION < 0 means don't truncate the string.
12653
12654 This is roughly equivalent to printf format specifiers:
12655
12656 FIELD_WIDTH PRECISION PRINTF
12657 ----------------------------------------
12658 -1 -1 %s
12659 -1 10 %.10s
12660 10 -1 %10s
12661 20 10 %20.10s
12662
12663 MULTIBYTE zero means do not display multibyte chars, > 0 means do
12664 display them, and < 0 means obey the current buffer's value of
12665 enable_multibyte_characters.
12666
12667 Value is the number of glyphs produced. */
12668
12669 static int
12670 display_string (string, lisp_string, face_string, face_string_pos,
12671 start, it, field_width, precision, max_x, multibyte)
12672 unsigned char *string;
12673 Lisp_Object lisp_string;
12674 Lisp_Object face_string;
12675 int face_string_pos;
12676 int start;
12677 struct it *it;
12678 int field_width, precision, max_x;
12679 int multibyte;
12680 {
12681 int hpos_at_start = it->hpos;
12682 int saved_face_id = it->face_id;
12683 struct glyph_row *row = it->glyph_row;
12684
12685 /* Initialize the iterator IT for iteration over STRING beginning
12686 with index START. We assume that IT may be modified here (which
12687 means that display_line has to do something when displaying a
12688 mini-buffer prompt, which it does). */
12689 reseat_to_string (it, string, lisp_string, start,
12690 precision, field_width, multibyte);
12691
12692 /* If displaying STRING, set up the face of the iterator
12693 from LISP_STRING, if that's given. */
12694 if (STRINGP (face_string))
12695 {
12696 int endptr;
12697 struct face *face;
12698
12699 it->face_id
12700 = face_at_string_position (it->w, face_string, face_string_pos,
12701 0, it->region_beg_charpos,
12702 it->region_end_charpos,
12703 &endptr, it->base_face_id);
12704 face = FACE_FROM_ID (it->f, it->face_id);
12705 it->face_box_p = face->box != FACE_NO_BOX;
12706 }
12707
12708 /* Set max_x to the maximum allowed X position. Don't let it go
12709 beyond the right edge of the window. */
12710 if (max_x <= 0)
12711 max_x = it->last_visible_x;
12712 else
12713 max_x = min (max_x, it->last_visible_x);
12714
12715 /* Skip over display elements that are not visible. because IT->w is
12716 hscrolled. */
12717 if (it->current_x < it->first_visible_x)
12718 move_it_in_display_line_to (it, 100000, it->first_visible_x,
12719 MOVE_TO_POS | MOVE_TO_X);
12720
12721 row->ascent = it->max_ascent;
12722 row->height = it->max_ascent + it->max_descent;
12723 row->phys_ascent = it->max_phys_ascent;
12724 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
12725
12726 /* This condition is for the case that we are called with current_x
12727 past last_visible_x. */
12728 while (it->current_x < max_x)
12729 {
12730 int x_before, x, n_glyphs_before, i, nglyphs;
12731
12732 /* Get the next display element. */
12733 if (!get_next_display_element (it))
12734 break;
12735
12736 /* Produce glyphs. */
12737 x_before = it->current_x;
12738 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
12739 PRODUCE_GLYPHS (it);
12740
12741 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
12742 i = 0;
12743 x = x_before;
12744 while (i < nglyphs)
12745 {
12746 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12747
12748 if (!it->truncate_lines_p
12749 && x + glyph->pixel_width > max_x)
12750 {
12751 /* End of continued line or max_x reached. */
12752 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
12753 it->current_x = x;
12754 break;
12755 }
12756 else if (x + glyph->pixel_width > it->first_visible_x)
12757 {
12758 /* Glyph is at least partially visible. */
12759 ++it->hpos;
12760 if (x < it->first_visible_x)
12761 it->glyph_row->x = x - it->first_visible_x;
12762 }
12763 else
12764 {
12765 /* Glyph is off the left margin of the display area.
12766 Should not happen. */
12767 abort ();
12768 }
12769
12770 row->ascent = max (row->ascent, it->max_ascent);
12771 row->height = max (row->height, it->max_ascent + it->max_descent);
12772 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
12773 row->phys_height = max (row->phys_height,
12774 it->max_phys_ascent + it->max_phys_descent);
12775 x += glyph->pixel_width;
12776 ++i;
12777 }
12778
12779 /* Stop if max_x reached. */
12780 if (i < nglyphs)
12781 break;
12782
12783 /* Stop at line ends. */
12784 if (ITERATOR_AT_END_OF_LINE_P (it))
12785 {
12786 it->continuation_lines_width = 0;
12787 break;
12788 }
12789
12790 set_iterator_to_next (it);
12791
12792 /* Stop if truncating at the right edge. */
12793 if (it->truncate_lines_p
12794 && it->current_x >= it->last_visible_x)
12795 {
12796 /* Add truncation mark, but don't do it if the line is
12797 truncated at a padding space. */
12798 if (IT_CHARPOS (*it) < it->string_nchars)
12799 {
12800 if (!FRAME_WINDOW_P (it->f))
12801 produce_special_glyphs (it, IT_TRUNCATION);
12802 it->glyph_row->truncated_on_right_p = 1;
12803 }
12804 break;
12805 }
12806 }
12807
12808 /* Maybe insert a truncation at the left. */
12809 if (it->first_visible_x
12810 && IT_CHARPOS (*it) > 0)
12811 {
12812 if (!FRAME_WINDOW_P (it->f))
12813 insert_left_trunc_glyphs (it);
12814 it->glyph_row->truncated_on_left_p = 1;
12815 }
12816
12817 it->face_id = saved_face_id;
12818
12819 /* Value is number of columns displayed. */
12820 return it->hpos - hpos_at_start;
12821 }
12822
12823
12824 \f
12825 /* This is like a combination of memq and assq. Return 1 if PROPVAL
12826 appears as an element of LIST or as the car of an element of LIST.
12827 If PROPVAL is a list, compare each element against LIST in that
12828 way, and return 1 if any element of PROPVAL is found in LIST.
12829 Otherwise return 0. This function cannot quit. */
12830
12831 int
12832 invisible_p (propval, list)
12833 register Lisp_Object propval;
12834 Lisp_Object list;
12835 {
12836 register Lisp_Object tail, proptail;
12837 for (tail = list; CONSP (tail); tail = XCDR (tail))
12838 {
12839 register Lisp_Object tem;
12840 tem = XCAR (tail);
12841 if (EQ (propval, tem))
12842 return 1;
12843 if (CONSP (tem) && EQ (propval, XCAR (tem)))
12844 return 1;
12845 }
12846 if (CONSP (propval))
12847 for (proptail = propval; CONSP (proptail);
12848 proptail = XCDR (proptail))
12849 {
12850 Lisp_Object propelt;
12851 propelt = XCAR (proptail);
12852 for (tail = list; CONSP (tail); tail = XCDR (tail))
12853 {
12854 register Lisp_Object tem;
12855 tem = XCAR (tail);
12856 if (EQ (propelt, tem))
12857 return 1;
12858 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
12859 return 1;
12860 }
12861 }
12862 return 0;
12863 }
12864
12865
12866 /* Return 1 if PROPVAL appears as the car of an element of LIST and
12867 the cdr of that element is non-nil. If PROPVAL is a list, check
12868 each element of PROPVAL in that way, and the first time some
12869 element is found, return 1 if the cdr of that element is non-nil.
12870 Otherwise return 0. This function cannot quit. */
12871
12872 int
12873 invisible_ellipsis_p (propval, list)
12874 register Lisp_Object propval;
12875 Lisp_Object list;
12876 {
12877 register Lisp_Object tail, proptail;
12878
12879 for (tail = list; CONSP (tail); tail = XCDR (tail))
12880 {
12881 register Lisp_Object tem;
12882 tem = XCAR (tail);
12883 if (CONSP (tem) && EQ (propval, XCAR (tem)))
12884 return ! NILP (XCDR (tem));
12885 }
12886
12887 if (CONSP (propval))
12888 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
12889 {
12890 Lisp_Object propelt;
12891 propelt = XCAR (proptail);
12892 for (tail = list; CONSP (tail); tail = XCDR (tail))
12893 {
12894 register Lisp_Object tem;
12895 tem = XCAR (tail);
12896 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
12897 return ! NILP (XCDR (tem));
12898 }
12899 }
12900
12901 return 0;
12902 }
12903
12904
12905 \f
12906 /***********************************************************************
12907 Initialization
12908 ***********************************************************************/
12909
12910 void
12911 syms_of_xdisp ()
12912 {
12913 Vwith_echo_area_save_vector = Qnil;
12914 staticpro (&Vwith_echo_area_save_vector);
12915
12916 Vmessage_stack = Qnil;
12917 staticpro (&Vmessage_stack);
12918
12919 Qinhibit_redisplay = intern ("inhibit-redisplay");
12920 staticpro (&Qinhibit_redisplay);
12921
12922 #if GLYPH_DEBUG
12923 defsubr (&Sdump_glyph_matrix);
12924 defsubr (&Sdump_glyph_row);
12925 defsubr (&Sdump_tool_bar_row);
12926 defsubr (&Strace_redisplay_toggle);
12927 defsubr (&Strace_to_stderr);
12928 #endif
12929
12930 staticpro (&Qmenu_bar_update_hook);
12931 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
12932
12933 staticpro (&Qoverriding_terminal_local_map);
12934 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
12935
12936 staticpro (&Qoverriding_local_map);
12937 Qoverriding_local_map = intern ("overriding-local-map");
12938
12939 staticpro (&Qwindow_scroll_functions);
12940 Qwindow_scroll_functions = intern ("window-scroll-functions");
12941
12942 staticpro (&Qredisplay_end_trigger_functions);
12943 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
12944
12945 staticpro (&Qinhibit_point_motion_hooks);
12946 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
12947
12948 QCdata = intern (":data");
12949 staticpro (&QCdata);
12950 Qdisplay = intern ("display");
12951 staticpro (&Qdisplay);
12952 Qspace_width = intern ("space-width");
12953 staticpro (&Qspace_width);
12954 Qraise = intern ("raise");
12955 staticpro (&Qraise);
12956 Qspace = intern ("space");
12957 staticpro (&Qspace);
12958 Qmargin = intern ("margin");
12959 staticpro (&Qmargin);
12960 Qleft_margin = intern ("left-margin");
12961 staticpro (&Qleft_margin);
12962 Qright_margin = intern ("right-margin");
12963 staticpro (&Qright_margin);
12964 Qalign_to = intern ("align-to");
12965 staticpro (&Qalign_to);
12966 QCalign_to = intern (":align-to");
12967 staticpro (&QCalign_to);
12968 Qrelative_width = intern ("relative-width");
12969 staticpro (&Qrelative_width);
12970 QCrelative_width = intern (":relative-width");
12971 staticpro (&QCrelative_width);
12972 QCrelative_height = intern (":relative-height");
12973 staticpro (&QCrelative_height);
12974 QCeval = intern (":eval");
12975 staticpro (&QCeval);
12976 Qwhen = intern ("when");
12977 staticpro (&Qwhen);
12978 QCfile = intern (":file");
12979 staticpro (&QCfile);
12980 Qfontified = intern ("fontified");
12981 staticpro (&Qfontified);
12982 Qfontification_functions = intern ("fontification-functions");
12983 staticpro (&Qfontification_functions);
12984 Qtrailing_whitespace = intern ("trailing-whitespace");
12985 staticpro (&Qtrailing_whitespace);
12986 Qimage = intern ("image");
12987 staticpro (&Qimage);
12988 Qmessage_truncate_lines = intern ("message-truncate-lines");
12989 staticpro (&Qmessage_truncate_lines);
12990
12991 last_arrow_position = Qnil;
12992 last_arrow_string = Qnil;
12993 staticpro (&last_arrow_position);
12994 staticpro (&last_arrow_string);
12995
12996 echo_buffer[0] = echo_buffer[1] = Qnil;
12997 staticpro (&echo_buffer[0]);
12998 staticpro (&echo_buffer[1]);
12999
13000 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
13001 staticpro (&echo_area_buffer[0]);
13002 staticpro (&echo_area_buffer[1]);
13003
13004 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
13005 "Non-nil means highlight trailing whitespace.\n\
13006 The face used for trailing whitespace is `trailing-whitespace'.");
13007 Vshow_trailing_whitespace = Qnil;
13008
13009 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
13010 "Non-nil means don't actually do any redisplay.\n\
13011 This is used for internal purposes.");
13012 Vinhibit_redisplay = Qnil;
13013
13014 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
13015 "String (or mode line construct) included (normally) in `mode-line-format'.");
13016 Vglobal_mode_string = Qnil;
13017
13018 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
13019 "Marker for where to display an arrow on top of the buffer text.\n\
13020 This must be the beginning of a line in order to work.\n\
13021 See also `overlay-arrow-string'.");
13022 Voverlay_arrow_position = Qnil;
13023
13024 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
13025 "String to display as an arrow. See also `overlay-arrow-position'.");
13026 Voverlay_arrow_string = Qnil;
13027
13028 DEFVAR_INT ("scroll-step", &scroll_step,
13029 "*The number of lines to try scrolling a window by when point moves out.\n\
13030 If that fails to bring point back on frame, point is centered instead.\n\
13031 If this is zero, point is always centered after it moves off frame.");
13032
13033 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
13034 "*Scroll up to this many lines, to bring point back on screen.\n\
13035 A value of zero means to scroll the text to center point vertically\n\
13036 in the window.");
13037 scroll_conservatively = 0;
13038
13039 DEFVAR_INT ("scroll-margin", &scroll_margin,
13040 "*Number of lines of margin at the top and bottom of a window.\n\
13041 Recenter the window whenever point gets within this many lines\n\
13042 of the top or bottom of the window.");
13043 scroll_margin = 0;
13044
13045 #if GLYPH_DEBUG
13046 DEFVAR_INT ("debug-end-pos", &debug_end_pos, "Don't ask");
13047 #endif
13048
13049 DEFVAR_BOOL ("truncate-partial-width-windows",
13050 &truncate_partial_width_windows,
13051 "*Non-nil means truncate lines in all windows less than full frame wide.");
13052 truncate_partial_width_windows = 1;
13053
13054 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
13055 "*Non-nil means use inverse video for the mode line.");
13056 mode_line_inverse_video = 1;
13057
13058 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
13059 "*Maximum buffer size for which line number should be displayed.\n\
13060 If the buffer is bigger than this, the line number does not appear\n\
13061 in the mode line. A value of nil means no limit.");
13062 Vline_number_display_limit = Qnil;
13063
13064 DEFVAR_INT ("line-number-display-limit-width",
13065 &line_number_display_limit_width,
13066 "*Maximum line width (in characters) for line number display.\n\
13067 If the average length of the lines near point is bigger than this, then the\n\
13068 line number may be omitted from the mode line.");
13069 line_number_display_limit_width = 200;
13070
13071 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
13072 "*Non-nil means highlight region even in nonselected windows.");
13073 highlight_nonselected_windows = 0;
13074
13075 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
13076 "Non-nil if more than one frame is visible on this display.\n\
13077 Minibuffer-only frames don't count, but iconified frames do.\n\
13078 This variable is not guaranteed to be accurate except while processing\n\
13079 `frame-title-format' and `icon-title-format'.");
13080
13081 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
13082 "Template for displaying the title bar of visible frames.\n\
13083 \(Assuming the window manager supports this feature.)\n\
13084 This variable has the same structure as `mode-line-format' (which see),\n\
13085 and is used only on frames for which no explicit name has been set\n\
13086 \(see `modify-frame-parameters').");
13087 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
13088 "Template for displaying the title bar of an iconified frame.\n\
13089 \(Assuming the window manager supports this feature.)\n\
13090 This variable has the same structure as `mode-line-format' (which see),\n\
13091 and is used only on frames for which no explicit name has been set\n\
13092 \(see `modify-frame-parameters').");
13093 Vicon_title_format
13094 = Vframe_title_format
13095 = Fcons (intern ("multiple-frames"),
13096 Fcons (build_string ("%b"),
13097 Fcons (Fcons (build_string (""),
13098 Fcons (intern ("invocation-name"),
13099 Fcons (build_string ("@"),
13100 Fcons (intern ("system-name"),
13101 Qnil)))),
13102 Qnil)));
13103
13104 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
13105 "Maximum number of lines to keep in the message log buffer.\n\
13106 If nil, disable message logging. If t, log messages but don't truncate\n\
13107 the buffer when it becomes large.");
13108 XSETFASTINT (Vmessage_log_max, 50);
13109
13110 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
13111 "Functions called before redisplay, if window sizes have changed.\n\
13112 The value should be a list of functions that take one argument.\n\
13113 Just before redisplay, for each frame, if any of its windows have changed\n\
13114 size since the last redisplay, or have been split or deleted,\n\
13115 all the functions in the list are called, with the frame as argument.");
13116 Vwindow_size_change_functions = Qnil;
13117
13118 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
13119 "List of Functions to call before redisplaying a window with scrolling.\n\
13120 Each function is called with two arguments, the window\n\
13121 and its new display-start position. Note that the value of `window-end'\n\
13122 is not valid when these functions are called.");
13123 Vwindow_scroll_functions = Qnil;
13124
13125 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
13126 "*Non-nil means automatically resize tool-bars.\n\
13127 This increases a tool-bar's height if not all tool-bar items are visible.\n\
13128 It decreases a tool-bar's height when it would display blank lines\n\
13129 otherwise.");
13130 auto_resize_tool_bars_p = 1;
13131
13132 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
13133 "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
13134 auto_raise_tool_bar_buttons_p = 1;
13135
13136 DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin,
13137 "*Margin around tool-bar buttons in pixels.");
13138 tool_bar_button_margin = 1;
13139
13140 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
13141 "Relief thickness of tool-bar buttons.");
13142 tool_bar_button_relief = 3;
13143
13144 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
13145 "List of functions to call to fontify regions of text.\n\
13146 Each function is called with one argument POS. Functions must\n\
13147 fontify a region starting at POS in the current buffer, and give\n\
13148 fontified regions the property `fontified'.\n\
13149 This variable automatically becomes buffer-local when set.");
13150 Vfontification_functions = Qnil;
13151 Fmake_local_variable (Qfontification_functions);
13152
13153 DEFVAR_BOOL ("unibyte-display-via-language-environment",
13154 &unibyte_display_via_language_environment,
13155 "*Non-nil means display unibyte text according to language environment.\n\
13156 Specifically this means that unibyte non-ASCII characters\n\
13157 are displayed by converting them to the equivalent multibyte characters\n\
13158 according to the current language environment. As a result, they are\n\
13159 displayed according to the current fontset.");
13160 unibyte_display_via_language_environment = 0;
13161
13162 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
13163 "*Maximum height for resizing mini-windows.\n\
13164 If a float, it specifies a fraction of the mini-window frame's height.\n\
13165 If an integer, it specifies a number of lines.\n\
13166 If nil, don't resize.");
13167 Vmax_mini_window_height = make_float (0.25);
13168
13169 DEFVAR_BOOL ("cursor-in-non-selected-windows",
13170 &cursor_in_non_selected_windows,
13171 "*Non-nil means display a hollow cursor in non-selected windows.\n\
13172 Nil means don't display a cursor there.");
13173 cursor_in_non_selected_windows = 1;
13174
13175 DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p,
13176 "*Non-nil means scroll the display automatically to make point visible.");
13177 automatic_hscrolling_p = 1;
13178
13179 DEFVAR_LISP ("image-types", &Vimage_types,
13180 "List of supported image types.\n\
13181 Each element of the list is a symbol for a supported image type.");
13182 Vimage_types = Qnil;
13183
13184 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
13185 "If non-nil, messages are truncated instead of resizing the echo area.\n\
13186 Bind this around calls to `message' to let it take effect.");
13187 message_truncate_lines = 0;
13188 }
13189
13190
13191 /* Initialize this module when Emacs starts. */
13192
13193 void
13194 init_xdisp ()
13195 {
13196 Lisp_Object root_window;
13197 struct window *mini_w;
13198
13199 CHARPOS (this_line_start_pos) = 0;
13200
13201 mini_w = XWINDOW (minibuf_window);
13202 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
13203
13204 if (!noninteractive)
13205 {
13206 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
13207 int i;
13208
13209 XSETFASTINT (XWINDOW (root_window)->top, FRAME_TOP_MARGIN (f));
13210 set_window_height (root_window,
13211 FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
13212 0);
13213 XSETFASTINT (mini_w->top, FRAME_HEIGHT (f) - 1);
13214 set_window_height (minibuf_window, 1, 0);
13215
13216 XSETFASTINT (XWINDOW (root_window)->width, FRAME_WIDTH (f));
13217 XSETFASTINT (mini_w->width, FRAME_WIDTH (f));
13218
13219 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
13220 scratch_glyph_row.glyphs[TEXT_AREA + 1]
13221 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
13222
13223 /* The default ellipsis glyphs `...'. */
13224 for (i = 0; i < 3; ++i)
13225 XSETFASTINT (default_invis_vector[i], '.');
13226 }
13227
13228 #ifdef HAVE_WINDOW_SYSTEM
13229 {
13230 /* Allocate the buffer for frame titles. */
13231 int size = 100;
13232 frame_title_buf = (char *) xmalloc (size);
13233 frame_title_buf_end = frame_title_buf + size;
13234 frame_title_ptr = NULL;
13235 }
13236 #endif /* HAVE_WINDOW_SYSTEM */
13237 }
13238
13239