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