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.
5 This file is part of GNU Emacs.
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)
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.
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. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
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
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
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.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
55 +--------------+ redisplay() +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
59 +----------------------------------+ |
60 Don't use this path when called |
63 expose_window (asynchronous) |
65 X expose events -----+
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.
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
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.
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
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
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
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.
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)
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.
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
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.
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.
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. */
178 #include "termchar.h"
179 #include "dispextern.h"
183 #include "commands.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "keyboard.h"
191 #include "region-cache.h"
193 #ifdef HAVE_X_WINDOWS
197 #define min(a, b) ((a) < (b) ? (a) : (b))
198 #define max(a, b) ((a) > (b) ? (a) : (b))
200 #define INFINITY 10000000
202 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
203 extern void set_frame_menubar ();
204 extern int pending_menu_activation
;
207 extern int interrupt_input
;
208 extern int command_loop_level
;
210 extern int minibuffer_auto_raise
;
212 extern Lisp_Object Qface
;
214 extern Lisp_Object Voverriding_local_map
;
215 extern Lisp_Object Voverriding_local_map_menu_flag
;
216 extern Lisp_Object Qmenu_item
;
218 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
219 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
220 Lisp_Object Qredisplay_end_trigger_functions
;
221 Lisp_Object Qinhibit_point_motion_hooks
;
222 Lisp_Object QCeval
, QCwhen
;
223 Lisp_Object Qfontified
;
225 /* Functions called to fontify regions of text. */
227 Lisp_Object Vfontification_functions
;
228 Lisp_Object Qfontification_functions
;
230 /* Non-zero means draw toolbar buttons raised when the mouse moves
233 int auto_raise_toolbar_buttons_p
;
235 /* Margin around toolbar buttons in pixels. */
237 int toolbar_button_margin
;
239 /* Thickness of shadow to draw around toolbar buttons. */
241 int toolbar_button_relief
;
243 /* Non-zero means automatically resize toolbars so that all toolbar
244 items are visible, and no blank lines remain. */
246 int auto_resize_toolbars_p
;
248 /* Non-nil means don't actually do any redisplay. */
250 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
252 /* Names of text properties relevant for redisplay. */
254 Lisp_Object Qdisplay
, Qrelative_width
, Qwidth
, Qalign_to
;
255 extern Lisp_Object Qface
, Qinvisible
, Qimage
;
257 /* Symbols used in text property values. */
259 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
260 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qheight
, Qraise
;
262 /* Name of the variable controlling the highlighting of trailing
263 whitespace. The implementation uses find_symbol_value to get its
266 Lisp_Object Qshow_trailing_whitespace
;
268 /* Name of the face used to highlight trailing whitespace. */
270 Lisp_Object Qtrailing_whitespace
;
272 /* The symbol `image' which is the car of the lists used to represent
277 /* Non-zero means print newline to stdout before next mini-buffer
280 int noninteractive_need_newline
;
282 /* Non-zero means print newline to message log before next message. */
284 static int message_log_need_newline
;
287 /* The buffer position of the first character appearing entirely or
288 partially on the line of the selected window which contains the
289 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
290 redisplay optimization in redisplay_internal. */
292 static struct text_pos this_line_start_pos
;
294 /* Number of characters past the end of the line above, including the
295 terminating newline. */
297 static struct text_pos this_line_end_pos
;
299 /* The vertical positions and the height of this line. */
301 static int this_line_vpos
;
302 static int this_line_y
;
303 static int this_line_pixel_height
;
305 /* X position at which this display line starts. Usually zero;
306 negative if first character is partially visible. */
308 static int this_line_start_x
;
310 /* Buffer that this_line_.* variables are referring to. */
312 static struct buffer
*this_line_buffer
;
314 /* Nonzero means truncate lines in all windows less wide than the
317 int truncate_partial_width_windows
;
319 /* A flag to control how to display unibyte 8-bit character. */
321 int unibyte_display_via_language_environment
;
323 /* Nonzero means we have more than one non-mini-buffer-only frame.
324 Not guaranteed to be accurate except while parsing
325 frame-title-format. */
329 Lisp_Object Vglobal_mode_string
;
331 /* Marker for where to display an arrow on top of the buffer text. */
333 Lisp_Object Voverlay_arrow_position
;
335 /* String to display for the arrow. Only used on terminal frames. */
337 Lisp_Object Voverlay_arrow_string
;
339 /* Values of those variables at last redisplay. However, if
340 Voverlay_arrow_position is a marker, last_arrow_position is its
341 numerical position. */
343 static Lisp_Object last_arrow_position
, last_arrow_string
;
345 /* Like mode-line-format, but for the title bar on a visible frame. */
347 Lisp_Object Vframe_title_format
;
349 /* Like mode-line-format, but for the title bar on an iconified frame. */
351 Lisp_Object Vicon_title_format
;
353 /* List of functions to call when a window's size changes. These
354 functions get one arg, a frame on which one or more windows' sizes
357 static Lisp_Object Vwindow_size_change_functions
;
359 Lisp_Object Qmenu_bar_update_hook
;
361 /* Nonzero if overlay arrow has been displayed once in this window. */
363 static int overlay_arrow_seen
;
365 /* Nonzero means highlight the region even in nonselected windows. */
367 int highlight_nonselected_windows
;
369 /* If cursor motion alone moves point off frame, try scrolling this
370 many lines up or down if that will bring it back. */
372 static int scroll_step
;
374 /* Non-0 means scroll just far enough to bring point back on the
375 screen, when appropriate. */
377 static int scroll_conservatively
;
379 /* Recenter the window whenever point gets within this many lines of
380 the top or bottom of the window. This value is translated into a
381 pixel value by multiplying it with CANON_Y_UNIT, which means that
382 there is really a fixed pixel height scroll margin. */
386 /* Number of characters of overlap to show, when scrolling a one-line
387 window such as a minibuffer. */
389 static int minibuffer_scroll_overlap
;
391 /* Number of windows showing the buffer of the selected window (or
392 another buffer with the same base buffer). keyboard.c refers to
397 /* Vector containing glyphs for an ellipsis `...'. */
399 static Lisp_Object default_invis_vector
[3];
401 /* Nonzero means display mode line highlighted. */
403 int mode_line_inverse_video
;
405 /* Prompt to display in front of the mini-buffer contents. */
407 Lisp_Object minibuf_prompt
;
409 /* Width of current mini-buffer prompt. Only set after display_line
410 of the line that contains the prompt. */
412 int minibuf_prompt_width
;
413 int minibuf_prompt_pixel_width
;
415 /* Message to display instead of mini-buffer contents. This is what
416 the functions error and message make, and command echoing uses it
417 as well. It overrides the minibuf_prompt as well as the buffer. */
419 char *echo_area_glyphs
;
421 /* A Lisp string to display instead of mini-buffer contents, analogous
422 to echo_area_glyphs. If this is a string, display that string.
423 Otherwise, if echo_area_glyphs is non-null, display that. */
425 Lisp_Object echo_area_message
;
427 /* This is the length of the message in echo_area_glyphs or
428 echo_area_message. */
430 int echo_area_glyphs_length
;
432 /* Value of echo_area_glyphs when it was last acted on. If this is
433 nonzero, there is a message on the frame in the mini-buffer and it
434 should be erased as soon as it is no longer requested to appear. */
436 char *previous_echo_glyphs
;
437 Lisp_Object previous_echo_area_message
;
438 static int previous_echo_glyphs_length
;
440 /* This is the window where the echo area message was displayed. It
441 is always a mini-buffer window, but it may not be the same window
442 currently active as a mini-buffer. */
444 Lisp_Object echo_area_window
;
446 /* Nonzero means multibyte characters were enabled when the echo area
447 message was specified. */
449 int message_enable_multibyte
;
451 /* True if we should redraw the mode lines on the next redisplay. */
453 int update_mode_lines
;
455 /* Smallest number of characters before the gap at any time since last
456 redisplay that finished. Valid for current buffer when
457 try_window_id can be called. */
461 /* Smallest number of characters after the gap at any time since last
462 redisplay that finished. Valid for current buffer when
463 try_window_id can be called. */
467 /* MODIFF as of last redisplay that finished; if it matches MODIFF,
468 and overlay_unchanged_modified matches OVERLAY_MODIFF, that means
469 beg_unchanged and end_unchanged contain no useful information. */
471 int unchanged_modified
;
473 /* OVERLAY_MODIFF as of last redisplay that finished. */
475 int overlay_unchanged_modified
;
477 /* Nonzero if window sizes or contents have changed since last
478 redisplay that finished */
480 int windows_or_buffers_changed
;
482 /* Nonzero after display_mode_line if %l was used and it displayed a
485 int line_number_displayed
;
487 /* Maximum buffer size for which to display line numbers. */
489 static int line_number_display_limit
;
491 /* Number of lines to keep in the message log buffer. t means
492 infinite. nil means don't log at all. */
494 Lisp_Object Vmessage_log_max
;
496 /* A scratch glyph row with contents used for generating truncation
497 glyphs. Also used in direct_output_for_insert. */
499 #define MAX_SCRATCH_GLYPHS 100
500 struct glyph_row scratch_glyph_row
;
501 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
503 /* Ascent and height of the last line processed by move_it_to. */
505 static int last_max_ascent
, last_height
;
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. */
513 #define TEXT_PROP_DISTANCE_LIMIT 100
515 /* Non-zero means print traces of redisplay if compiled with
519 int trace_redisplay_p
;
522 /* Value returned from text property handlers (see below). */
527 HANDLED_RECOMPUTE_PROPS
,
528 HANDLED_OVERLAY_STRING_CONSUMED
,
532 /* A description of text properties that redisplay is interested
537 /* The name of the property. */
540 /* A unique index for the property. */
543 /* A handler function called to set up iterator IT from the property
544 at IT's current position. Value is used to steer handle_stop. */
545 enum prop_handled (*handler
) P_ ((struct it
*it
));
548 static enum prop_handled handle_face_prop
P_ ((struct it
*));
549 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
550 static enum prop_handled handle_display_prop
P_ ((struct it
*));
551 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
552 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
554 /* Properties handled by iterators. */
556 static struct props it_props
[] =
558 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
559 /* Handle `face' before `display' because some sub-properties of
560 `display' need to know the face. */
561 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
562 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
563 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
567 /* Value is the position described by X. If X is a marker, value is
568 the marker_position of X. Otherwise, value is X. */
570 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
572 /* Enumeration returned by some move_it_.* functions internally. */
576 /* Not used. Undefined value. */
579 /* Move ended at the requested buffer position or ZV. */
580 MOVE_POS_MATCH_OR_ZV
,
582 /* Move ended at the requested X pixel position. */
585 /* Move within a line ended at the end of a line that must be
589 /* Move within a line ended at the end of a line that would
590 be displayed truncated. */
593 /* Move within a line ended at a line end. */
599 /* Function prototypes. */
601 static int string_char_and_length
P_ ((unsigned char *, int, int *));
602 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
604 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
605 static Lisp_Object eval_handler
P_ ((Lisp_Object
));
606 static Lisp_Object eval_form
P_ ((Lisp_Object
));
607 static void insert_left_trunc_glyphs
P_ ((struct it
*));
608 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*));
609 static void extend_face_to_end_of_line
P_ ((struct it
*));
610 static void append_space
P_ ((struct it
*, int));
611 static void make_cursor_line_fully_visible
P_ ((struct window
*));
612 static int try_scrolling
P_ ((Lisp_Object
, int, int, int, int));
613 static int trailing_whitespace_p
P_ ((int));
614 static int message_log_check_duplicate
P_ ((int, int, int, int));
615 int invisible_p
P_ ((Lisp_Object
, Lisp_Object
));
616 int invisible_ellipsis_p
P_ ((Lisp_Object
, Lisp_Object
));
617 static void push_it
P_ ((struct it
*));
618 static void pop_it
P_ ((struct it
*));
619 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
620 static void redisplay_internal
P_ ((int));
621 static void echo_area_display
P_ ((int));
622 static void redisplay_windows
P_ ((Lisp_Object
));
623 static void redisplay_window
P_ ((Lisp_Object
, int));
624 static void update_menu_bar
P_ ((struct frame
*, int));
625 static int try_window_reusing_current_matrix
P_ ((struct window
*));
626 static int try_window_id
P_ ((struct window
*));
627 static int display_line
P_ ((struct it
*));
628 static void display_mode_lines
P_ ((struct window
*));
629 static void display_mode_line
P_ ((struct window
*, enum face_id
,
631 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
));
632 static char *decode_mode_spec
P_ ((struct window
*, char, int, int));
633 static void display_menu_bar
P_ ((struct window
*));
634 static int display_count_lines
P_ ((int, int, int, int, int *));
635 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
636 int, int, struct it
*, int, int, int, int));
637 static void compute_line_metrics
P_ ((struct it
*));
638 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
639 static int get_overlay_strings
P_ ((struct it
*));
640 static void next_overlay_string
P_ ((struct it
*));
641 void set_iterator_to_next
P_ ((struct it
*));
642 static void reseat
P_ ((struct it
*, struct text_pos
, int));
643 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
644 static void back_to_previous_visible_line_start
P_ ((struct it
*));
645 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
646 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
647 static int next_element_from_display_vector
P_ ((struct it
*));
648 static int next_element_from_string
P_ ((struct it
*));
649 static int next_element_from_c_string
P_ ((struct it
*));
650 static int next_element_from_buffer
P_ ((struct it
*));
651 static int next_element_from_image
P_ ((struct it
*));
652 static int next_element_from_stretch
P_ ((struct it
*));
653 static void load_overlay_strings
P_ ((struct it
*));
654 static void init_from_display_pos
P_ ((struct it
*, struct window
*,
655 struct display_pos
*));
656 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
657 Lisp_Object
, int, int, int, int));
658 static int charset_at_position
P_ ((struct text_pos
));
659 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
661 void move_it_vertically_backward
P_ ((struct it
*, int));
662 static void init_to_row_start
P_ ((struct it
*, struct window
*,
663 struct glyph_row
*));
664 static void init_to_row_end
P_ ((struct it
*, struct window
*,
665 struct glyph_row
*));
666 static void back_to_previous_line_start
P_ ((struct it
*));
667 static void forward_to_next_line_start
P_ ((struct it
*));
668 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
670 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
671 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
672 static int number_of_chars
P_ ((unsigned char *, int));
673 static void compute_stop_pos
P_ ((struct it
*));
674 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
676 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
677 static int next_overlay_change
P_ ((int));
678 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
679 Lisp_Object
, struct text_pos
*));
681 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
682 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
684 #ifdef HAVE_WINDOW_SYSTEM
686 static void update_toolbar
P_ ((struct frame
*, int));
687 static void build_desired_toolbar_string
P_ ((struct frame
*f
));
688 static int redisplay_toolbar
P_ ((struct frame
*));
689 static void display_toolbar_line
P_ ((struct it
*));
691 #endif /* HAVE_WINDOW_SYSTEM */
694 /***********************************************************************
695 Window display dimensions
696 ***********************************************************************/
698 /* Return the window-relative maximum y + 1 for glyph rows displaying
699 text in window W. This is the height of W minus the height of a
700 mode line, if any. */
703 window_text_bottom_y (w
)
706 struct frame
*f
= XFRAME (w
->frame
);
707 int height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
709 if (WINDOW_WANTS_MODELINE_P (w
))
710 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
715 /* Return the pixel width of display area AREA of window W. AREA < 0
716 means return the total width of W, not including bitmap areas to
717 the left and right of the window. */
720 window_box_width (w
, area
)
724 struct frame
*f
= XFRAME (w
->frame
);
725 int width
= XFASTINT (w
->width
);
727 if (!w
->pseudo_window_p
)
729 width
-= FRAME_SCROLL_BAR_WIDTH (f
) + 2 * FRAME_FLAGS_AREA_COLS (f
);
731 if (area
== TEXT_AREA
)
733 if (INTEGERP (w
->left_margin_width
))
734 width
-= XFASTINT (w
->left_margin_width
);
735 if (INTEGERP (w
->right_margin_width
))
736 width
-= XFASTINT (w
->right_margin_width
);
738 else if (area
== LEFT_MARGIN_AREA
)
739 width
= (INTEGERP (w
->left_margin_width
)
740 ? XFASTINT (w
->left_margin_width
) : 0);
741 else if (area
== RIGHT_MARGIN_AREA
)
742 width
= (INTEGERP (w
->right_margin_width
)
743 ? XFASTINT (w
->right_margin_width
) : 0);
746 return width
* CANON_X_UNIT (f
);
750 /* Return the pixel height of the display area of window W, not
751 including mode lines of W, if any.. */
754 window_box_height (w
)
757 struct frame
*f
= XFRAME (w
->frame
);
758 int height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
760 if (WINDOW_WANTS_MODELINE_P (w
))
761 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
763 if (WINDOW_WANTS_TOP_LINE_P (w
))
764 height
-= CURRENT_TOP_LINE_HEIGHT (w
);
770 /* Return the frame-relative coordinate of the left edge of display
771 area AREA of window W. AREA < 0 means return the left edge of the
772 whole window, to the right of any bitmap area at the left side of
776 window_box_left (w
, area
)
780 struct frame
*f
= XFRAME (w
->frame
);
781 int x
= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
783 if (!w
->pseudo_window_p
)
785 x
+= (WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
)
786 + FRAME_FLAGS_AREA_WIDTH (f
));
788 if (area
== TEXT_AREA
)
789 x
+= window_box_width (w
, LEFT_MARGIN_AREA
);
790 else if (area
== RIGHT_MARGIN_AREA
)
791 x
+= (window_box_width (w
, LEFT_MARGIN_AREA
)
792 + window_box_width (w
, TEXT_AREA
));
799 /* Return the frame-relative coordinate of the right edge of display
800 area AREA of window W. AREA < 0 means return the left edge of the
801 whole window, to the left of any bitmap area at the right side of
805 window_box_right (w
, area
)
809 return window_box_left (w
, area
) + window_box_width (w
, area
);
813 /* Get the bounding box of the display area AREA of window W, without
814 mode lines, in frame-relative coordinates. AREA < 0 means the
815 whole window, not including bitmap areas to the left and right of
816 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
817 coordinates of the upper-left corner of the box. Return in
818 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
821 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
824 int *box_x
, *box_y
, *box_width
, *box_height
;
826 struct frame
*f
= XFRAME (w
->frame
);
828 *box_width
= window_box_width (w
, area
);
829 *box_height
= window_box_height (w
);
830 *box_x
= window_box_left (w
, area
);
831 *box_y
= (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
)
832 + XFASTINT (w
->top
) * CANON_Y_UNIT (f
));
833 if (WINDOW_WANTS_TOP_LINE_P (w
))
834 *box_y
+= CURRENT_TOP_LINE_HEIGHT (w
);
838 /* Get the bounding box of the display area AREA of window W, without
839 mode lines. AREA < 0 means the whole window, not including bitmap
840 areas to the left and right of the window. Return in *TOP_LEFT_X
841 and TOP_LEFT_Y the frame-relative pixel coordinates of the
842 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
843 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
847 window_box_edges (w
, area
, top_left_x
, top_left_y
,
848 bottom_right_x
, bottom_right_y
)
851 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
853 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
855 *bottom_right_x
+= *top_left_x
;
856 *bottom_right_y
+= *top_left_y
;
861 /***********************************************************************
863 ***********************************************************************/
865 /* Return the next character from STR which is MAXLEN bytes long.
866 Return in *LEN the length of the character. This is like
867 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
868 we find one, we return a `?', but with the length of the illegal
872 string_char_and_length (str
, maxlen
, len
)
878 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
879 if (!CHAR_VALID_P (c
, 1))
880 /* We may not change the length here because other places in Emacs
881 don't use this function, i.e. they silently accept illegal
890 /* Given a position POS containing a valid character and byte position
891 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
893 static struct text_pos
894 string_pos_nchars_ahead (pos
, string
, nchars
)
899 xassert (STRINGP (string
) && nchars
>= 0);
901 if (STRING_MULTIBYTE (string
))
903 int rest
= STRING_BYTES (XSTRING (string
)) - BYTEPOS (pos
);
904 unsigned char *p
= XSTRING (string
)->data
+ BYTEPOS (pos
);
909 string_char_and_length (p
, rest
, &len
);
910 p
+= len
, rest
-= len
;
913 BYTEPOS (pos
) += len
;
917 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
923 /* Value is the text position, i.e. character and byte position,
924 for character position CHARPOS in STRING. */
926 static INLINE
struct text_pos
927 string_pos (charpos
, string
)
932 xassert (STRINGP (string
));
933 xassert (charpos
>= 0);
934 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
939 /* Value is a text position, i.e. character and byte position, for
940 character position CHARPOS in C string S. MULTIBYTE_P non-zero
941 means recognize multibyte characters. */
943 static struct text_pos
944 c_string_pos (charpos
, s
, multibyte_p
)
952 xassert (charpos
>= 0);
956 int rest
= strlen (s
), len
;
958 SET_TEXT_POS (pos
, 0, 0);
961 string_char_and_length (s
, rest
, &len
);
962 s
+= len
, rest
-= len
;
965 BYTEPOS (pos
) += len
;
969 SET_TEXT_POS (pos
, charpos
, charpos
);
975 /* Value is the number of characters in C string S. MULTIBYTE_P
976 non-zero means recognize multibyte characters. */
979 number_of_chars (s
, multibyte_p
)
987 int rest
= strlen (s
), len
;
988 unsigned char *p
= (unsigned char *) s
;
990 for (nchars
= 0; rest
> 0; ++nchars
)
992 string_char_and_length (p
, rest
, &len
);
993 rest
-= len
, p
+= len
;
1003 /* Compute byte position NEWPOS->bytepos corresponding to
1004 NEWPOS->charpos. POS is a known position in string STRING.
1005 NEWPOS->charpos must be >= POS.charpos. */
1008 compute_string_pos (newpos
, pos
, string
)
1009 struct text_pos
*newpos
, pos
;
1012 xassert (STRINGP (string
));
1013 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1015 if (STRING_MULTIBYTE (string
))
1016 *newpos
= string_pos_nchars_ahead (pos
, CHARPOS (*newpos
) - CHARPOS (pos
),
1019 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1023 /* Return the charset of the character at position POS in
1027 charset_at_position (pos
)
1028 struct text_pos pos
;
1031 unsigned char *p
= BYTE_POS_ADDR (BYTEPOS (pos
));
1033 multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
1036 int maxlen
= ((BYTEPOS (pos
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
1039 c
= string_char_and_length (p
, maxlen
, &len
);
1044 return CHAR_CHARSET (c
);
1049 /***********************************************************************
1050 Lisp form evaluation
1051 ***********************************************************************/
1053 /* Error handler for eval_form. */
1063 /* Evaluate SEXPR and return the result, or nil if something went
1070 int count
= specpdl_ptr
- specpdl
;
1072 specbind (Qinhibit_redisplay
, Qt
);
1073 val
= internal_condition_case_1 (Feval
, sexpr
, Qerror
, eval_handler
);
1074 return unbind_to (count
, val
);
1079 /***********************************************************************
1081 ***********************************************************************/
1085 /* Define CHECK_IT to perform sanity checks on iterators.
1086 This is for debugging. It is too slow to do unconditionally. */
1092 if (it
->method
== next_element_from_string
)
1094 xassert (STRINGP (it
->string
));
1095 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1097 else if (it
->method
== next_element_from_buffer
)
1099 /* Check that character and byte positions agree. */
1100 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1104 xassert (it
->current
.dpvec_index
>= 0);
1106 xassert (it
->current
.dpvec_index
< 0);
1109 #define CHECK_IT(IT) check_it ((IT))
1113 #define CHECK_IT(IT) (void) 0
1120 /* Check that the window end of window W is what we expect it
1121 to be---the last row in the current matrix displaying text. */
1124 check_window_end (w
)
1127 if (!MINI_WINDOW_P (w
)
1128 && !NILP (w
->window_end_valid
))
1130 struct glyph_row
*row
;
1131 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1132 XFASTINT (w
->window_end_vpos
)),
1134 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1135 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1139 #define CHECK_WINDOW_END(W) check_window_end ((W))
1141 #else /* not GLYPH_DEBUG */
1143 #define CHECK_WINDOW_END(W) (void) 0
1145 #endif /* not GLYPH_DEBUG */
1149 /***********************************************************************
1150 Iterator initialization
1151 ***********************************************************************/
1153 /* Initialize IT for displaying current_buffer in window W, starting
1154 at character position CHARPOS. CHARPOS < 0 means that no buffer
1155 position is specified which is useful when the iterator is assigned
1156 a position later. BYTEPOS is the byte position corresponding to
1157 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1159 If ROW is not null, calls to produce_glyphs with IT as parameter
1160 will produce glyphs in that row.
1162 BASE_FACE_ID is the id of a base face to use. It must be one of
1163 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1164 TOP_LINE_FACE_ID for displaying mode lines, or TOOLBAR_FACE_ID for
1165 displaying the toolbar.
1167 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1168 TOP_LINE_FACE_ID, the iterator will be initialized to use the
1169 corresponding mode line glyph row of the desired matrix of W. */
1172 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
1175 int charpos
, bytepos
;
1176 struct glyph_row
*row
;
1177 enum face_id base_face_id
;
1179 int highlight_region_p
;
1182 /* Some precondition checks. */
1183 xassert (w
!= NULL
&& it
!= NULL
);
1184 xassert (charpos
< 0 || current_buffer
== XBUFFER (w
->buffer
));
1185 xassert (charpos
< 0 || (charpos
> 0 && charpos
<= ZV
));
1187 /* If face attributes have been changed since the last redisplay,
1188 free realized faces now because they depend on face definitions
1189 that might have changed. */
1190 if (face_change_count
)
1192 face_change_count
= 0;
1193 free_all_realized_faces (Qnil
);
1196 /* Use one of the mode line rows of W's desired matrix if
1200 if (base_face_id
== MODE_LINE_FACE_ID
)
1201 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
1202 else if (base_face_id
== TOP_LINE_FACE_ID
)
1203 row
= MATRIX_TOP_LINE_ROW (w
->desired_matrix
);
1207 bzero (it
, sizeof *it
);
1208 it
->current
.overlay_string_index
= -1;
1209 it
->current
.dpvec_index
= -1;
1210 it
->charset
= CHARSET_ASCII
;
1211 it
->base_face_id
= base_face_id
;
1213 /* The window in which we iterate over current_buffer: */
1214 XSETWINDOW (it
->window
, w
);
1216 it
->f
= XFRAME (w
->frame
);
1218 /* If realized faces have been removed, e.g. because of face
1219 attribute changes of named faces, recompute them. */
1220 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
1221 recompute_basic_faces (it
->f
);
1223 /* Should we highlight trailing whitespace? */
1224 value
= find_symbol_value (Qshow_trailing_whitespace
);
1225 it
->show_trailing_whitespace_p
1226 = EQ (value
, Qunbound
) ? 0 : !NILP (value
);
1228 /* Current value of the `space-width', and 'height' properties. */
1229 it
->space_width
= Qnil
;
1230 it
->font_height
= Qnil
;
1232 /* Are control characters displayed as `^C'? */
1233 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
1235 /* -1 means everything between a CR and the following line end
1236 is invisible. >0 means lines indented more than this value are
1238 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
1239 ? XFASTINT (current_buffer
->selective_display
)
1240 : (!NILP (current_buffer
->selective_display
)
1242 it
->selective_display_ellipsis_p
1243 = !NILP (current_buffer
->selective_display_ellipses
);
1245 /* Display table to use. */
1246 it
->dp
= window_display_table (w
);
1248 /* Are multibyte characters enabled in current_buffer? */
1249 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
1251 /* Non-zero if we should highlight the region. */
1253 = (!NILP (Vtransient_mark_mode
)
1254 && !NILP (current_buffer
->mark_active
)
1255 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
1257 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1258 start and end of a visible region in window IT->w. Set both to
1259 -1 to indicate no region. */
1260 if (highlight_region_p
1261 /* Maybe highlight only in selected window. */
1262 && (/* Either show region everywhere. */
1263 highlight_nonselected_windows
1264 /* Or show region in the selected window. */
1265 || w
== XWINDOW (selected_window
)
1266 /* Or show the region if we are in the mini-buffer and W is
1267 the window the mini-buffer refers to. */
1268 || (MINI_WINDOW_P (XWINDOW (selected_window
))
1269 && w
== XWINDOW (Vminibuf_scroll_window
))))
1271 int charpos
= marker_position (current_buffer
->mark
);
1272 it
->region_beg_charpos
= min (PT
, charpos
);
1273 it
->region_end_charpos
= max (PT
, charpos
);
1276 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
1278 /* Get the position at which the redisplay_end_trigger hook should
1279 be run, if it is to be run at all. */
1280 if (MARKERP (w
->redisplay_end_trigger
)
1281 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
1282 it
->redisplay_end_trigger_charpos
1283 = marker_position (w
->redisplay_end_trigger
);
1284 else if (INTEGERP (w
->redisplay_end_trigger
))
1285 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
1287 /* Correct bogus values of tab_width. */
1288 it
->tab_width
= XINT (current_buffer
->tab_width
);
1289 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
1292 /* Are lines in the display truncated? */
1293 it
->truncate_lines_p
1294 = (base_face_id
!= DEFAULT_FACE_ID
1295 || XINT (it
->w
->hscroll
)
1296 || (truncate_partial_width_windows
1297 && !WINDOW_FULL_WIDTH_P (it
->w
))
1298 || !NILP (current_buffer
->truncate_lines
));
1300 /* Get dimensions of truncation and continuation glyphs. These are
1301 displayed as bitmaps under X, so we don't need them for such
1303 if (!FRAME_WINDOW_P (it
->f
))
1305 if (it
->truncate_lines_p
)
1307 /* We will need the truncation glyph. */
1308 xassert (it
->glyph_row
== NULL
);
1309 produce_special_glyphs (it
, IT_TRUNCATION
);
1310 it
->truncation_pixel_width
= it
->pixel_width
;
1314 /* We will need the continuation glyph. */
1315 xassert (it
->glyph_row
== NULL
);
1316 produce_special_glyphs (it
, IT_CONTINUATION
);
1317 it
->continuation_pixel_width
= it
->pixel_width
;
1320 /* Reset these values to zero becaue the produce_special_glyphs
1321 above has changed them. */
1322 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
1323 it
->phys_ascent
= it
->phys_descent
= 0;
1326 /* Set this after getting the dimensions of truncation and
1327 continuation glyphs, so that we don't produce glyphs when calling
1328 produce_special_glyphs, above. */
1329 it
->glyph_row
= row
;
1330 it
->area
= TEXT_AREA
;
1332 /* Get the dimensions of the display area. The display area
1333 consists of the visible window area plus a horizontally scrolled
1334 part to the left of the window. All x-values are relative to the
1335 start of this total display area. */
1336 if (base_face_id
!= DEFAULT_FACE_ID
)
1338 /* Mode lines, menu bar in terminal frames. */
1339 it
->first_visible_x
= 0;
1340 it
->last_visible_x
= XFASTINT (w
->width
) * CANON_X_UNIT (it
->f
);
1345 = XFASTINT (it
->w
->hscroll
) * CANON_X_UNIT (it
->f
);
1346 it
->last_visible_x
= (it
->first_visible_x
1347 + window_box_width (w
, TEXT_AREA
));
1349 /* If we truncate lines, leave room for the truncator glyph(s) at
1350 the right margin. Otherwise, leave room for the continuation
1351 glyph(s). Truncation and continuation glyphs are not inserted
1352 for window-based redisplay. */
1353 if (!FRAME_WINDOW_P (it
->f
))
1355 if (it
->truncate_lines_p
)
1356 it
->last_visible_x
-= it
->truncation_pixel_width
;
1358 it
->last_visible_x
-= it
->continuation_pixel_width
;
1361 it
->top_line_p
= WINDOW_WANTS_TOP_LINE_P (w
);
1362 it
->current_y
= WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
) + w
->vscroll
;
1365 /* Leave room for a border glyph. */
1366 if (!FRAME_WINDOW_P (it
->f
)
1367 && !WINDOW_RIGHTMOST_P (it
->w
))
1368 it
->last_visible_x
-= 1;
1370 it
->last_visible_y
= window_text_bottom_y (w
);
1372 /* For mode lines and alike, arrange for the first glyph having a
1373 left box line if the face specifies a box. */
1374 if (base_face_id
!= DEFAULT_FACE_ID
)
1378 it
->face_id
= base_face_id
;
1380 /* If we have a boxed mode line, make the first character appear
1381 with a left box line. */
1382 face
= FACE_FROM_ID (it
->f
, base_face_id
);
1383 if (face
->box
!= FACE_NO_BOX
)
1384 it
->start_of_box_run_p
= 1;
1387 /* If a buffer position was specified, set the iterator there,
1388 getting overlays and face properties from that position. */
1391 it
->end_charpos
= ZV
;
1393 IT_CHARPOS (*it
) = charpos
;
1395 /* Compute byte position if not specified. */
1397 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
1399 IT_BYTEPOS (*it
) = bytepos
;
1401 /* Compute faces etc. */
1402 reseat (it
, it
->current
.pos
, 1);
1409 /* Initialize IT for the display of window W with window start POS. */
1412 start_display (it
, w
, pos
)
1415 struct text_pos pos
;
1417 int start_at_line_beg_p
;
1418 struct glyph_row
*row
;
1419 int first_vpos
= WINDOW_WANTS_TOP_LINE_P (w
) ? 1 : 0;
1422 row
= w
->desired_matrix
->rows
+ first_vpos
;
1423 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
1424 first_y
= it
->current_y
;
1426 /* If window start is not at a line start, move back to the line
1427 start. This makes sure that we take continuation lines into
1429 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
1430 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
1431 if (!start_at_line_beg_p
)
1432 reseat_at_previous_visible_line_start (it
);
1434 #if NO_PROMPT_IN_BUFFER
1435 /* Take the mini-buffer prompt width into account for tab
1437 if (MINI_WINDOW_P (w
) && IT_CHARPOS (*it
) == BEGV
)
1439 /* Why is mini-buffer_prompt_width guaranteed to be set here? */
1440 it
->prompt_width
= minibuf_prompt_pixel_width
;
1442 #endif /* NO_PROMPT_IN_BUFFER */
1444 /* If window start is not at a line start, skip forward to POS to
1445 get the correct continuation_lines_width and current_x. */
1446 if (!start_at_line_beg_p
)
1448 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
1450 /* If lines are continued, this line may end in the middle of a
1451 multi-glyph character (e.g. a control character displayed as
1452 \003, or in the middle of an overlay string). In this case
1453 move_it_to above will not have taken us to the start of
1454 the continuation line but to the end of the continued line. */
1455 if (!it
->truncate_lines_p
&& it
->current_x
> 0)
1457 if (it
->current
.dpvec_index
>= 0
1458 || it
->current
.overlay_string_index
>= 0)
1460 set_iterator_to_next (it
);
1461 move_it_in_display_line_to (it
, -1, -1, 0);
1463 it
->continuation_lines_width
+= it
->current_x
;
1466 it
->current_y
= first_y
;
1468 it
->current_x
= it
->hpos
= 0;
1471 #if 0 /* Don't assert the following because start_display is sometimes
1472 called intentionally with a window start that is not at a
1473 line start. Please leave this code in as a comment. */
1475 /* Window start should be on a line start, now. */
1476 xassert (it
->continuation_lines_width
1477 || IT_CHARPOS (it
) == BEGV
1478 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
1483 /* Initialize IT for stepping through current_buffer in window W,
1484 starting at position POS that includes overlay string and display
1485 vector/ control character translation position information. */
1488 init_from_display_pos (it
, w
, pos
)
1491 struct display_pos
*pos
;
1493 /* Keep in mind: the call to reseat in init_iterator skips invisible
1494 text, so we might end up at a position different from POS. This
1495 is only a problem when POS is a row start after a newline and an
1496 overlay starts there with an after-string, and the overlay has an
1497 invisible property. Since we don't skip invisible text in
1498 display_line and elsewhere immediately after consuming the
1499 newline before the row start, such a POS will not be in a string,
1500 but the call to init_iterator below will move us to the
1502 init_iterator (it
, w
, CHARPOS (pos
->pos
), BYTEPOS (pos
->pos
),
1503 NULL
, DEFAULT_FACE_ID
);
1505 /* If position is within an overlay string, set up IT to
1506 the right overlay string. */
1507 if (pos
->overlay_string_index
>= 0)
1511 /* We already have the first chunk of overlay strings in
1512 IT->overlay_strings. Load more until the one for
1513 pos->overlay_string_index is in IT->overlay_strings. */
1514 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
1516 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
1517 it
->current
.overlay_string_index
= 0;
1520 load_overlay_strings (it
);
1521 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
1525 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
1526 relative_index
= (it
->current
.overlay_string_index
1527 % OVERLAY_STRING_CHUNK_SIZE
);
1528 it
->string
= it
->overlay_strings
[relative_index
];
1529 it
->current
.string_pos
= pos
->string_pos
;
1530 it
->method
= next_element_from_string
;
1532 else if (CHARPOS (pos
->string_pos
) >= 0)
1534 /* Recorded position is not in an overlay string, but in another
1535 string. This can only be a string from a `display' property.
1536 IT should already be filled with that string. */
1537 it
->current
.string_pos
= pos
->string_pos
;
1538 xassert (STRINGP (it
->string
));
1541 /* Restore position in display vector translations or control
1542 character translations. */
1543 if (pos
->dpvec_index
>= 0)
1545 /* This fills IT->dpvec. */
1546 get_next_display_element (it
);
1547 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
1548 it
->current
.dpvec_index
= pos
->dpvec_index
;
1555 /* Initialize IT for stepping through current_buffer in window W
1556 starting at ROW->start. */
1559 init_to_row_start (it
, w
, row
)
1562 struct glyph_row
*row
;
1564 init_from_display_pos (it
, w
, &row
->start
);
1565 it
->continuation_lines_width
= row
->continuation_lines_width
;
1570 /* Initialize IT for stepping through current_buffer in window W
1571 starting in the line following ROW, i.e. starting at ROW->end. */
1574 init_to_row_end (it
, w
, row
)
1577 struct glyph_row
*row
;
1579 init_from_display_pos (it
, w
, &row
->end
);
1581 if (row
->continued_p
)
1582 it
->continuation_lines_width
= (row
->continuation_lines_width
1583 + row
->pixel_width
);
1590 /***********************************************************************
1592 ***********************************************************************/
1594 /* Called when IT reaches IT->stop_charpos. Handle text property and
1595 overlay changes. Set IT->stop_charpos to the next position where
1602 enum prop_handled handled
;
1603 int handle_overlay_change_p
= 1;
1607 it
->current
.dpvec_index
= -1;
1611 handled
= HANDLED_NORMALLY
;
1613 /* Call text property handlers. */
1614 for (p
= it_props
; p
->handler
; ++p
)
1616 handled
= p
->handler (it
);
1618 if (handled
== HANDLED_RECOMPUTE_PROPS
)
1620 else if (handled
== HANDLED_RETURN
)
1622 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
1623 handle_overlay_change_p
= 0;
1626 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
1628 /* Don't check for overlay strings below when set to deliver
1629 characters from a display vector. */
1630 if (it
->method
== next_element_from_display_vector
)
1631 handle_overlay_change_p
= 0;
1633 /* Handle overlay changes. */
1634 if (handle_overlay_change_p
)
1635 handled
= handle_overlay_change (it
);
1637 /* Determine where to stop next. */
1638 if (handled
== HANDLED_NORMALLY
)
1639 compute_stop_pos (it
);
1642 while (handled
== HANDLED_RECOMPUTE_PROPS
);
1646 /* Compute IT->stop_charpos from text property and overlay change
1647 information for IT's current position. */
1650 compute_stop_pos (it
)
1653 register INTERVAL iv
, next_iv
;
1654 Lisp_Object object
, limit
, position
;
1656 /* If nowhere else, stop at the end. */
1657 it
->stop_charpos
= it
->end_charpos
;
1659 if (STRINGP (it
->string
))
1661 /* Strings are usually short, so don't limit the search for
1663 object
= it
->string
;
1665 XSETFASTINT (position
, IT_STRING_CHARPOS (*it
));
1671 /* If next overlay change is in front of the current stop pos
1672 (which is IT->end_charpos), stop there. Note: value of
1673 next_overlay_change is point-max if no overlay change
1675 charpos
= next_overlay_change (IT_CHARPOS (*it
));
1676 if (charpos
< it
->stop_charpos
)
1677 it
->stop_charpos
= charpos
;
1679 /* If showing the region, we have to stop at the region
1680 start or end because the face might change there. */
1681 if (it
->region_beg_charpos
> 0)
1683 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
1684 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
1685 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
1686 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
1689 /* Set up variables for computing the stop position from text
1690 property changes. */
1691 XSETBUFFER (object
, current_buffer
);
1692 XSETFASTINT (limit
, IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
1693 XSETFASTINT (position
, IT_CHARPOS (*it
));
1697 /* Get the interval containing IT's position. Value is a null
1698 interval if there isn't such an interval. */
1699 iv
= validate_interval_range (object
, &position
, &position
, 0);
1700 if (!NULL_INTERVAL_P (iv
))
1702 Lisp_Object values_here
[LAST_PROP_IDX
];
1705 /* Get properties here. */
1706 for (p
= it_props
; p
->handler
; ++p
)
1707 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
1709 /* Look for an interval following iv that has different
1711 for (next_iv
= next_interval (iv
);
1712 (!NULL_INTERVAL_P (next_iv
)
1714 || XFASTINT (limit
) > next_iv
->position
));
1715 next_iv
= next_interval (next_iv
))
1717 for (p
= it_props
; p
->handler
; ++p
)
1719 Lisp_Object new_value
;
1721 new_value
= textget (next_iv
->plist
, *p
->name
);
1722 if (!EQ (values_here
[p
->idx
], new_value
))
1730 if (!NULL_INTERVAL_P (next_iv
))
1732 if (INTEGERP (limit
)
1733 && next_iv
->position
>= XFASTINT (limit
))
1734 /* No text property change up to limit. */
1735 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
1737 /* Text properties change in next_iv. */
1738 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
1742 xassert (STRINGP (it
->string
)
1743 || (it
->stop_charpos
>= BEGV
1744 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
1748 /* Return the position of the next overlay change after POS in
1749 current_buffer. Value is point-max if no overlay change
1750 follows. This is like `next-overlay-change' but doesn't use
1754 next_overlay_change (pos
)
1759 Lisp_Object
*overlays
;
1763 /* Get all overlays at the given position. */
1765 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
1766 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
);
1767 if (noverlays
> len
)
1770 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
1771 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
);
1774 /* If any of these overlays ends before endpos,
1775 use its ending point instead. */
1776 for (i
= 0; i
< noverlays
; ++i
)
1781 oend
= OVERLAY_END (overlays
[i
]);
1782 oendpos
= OVERLAY_POSITION (oend
);
1783 endpos
= min (endpos
, oendpos
);
1791 /***********************************************************************
1793 ***********************************************************************/
1795 /* Handle changes in the `fontified' property of the current buffer by
1796 calling hook functions from Qfontification_functions to fontify
1799 static enum prop_handled
1800 handle_fontified_prop (it
)
1803 Lisp_Object prop
, pos
;
1804 enum prop_handled handled
= HANDLED_NORMALLY
;
1806 /* Get the value of the `fontified' property at IT's current buffer
1807 position. (The `fontified' property doesn't have a special
1808 meaning in strings.) If the value is nil, call functions from
1809 Qfontification_functions. */
1810 if (!STRINGP (it
->string
)
1812 && !NILP (Vfontification_functions
)
1813 && (pos
= make_number (IT_CHARPOS (*it
)),
1814 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
1817 Lisp_Object args
[2];
1819 /* Run the hook functions. */
1820 args
[0] = Qfontification_functions
;
1822 Frun_hook_with_args (make_number (2), args
);
1824 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
1825 something. This avoids an endless loop if they failed to
1826 fontify the text for which reason ever. */
1827 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
1828 handled
= HANDLED_RECOMPUTE_PROPS
;
1836 /***********************************************************************
1838 ***********************************************************************/
1840 /* Set up iterator IT from face properties at its current position.
1841 Called from handle_stop. */
1843 static enum prop_handled
1844 handle_face_prop (it
)
1847 int new_face_id
, next_stop
;
1849 if (!STRINGP (it
->string
))
1852 = face_at_buffer_position (it
->w
,
1854 it
->region_beg_charpos
,
1855 it
->region_end_charpos
,
1858 + TEXT_PROP_DISTANCE_LIMIT
),
1861 /* Is this a start of a run of characters with box face?
1862 Caveat: this can be called for a freshly initialized
1863 iterator; face_id is -1 is this case. We know that the new
1864 face will not change until limit, i.e. if the new face has a
1865 box, all characters up to limit will have one. But, as
1866 usual, we don't know whether limit is really the end. */
1867 if (new_face_id
!= it
->face_id
)
1869 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
1871 /* If new face has a box but old face has not, this is
1872 the start of a run of characters with box, i.e. it has
1873 a shadow on the left side. The value of face_id of the
1874 iterator will be -1 if this is the initial call that gets
1875 the face. In this case, we have to look in front of IT's
1876 position and see whether there is a face != new_face_id. */
1877 it
->start_of_box_run_p
1878 = (new_face
->box
!= FACE_NO_BOX
1879 && (it
->face_id
>= 0
1880 || IT_CHARPOS (*it
) == BEG
1881 || new_face_id
!= face_before_it_pos (it
)));
1882 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
1888 = face_at_string_position (it
->w
,
1890 IT_STRING_CHARPOS (*it
),
1891 (it
->current
.overlay_string_index
>= 0
1894 it
->region_beg_charpos
,
1895 it
->region_end_charpos
,
1899 #if 0 /* This shouldn't be neccessary. Let's check it. */
1900 /* If IT is used to display a mode line we would really like to
1901 use the mode line face instead of the frame's default face. */
1902 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
1903 && new_face_id
== DEFAULT_FACE_ID
)
1904 new_face_id
= MODE_LINE_FACE_ID
;
1907 /* Is this a start of a run of characters with box? Caveat:
1908 this can be called for a freshly allocated iterator; face_id
1909 is -1 is this case. We know that the new face will not
1910 change until the next check pos, i.e. if the new face has a
1911 box, all characters up to that position will have a
1912 box. But, as usual, we don't know whether that position
1913 is really the end. */
1914 if (new_face_id
!= it
->face_id
)
1916 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
1917 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1919 /* If new face has a box but old face hasn't, this is the
1920 start of a run of characters with box, i.e. it has a
1921 shadow on the left side. */
1922 it
->start_of_box_run_p
1923 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
1924 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
1928 it
->face_id
= new_face_id
;
1929 it
->charset
= CHARSET_ASCII
;
1930 return HANDLED_NORMALLY
;
1934 /* Compute the face one character before or after the current position
1935 of IT. BEFORE_P non-zero means get the face in front of IT's
1936 position. Value is the id of the face. */
1939 face_before_or_after_it_pos (it
, before_p
)
1944 int next_check_charpos
;
1945 struct text_pos pos
;
1947 xassert (it
->s
== NULL
);
1949 if (STRINGP (it
->string
))
1951 /* No face change past the end of the string (for the case
1952 we are padding with spaces). No face change before the
1954 if (IT_STRING_CHARPOS (*it
) >= XSTRING (it
->string
)->size
1955 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
1958 /* Set pos to the position before or after IT's current position. */
1960 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
1962 pos
= string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
);
1964 /* Get the face for ASCII, or unibyte. */
1966 = face_at_string_position (it
->w
,
1969 (it
->current
.overlay_string_index
>= 0
1972 it
->region_beg_charpos
,
1973 it
->region_end_charpos
,
1974 &next_check_charpos
,
1977 /* Correct the face for charsets different from ASCII. Do it
1978 for the multibyte case only. The face returned above is
1979 suitable for unibyte text if IT->string is unibyte. */
1980 if (STRING_MULTIBYTE (it
->string
))
1982 unsigned char *p
= XSTRING (it
->string
)->data
+ BYTEPOS (pos
);
1983 int rest
= STRING_BYTES (XSTRING (it
->string
)) - BYTEPOS (pos
);
1984 int c
, len
, charset
;
1986 c
= string_char_and_length (p
, rest
, &len
);
1987 charset
= CHAR_CHARSET (c
);
1988 if (charset
!= CHARSET_ASCII
)
1989 face_id
= FACE_FOR_CHARSET (it
->f
, face_id
, charset
);
1994 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
1995 pos
= it
->current
.pos
;
2002 /* Determine face for CHARSET_ASCII, or unibyte. */
2003 face_id
= face_at_buffer_position (it
->w
,
2005 it
->region_beg_charpos
,
2006 it
->region_end_charpos
,
2007 &next_check_charpos
,
2010 /* Correct the face for charsets different from ASCII. Do it
2011 for the multibyte case only. The face returned above is
2012 suitable for unibyte text if current_buffer is unibyte. */
2013 if (it
->multibyte_p
)
2015 int charset
= charset_at_position (pos
);
2016 if (charset
!= CHARSET_ASCII
)
2017 face_id
= FACE_FOR_CHARSET (it
->f
, face_id
, charset
);
2026 /***********************************************************************
2028 ***********************************************************************/
2030 /* Set up iterator IT from invisible properties at its current
2031 position. Called from handle_stop. */
2033 static enum prop_handled
2034 handle_invisible_prop (it
)
2037 enum prop_handled handled
= HANDLED_NORMALLY
;
2039 if (STRINGP (it
->string
))
2041 extern Lisp_Object Qinvisible
;
2042 Lisp_Object prop
, end_charpos
, limit
, charpos
;
2044 /* Get the value of the invisible text property at the
2045 current position. Value will be nil if there is no such
2047 XSETFASTINT (charpos
, IT_STRING_CHARPOS (*it
));
2048 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
2052 handled
= HANDLED_RECOMPUTE_PROPS
;
2054 /* Get the position at which the next change of the
2055 invisible text property can be found in IT->string.
2056 Value will be nil if the property value is the same for
2057 all the rest of IT->string. */
2058 XSETINT (limit
, XSTRING (it
->string
)->size
);
2059 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
2062 /* Text at current position is invisible. The next
2063 change in the property is at position end_charpos.
2064 Move IT's current position to that position. */
2065 if (INTEGERP (end_charpos
)
2066 && XFASTINT (end_charpos
) < XFASTINT (limit
))
2068 struct text_pos old
;
2069 old
= it
->current
.string_pos
;
2070 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
2071 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
2075 /* The rest of the string is invisible. If this is an
2076 overlay string, proceed with the next overlay string
2077 or whatever comes and return a character from there. */
2078 if (it
->current
.overlay_string_index
>= 0)
2080 next_overlay_string (it
);
2081 /* Don't check for overlay strings when we just
2082 finished processing them. */
2083 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
2087 struct Lisp_String
*s
= XSTRING (it
->string
);
2088 IT_STRING_CHARPOS (*it
) = s
->size
;
2089 IT_STRING_BYTEPOS (*it
) = STRING_BYTES (s
);
2096 int visible_p
, newpos
, next_stop
;
2097 Lisp_Object pos
, prop
;
2099 /* First of all, is there invisible text at this position? */
2100 XSETFASTINT (pos
, IT_CHARPOS (*it
));
2101 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
2103 /* If we are on invisible text, skip over it. */
2104 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
2106 /* Record whether we have to display an ellipsis for the
2108 int display_ellipsis_p
2109 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop
);
2111 handled
= HANDLED_RECOMPUTE_PROPS
;
2113 /* Loop skipping over invisible text. The loop is left at
2114 ZV or with IT on the first char being visible again. */
2117 /* Try to skip some invisible text. Return value is the
2118 position reached which can be equal to IT's position
2119 if there is nothing invisible here. This skips both
2120 over invisible text properties and overlays with
2121 invisible property. */
2122 newpos
= skip_invisible (IT_CHARPOS (*it
),
2123 &next_stop
, ZV
, it
->window
);
2125 /* If we skipped nothing at all we weren't at invisible
2126 text in the first place. If everything to the end of
2127 the buffer was skipped, end the loop. */
2128 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
2132 /* We skipped some characters but not necessarily
2133 all there are. Check if we ended up on visible
2134 text. Fget_char_property returns the property of
2135 the char before the given position, i.e. if we
2136 get visible_p = 1, this means that the char at
2137 newpos is visible. */
2138 XSETFASTINT (pos
, newpos
);
2139 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
2140 visible_p
= !TEXT_PROP_MEANS_INVISIBLE (prop
);
2143 /* If we ended up on invisible text, proceed to
2144 skip starting with next_stop. */
2146 IT_CHARPOS (*it
) = next_stop
;
2150 /* The position newpos is now either ZV or on visible text. */
2151 IT_CHARPOS (*it
) = newpos
;
2152 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
2154 /* Maybe return `...' next for the end of the invisible text. */
2155 if (display_ellipsis_p
)
2158 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
2160 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
2161 it
->dpvec
= v
->contents
;
2162 it
->dpend
= v
->contents
+ v
->size
;
2166 /* Default `...'. */
2167 it
->dpvec
= default_invis_vector
;
2168 it
->dpend
= default_invis_vector
+ 3;
2171 /* The ellipsis display does not replace the display of
2172 the character at the new position. Indicate this by
2173 setting IT->dpvec_char_len to zero. */
2174 it
->dpvec_char_len
= 0;
2176 it
->current
.dpvec_index
= 0;
2177 it
->method
= next_element_from_display_vector
;
2187 /***********************************************************************
2189 ***********************************************************************/
2191 /* Set up iterator IT from `display' property at its current position.
2192 Called from handle_stop. */
2194 static enum prop_handled
2195 handle_display_prop (it
)
2198 Lisp_Object prop
, object
;
2199 struct text_pos
*position
;
2200 int space_or_image_found_p
;
2202 if (STRINGP (it
->string
))
2204 object
= it
->string
;
2205 position
= &it
->current
.string_pos
;
2210 position
= &it
->current
.pos
;
2213 /* Reset those iterator values set from display property values. */
2214 it
->font_height
= Qnil
;
2215 it
->space_width
= Qnil
;
2218 /* We don't support recursive `display' properties, i.e. string
2219 values that have a string `display' property, that have a string
2220 `display' property etc. */
2221 if (!it
->string_from_display_prop_p
)
2222 it
->area
= TEXT_AREA
;
2224 prop
= Fget_char_property (make_number (position
->charpos
),
2227 return HANDLED_NORMALLY
;
2229 space_or_image_found_p
= 0;
2230 if (CONSP (prop
) && CONSP (XCAR (prop
)))
2232 while (CONSP (prop
))
2234 if (handle_single_display_prop (it
, XCAR (prop
), object
, position
))
2235 space_or_image_found_p
= 1;
2239 else if (VECTORP (prop
))
2242 for (i
= 0; i
< XVECTOR (prop
)->size
; ++i
)
2243 if (handle_single_display_prop (it
, XVECTOR (prop
)->contents
[i
],
2245 space_or_image_found_p
= 1;
2249 if (handle_single_display_prop (it
, prop
, object
, position
))
2250 space_or_image_found_p
= 1;
2253 return space_or_image_found_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
2257 /* Value is the position of the end of the `display' property stating
2258 at START_POS in OBJECT. */
2260 static struct text_pos
2261 display_prop_end (it
, object
, start_pos
)
2264 struct text_pos start_pos
;
2267 struct text_pos end_pos
;
2269 /* Characters having this form of property are not displayed, so
2270 we have to find the end of the property. */
2271 end
= Fnext_single_property_change (make_number (start_pos
.charpos
),
2272 Qdisplay
, object
, Qnil
);
2275 /* A nil value of `end' means there are no changes of the
2276 property to the end of the buffer or string. */
2277 if (it
->current
.overlay_string_index
>= 0)
2278 end_pos
.charpos
= XSTRING (it
->string
)->size
;
2280 end_pos
.charpos
= it
->end_charpos
;
2283 end_pos
.charpos
= XFASTINT (end
);
2285 if (STRINGP (it
->string
))
2286 compute_string_pos (&end_pos
, start_pos
, it
->string
);
2288 end_pos
.bytepos
= CHAR_TO_BYTE (end_pos
.charpos
);
2294 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2295 is the object in which the `display' property was found. *POSITION
2296 is the position at which it was found.
2298 If PROP is a `space' or `image' sub-property, set *POSITION to the
2299 end position of the `display' property.
2301 Value is non-zero if a `space' or `image' property value was found. */
2304 handle_single_display_prop (it
, prop
, object
, position
)
2308 struct text_pos
*position
;
2311 int space_or_image_found_p
= 0;
2315 /* If PROP is a list of the form `(:when FORM VALUE)', FORM is
2316 evaluated. If the result is nil, VALUE is ignored. */
2318 if (CONSP (prop
) && EQ (XCAR (prop
), QCwhen
))
2330 if (!NILP (form
) && !EQ (form
, Qt
))
2332 struct gcpro gcpro1
;
2333 struct text_pos end_pos
, pt
;
2335 end_pos
= display_prop_end (it
, object
, *position
);
2338 /* Temporarily set point to the end position, and then evaluate
2339 the form. This makes `(eolp)' work as FORM. */
2341 BYTEPOS (pt
) = PT_BYTE
;
2342 TEMP_SET_PT_BOTH (CHARPOS (end_pos
), BYTEPOS (end_pos
));
2343 form
= eval_form (form
);
2344 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
2352 && EQ (XCAR (prop
), Qheight
)
2353 && CONSP (XCDR (prop
)))
2355 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2358 /* `(height HEIGHT)'. */
2359 it
->font_height
= XCAR (XCDR (prop
));
2360 if (!NILP (it
->font_height
))
2362 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2363 int new_height
= -1;
2365 if (CONSP (it
->font_height
)
2366 && (EQ (XCAR (it
->font_height
), Qplus
)
2367 || EQ (XCAR (it
->font_height
), Qminus
))
2368 && CONSP (XCDR (it
->font_height
))
2369 && INTEGERP (XCAR (XCDR (it
->font_height
))))
2371 /* `(+ N)' or `(- N)' where N is an integer. */
2372 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
2373 if (EQ (XCAR (it
->font_height
), Qplus
))
2375 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
2377 else if (SYMBOLP (it
->font_height
))
2379 /* Call function with current height as argument.
2380 Value is the new height. */
2381 Lisp_Object form
, height
;
2382 struct gcpro gcpro1
;
2384 height
= face
->lface
[LFACE_HEIGHT_INDEX
];
2385 form
= Fcons (it
->font_height
, Fcons (height
, Qnil
));
2387 height
= eval_form (form
);
2388 if (NUMBERP (height
))
2389 new_height
= XFLOATINT (height
);
2392 else if (NUMBERP (it
->font_height
))
2394 /* Value is a multiple of the canonical char height. */
2397 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
2398 new_height
= (XFLOATINT (it
->font_height
)
2399 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
2403 /* Evaluate IT->font_height with `height' bound to the
2404 current specified height to get the new height. */
2406 int count
= specpdl_ptr
- specpdl
;
2408 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
2409 value
= eval_form (it
->font_height
);
2410 unbind_to (count
, Qnil
);
2412 if (NUMBERP (value
))
2413 new_height
= XFLOATINT (value
);
2417 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
2420 else if (CONSP (prop
)
2421 && EQ (XCAR (prop
), Qspace_width
)
2422 && CONSP (XCDR (prop
)))
2424 /* `(space_width WIDTH)'. */
2425 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2428 value
= XCAR (XCDR (prop
));
2429 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
2430 it
->space_width
= value
;
2432 else if (CONSP (prop
)
2433 && EQ (XCAR (prop
), Qraise
)
2434 && CONSP (XCDR (prop
)))
2436 #ifdef HAVE_WINDOW_SYSTEM
2437 /* `(raise FACTOR)'. */
2438 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2441 value
= XCAR (XCDR (prop
));
2442 if (NUMBERP (value
))
2444 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2445 it
->voffset
= - (XFLOATINT (value
)
2446 * (face
->font
->ascent
+ face
->font
->descent
));
2448 #endif /* HAVE_WINDOW_SYSTEM */
2450 else if (!it
->string_from_display_prop_p
)
2452 /* `(left-margin VALUE)' or `(right-margin VALUE)
2453 or `(nil VALUE)' or VALUE. */
2454 Lisp_Object location
, value
;
2455 struct text_pos start_pos
;
2458 /* Characters having this form of property are not displayed, so
2459 we have to find the end of the property. */
2460 space_or_image_found_p
= 1;
2461 start_pos
= *position
;
2462 *position
= display_prop_end (it
, object
, start_pos
);
2464 /* Let's stop at the new position and assume that all
2465 text properties change there. */
2466 it
->stop_charpos
= position
->charpos
;
2469 && !EQ (XCAR (prop
), Qspace
)
2470 && !EQ (XCAR (prop
), Qimage
))
2472 location
= XCAR (prop
);
2473 value
= XCDR (prop
);
2481 #ifdef HAVE_WINDOW_SYSTEM
2482 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2483 valid_p
= STRINGP (value
);
2485 valid_p
= (STRINGP (value
)
2486 || (CONSP (value
) && EQ (XCAR (value
), Qspace
))
2487 || valid_image_p (value
));
2488 #else /* not HAVE_WINDOW_SYSTEM */
2489 valid_p
= STRINGP (value
);
2490 #endif /* not HAVE_WINDOW_SYSTEM */
2492 if ((EQ (location
, Qleft_margin
)
2493 || EQ (location
, Qright_margin
)
2497 /* Save current settings of IT so that we can restore them
2498 when we are finished with the glyph property value. */
2501 if (NILP (location
))
2502 it
->area
= TEXT_AREA
;
2503 else if (EQ (location
, Qleft_margin
))
2504 it
->area
= LEFT_MARGIN_AREA
;
2506 it
->area
= RIGHT_MARGIN_AREA
;
2508 if (STRINGP (value
))
2511 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
2512 it
->current
.overlay_string_index
= -1;
2513 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
2514 it
->end_charpos
= it
->string_nchars
2515 = XSTRING (it
->string
)->size
;
2516 it
->method
= next_element_from_string
;
2517 it
->stop_charpos
= 0;
2518 it
->string_from_display_prop_p
= 1;
2520 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
2522 it
->method
= next_element_from_stretch
;
2524 it
->current
.pos
= it
->position
= start_pos
;
2526 #ifdef HAVE_WINDOW_SYSTEM
2529 it
->what
= IT_IMAGE
;
2530 it
->image_id
= lookup_image (it
->f
, value
);
2531 it
->position
= start_pos
;
2532 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
2533 it
->method
= next_element_from_image
;
2535 /* Say that we don't have consumed the characters with
2536 `display' property yet. The call to pop_it in
2537 set_iterator_to_next will clean this up. */
2538 *position
= start_pos
;
2540 #endif /* HAVE_WINDOW_SYSTEM */
2544 return space_or_image_found_p
;
2549 /***********************************************************************
2551 ***********************************************************************/
2553 /* The following structure is used to record overlay strings for
2554 later sorting in load_overlay_strings. */
2556 struct overlay_entry
2564 /* Set up iterator IT from overlay strings at its current position.
2565 Called from handle_stop. */
2567 static enum prop_handled
2568 handle_overlay_change (it
)
2571 /* Overlays are handled in current_buffer only. */
2572 if (STRINGP (it
->string
))
2573 return HANDLED_NORMALLY
;
2575 return (get_overlay_strings (it
)
2576 ? HANDLED_RECOMPUTE_PROPS
2577 : HANDLED_NORMALLY
);
2581 /* Set up the next overlay string for delivery by IT, if there is an
2582 overlay string to deliver. Called by set_iterator_to_next when the
2583 end of the current overlay string is reached. If there are more
2584 overlay strings to display, IT->string and
2585 IT->current.overlay_string_index are set appropriately here.
2586 Otherwise IT->string is set to nil. */
2589 next_overlay_string (it
)
2592 ++it
->current
.overlay_string_index
;
2593 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
2595 /* No more overlay strings. Restore IT's settings to what
2596 they were before overlay strings were processed, and
2597 continue to deliver from current_buffer. */
2599 xassert (it
->stop_charpos
>= BEGV
2600 && it
->stop_charpos
<= it
->end_charpos
);
2602 it
->current
.overlay_string_index
= -1;
2603 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
2604 it
->n_overlay_strings
= 0;
2605 it
->method
= next_element_from_buffer
;
2609 /* There are more overlay strings to process. If
2610 IT->current.overlay_string_index has advanced to a position
2611 where we must load IT->overlay_strings with more strings, do
2613 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
2615 if (it
->current
.overlay_string_index
&& i
== 0)
2616 load_overlay_strings (it
);
2618 /* Initialize IT to deliver display elements from the overlay
2620 it
->string
= it
->overlay_strings
[i
];
2621 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
2622 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
2623 it
->method
= next_element_from_string
;
2624 it
->stop_charpos
= 0;
2631 /* Compare two overlay_entry structures E1 and E2. Used as a
2632 comparison function for qsort in load_overlay_strings. Overlay
2633 strings for the same position are sorted so that
2635 1. All after-strings come in front of before-strings.
2637 2. Within after-strings, strings are sorted so that overlay strings
2638 from overlays with higher priorities come first.
2640 2. Within before-strings, strings are sorted so that overlay
2641 strings from overlays with higher priorities come last.
2643 Value is analogous to strcmp. */
2647 compare_overlay_entries (e1
, e2
)
2650 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
2651 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
2654 if (entry1
->after_string_p
!= entry2
->after_string_p
)
2655 /* Let after-strings appear in front of before-strings. */
2656 result
= entry1
->after_string_p
? -1 : 1;
2657 else if (entry1
->after_string_p
)
2658 /* After-strings sorted in order of decreasing priority. */
2659 result
= entry2
->priority
- entry1
->priority
;
2661 /* Before-strings sorted in order of increasing priority. */
2662 result
= entry1
->priority
- entry2
->priority
;
2668 /* Load the vector IT->overlay_strings with overlay strings from IT's
2669 current buffer position. Set IT->n_overlays to the total number of
2670 overlay strings found.
2672 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
2673 a time. On entry into load_overlay_strings,
2674 IT->current.overlay_string_index gives the number of overlay
2675 strings that have already been loaded by previous calls to this
2678 Overlay strings are sorted so that after-string strings come in
2679 front of before-string strings. Within before and after-strings,
2680 strings are sorted by overlay priority. See also function
2681 compare_overlay_entries. */
2684 load_overlay_strings (it
)
2687 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
2688 Lisp_Object ov
, overlay
, window
, str
;
2692 struct overlay_entry
*entries
2693 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
2695 /* Append the overlay string STRING of overlay OVERLAY to vector
2696 `entries' which has size `size' and currently contains `n'
2697 elements. AFTER_P non-zero means STRING is an after-string of
2699 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
2702 Lisp_Object priority; \
2706 int new_size = 2 * size; \
2707 struct overlay_entry *old = entries; \
2709 (struct overlay_entry *) alloca (new_size \
2710 * sizeof *entries); \
2711 bcopy (old, entries, size * sizeof *entries); \
2715 entries[n].string = (STRING); \
2716 priority = Foverlay_get ((OVERLAY), Qpriority); \
2717 entries[n].priority \
2718 = INTEGERP (priority) ? XFASTINT (priority) : 0; \
2719 entries[n].after_string_p = (AFTER_P); \
2724 /* Process overlay before the overlay center. */
2725 for (ov
= current_buffer
->overlays_before
;
2727 ov
= XCONS (ov
)->cdr
)
2729 overlay
= XCONS (ov
)->car
;
2730 xassert (OVERLAYP (overlay
));
2731 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
2732 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
2734 if (end
< IT_CHARPOS (*it
))
2737 /* Skip this overlay if it doesn't start or end at IT's current
2739 if (end
!= IT_CHARPOS (*it
) && start
!= IT_CHARPOS (*it
))
2742 /* Skip this overlay if it doesn't apply to IT->w. */
2743 window
= Foverlay_get (overlay
, Qwindow
);
2744 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
2747 /* If overlay has a non-empty before-string, record it. */
2748 if (start
== IT_CHARPOS (*it
)
2749 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
2750 && XSTRING (str
)->size
)
2751 RECORD_OVERLAY_STRING (overlay
, str
, 0);
2753 /* If overlay has a non-empty after-string, record it. */
2754 if (end
== IT_CHARPOS (*it
)
2755 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
2756 && XSTRING (str
)->size
)
2757 RECORD_OVERLAY_STRING (overlay
, str
, 1);
2760 /* Process overlays after the overlay center. */
2761 for (ov
= current_buffer
->overlays_after
;
2763 ov
= XCONS (ov
)->cdr
)
2765 overlay
= XCONS (ov
)->car
;
2766 xassert (OVERLAYP (overlay
));
2767 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
2768 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
2770 if (start
> IT_CHARPOS (*it
))
2773 /* Skip this overlay if it doesn't start or end at IT's current
2775 if (end
!= IT_CHARPOS (*it
) && start
!= IT_CHARPOS (*it
))
2778 /* Skip this overlay if it doesn't apply to IT->w. */
2779 window
= Foverlay_get (overlay
, Qwindow
);
2780 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
2783 /* If overlay has a non-empty before-string, record it. */
2784 if (start
== IT_CHARPOS (*it
)
2785 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
2786 && XSTRING (str
)->size
)
2787 RECORD_OVERLAY_STRING (overlay
, str
, 0);
2789 /* If overlay has a non-empty after-string, record it. */
2790 if (end
== IT_CHARPOS (*it
)
2791 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
2792 && XSTRING (str
)->size
)
2793 RECORD_OVERLAY_STRING (overlay
, str
, 1);
2796 #undef RECORD_OVERLAY_STRING
2799 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
2801 /* Record the total number of strings to process. */
2802 it
->n_overlay_strings
= n
;
2804 /* IT->current.overlay_string_index is the number of overlay strings
2805 that have already been consumed by IT. Copy some of the
2806 remaining overlay strings to IT->overlay_strings. */
2808 j
= it
->current
.overlay_string_index
;
2809 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
2810 it
->overlay_strings
[i
++] = entries
[j
++].string
;
2816 /* Get the first chunk of overlay strings at IT's current buffer
2817 position. Value is non-zero if at least one overlay string was
2821 get_overlay_strings (it
)
2824 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
2825 process. This fills IT->overlay_strings with strings, and sets
2826 IT->n_overlay_strings to the total number of strings to process.
2827 IT->pos.overlay_string_index has to be set temporarily to zero
2828 because load_overlay_strings needs this; it must be set to -1
2829 when no overlay strings are found because a zero value would
2830 indicate a position in the first overlay string. */
2831 it
->current
.overlay_string_index
= 0;
2832 load_overlay_strings (it
);
2834 /* If we found overlay strings, set up IT to deliver display
2835 elements from the first one. Otherwise set up IT to deliver
2836 from current_buffer. */
2837 if (it
->n_overlay_strings
)
2839 /* Make sure we know settings in current_buffer, so that we can
2840 restore meaningful values when we're done with the overlay
2842 compute_stop_pos (it
);
2843 xassert (it
->face_id
>= 0);
2845 /* Save IT's settings. They are restored after all overlay
2846 strings have been processed. */
2847 xassert (it
->sp
== 0);
2850 /* Set up IT to deliver display elements from the first overlay
2852 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
2853 it
->stop_charpos
= 0;
2854 it
->string
= it
->overlay_strings
[0];
2855 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
2856 xassert (STRINGP (it
->string
));
2857 it
->method
= next_element_from_string
;
2862 it
->current
.overlay_string_index
= -1;
2863 it
->method
= next_element_from_buffer
;
2868 /* Value is non-zero if we found at least one overlay string. */
2869 return STRINGP (it
->string
);
2874 /***********************************************************************
2875 Saving and restoring state
2876 ***********************************************************************/
2878 /* Save current settings of IT on IT->stack. Called, for example,
2879 before setting up IT for an overlay string, to be able to restore
2880 IT's settings to what they were after the overlay string has been
2887 struct iterator_stack_entry
*p
;
2889 xassert (it
->sp
< 2);
2890 p
= it
->stack
+ it
->sp
;
2892 p
->stop_charpos
= it
->stop_charpos
;
2893 xassert (it
->face_id
>= 0);
2894 p
->face_id
= it
->face_id
;
2895 p
->string
= it
->string
;
2896 p
->pos
= it
->current
;
2897 p
->end_charpos
= it
->end_charpos
;
2898 p
->string_nchars
= it
->string_nchars
;
2900 p
->multibyte_p
= it
->multibyte_p
;
2901 p
->space_width
= it
->space_width
;
2902 p
->font_height
= it
->font_height
;
2903 p
->voffset
= it
->voffset
;
2904 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
2909 /* Restore IT's settings from IT->stack. Called, for example, when no
2910 more overlay strings must be processed, and we return to delivering
2911 display elements from a buffer, or when the end of a string from a
2912 `display' property is reached and we return to delivering display
2913 elements from an overlay string, or from a buffer. */
2919 struct iterator_stack_entry
*p
;
2921 xassert (it
->sp
> 0);
2923 p
= it
->stack
+ it
->sp
;
2924 it
->stop_charpos
= p
->stop_charpos
;
2925 it
->face_id
= p
->face_id
;
2926 it
->string
= p
->string
;
2927 it
->current
= p
->pos
;
2928 it
->end_charpos
= p
->end_charpos
;
2929 it
->string_nchars
= p
->string_nchars
;
2931 it
->multibyte_p
= p
->multibyte_p
;
2932 it
->space_width
= p
->space_width
;
2933 it
->font_height
= p
->font_height
;
2934 it
->voffset
= p
->voffset
;
2935 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
2940 /***********************************************************************
2942 ***********************************************************************/
2944 /* Set IT's current position to the previous line start. */
2947 back_to_previous_line_start (it
)
2950 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
2951 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
2955 /* Set IT's current position to the next line start. */
2958 forward_to_next_line_start (it
)
2961 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
), 1);
2962 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
2966 /* Set IT's current position to the previous visible line start. Skip
2967 invisible text that is so either due to text properties or due to
2968 selective display. Caution: this does not change IT->current_x and
2972 back_to_previous_visible_line_start (it
)
2977 /* Go back one newline if not on BEGV already. */
2978 if (IT_CHARPOS (*it
) > BEGV
)
2979 back_to_previous_line_start (it
);
2981 /* Move over lines that are invisible because of selective display
2982 or text properties. */
2983 while (IT_CHARPOS (*it
) > BEGV
2988 /* If selective > 0, then lines indented more than that values
2990 if (it
->selective
> 0
2991 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
2994 #ifdef USE_TEXT_PROPERTIES
2999 prop
= Fget_char_property (IT_CHARPOS (*it
), Qinvisible
, it
->window
);
3000 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
3003 #endif /* USE_TEXT_PROPERTIES */
3005 /* Back one more newline if the current one is invisible. */
3007 back_to_previous_line_start (it
);
3010 xassert (IT_CHARPOS (*it
) >= BEGV
);
3011 xassert (IT_CHARPOS (*it
) == BEGV
3012 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
3017 /* Reseat iterator IT at the previous visible line start. Skip
3018 invisible text that is so either due to text properties or due to
3019 selective display. At the end, update IT's overlay information,
3020 face information etc. */
3023 reseat_at_previous_visible_line_start (it
)
3026 back_to_previous_visible_line_start (it
);
3027 reseat (it
, it
->current
.pos
, 1);
3032 /* Reseat iterator IT on the next visible line start in the current
3033 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3034 preceding the line start. Skip over invisible text that is so
3035 because of selective display. Compute faces, overlays etc at the
3036 new position. Note that this function does not skip over text that
3037 is invisible because of text properties. */
3040 reseat_at_next_visible_line_start (it
, on_newline_p
)
3044 /* Restore the buffer position when currently not delivering display
3045 elements from the current buffer. This is the case, for example,
3046 when called at the end of a truncated overlay string. */
3049 it
->method
= next_element_from_buffer
;
3051 /* Otherwise, scan_buffer would not work. */
3052 if (IT_CHARPOS (*it
) < ZV
)
3054 /* If on a newline, advance past it. Otherwise, find the next
3055 newline which automatically gives us the position following
3057 if (FETCH_BYTE (IT_BYTEPOS (*it
)) == '\n')
3063 forward_to_next_line_start (it
);
3065 /* We must either have reached the end of the buffer or end up
3067 xassert (IT_CHARPOS (*it
) == ZV
3068 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
3070 /* Skip over lines that are invisible because they are indented
3071 more than the value of IT->selective. */
3072 if (it
->selective
> 0)
3073 while (IT_CHARPOS (*it
) < ZV
3074 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
3076 forward_to_next_line_start (it
);
3078 /* Position on the newline if we should. */
3079 if (on_newline_p
&& IT_CHARPOS (*it
) > BEGV
)
3082 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
3085 /* Set the iterator there. The 0 as the last parameter of
3086 reseat means don't force a text property lookup. The lookup
3087 is then only done if we've skipped past the iterator's
3088 check_charpos'es. This optimization is important because
3089 text property lookups tend to be expensive. */
3090 reseat (it
, it
->current
.pos
, 0);
3098 /***********************************************************************
3099 Changing an iterator's position
3100 ***********************************************************************/
3102 /* Change IT's current position to POS in current_buffer. If FORCE_P
3103 is non-zero, always check for text properties at the new position.
3104 Otherwise, text properties are only looked up if POS >=
3105 IT->check_charpos of a property. */
3108 reseat (it
, pos
, force_p
)
3110 struct text_pos pos
;
3113 int original_pos
= IT_CHARPOS (*it
);
3115 reseat_1 (it
, pos
, 0);
3117 /* Determine where to check text properties. Avoid doing it
3118 where possible because text property lookup is very expensive. */
3120 || CHARPOS (pos
) > it
->stop_charpos
3121 || CHARPOS (pos
) < original_pos
)
3128 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3129 IT->stop_pos to POS, also. */
3132 reseat_1 (it
, pos
, set_stop_p
)
3134 struct text_pos pos
;
3137 /* Don't call this function when scanning a C string. */
3138 xassert (it
->s
== NULL
);
3140 /* POS must be a reasonable value. */
3141 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
3143 it
->current
.pos
= it
->position
= pos
;
3144 XSETBUFFER (it
->object
, current_buffer
);
3146 it
->current
.dpvec_index
= -1;
3147 it
->current
.overlay_string_index
= -1;
3148 IT_STRING_CHARPOS (*it
) = -1;
3149 IT_STRING_BYTEPOS (*it
) = -1;
3151 it
->method
= next_element_from_buffer
;
3155 it
->stop_charpos
= CHARPOS (pos
);
3159 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3160 If S is non-null, it is a C string to iterate over. Otherwise,
3161 STRING gives a Lisp string to iterate over.
3163 If PRECISION > 0, don't return more then PRECISION number of
3164 characters from the string.
3166 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3167 characters have been returned. FIELD_WIDTH < 0 means an infinite
3170 MULTIBYTE = 0 means disable processing of multibyte characters,
3171 MULTIBYTE > 0 means enable it,
3172 MULTIBYTE < 0 means use IT->multibyte_p.
3174 IT must be initialized via a prior call to init_iterator before
3175 calling this function. */
3178 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
3183 int precision
, field_width
, multibyte
;
3185 /* No region in strings. */
3186 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
3188 /* No text property checks performed by default, but see below. */
3189 it
->stop_charpos
= -1;
3191 /* Set iterator position and end position. */
3192 bzero (&it
->current
, sizeof it
->current
);
3193 it
->current
.overlay_string_index
= -1;
3194 it
->current
.dpvec_index
= -1;
3195 it
->charset
= CHARSET_ASCII
;
3196 xassert (charpos
>= 0);
3198 /* Use the setting of MULTIBYTE if specified. */
3200 it
->multibyte_p
= multibyte
> 0;
3204 xassert (STRINGP (string
));
3205 it
->string
= string
;
3207 it
->end_charpos
= it
->string_nchars
= XSTRING (string
)->size
;
3208 it
->method
= next_element_from_string
;
3209 it
->current
.string_pos
= string_pos (charpos
, string
);
3216 /* Note that we use IT->current.pos, not it->current.string_pos,
3217 for displaying C strings. */
3218 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
3219 if (it
->multibyte_p
)
3221 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
3222 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
3226 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
3227 it
->end_charpos
= it
->string_nchars
= strlen (s
);
3230 it
->method
= next_element_from_c_string
;
3233 /* PRECISION > 0 means don't return more than PRECISION characters
3235 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
3236 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
3238 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3239 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3240 FIELD_WIDTH < 0 means infinite field width. This is useful for
3241 padding with `-' at the end of a mode line. */
3242 if (field_width
< 0)
3243 field_width
= INFINITY
;
3244 if (field_width
> it
->end_charpos
- charpos
)
3245 it
->end_charpos
= charpos
+ field_width
;
3247 /* Use the standard display table for displaying strings. */
3248 if (DISP_TABLE_P (Vstandard_display_table
))
3249 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
3251 it
->stop_charpos
= charpos
;
3257 /***********************************************************************
3259 ***********************************************************************/
3261 /* Load IT's display element fields with information about the next
3262 display element from the current position of IT. Value is zero if
3263 end of buffer (or C string) is reached. */
3266 get_next_display_element (it
)
3269 /* Non-zero means that we found an display element. Zero means that
3270 we hit the end of what we iterate over. Performance note: the
3271 function pointer `method' used here turns out to be faster than
3272 using a sequence of if-statements. */
3273 int success_p
= (*it
->method
) (it
);
3276 if (it
->what
== IT_CHARACTER
)
3278 /* Map via display table or translate control characters.
3279 IT->c, IT->len etc. have been set to the next character by
3280 the function call above. If we have a display table, and it
3281 contains an entry for IT->c, translate it. Don't do this if
3282 IT->c itself comes from a display table, otherwise we could
3283 end up in an infinite recursion. (An alternative could be to
3284 count the recursion depth of this function and signal an
3285 error when a certain maximum depth is reached.) Is it worth
3287 if (success_p
&& it
->dpvec
== NULL
)
3292 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
3295 struct Lisp_Vector
*v
= XVECTOR (dv
);
3297 /* Return the first character from the display table
3298 entry, if not empty. If empty, don't display the
3299 current character. */
3302 it
->dpvec_char_len
= it
->len
;
3303 it
->dpvec
= v
->contents
;
3304 it
->dpend
= v
->contents
+ v
->size
;
3305 it
->current
.dpvec_index
= 0;
3306 it
->method
= next_element_from_display_vector
;
3309 success_p
= get_next_display_element (it
);
3312 /* Translate control characters into `\003' or `^C' form.
3313 Control characters coming from a display table entry are
3314 currently not translated because we use IT->dpvec to hold
3315 the translation. This could easily be changed but I
3316 don't believe that it is worth doing. */
3317 else if ((it
->c
< ' '
3318 && (it
->area
!= TEXT_AREA
3325 /* IT->c is a control character which must be displayed
3326 either as '\003' or as `^C' where the '\\' and '^'
3327 can be defined in the display table. Fill
3328 IT->ctl_chars with glyphs for what we have to
3329 display. Then, set IT->dpvec to these glyphs. */
3332 if (it
->c
< 128 && it
->ctl_arrow_p
)
3334 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3336 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
3337 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
3338 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
3340 g
= FAST_MAKE_GLYPH ('^', 0);
3341 XSETINT (it
->ctl_chars
[0], g
);
3343 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
3344 XSETINT (it
->ctl_chars
[1], g
);
3346 /* Set up IT->dpvec and return first character from it. */
3347 it
->dpvec_char_len
= it
->len
;
3348 it
->dpvec
= it
->ctl_chars
;
3349 it
->dpend
= it
->dpvec
+ 2;
3350 it
->current
.dpvec_index
= 0;
3351 it
->method
= next_element_from_display_vector
;
3352 get_next_display_element (it
);
3356 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3358 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
3359 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
3360 g
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
3362 g
= FAST_MAKE_GLYPH ('\\', 0);
3363 XSETINT (it
->ctl_chars
[0], g
);
3365 /* Insert three more glyphs into IT->ctl_chars for
3366 the octal display of the character. */
3367 g
= FAST_MAKE_GLYPH (((it
->c
>> 6) & 7) + '0', 0);
3368 XSETINT (it
->ctl_chars
[1], g
);
3369 g
= FAST_MAKE_GLYPH (((it
->c
>> 3) & 7) + '0', 0);
3370 XSETINT (it
->ctl_chars
[2], g
);
3371 g
= FAST_MAKE_GLYPH ((it
->c
& 7) + '0', 0);
3372 XSETINT (it
->ctl_chars
[3], g
);
3374 /* Set up IT->dpvec and return the first character
3376 it
->dpvec_char_len
= it
->len
;
3377 it
->dpvec
= it
->ctl_chars
;
3378 it
->dpend
= it
->dpvec
+ 4;
3379 it
->current
.dpvec_index
= 0;
3380 it
->method
= next_element_from_display_vector
;
3381 get_next_display_element (it
);
3386 /* Adjust face id if charset changes. There are no charset
3387 changes in unibyte text because Emacs' charsets are not
3388 applicable there. */
3391 && (charset
= CHAR_CHARSET (it
->c
),
3392 charset
!= it
->charset
))
3394 it
->charset
= charset
;
3395 it
->face_id
= FACE_FOR_CHARSET (it
->f
, it
->face_id
, charset
);
3399 /* Is this character the last one of a run of characters with
3400 box? If yes, set IT->end_of_box_run_p to 1. */
3407 it
->end_of_box_run_p
3408 = ((face_id
= face_after_it_pos (it
),
3409 face_id
!= it
->face_id
)
3410 && (face
= FACE_FROM_ID (it
->f
, face_id
),
3411 face
->box
== FACE_NO_BOX
));
3414 /* Value is 0 if end of buffer or string reached. */
3419 /* Move IT to the next display element.
3421 Functions get_next_display_element and set_iterator_to_next are
3422 separate because I find this arrangement easier to handle than a
3423 get_next_display_element function that also increments IT's
3424 position. The way it is we can first look at an iterator's current
3425 display element, decide whether it fits on a line, and if it does,
3426 increment the iterator position. The other way around we probably
3427 would either need a flag indicating whether the iterator has to be
3428 incremented the next time, or we would have to implement a
3429 decrement position function which would not be easy to write. */
3432 set_iterator_to_next (it
)
3435 if (it
->method
== next_element_from_buffer
)
3437 /* The current display element of IT is a character from
3438 current_buffer. Advance in the buffer, and maybe skip over
3439 invisible lines that are so because of selective display. */
3440 if (ITERATOR_AT_END_OF_LINE_P (it
))
3441 reseat_at_next_visible_line_start (it
, 0);
3444 xassert (it
->len
!= 0);
3445 IT_BYTEPOS (*it
) += it
->len
;
3446 IT_CHARPOS (*it
) += 1;
3447 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
3450 else if (it
->method
== next_element_from_c_string
)
3452 /* Current display element of IT is from a C string. */
3453 IT_BYTEPOS (*it
) += it
->len
;
3454 IT_CHARPOS (*it
) += 1;
3456 else if (it
->method
== next_element_from_display_vector
)
3458 /* Current display element of IT is from a display table entry.
3459 Advance in the display table definition. Reset it to null if
3460 end reached, and continue with characters from buffers/
3464 ++it
->current
.dpvec_index
;
3466 /* Restore face and charset of the iterator to what they were
3467 before the display vector entry (these entries may contain
3468 faces, and of course characters of different charsets). */
3469 it
->face_id
= it
->saved_face_id
;
3470 it
->charset
= FACE_FROM_ID (it
->f
, it
->face_id
)->charset
;
3472 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
3475 it
->method
= next_element_from_c_string
;
3476 else if (STRINGP (it
->string
))
3477 it
->method
= next_element_from_string
;
3479 it
->method
= next_element_from_buffer
;
3482 it
->current
.dpvec_index
= -1;
3484 /* Skip over characters which were displayed via IT->dpvec. */
3485 if (it
->dpvec_char_len
< 0)
3486 reseat_at_next_visible_line_start (it
, 1);
3487 else if (it
->dpvec_char_len
> 0)
3489 it
->len
= it
->dpvec_char_len
;
3490 set_iterator_to_next (it
);
3494 else if (it
->method
== next_element_from_string
)
3496 /* Current display element is a character from a Lisp string. */
3497 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
3498 IT_STRING_BYTEPOS (*it
) += it
->len
;
3499 IT_STRING_CHARPOS (*it
) += 1;
3501 consider_string_end
:
3503 if (it
->current
.overlay_string_index
>= 0)
3505 /* IT->string is an overlay string. Advance to the
3506 next, if there is one. */
3507 if (IT_STRING_CHARPOS (*it
) >= XSTRING (it
->string
)->size
)
3508 next_overlay_string (it
);
3512 /* IT->string is not an overlay string. If we reached
3513 its end, and there is something on IT->stack, proceed
3514 with what is on the stack. This can be either another
3515 string, this time an overlay string, or a buffer. */
3516 if (IT_STRING_CHARPOS (*it
) == XSTRING (it
->string
)->size
3520 if (!STRINGP (it
->string
))
3521 it
->method
= next_element_from_buffer
;
3525 else if (it
->method
== next_element_from_image
3526 || it
->method
== next_element_from_stretch
)
3528 /* The position etc with which we have to proceed are on
3529 the stack. The position may be at the end of a string,
3530 if the `display' property takes up the whole string. */
3533 if (STRINGP (it
->string
))
3535 it
->method
= next_element_from_string
;
3536 goto consider_string_end
;
3539 it
->method
= next_element_from_buffer
;
3542 /* There are no other methods defined, so this should be a bug. */
3545 /* Reset flags indicating start and end of a sequence of
3546 characters with box. */
3547 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
3549 xassert (it
->method
!= next_element_from_string
3550 || (STRINGP (it
->string
)
3551 && IT_STRING_CHARPOS (*it
) >= 0));
3555 /* Load IT's display element fields with information about the next
3556 display element which comes from a display table entry or from the
3557 result of translating a control character to one of the forms `^C'
3558 or `\003'. IT->dpvec holds the glyphs to return as characters. */
3561 next_element_from_display_vector (it
)
3565 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
3567 /* Remember the current face id in case glyphs specify faces.
3568 IT's face is restored in set_iterator_to_next. */
3569 it
->saved_face_id
= it
->face_id
;
3571 if (INTEGERP (*it
->dpvec
)
3572 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
3577 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
3578 it
->c
= FAST_GLYPH_CHAR (g
);
3579 it
->len
= CHAR_LEN (it
->c
);
3581 /* The entry may contain a face id to use. Such a face id is
3582 the id of a Lisp face, not a realized face. A face id of
3583 zero means no face. */
3584 lface_id
= FAST_GLYPH_FACE (g
);
3587 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
3590 it
->face_id
= face_id
;
3591 it
->charset
= CHARSET_ASCII
;
3596 /* Display table entry is invalid. Return a space. */
3597 it
->c
= ' ', it
->len
= 1;
3599 /* Don't change position and object of the iterator here. They are
3600 still the values of the character that had this display table
3601 entry or was translated, and that's what we want. */
3602 it
->what
= IT_CHARACTER
;
3607 /* Load IT with the next display element from Lisp string IT->string.
3608 IT->current.string_pos is the current position within the string.
3609 If IT->current.overlay_string_index >= 0, the Lisp string is an
3613 next_element_from_string (it
)
3616 struct text_pos position
;
3618 xassert (STRINGP (it
->string
));
3619 xassert (IT_STRING_CHARPOS (*it
) >= 0);
3620 position
= it
->current
.string_pos
;
3622 /* Time to check for invisible text? */
3623 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
3624 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
3628 /* Since a handler may have changed IT->method, we must
3630 return get_next_display_element (it
);
3633 if (it
->current
.overlay_string_index
>= 0)
3635 /* Get the next character from an overlay string. In overlay
3636 strings, There is no field width or padding with spaces to
3638 if (IT_STRING_CHARPOS (*it
) >= XSTRING (it
->string
)->size
)
3643 else if (STRING_MULTIBYTE (it
->string
))
3645 int remaining
= (STRING_BYTES (XSTRING (it
->string
))
3646 - IT_STRING_BYTEPOS (*it
));
3647 unsigned char *s
= (XSTRING (it
->string
)->data
3648 + IT_STRING_BYTEPOS (*it
));
3649 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
3653 it
->c
= XSTRING (it
->string
)->data
[IT_STRING_BYTEPOS (*it
)];
3659 /* Get the next character from a Lisp string that is not an
3660 overlay string. Such strings come from the mode line, for
3661 example. We may have to pad with spaces, or truncate the
3662 string. See also next_element_from_c_string. */
3663 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
3668 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
3670 /* Pad with spaces. */
3671 it
->c
= ' ', it
->len
= 1;
3672 CHARPOS (position
) = BYTEPOS (position
) = -1;
3674 else if (STRING_MULTIBYTE (it
->string
))
3676 int maxlen
= (STRING_BYTES (XSTRING (it
->string
))
3677 - IT_STRING_BYTEPOS (*it
));
3678 unsigned char *s
= (XSTRING (it
->string
)->data
3679 + IT_STRING_BYTEPOS (*it
));
3680 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
3684 it
->c
= XSTRING (it
->string
)->data
[IT_STRING_BYTEPOS (*it
)];
3689 /* Record what we have and where it came from. Note that we store a
3690 buffer position in IT->position although it could arguably be a
3692 it
->what
= IT_CHARACTER
;
3693 it
->object
= it
->string
;
3694 it
->position
= position
;
3699 /* Load IT with next display element from C string IT->s.
3700 IT->string_nchars is the maximum number of characters to return
3701 from the string. IT->end_charpos may be greater than
3702 IT->string_nchars when this function is called, in which case we
3703 may have to return padding spaces. Value is zero if end of string
3704 reached, including padding spaces. */
3707 next_element_from_c_string (it
)
3713 it
->what
= IT_CHARACTER
;
3714 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
3717 /* IT's position can be greater IT->string_nchars in case a field
3718 width or precision has been specified when the iterator was
3720 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
3722 /* End of the game. */
3726 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
3728 /* Pad with spaces. */
3729 it
->c
= ' ', it
->len
= 1;
3730 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
3732 else if (it
->multibyte_p
)
3734 /* Implementation note: The calls to strlen apparently aren't a
3735 performance problem because there is no noticeable performance
3736 difference between Emacs running in unibyte or multibyte mode. */
3737 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
3738 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
3742 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
3748 /* Set up IT to return characters from an ellipsis, if appropriate.
3749 The definition of the ellipsis glyphs may come from a display table
3750 entry. This function Fills IT with the first glyph from the
3751 ellipsis if an ellipsis is to be displayed. */
3754 next_element_from_ellipsis (it
)
3757 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3759 /* Use the display table definition for `...'. Invalid glyphs
3760 will be handled by the method returning elements from dpvec. */
3761 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3762 it
->dpvec_char_len
= it
->len
;
3763 it
->dpvec
= v
->contents
;
3764 it
->dpend
= v
->contents
+ v
->size
;
3765 it
->current
.dpvec_index
= 0;
3766 it
->method
= next_element_from_display_vector
;
3767 get_next_display_element (it
);
3769 else if (it
->selective_display_ellipsis_p
)
3771 /* Use default `...' which is stored in default_invis_vector. */
3772 it
->dpvec_char_len
= it
->len
;
3773 it
->dpvec
= default_invis_vector
;
3774 it
->dpend
= default_invis_vector
+ 3;
3775 it
->current
.dpvec_index
= 0;
3776 it
->method
= next_element_from_display_vector
;
3777 get_next_display_element (it
);
3782 /* Deliver an image display element. The iterator IT is already
3783 filled with image information (done in handle_display_prop). Value
3788 next_element_from_image (it
)
3791 it
->what
= IT_IMAGE
;
3796 /* Fill iterator IT with next display element from a stretch glyph
3797 property. IT->object is the value of the text property. Value is
3801 next_element_from_stretch (it
)
3804 it
->what
= IT_STRETCH
;
3809 /* Load IT with the next display element from current_buffer. Value
3810 is zero if end of buffer reached. IT->stop_charpos is the next
3811 position at which to stop and check for text properties or buffer
3815 next_element_from_buffer (it
)
3820 /* Check this assumption, otherwise, we would never enter the
3821 if-statement, below. */
3822 xassert (IT_CHARPOS (*it
) >= BEGV
3823 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
3825 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
3827 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
3829 int overlay_strings_follow_p
;
3831 /* End of the game, except when overlay strings follow that
3832 haven't been returned yet. */
3833 if (it
->overlay_strings_at_end_processed_p
)
3834 overlay_strings_follow_p
= 0;
3837 it
->overlay_strings_at_end_processed_p
= 1;
3838 overlay_strings_follow_p
3839 = get_overlay_strings (it
);
3842 if (overlay_strings_follow_p
)
3843 success_p
= get_next_display_element (it
);
3847 it
->position
= it
->current
.pos
;
3854 return get_next_display_element (it
);
3859 /* No face changes, overlays etc. in sight, so just return a
3860 character from current_buffer. */
3863 /* Maybe run the redisplay end trigger hook. Performance note:
3864 This doesn't seem to cost measurable time. */
3865 if (it
->redisplay_end_trigger_charpos
3867 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
3868 run_redisplay_end_trigger_hook (it
);
3870 /* Get the next character, maybe multibyte. */
3871 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
3872 if (it
->multibyte_p
)
3874 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
3875 - IT_BYTEPOS (*it
));
3876 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
3879 it
->c
= *p
, it
->len
= 1;
3881 /* Record what we have and where it came from. */
3882 it
->what
= IT_CHARACTER
;;
3883 it
->object
= it
->w
->buffer
;
3884 it
->position
= it
->current
.pos
;
3886 /* Normally we return the character found above, except when we
3887 really want to return an ellipsis for selective display. */
3892 /* A value of selective > 0 means hide lines indented more
3893 than that number of columns. */
3894 if (it
->selective
> 0
3895 && IT_CHARPOS (*it
) + 1 < ZV
3896 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
3897 IT_BYTEPOS (*it
) + 1,
3900 next_element_from_ellipsis (it
);
3901 it
->dpvec_char_len
= -1;
3904 else if (it
->c
== '\r' && it
->selective
== -1)
3906 /* A value of selective == -1 means that everything from the
3907 CR to the end of the line is invisible, with maybe an
3908 ellipsis displayed for it. */
3909 next_element_from_ellipsis (it
);
3910 it
->dpvec_char_len
= -1;
3915 /* Value is zero if end of buffer reached. */
3916 xassert (!success_p
|| it
->len
> 0);
3921 /* Run the redisplay end trigger hook for IT. */
3924 run_redisplay_end_trigger_hook (it
)
3927 Lisp_Object args
[3];
3929 /* IT->glyph_row should be non-null, i.e. we should be actually
3930 displaying something, or otherwise we should not run the hook. */
3931 xassert (it
->glyph_row
);
3933 /* Set up hook arguments. */
3934 args
[0] = Qredisplay_end_trigger_functions
;
3935 args
[1] = it
->window
;
3936 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
3937 it
->redisplay_end_trigger_charpos
= 0;
3939 /* Since we are *trying* to run these functions, don't try to run
3940 them again, even if they get an error. */
3941 it
->w
->redisplay_end_trigger
= Qnil
;
3942 Frun_hook_with_args (3, args
);
3944 /* Notice if it changed the face of the character we are on. */
3945 handle_face_prop (it
);
3950 /***********************************************************************
3951 Moving an iterator without producing glyphs
3952 ***********************************************************************/
3954 /* Move iterator IT to a specified buffer or X position within one
3955 line on the display without producing glyphs.
3957 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
3958 whichever is reached first.
3960 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
3962 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
3963 0 <= TO_X <= IT->last_visible_x. This means in particular, that
3964 TO_X includes the amount by which a window is horizontally
3969 MOVE_POS_MATCH_OR_ZV
3970 - when TO_POS or ZV was reached.
3973 -when TO_X was reached before TO_POS or ZV were reached.
3976 - when we reached the end of the display area and the line must
3980 - when we reached the end of the display area and the line is
3984 - when we stopped at a line end, i.e. a newline or a CR and selective
3988 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
3990 int to_charpos
, to_x
, op
;
3992 enum move_it_result result
= MOVE_UNDEFINED
;
3993 struct glyph_row
*saved_glyph_row
;
3995 /* Don't produce glyphs in produce_glyphs. */
3996 saved_glyph_row
= it
->glyph_row
;
3997 it
->glyph_row
= NULL
;
3999 #if NO_PROMPT_IN_BUFFER
4000 /* Take a mini-buffer prompt into account. */
4001 if (MINI_WINDOW_P (it
->w
)
4002 && IT_CHARPOS (*it
) == BEGV
)
4004 it
->current_x
= minibuf_prompt_pixel_width
;
4005 it
->hpos
= minibuf_prompt_width
;
4013 /* Stop when ZV or TO_CHARPOS reached. */
4014 if (!get_next_display_element (it
)
4015 || ((op
& MOVE_TO_POS
) != 0
4016 && BUFFERP (it
->object
)
4017 && IT_CHARPOS (*it
) >= to_charpos
))
4019 result
= MOVE_POS_MATCH_OR_ZV
;
4023 /* The call to produce_glyphs will get the metrics of the
4024 display element IT is loaded with. We record in x the
4025 x-position before this display element in case it does not
4028 PRODUCE_GLYPHS (it
);
4030 if (it
->area
!= TEXT_AREA
)
4032 set_iterator_to_next (it
);
4036 /* The number of glyphs we get back in IT->nglyphs will normally
4037 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4038 character on a terminal frame, or (iii) a line end. For the
4039 second case, IT->nglyphs - 1 padding glyphs will be present
4040 (on X frames, there is only one glyph produced for a
4041 composite character.
4043 The behavior implemented below means, for continuation lines,
4044 that as many spaces of a TAB as fit on the current line are
4045 displayed there. For terminal frames, as many glyphs of a
4046 multi-glyph character are displayed in the current line, too.
4047 This is what the old redisplay code did, and we keep it that
4048 way. Under X, the whole shape of a complex character must
4049 fit on the line or it will be completely displayed in the
4052 Note that both for tabs and padding glyphs, all glyphs have
4056 /* More than one glyph or glyph doesn't fit on line. All
4057 glyphs have the same width. */
4058 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
4061 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
4063 new_x
= x
+ single_glyph_width
;
4065 /* We want to leave anything reaching TO_X to the caller. */
4066 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
4069 result
= MOVE_X_REACHED
;
4072 else if (/* Lines are continued. */
4073 !it
->truncate_lines_p
4074 && (/* And glyph doesn't fit on the line. */
4075 new_x
> it
->last_visible_x
4076 /* Or it fits exactly and we're on a window
4078 || (new_x
== it
->last_visible_x
4079 && FRAME_WINDOW_P (it
->f
))))
4081 if (/* IT->hpos == 0 means the very first glyph
4082 doesn't fit on the line, e.g. a wide image. */
4084 || (new_x
== it
->last_visible_x
4085 && FRAME_WINDOW_P (it
->f
)))
4088 it
->current_x
= new_x
;
4089 if (i
== it
->nglyphs
- 1)
4090 set_iterator_to_next (it
);
4095 result
= MOVE_LINE_CONTINUED
;
4098 else if (new_x
> it
->first_visible_x
)
4100 /* Glyph is visible. Increment number of glyphs that
4101 would be displayed. */
4106 /* Glyph is completely off the left margin of the display
4107 area. Nothing to do. */
4111 if (result
!= MOVE_UNDEFINED
)
4114 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
4116 /* Stop when TO_X specified and reached. This check is
4117 necessary here because of lines consisting of a line end,
4118 only. The line end will not produce any glyphs and we
4119 would never get MOVE_X_REACHED. */
4120 xassert (it
->nglyphs
== 0);
4121 result
= MOVE_X_REACHED
;
4125 /* Is this a line end? If yes, we're done. */
4126 if (ITERATOR_AT_END_OF_LINE_P (it
))
4128 result
= MOVE_NEWLINE_OR_CR
;
4132 /* The current display element has been consumed. Advance
4134 set_iterator_to_next (it
);
4136 /* Stop if lines are truncated and IT's current x-position is
4137 past the right edge of the window now. */
4138 if (it
->truncate_lines_p
4139 && it
->current_x
>= it
->last_visible_x
)
4141 result
= MOVE_LINE_TRUNCATED
;
4146 /* Restore the iterator settings altered at the beginning of this
4148 it
->glyph_row
= saved_glyph_row
;
4153 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4154 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4155 the description of enum move_operation_enum.
4157 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4158 screen line, this function will set IT to the next position >
4162 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
4164 int to_charpos
, to_x
, to_y
, to_vpos
;
4167 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
4170 xassert (XBUFFER (it
->w
->buffer
) == current_buffer
);
4174 if (op
& MOVE_TO_VPOS
)
4176 /* If no TO_CHARPOS and no TO_X specified, stop at the
4177 start of the line TO_VPOS. */
4178 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
4180 if (it
->vpos
== to_vpos
)
4182 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
4186 /* TO_VPOS >= 0 means stop at TO_X in the line at
4187 TO_VPOS, or at TO_POS, whichever comes first. */
4188 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
4190 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
4192 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
4194 /* We have reached TO_X but not in the line we want. */
4195 skip
= move_it_in_display_line_to (it
, to_charpos
,
4197 if (skip
== MOVE_POS_MATCH_OR_ZV
)
4202 else if (op
& MOVE_TO_Y
)
4204 struct it it_backup
;
4207 /* TO_Y specified means stop at TO_X in the line containing
4208 TO_Y---or at TO_CHARPOS if this is reached first. The
4209 problem is that we can't really tell whether the line
4210 contains TO_Y before we have completely scanned it, and
4211 this may skip past TO_X. What we do is to first scan to
4214 If TO_X is not specified, use a TO_X of zero. The reason
4215 is to make the outcome of this function more predictable.
4216 If we didn't use TO_X == 0, we would stop at the end of
4217 the line which is probably not what a caller would expect
4219 skip
= move_it_in_display_line_to (it
, to_charpos
,
4223 | (op
& MOVE_TO_POS
)));
4225 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4226 if (skip
== MOVE_POS_MATCH_OR_ZV
)
4229 /* If TO_X was reached, we would like to know whether TO_Y
4230 is in the line. This can only be said if we know the
4231 total line height which requires us to scan the rest of
4234 if (skip
== MOVE_X_REACHED
)
4237 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
4241 /* Now, decide whether TO_Y is in this line. */
4242 line_height
= it
->max_ascent
+ it
->max_descent
;
4244 if (to_y
>= it
->current_y
4245 && to_y
< it
->current_y
+ line_height
)
4247 if (skip
== MOVE_X_REACHED
)
4248 /* If TO_Y is in this line and TO_X was reached above,
4249 we scanned too far. We have to restore IT's settings
4250 to the ones before skipping. */
4254 else if (skip
== MOVE_X_REACHED
)
4257 if (skip
== MOVE_POS_MATCH_OR_ZV
)
4265 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
4269 case MOVE_POS_MATCH_OR_ZV
:
4272 case MOVE_NEWLINE_OR_CR
:
4273 set_iterator_to_next (it
);
4274 it
->continuation_lines_width
= 0;
4277 case MOVE_LINE_TRUNCATED
:
4278 it
->continuation_lines_width
= 0;
4279 reseat_at_next_visible_line_start (it
, 0);
4280 if ((op
& MOVE_TO_POS
) != 0
4281 && IT_CHARPOS (*it
) > to_charpos
)
4285 case MOVE_LINE_CONTINUED
:
4286 it
->continuation_lines_width
+= it
->current_x
;
4293 /* Reset/increment for the next run. */
4294 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
4295 it
->current_x
= it
->hpos
= 0;
4296 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
4298 last_height
= it
->max_ascent
+ it
->max_descent
;
4299 last_max_ascent
= it
->max_ascent
;
4300 it
->max_ascent
= it
->max_descent
= 0;
4306 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4308 If DY > 0, move IT backward at least that many pixels. DY = 0
4309 means move IT backward to the preceding line start or BEGV. This
4310 function may move over more than DY pixels if IT->current_y - DY
4311 ends up in the middle of a line; in this case IT->current_y will be
4312 set to the top of the line moved to. */
4315 move_it_vertically_backward (it
, dy
)
4319 int nlines
, h
, line_height
;
4321 int start_pos
= IT_CHARPOS (*it
);
4325 /* Estimate how many newlines we must move back. */
4326 nlines
= max (1, dy
/ CANON_Y_UNIT (it
->f
));
4328 /* Set the iterator's position that many lines back. */
4329 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
4330 back_to_previous_visible_line_start (it
);
4332 /* Reseat the iterator here. When moving backward, we don't want
4333 reseat to skip forward over invisible text, set up the iterator
4334 to deliver from overlay strings at the new position etc. So,
4335 use reseat_1 here. */
4336 reseat_1 (it
, it
->current
.pos
, 1);
4338 /* We are now surely at a line start. */
4339 it
->current_x
= it
->hpos
= 0;
4341 /* Move forward and see what y-distance we moved. First move to the
4342 start of the next line so that we get its height. We need this
4343 height to be able to tell whether we reached the specified
4346 it2
.max_ascent
= it2
.max_descent
= 0;
4347 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
4348 MOVE_TO_POS
| MOVE_TO_VPOS
);
4349 xassert (IT_CHARPOS (*it
) >= BEGV
);
4350 line_height
= it2
.max_ascent
+ it2
.max_descent
;
4351 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
4352 xassert (IT_CHARPOS (*it
) >= BEGV
);
4353 h
= it2
.current_y
- it
->current_y
;
4354 nlines
= it2
.vpos
- it
->vpos
;
4356 /* Correct IT's y and vpos position. */
4362 /* DY == 0 means move to the start of the screen line. The
4363 value of nlines is > 0 if continuation lines were involved. */
4365 move_it_by_lines (it
, nlines
, 1);
4366 xassert (IT_CHARPOS (*it
) <= start_pos
);
4370 /* The y-position we try to reach. Note that h has been
4371 subtracted in front of the if-statement. */
4372 int target_y
= it
->current_y
+ h
- dy
;
4374 /* If we did not reach target_y, try to move further backward if
4375 we can. If we moved too far backward, try to move forward. */
4376 if (target_y
< it
->current_y
4377 && IT_CHARPOS (*it
) > BEGV
)
4379 move_it_vertically (it
, target_y
- it
->current_y
);
4380 xassert (IT_CHARPOS (*it
) >= BEGV
);
4382 else if (target_y
>= it
->current_y
+ line_height
4383 && IT_CHARPOS (*it
) < ZV
)
4385 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
4386 xassert (IT_CHARPOS (*it
) >= BEGV
);
4392 /* Move IT by a specified amount of pixel lines DY. DY negative means
4393 move backwards. DY = 0 means move to start of screen line. At the
4394 end, IT will be on the start of a screen line. */
4397 move_it_vertically (it
, dy
)
4402 move_it_vertically_backward (it
, -dy
);
4405 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
4406 MOVE_TO_POS
| MOVE_TO_Y
);
4408 /* If buffer ends in ZV without a newline, move to the start of
4409 the line to satisfy the post-condition. */
4410 if (IT_CHARPOS (*it
) == ZV
4411 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
4412 move_it_by_lines (it
, 0, 0);
4417 /* Return non-zero if some text between buffer positions START_CHARPOS
4418 and END_CHARPOS is invisible. IT->window is the window for text
4422 invisible_text_between_p (it
, start_charpos
, end_charpos
)
4424 int start_charpos
, end_charpos
;
4426 #ifdef USE_TEXT_PROPERTIES
4427 Lisp_Object prop
, limit
;
4428 int invisible_found_p
;
4430 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
4432 /* Is text at START invisible? */
4433 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
4435 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4436 invisible_found_p
= 1;
4439 limit
= Fnext_single_property_change (make_number (start_charpos
),
4442 make_number (end_charpos
));
4443 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
4446 return invisible_found_p
;
4448 #else /* not USE_TEXT_PROPERTIES */
4450 #endif /* not USE_TEXT_PROPERTIES */
4454 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
4455 negative means move up. DVPOS == 0 means move to the start of the
4456 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
4457 NEED_Y_P is zero, IT->current_y will be left unchanged.
4459 Further optimization ideas: If we would know that IT->f doesn't use
4460 a face with proportional font, we could be faster for
4461 truncate-lines nil. */
4464 move_it_by_lines (it
, dvpos
, need_y_p
)
4466 int dvpos
, need_y_p
;
4468 struct position pos
;
4470 if (!FRAME_WINDOW_P (it
->f
))
4472 struct text_pos textpos
;
4474 /* We can use vmotion on frames without proportional fonts. */
4475 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
4476 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
4477 reseat (it
, textpos
, 1);
4478 it
->vpos
+= pos
.vpos
;
4479 it
->current_y
+= pos
.vpos
;
4481 else if (dvpos
== 0)
4483 /* DVPOS == 0 means move to the start of the screen line. */
4484 move_it_vertically_backward (it
, 0);
4485 xassert (it
->current_x
== 0 && it
->hpos
== 0);
4489 /* If there are no continuation lines, and if there is no
4490 selective display, try the simple method of moving forward
4491 DVPOS newlines, then see where we are. */
4492 if (!need_y_p
&& it
->truncate_lines_p
&& it
->selective
== 0)
4494 int shortage
= 0, charpos
;
4496 if (FETCH_BYTE (IT_BYTEPOS (*it
) == '\n'))
4497 charpos
= IT_CHARPOS (*it
) + 1;
4499 charpos
= scan_buffer ('\n', IT_CHARPOS (*it
), 0, dvpos
,
4502 if (!invisible_text_between_p (it
, IT_CHARPOS (*it
), charpos
))
4504 struct text_pos pos
;
4505 CHARPOS (pos
) = charpos
;
4506 BYTEPOS (pos
) = CHAR_TO_BYTE (charpos
);
4507 reseat (it
, pos
, 1);
4508 it
->vpos
+= dvpos
- shortage
;
4509 it
->hpos
= it
->current_x
= 0;
4514 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
4519 int start_charpos
, i
;
4521 /* If there are no continuation lines, and if there is no
4522 selective display, try the simple method of moving backward
4524 if (!need_y_p
&& it
->truncate_lines_p
&& it
->selective
== 0)
4527 int charpos
= IT_CHARPOS (*it
);
4528 int bytepos
= IT_BYTEPOS (*it
);
4530 /* If in the middle of a line, go to its start. */
4531 if (charpos
> BEGV
&& FETCH_BYTE (bytepos
- 1) != '\n')
4533 charpos
= find_next_newline_no_quit (charpos
, -1);
4534 bytepos
= CHAR_TO_BYTE (charpos
);
4537 if (charpos
== BEGV
)
4539 struct text_pos pos
;
4540 CHARPOS (pos
) = charpos
;
4541 BYTEPOS (pos
) = bytepos
;
4542 reseat (it
, pos
, 1);
4543 it
->hpos
= it
->current_x
= 0;
4548 charpos
= scan_buffer ('\n', charpos
- 1, 0, dvpos
, &shortage
, 0);
4549 if (!invisible_text_between_p (it
, charpos
, IT_CHARPOS (*it
)))
4551 struct text_pos pos
;
4552 CHARPOS (pos
) = charpos
;
4553 BYTEPOS (pos
) = CHAR_TO_BYTE (charpos
);
4554 reseat (it
, pos
, 1);
4555 it
->vpos
+= dvpos
+ (shortage
? shortage
- 1 : 0);
4556 it
->hpos
= it
->current_x
= 0;
4562 /* Go back -DVPOS visible lines and reseat the iterator there. */
4563 start_charpos
= IT_CHARPOS (*it
);
4564 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
4565 back_to_previous_visible_line_start (it
);
4566 reseat (it
, it
->current
.pos
, 1);
4567 it
->current_x
= it
->hpos
= 0;
4569 /* Above call may have moved too far if continuation lines
4570 are involved. Scan forward and see if it did. */
4572 it2
.vpos
= it2
.current_y
= 0;
4573 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
4574 it
->vpos
-= it2
.vpos
;
4575 it
->current_y
-= it2
.current_y
;
4576 it
->current_x
= it
->hpos
= 0;
4578 /* If we moved too far, move IT some lines forward. */
4579 if (it2
.vpos
> -dvpos
)
4581 int delta
= it2
.vpos
+ dvpos
;
4582 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
4589 /***********************************************************************
4591 ***********************************************************************/
4594 /* Output a newline in the *Messages* buffer if "needs" one. */
4597 message_log_maybe_newline ()
4599 if (message_log_need_newline
)
4600 message_dolog ("", 0, 1, 0);
4604 /* Add a string M of length LEN to the message log, optionally
4605 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
4606 nonzero, means interpret the contents of M as multibyte. This
4607 function calls low-level routines in order to bypass text property
4608 hooks, etc. which might not be safe to run. */
4611 message_dolog (m
, len
, nlflag
, multibyte
)
4613 int len
, nlflag
, multibyte
;
4615 if (!NILP (Vmessage_log_max
))
4617 struct buffer
*oldbuf
;
4618 Lisp_Object oldpoint
, oldbegv
, oldzv
;
4619 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
4620 int point_at_end
= 0;
4622 Lisp_Object old_deactivate_mark
, tem
;
4623 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
4625 old_deactivate_mark
= Vdeactivate_mark
;
4626 oldbuf
= current_buffer
;
4627 Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
4628 current_buffer
->undo_list
= Qt
;
4630 oldpoint
= Fpoint_marker ();
4631 oldbegv
= Fpoint_min_marker ();
4632 oldzv
= Fpoint_max_marker ();
4633 GCPRO4 (oldpoint
, oldbegv
, oldzv
, old_deactivate_mark
);
4641 BEGV_BYTE
= BEG_BYTE
;
4644 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
4646 /* Insert the string--maybe converting multibyte to single byte
4647 or vice versa, so that all the text fits the buffer. */
4649 && NILP (current_buffer
->enable_multibyte_characters
))
4652 unsigned char work
[1];
4654 /* Convert a multibyte string to single-byte
4655 for the *Message* buffer. */
4656 for (i
= 0; i
< len
; i
+= nbytes
)
4658 c
= string_char_and_length (m
+ i
, len
- i
, &nbytes
);
4659 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
4661 : multibyte_char_to_unibyte (c
, Qnil
));
4662 insert_1_both (work
, 1, 1, 1, 0, 0);
4665 else if (! multibyte
4666 && ! NILP (current_buffer
->enable_multibyte_characters
))
4669 unsigned char *msg
= (unsigned char *) m
;
4670 unsigned char *str
, work
[4];
4671 /* Convert a single-byte string to multibyte
4672 for the *Message* buffer. */
4673 for (i
= 0; i
< len
; i
++)
4675 c
= unibyte_char_to_multibyte (msg
[i
]);
4676 nbytes
= CHAR_STRING (c
, work
, str
);
4677 insert_1_both (work
, 1, nbytes
, 1, 0, 0);
4681 insert_1 (m
, len
, 1, 0, 0);
4685 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
4686 insert_1 ("\n", 1, 1, 0, 0);
4688 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
4690 this_bol_byte
= PT_BYTE
;
4694 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
4696 prev_bol_byte
= PT_BYTE
;
4698 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
4699 this_bol
, this_bol_byte
);
4702 del_range_both (prev_bol
, prev_bol_byte
,
4703 this_bol
, this_bol_byte
, 0);
4709 /* If you change this format, don't forget to also
4710 change message_log_check_duplicate. */
4711 sprintf (dupstr
, " [%d times]", dup
);
4712 duplen
= strlen (dupstr
);
4713 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
4714 insert_1 (dupstr
, duplen
, 1, 0, 1);
4719 if (NATNUMP (Vmessage_log_max
))
4721 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
4722 -XFASTINT (Vmessage_log_max
) - 1, 0);
4723 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
4726 BEGV
= XMARKER (oldbegv
)->charpos
;
4727 BEGV_BYTE
= marker_byte_position (oldbegv
);
4736 ZV
= XMARKER (oldzv
)->charpos
;
4737 ZV_BYTE
= marker_byte_position (oldzv
);
4741 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
4743 /* We can't do Fgoto_char (oldpoint) because it will run some
4745 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
4746 XMARKER (oldpoint
)->bytepos
);
4749 free_marker (oldpoint
);
4750 free_marker (oldbegv
);
4751 free_marker (oldzv
);
4753 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
4754 set_buffer_internal (oldbuf
);
4756 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
4757 message_log_need_newline
= !nlflag
;
4758 Vdeactivate_mark
= old_deactivate_mark
;
4763 /* We are at the end of the buffer after just having inserted a newline.
4764 (Note: We depend on the fact we won't be crossing the gap.)
4765 Check to see if the most recent message looks a lot like the previous one.
4766 Return 0 if different, 1 if the new one should just replace it, or a
4767 value N > 1 if we should also append " [N times]". */
4770 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
4771 int prev_bol
, this_bol
;
4772 int prev_bol_byte
, this_bol_byte
;
4775 int len
= Z_BYTE
- 1 - this_bol_byte
;
4777 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
4778 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
4780 for (i
= 0; i
< len
; i
++)
4782 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.'
4791 if (*p1
++ == ' ' && *p1
++ == '[')
4794 while (*p1
>= '0' && *p1
<= '9')
4795 n
= n
* 10 + *p1
++ - '0';
4796 if (strncmp (p1
, " times]\n", 8) == 0)
4803 /* Display an echo area message M with a specified length of LEN
4804 chars. The string may include null characters. If M is 0, clear
4805 out any existing message, and let the mini-buffer text show through.
4807 The buffer M must continue to exist until after the echo area gets
4808 cleared or some other message gets displayed there. This means do
4809 not pass text that is stored in a Lisp string; do not pass text in
4810 a buffer that was alloca'd. */
4813 message2 (m
, len
, multibyte
)
4818 /* First flush out any partial line written with print. */
4819 message_log_maybe_newline ();
4821 message_dolog (m
, len
, 1, multibyte
);
4822 message2_nolog (m
, len
, multibyte
);
4826 /* The non-logging counterpart of message2. */
4829 message2_nolog (m
, len
, multibyte
)
4833 message_enable_multibyte
= multibyte
;
4837 if (noninteractive_need_newline
)
4838 putc ('\n', stderr
);
4839 noninteractive_need_newline
= 0;
4841 fwrite (m
, len
, 1, stderr
);
4842 if (cursor_in_echo_area
== 0)
4843 fprintf (stderr
, "\n");
4846 /* A null message buffer means that the frame hasn't really been
4847 initialized yet. Error messages get reported properly by
4848 cmd_error, so this must be just an informative message; toss it. */
4849 else if (INTERACTIVE
4850 && selected_frame
->glyphs_initialized_p
4851 && FRAME_MESSAGE_BUF (selected_frame
))
4853 Lisp_Object mini_window
;
4856 /* Get the frame containing the mini-buffer
4857 that the selected frame is using. */
4858 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
4859 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
4861 FRAME_SAMPLE_VISIBILITY (f
);
4862 if (FRAME_VISIBLE_P (selected_frame
)
4863 && ! FRAME_VISIBLE_P (f
))
4864 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
4868 echo_area_glyphs
= m
;
4869 echo_area_glyphs_length
= len
;
4870 echo_area_message
= Qnil
;
4872 if (minibuffer_auto_raise
)
4873 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
4877 echo_area_glyphs
= previous_echo_glyphs
= NULL
;
4878 echo_area_message
= previous_echo_area_message
= Qnil
;
4881 do_pending_window_change ();
4882 echo_area_display (1);
4883 do_pending_window_change ();
4884 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
4885 (*frame_up_to_date_hook
) (f
);
4890 /* Display an echo area message M with a specified length of LEN
4891 chars. The string may include null characters. If M is not a
4892 string, clear out any existing message, and let the mini-buffer
4893 text show through. */
4896 message3 (m
, len
, multibyte
)
4901 struct gcpro gcpro1
;
4905 /* First flush out any partial line written with print. */
4906 message_log_maybe_newline ();
4908 message_dolog (XSTRING (m
)->data
, len
, 1, multibyte
);
4909 message3_nolog (m
, len
, multibyte
);
4915 /* The non-logging version of message3. */
4918 message3_nolog (m
, len
, multibyte
)
4922 message_enable_multibyte
= multibyte
;
4926 if (noninteractive_need_newline
)
4927 putc ('\n', stderr
);
4928 noninteractive_need_newline
= 0;
4930 fwrite (XSTRING (m
)->data
, len
, 1, stderr
);
4931 if (cursor_in_echo_area
== 0)
4932 fprintf (stderr
, "\n");
4935 /* A null message buffer means that the frame hasn't really been
4936 initialized yet. Error messages get reported properly by
4937 cmd_error, so this must be just an informative message; toss it. */
4938 else if (INTERACTIVE
4939 && selected_frame
->glyphs_initialized_p
4940 && FRAME_MESSAGE_BUF (selected_frame
))
4942 Lisp_Object mini_window
;
4945 /* Get the frame containing the mini-buffer
4946 that the selected frame is using. */
4947 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
4948 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
4950 FRAME_SAMPLE_VISIBILITY (f
);
4951 if (FRAME_VISIBLE_P (selected_frame
)
4952 && ! FRAME_VISIBLE_P (f
))
4953 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
4957 echo_area_glyphs
= NULL
;
4958 echo_area_message
= m
;
4959 echo_area_glyphs_length
= len
;
4961 if (minibuffer_auto_raise
)
4962 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
4966 echo_area_glyphs
= previous_echo_glyphs
= NULL
;
4967 echo_area_message
= previous_echo_area_message
= Qnil
;
4970 do_pending_window_change ();
4971 echo_area_display (1);
4972 do_pending_window_change ();
4973 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
4974 (*frame_up_to_date_hook
) (f
);
4979 /* Display a null-terminated echo area message M. If M is 0, clear
4980 out any existing message, and let the mini-buffer text show through.
4982 The buffer M must continue to exist until after the echo area gets
4983 cleared or some other message gets displayed there. Do not pass
4984 text that is stored in a Lisp string. Do not pass text in a buffer
4985 that was alloca'd. */
4991 message2 (m
, (m
? strlen (m
) : 0), 0);
4995 /* The non-logging counterpart of message1. */
5001 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
5004 /* Display a message M which contains a single %s
5005 which gets replaced with STRING. */
5008 message_with_string (m
, string
, log
)
5017 if (noninteractive_need_newline
)
5018 putc ('\n', stderr
);
5019 noninteractive_need_newline
= 0;
5020 fprintf (stderr
, m
, XSTRING (string
)->data
);
5021 if (cursor_in_echo_area
== 0)
5022 fprintf (stderr
, "\n");
5026 else if (INTERACTIVE
)
5028 /* The frame whose minibuffer we're going to display the message on.
5029 It may be larger than the selected frame, so we need
5030 to use its buffer, not the selected frame's buffer. */
5031 Lisp_Object mini_window
;
5034 /* Get the frame containing the minibuffer
5035 that the selected frame is using. */
5036 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
5037 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
5039 /* A null message buffer means that the frame hasn't really been
5040 initialized yet. Error messages get reported properly by
5041 cmd_error, so this must be just an informative message; toss it. */
5042 if (FRAME_MESSAGE_BUF (f
))
5046 a
[0] = (char *) XSTRING (string
)->data
;
5048 len
= doprnt (FRAME_MESSAGE_BUF (f
),
5049 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
5052 message2 (FRAME_MESSAGE_BUF (f
), len
,
5053 STRING_MULTIBYTE (string
));
5055 message2_nolog (FRAME_MESSAGE_BUF (f
), len
,
5056 STRING_MULTIBYTE (string
));
5058 /* Print should start at the beginning of the message
5059 buffer next time. */
5060 message_buf_print
= 0;
5066 /* Truncate what will be displayed in the echo area
5067 the next time we display it--but don't redisplay it now. */
5070 truncate_echo_area (len
)
5073 /* A null message buffer means that the frame hasn't really been
5074 initialized yet. Error messages get reported properly by
5075 cmd_error, so this must be just an informative message; toss it. */
5076 if (!noninteractive
&& INTERACTIVE
&& FRAME_MESSAGE_BUF (selected_frame
))
5077 echo_area_glyphs_length
= len
;
5081 /* Nonzero if FRAME_MESSAGE_BUF (selected_frame) is being used by
5082 print; zero if being used by message. */
5084 int message_buf_print
;
5087 /* Dump an informative message to the minibuf. If M is 0, clear out
5088 any existing message, and let the mini-buffer text show through. */
5092 message (m
, a1
, a2
, a3
)
5094 EMACS_INT a1
, a2
, a3
;
5100 if (noninteractive_need_newline
)
5101 putc ('\n', stderr
);
5102 noninteractive_need_newline
= 0;
5103 fprintf (stderr
, m
, a1
, a2
, a3
);
5104 if (cursor_in_echo_area
== 0)
5105 fprintf (stderr
, "\n");
5109 else if (INTERACTIVE
)
5111 /* The frame whose mini-buffer we're going to display the message
5112 on. It may be larger than the selected frame, so we need to
5113 use its buffer, not the selected frame's buffer. */
5114 Lisp_Object mini_window
;
5117 /* Get the frame containing the mini-buffer
5118 that the selected frame is using. */
5119 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
5120 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
5122 /* A null message buffer means that the frame hasn't really been
5123 initialized yet. Error messages get reported properly by
5124 cmd_error, so this must be just an informative message; toss
5126 if (FRAME_MESSAGE_BUF (f
))
5137 len
= doprnt (FRAME_MESSAGE_BUF (f
),
5138 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
5140 len
= doprnt (FRAME_MESSAGE_BUF (f
),
5141 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
5143 #endif /* NO_ARG_ARRAY */
5145 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
5150 /* Print should start at the beginning of the message
5151 buffer next time. */
5152 message_buf_print
= 0;
5158 /* The non-logging version of message. */
5161 message_nolog (m
, a1
, a2
, a3
)
5163 EMACS_INT a1
, a2
, a3
;
5165 Lisp_Object old_log_max
;
5166 old_log_max
= Vmessage_log_max
;
5167 Vmessage_log_max
= Qnil
;
5168 message (m
, a1
, a2
, a3
);
5169 Vmessage_log_max
= old_log_max
;
5173 /* Display echo_area_message or echo_area_glyphs in the current
5179 if (STRINGP (echo_area_message
))
5180 message3 (echo_area_message
, echo_area_glyphs_length
,
5181 !NILP (current_buffer
->enable_multibyte_characters
));
5183 message2 (echo_area_glyphs
, echo_area_glyphs_length
,
5184 !NILP (current_buffer
->enable_multibyte_characters
));
5188 /* Redisplay the echo area of selected_frame. If UPDATE_FRAME_P is
5189 non-zero update selected_frame. */
5192 echo_area_display (update_frame_p
)
5195 Lisp_Object mini_window
;
5199 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
5200 w
= XWINDOW (mini_window
);
5201 f
= XFRAME (WINDOW_FRAME (w
));
5203 /* Don't display if frame is invisible or not yet initialized. */
5204 if (!FRAME_VISIBLE_P (f
)
5205 || !f
->glyphs_initialized_p
)
5208 /* When Emacs starts, selected_frame may be a visible terminal
5209 frame, even if we run under a window system. If we let this
5210 through, a message would be displayed on the terminal. */
5211 #ifdef HAVE_WINDOW_SYSTEM
5212 if (!inhibit_window_system
&& !FRAME_WINDOW_P (selected_frame
))
5214 #endif /* HAVE_WINDOW_SYSTEM */
5216 /* Redraw garbaged frames. */
5219 /* Old redisplay called redraw_garbaged_frames here which in
5220 turn called redraw_frame which in turn called clear_frame.
5221 The call to clear_frame is a source of flickering. After
5222 checking the places where SET_FRAME_GARBAGED is called, I
5223 believe a clear_frame is not necessary. It should suffice in
5224 the new redisplay to invalidate all current matrices, and
5225 ensure a complete redisplay of all windows. */
5226 Lisp_Object tail
, frame
;
5228 FOR_EACH_FRAME (tail
, frame
)
5230 struct frame
*f
= XFRAME (frame
);
5232 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
5234 clear_current_matrices (f
);
5240 ++windows_or_buffers_changed
;
5243 if (echo_area_glyphs
5244 || STRINGP (echo_area_message
)
5245 || minibuf_level
== 0)
5249 echo_area_window
= mini_window
;
5250 clear_glyph_matrix (w
->desired_matrix
);
5251 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, DEFAULT_FACE_ID
);
5253 if (STRINGP (echo_area_message
)
5254 && echo_area_glyphs_length
)
5256 prepare_desired_row (it
.glyph_row
);
5257 display_string (NULL
, echo_area_message
, Qnil
, 0, 0,
5258 &it
, -1, echo_area_glyphs_length
, 0,
5259 message_enable_multibyte
);
5260 it
.glyph_row
->truncated_on_right_p
= 0;
5261 compute_line_metrics (&it
);
5263 else if (echo_area_glyphs
5264 && echo_area_glyphs_length
)
5266 prepare_desired_row (it
.glyph_row
);
5267 display_string (echo_area_glyphs
, Qnil
, Qnil
, 0, 0, &it
,
5268 -1, echo_area_glyphs_length
, 0,
5269 message_enable_multibyte
);
5270 it
.glyph_row
->truncated_on_right_p
= 0;
5271 compute_line_metrics (&it
);
5274 blank_row (w
, it
.glyph_row
, 0);
5276 it
.glyph_row
->y
= it
.current_y
;
5277 it
.current_y
+= it
.glyph_row
->height
;
5279 /* Clear the rest of the lines. */
5280 while (it
.current_y
< it
.last_visible_y
)
5283 blank_row (w
, it
.glyph_row
, it
.current_y
);
5284 it
.current_y
+= it
.glyph_row
->height
;
5287 w
->must_be_updated_p
= 1;
5290 /* Calling update_single_window is faster when we can use
5291 window-based redisplay. */
5292 if (FRAME_WINDOW_P (f
))
5294 update_single_window (w
, 1);
5295 rif
->flush_display (f
);
5298 update_frame (f
, 1, 1);
5301 else if (!EQ (mini_window
, selected_window
))
5302 windows_or_buffers_changed
++;
5304 /* Prevent redisplay optimization in redisplay_internal by resetting
5305 this_line_start_pos. This is done because the mini-buffer now
5306 displays the message instead of its buffer text. */
5307 if (EQ (mini_window
, selected_window
))
5308 CHARPOS (this_line_start_pos
) = 0;
5310 previous_echo_glyphs
= echo_area_glyphs
;
5311 previous_echo_area_message
= echo_area_message
;
5312 previous_echo_glyphs_length
= echo_area_glyphs_length
;
5317 /***********************************************************************
5319 ***********************************************************************/
5322 #ifdef HAVE_WINDOW_SYSTEM
5324 /* A buffer for constructing frame titles in it; allocated from the
5325 heap in init_xdisp and resized as needed in store_frame_title_char. */
5327 static char *frame_title_buf
;
5329 /* The buffer's end, and a current output position in it. */
5331 static char *frame_title_buf_end
;
5332 static char *frame_title_ptr
;
5335 /* Store a single character C for the frame title in frame_title_buf.
5336 Re-allocate frame_title_buf if necessary. */
5339 store_frame_title_char (c
)
5342 /* If output position has reached the end of the allocated buffer,
5343 double the buffer's size. */
5344 if (frame_title_ptr
== frame_title_buf_end
)
5346 int len
= frame_title_ptr
- frame_title_buf
;
5347 int new_size
= 2 * len
* sizeof *frame_title_buf
;
5348 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
5349 frame_title_buf_end
= frame_title_buf
+ new_size
;
5350 frame_title_ptr
= frame_title_buf
+ len
;
5353 *frame_title_ptr
++ = c
;
5357 /* Store part of a frame title in frame_title_buf, beginning at
5358 frame_title_ptr. STR is the string to store. Do not copy more
5359 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
5360 the whole string. Pad with spaces until FIELD_WIDTH number of
5361 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
5362 Called from display_mode_element when it is used to build a frame
5366 store_frame_title (str
, field_width
, precision
)
5368 int field_width
, precision
;
5372 /* Copy at most PRECISION chars from STR. */
5373 while ((precision
<= 0 || n
< precision
)
5376 store_frame_title_char (*str
++);
5380 /* Fill up with spaces until FIELD_WIDTH reached. */
5381 while (field_width
> 0
5384 store_frame_title_char (' ');
5392 /* Set the title of FRAME, if it has changed. The title format is
5393 Vicon_title_format if FRAME is iconified, otherwise it is
5394 frame_title_format. */
5397 x_consider_frame_title (frame
)
5400 struct frame
*f
= XFRAME (frame
);
5402 if (FRAME_WINDOW_P (f
)
5403 || FRAME_MINIBUF_ONLY_P (f
)
5404 || f
->explicit_name
)
5406 /* Do we have more than one visible frame on this X display? */
5409 struct buffer
*obuf
;
5413 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
5415 struct frame
*tf
= XFRAME (XCONS (tail
)->car
);
5418 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
5419 && !FRAME_MINIBUF_ONLY_P (tf
)
5420 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
5424 /* Set global variable indicating that multiple frames exist. */
5425 multiple_frames
= CONSP (tail
);
5427 /* Switch to the buffer of selected window of the frame. Set up
5428 frame_title_ptr so that display_mode_element will output into it;
5429 then display the title. */
5430 obuf
= current_buffer
;
5431 Fset_buffer (XWINDOW (f
->selected_window
)->buffer
);
5432 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
5433 frame_title_ptr
= frame_title_buf
;
5434 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
5435 NULL
, DEFAULT_FACE_ID
);
5436 len
= display_mode_element (&it
, 0, -1, -1, fmt
);
5437 frame_title_ptr
= NULL
;
5438 set_buffer_internal (obuf
);
5440 /* Set the title only if it's changed. This avoids consing in
5441 the common case where it hasn't. (If it turns out that we've
5442 already wasted too much time by walking through the list with
5443 display_mode_element, then we might need to optimize at a
5444 higher level than this.) */
5445 if (! STRINGP (f
->name
)
5446 || STRING_BYTES (XSTRING (f
->name
)) != len
5447 || bcmp (frame_title_buf
, XSTRING (f
->name
)->data
, len
) != 0)
5448 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
5452 #else /* not HAVE_WINDOW_SYSTEM */
5454 #define frame_title_ptr ((char *)0)
5455 #define store_frame_title(str, mincol, maxcol) 0
5457 #endif /* not HAVE_WINDOW_SYSTEM */
5462 /***********************************************************************
5464 ***********************************************************************/
5467 /* Prepare for redisplay by updating menu-bar item lists when
5468 appropriate. This can call eval. */
5471 prepare_menu_bars ()
5474 struct gcpro gcpro1
, gcpro2
;
5476 struct frame
*tooltip_frame
;
5478 #ifdef HAVE_X_WINDOWS
5479 tooltip_frame
= tip_frame
;
5481 tooltip_frame
= NULL
;
5484 /* Update all frame titles based on their buffer names, etc. We do
5485 this before the menu bars so that the buffer-menu will show the
5486 up-to-date frame titles. */
5487 #ifdef HAVE_WINDOW_SYSTEM
5488 if (windows_or_buffers_changed
|| update_mode_lines
)
5490 Lisp_Object tail
, frame
;
5492 FOR_EACH_FRAME (tail
, frame
)
5495 if (f
!= tooltip_frame
5496 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
5497 x_consider_frame_title (frame
);
5500 #endif /* HAVE_WINDOW_SYSTEM */
5502 /* Update the menu bar item lists, if appropriate. This has to be
5503 done before any actual redisplay or generation of display lines. */
5504 all_windows
= (update_mode_lines
5505 || buffer_shared
> 1
5506 || windows_or_buffers_changed
);
5509 Lisp_Object tail
, frame
;
5510 int count
= specpdl_ptr
- specpdl
;
5512 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
5514 FOR_EACH_FRAME (tail
, frame
)
5518 /* Ignore tooltip frame. */
5519 if (f
== tooltip_frame
)
5522 /* If a window on this frame changed size, report that to
5523 the user and clear the size-change flag. */
5524 if (FRAME_WINDOW_SIZES_CHANGED (f
))
5526 Lisp_Object functions
;
5528 /* Clear flag first in case we get an error below. */
5529 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
5530 functions
= Vwindow_size_change_functions
;
5531 GCPRO2 (tail
, functions
);
5533 while (CONSP (functions
))
5535 call1 (XCAR (functions
), frame
);
5536 functions
= XCDR (functions
);
5542 update_menu_bar (f
, 0);
5543 #ifdef HAVE_WINDOW_SYSTEM
5544 update_toolbar (f
, 0);
5549 unbind_to (count
, Qnil
);
5553 update_menu_bar (selected_frame
, 1);
5554 #ifdef HAVE_WINDOW_SYSTEM
5555 update_toolbar (selected_frame
, 1);
5559 /* Motif needs this. See comment in xmenu.c. Turn it off when
5560 pending_menu_activation is not defined. */
5561 #ifdef USE_X_TOOLKIT
5562 pending_menu_activation
= 0;
5567 /* Update the menu bar item list for frame F. This has to be done
5568 before we start to fill in any display lines, because it can call
5571 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
5574 update_menu_bar (f
, save_match_data
)
5576 int save_match_data
;
5579 register struct window
*w
;
5581 window
= FRAME_SELECTED_WINDOW (f
);
5582 w
= XWINDOW (window
);
5584 if (update_mode_lines
)
5585 w
->update_mode_line
= Qt
;
5587 if (FRAME_WINDOW_P (f
)
5589 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5590 FRAME_EXTERNAL_MENU_BAR (f
)
5592 FRAME_MENU_BAR_LINES (f
) > 0
5594 : FRAME_MENU_BAR_LINES (f
) > 0)
5596 /* If the user has switched buffers or windows, we need to
5597 recompute to reflect the new bindings. But we'll
5598 recompute when update_mode_lines is set too; that means
5599 that people can use force-mode-line-update to request
5600 that the menu bar be recomputed. The adverse effect on
5601 the rest of the redisplay algorithm is about the same as
5602 windows_or_buffers_changed anyway. */
5603 if (windows_or_buffers_changed
5604 || !NILP (w
->update_mode_line
)
5605 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
5606 < BUF_MODIFF (XBUFFER (w
->buffer
)))
5607 != !NILP (w
->last_had_star
))
5608 || ((!NILP (Vtransient_mark_mode
)
5609 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
5610 != !NILP (w
->region_showing
)))
5612 struct buffer
*prev
= current_buffer
;
5613 int count
= specpdl_ptr
- specpdl
;
5615 set_buffer_internal_1 (XBUFFER (w
->buffer
));
5616 if (save_match_data
)
5617 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
5618 if (NILP (Voverriding_local_map_menu_flag
))
5620 specbind (Qoverriding_terminal_local_map
, Qnil
);
5621 specbind (Qoverriding_local_map
, Qnil
);
5624 /* Run the Lucid hook. */
5625 call1 (Vrun_hooks
, Qactivate_menubar_hook
);
5627 /* If it has changed current-menubar from previous value,
5628 really recompute the menu-bar from the value. */
5629 if (! NILP (Vlucid_menu_bar_dirty_flag
))
5630 call0 (Qrecompute_lucid_menubar
);
5632 safe_run_hooks (Qmenu_bar_update_hook
);
5633 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
5635 /* Redisplay the menu bar in case we changed it. */
5636 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
5637 if (FRAME_WINDOW_P (f
))
5638 set_frame_menubar (f
, 0, 0);
5640 /* On a terminal screen, the menu bar is an ordinary screen
5641 line, and this makes it get updated. */
5642 w
->update_mode_line
= Qt
;
5643 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5644 /* In the non-toolkit version, the menu bar is an ordinary screen
5645 line, and this makes it get updated. */
5646 w
->update_mode_line
= Qt
;
5647 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
5649 unbind_to (count
, Qnil
);
5650 set_buffer_internal_1 (prev
);
5657 /***********************************************************************
5659 ***********************************************************************/
5661 #ifdef HAVE_WINDOW_SYSTEM
5663 /* Update the toolbar item list for frame F. This has to be done
5664 before we start to fill in any display lines. Called from
5665 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
5666 and restore it here. */
5669 update_toolbar (f
, save_match_data
)
5671 int save_match_data
;
5673 if (WINDOWP (f
->toolbar_window
)
5674 && XFASTINT (XWINDOW (f
->toolbar_window
)->height
) > 0)
5679 window
= FRAME_SELECTED_WINDOW (f
);
5680 w
= XWINDOW (window
);
5682 /* If the user has switched buffers or windows, we need to
5683 recompute to reflect the new bindings. But we'll
5684 recompute when update_mode_lines is set too; that means
5685 that people can use force-mode-line-update to request
5686 that the menu bar be recomputed. The adverse effect on
5687 the rest of the redisplay algorithm is about the same as
5688 windows_or_buffers_changed anyway. */
5689 if (windows_or_buffers_changed
5690 || !NILP (w
->update_mode_line
)
5691 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
5692 < BUF_MODIFF (XBUFFER (w
->buffer
)))
5693 != !NILP (w
->last_had_star
))
5694 || ((!NILP (Vtransient_mark_mode
)
5695 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
5696 != !NILP (w
->region_showing
)))
5698 struct buffer
*prev
= current_buffer
;
5699 int count
= specpdl_ptr
- specpdl
;
5701 /* Set current_buffer to the buffer of the selected
5702 window of the frame, so that we get the right local
5704 set_buffer_internal_1 (XBUFFER (w
->buffer
));
5706 /* Save match data, if we must. */
5707 if (save_match_data
)
5708 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
5710 /* Make sure that we don't accidentally use bogus keymaps. */
5711 if (NILP (Voverriding_local_map_menu_flag
))
5713 specbind (Qoverriding_terminal_local_map
, Qnil
);
5714 specbind (Qoverriding_local_map
, Qnil
);
5717 /* Build desired toolbar items from keymaps. */
5718 f
->desired_toolbar_items
5719 = toolbar_items (f
->desired_toolbar_items
,
5720 &f
->n_desired_toolbar_items
);
5722 /* Redisplay the toolbar in case we changed it. */
5723 w
->update_mode_line
= Qt
;
5725 unbind_to (count
, Qnil
);
5726 set_buffer_internal_1 (prev
);
5732 /* Set F->desired_toolbar_string to a Lisp string representing frame
5733 F's desired toolbar contents. F->desired_toolbar_items must have
5734 been set up previously by calling prepare_menu_bars. */
5737 build_desired_toolbar_string (f
)
5740 int i
, size
, size_needed
, string_idx
;
5741 struct gcpro gcpro1
, gcpro2
, gcpro3
;
5742 Lisp_Object image
, plist
, props
;
5744 image
= plist
= props
= Qnil
;
5745 GCPRO3 (image
, plist
, props
);
5747 /* Prepare F->desired_toolbar_string. If we can reuse it, do so.
5748 Otherwise, make a new string. */
5750 /* The size of the string we might be able to reuse. */
5751 size
= (STRINGP (f
->desired_toolbar_string
)
5752 ? XSTRING (f
->desired_toolbar_string
)->size
5755 /* Each image in the string we build is preceded by a space,
5756 and there is a space at the end. */
5757 size_needed
= f
->n_desired_toolbar_items
+ 1;
5759 /* Reuse f->desired_toolbar_string, if possible. */
5760 if (size
< size_needed
)
5761 f
->desired_toolbar_string
= Fmake_string (make_number (size_needed
), ' ');
5764 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
5765 Fremove_text_properties (make_number (0), make_number (size
),
5766 props
, f
->desired_toolbar_string
);
5769 /* Put a `display' property on the string for the images to display,
5770 put a `menu_item' property on toolbar items with a value that
5771 is the index of the item in F's toolbar item vector. */
5772 for (i
= 0, string_idx
= 0;
5773 i
< f
->n_desired_toolbar_items
;
5774 ++i
, string_idx
+= 1)
5777 (XVECTOR (f->desired_toolbar_items) \
5778 ->contents[i * TOOLBAR_ITEM_NSLOTS + (IDX)])
5780 int enabled_p
= !NILP (PROP (TOOLBAR_ITEM_ENABLED_P
));
5781 int selected_p
= !NILP (PROP (TOOLBAR_ITEM_SELECTED_P
));
5783 extern Lisp_Object QCrelief
, QCmargin
, QCalgorithm
, Qimage
;
5784 extern Lisp_Object Qlaplace
;
5786 /* If image is a vector, choose the image according to the
5788 image
= PROP (TOOLBAR_ITEM_IMAGES
);
5789 if (VECTORP (image
))
5791 enum toolbar_item_image idx
;
5795 ? TOOLBAR_IMAGE_ENABLED_SELECTED
5796 : TOOLBAR_IMAGE_ENABLED_DESELECTED
);
5799 ? TOOLBAR_IMAGE_DISABLED_SELECTED
5800 : TOOLBAR_IMAGE_DISABLED_DESELECTED
);
5802 xassert (XVECTOR (image
)->size
>= idx
);
5803 image
= XVECTOR (image
)->contents
[idx
];
5806 /* Ignore invalid image specifications. */
5807 if (!valid_image_p (image
))
5810 /* Display the toolbar button pressed, or depressed. */
5811 plist
= Fcopy_sequence (XCDR (image
));
5813 /* Compute margin and relief to draw. */
5814 relief
= toolbar_button_relief
> 0 ? toolbar_button_relief
: 3;
5815 margin
= relief
+ max (0, toolbar_button_margin
);
5817 if (auto_raise_toolbar_buttons_p
)
5819 /* Add a `:relief' property to the image spec if the item is
5823 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
5829 /* If image is selected, display it pressed, i.e. with a
5830 negative relief. If it's not selected, display it with a
5832 plist
= Fplist_put (plist
, QCrelief
,
5834 ? make_number (-relief
)
5835 : make_number (relief
)));
5839 /* Put a margin around the image. */
5841 plist
= Fplist_put (plist
, QCmargin
, make_number (margin
));
5843 /* If button is not enabled, make the image appear disabled by
5844 applying an appropriate algorithm to it. */
5846 plist
= Fplist_put (plist
, QCalgorithm
, Qlaplace
);
5848 /* Put a `display' text property on the string for the image to
5849 display. Put a `menu-item' property on the string that gives
5850 the start of this item's properties in the toolbar items
5852 image
= Fcons (Qimage
, plist
);
5853 props
= list4 (Qdisplay
, image
,
5854 Qmenu_item
, make_number (i
* TOOLBAR_ITEM_NSLOTS
)),
5855 Fadd_text_properties (make_number (string_idx
),
5856 make_number (string_idx
+ 1),
5857 props
, f
->desired_toolbar_string
);
5865 /* Display one line of the toolbar of frame IT->f. */
5868 display_toolbar_line (it
)
5871 struct glyph_row
*row
= it
->glyph_row
;
5872 int max_x
= it
->last_visible_x
;
5875 prepare_desired_row (row
);
5876 row
->y
= it
->current_y
;
5878 while (it
->current_x
< max_x
)
5880 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
5882 /* Get the next display element. */
5883 if (!get_next_display_element (it
))
5886 /* Produce glyphs. */
5887 x_before
= it
->current_x
;
5888 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
5889 PRODUCE_GLYPHS (it
);
5891 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
5896 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
5898 if (x
+ glyph
->pixel_width
> max_x
)
5900 /* Glyph doesn't fit on line. */
5901 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
5907 x
+= glyph
->pixel_width
;
5911 /* Stop at line ends. */
5912 if (ITERATOR_AT_END_OF_LINE_P (it
))
5915 set_iterator_to_next (it
);
5920 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
5921 extend_face_to_end_of_line (it
);
5922 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
5923 last
->right_box_line_p
= 1;
5924 compute_line_metrics (it
);
5926 /* If line is empty, make it occupy the rest of the toolbar. */
5927 if (!row
->displays_text_p
)
5929 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
5930 row
->ascent
= row
->phys_ascent
= 0;
5933 row
->full_width_p
= 1;
5934 row
->continued_p
= 0;
5935 row
->truncated_on_left_p
= 0;
5936 row
->truncated_on_right_p
= 0;
5938 it
->current_x
= it
->hpos
= 0;
5939 it
->current_y
+= row
->height
;
5945 /* Value is the number of screen lines needed to make all toolbar
5946 items of frame F visible. */
5949 toolbar_lines_needed (f
)
5952 struct window
*w
= XWINDOW (f
->toolbar_window
);
5955 /* Initialize an iterator for iteration over F->desired_toolbar_string
5956 in the toolbar window of frame F. */
5957 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOLBAR_FACE_ID
);
5958 it
.first_visible_x
= 0;
5959 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
5960 reseat_to_string (&it
, NULL
, f
->desired_toolbar_string
, 0, 0, 0, -1);
5962 while (!ITERATOR_AT_END_P (&it
))
5964 it
.glyph_row
= w
->desired_matrix
->rows
;
5965 clear_glyph_row (it
.glyph_row
);
5966 display_toolbar_line (&it
);
5969 return (it
.current_y
+ CANON_Y_UNIT (f
) - 1) / CANON_Y_UNIT (f
);
5973 /* Display the toolbar of frame F. Value is non-zero if toolbar's
5974 height should be changed. */
5977 redisplay_toolbar (f
)
5982 struct glyph_row
*row
;
5983 int change_height_p
= 0;
5985 /* If frame hasn't a toolbar window or if it is zero-height, don't
5986 do anything. This means you must start with toolbar-lines
5987 non-zero to get the auto-sizing effect. Or in other words, you
5988 can turn off toolbars by specifying toolbar-lines zero. */
5989 if (!WINDOWP (f
->toolbar_window
)
5990 || (w
= XWINDOW (f
->toolbar_window
),
5991 XFASTINT (w
->height
) == 0))
5994 /* Set up an iterator for the toolbar window. */
5995 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOLBAR_FACE_ID
);
5996 it
.first_visible_x
= 0;
5997 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
6000 /* Build a string that represents the contents of the toolbar. */
6001 build_desired_toolbar_string (f
);
6002 reseat_to_string (&it
, NULL
, f
->desired_toolbar_string
, 0, 0, 0, -1);
6004 /* Display as many lines as needed to display all toolbar items. */
6005 while (it
.current_y
< it
.last_visible_y
)
6006 display_toolbar_line (&it
);
6008 /* It doesn't make much sense to try scrolling in the toolbar
6009 window, so don't do it. */
6010 w
->desired_matrix
->no_scrolling_p
= 1;
6011 w
->must_be_updated_p
= 1;
6013 if (auto_resize_toolbars_p
)
6017 /* If there are blank lines at the end, except for a partially
6018 visible blank line at the end that is smaller than
6019 CANON_Y_UNIT, change the toolbar's height. */
6020 row
= it
.glyph_row
- 1;
6021 if (!row
->displays_text_p
6022 && row
->height
>= CANON_Y_UNIT (f
))
6023 change_height_p
= 1;
6025 /* If row displays toolbar items, but is partially visible,
6026 change the toolbar's height. */
6027 if (row
->displays_text_p
6028 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
6029 change_height_p
= 1;
6031 /* Resize windows as needed by changing the `toolbar-lines'
6034 && (nlines
= toolbar_lines_needed (f
),
6035 nlines
!= XFASTINT (w
->height
)))
6037 extern Lisp_Object Qtoolbar_lines
;
6040 XSETFRAME (frame
, f
);
6041 clear_glyph_matrix (w
->desired_matrix
);
6042 Fmodify_frame_parameters (frame
,
6043 Fcons (Fcons (Qtoolbar_lines
,
6044 make_number (nlines
)),
6046 fonts_changed_p
= 1;
6050 return change_height_p
;
6054 /* Get information about the toolbar item which is displayed in GLYPH
6055 on frame F. Return in *PROP_IDX the index where toolbar item
6056 properties start in F->current_toolbar_items. Value is zero if
6057 GLYPH doesn't display a toolbar item. */
6060 toolbar_item_info (f
, glyph
, prop_idx
)
6062 struct glyph
*glyph
;
6068 /* Get the text property `menu-item' at pos. The value of that
6069 property is the start index of this item's properties in
6070 F->current_toolbar_items. */
6071 prop
= Fget_text_property (make_number (glyph
->charpos
),
6072 Qmenu_item
, f
->current_toolbar_string
);
6073 if (INTEGERP (prop
))
6075 *prop_idx
= XINT (prop
);
6084 #endif /* HAVE_WINDOW_SYSTEM */
6088 /************************************************************************
6089 Horizontal scrolling
6090 ************************************************************************/
6092 static int hscroll_window_tree
P_ ((Lisp_Object
));
6093 static int hscroll_windows
P_ ((Lisp_Object
));
6095 /* For all leaf windows in the window tree rooted at WINDOW, set their
6096 hscroll value so that PT is (i) visible in the window, and (ii) so
6097 that it is not within a certain margin at the window's left and
6098 right border. Value is non-zero if any window's hscroll has been
6102 hscroll_window_tree (window
)
6105 int hscrolled_p
= 0;
6107 while (WINDOWP (window
))
6109 struct window
*w
= XWINDOW (window
);
6111 if (WINDOWP (w
->hchild
))
6112 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
6113 else if (WINDOWP (w
->vchild
))
6114 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
6115 else if (w
->cursor
.vpos
>= 0)
6117 int hscroll_margin
, text_area_x
, text_area_y
;
6118 int text_area_width
, text_area_height
;
6119 struct glyph_row
*cursor_row
= MATRIX_ROW (w
->current_matrix
,
6122 window_box (w
, TEXT_AREA
, &text_area_x
, &text_area_y
,
6123 &text_area_width
, &text_area_height
);
6125 /* Scroll when cursor is inside this scroll margin. */
6126 hscroll_margin
= 5 * CANON_X_UNIT (XFRAME (w
->frame
));
6128 if ((XFASTINT (w
->hscroll
)
6129 && w
->cursor
.x
< hscroll_margin
)
6130 || (cursor_row
->truncated_on_right_p
6131 && (w
->cursor
.x
> text_area_width
- hscroll_margin
)))
6135 struct buffer
*saved_current_buffer
;
6138 /* Find point in a display of infinite width. */
6139 saved_current_buffer
= current_buffer
;
6140 current_buffer
= XBUFFER (w
->buffer
);
6142 if (w
== XWINDOW (selected_window
))
6143 pt
= BUF_PT (current_buffer
);
6146 pt
= marker_position (w
->pointm
);
6147 pt
= max (BEGV
, pt
);
6151 /* Move iterator to pt starting at cursor_row->start in
6152 a line with infinite width. */
6153 init_to_row_start (&it
, w
, cursor_row
);
6154 it
.last_visible_x
= INFINITY
;
6155 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
6156 current_buffer
= saved_current_buffer
;
6158 /* Center cursor in window. */
6159 hscroll
= (max (0, it
.current_x
- text_area_width
/ 2)
6160 / CANON_X_UNIT (it
.f
));
6162 /* Don't call Fset_window_hscroll if value hasn't
6163 changed because it will prevent redisplay
6165 if (XFASTINT (w
->hscroll
) != hscroll
)
6167 Fset_window_hscroll (window
, make_number (hscroll
));
6176 /* Value is non-zero if hscroll of any leaf window has been changed. */
6181 /* Set hscroll so that cursor is visible and not inside horizontal
6182 scroll margins for all windows in the tree rooted at WINDOW. See
6183 also hscroll_window_tree above. Value is non-zero if any window's
6184 hscroll has been changed. If it has, desired matrices on the frame
6185 of WINDOW are cleared. */
6188 hscroll_windows (window
)
6191 int hscrolled_p
= hscroll_window_tree (window
);
6193 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
6199 /************************************************************************
6201 ************************************************************************/
6203 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
6204 to a non-zero value. This is sometimes handy to have in a debugger
6209 /* Values of beg_unchanged and end_unchanged as of last call to
6212 int debug_beg_unchanged
, debug_end_unchanged
;
6214 /* First and last unchanged row for try_window_id. */
6216 int debug_first_unchanged_at_end_vpos
;
6217 int debug_last_unchanged_at_beg_vpos
;
6219 /* Delta vpos and y. */
6221 int debug_dvpos
, debug_dy
;
6223 /* Delta in characters and bytes for try_window_id. */
6225 int debug_delta
, debug_delta_bytes
;
6227 /* Values of window_end_pos and window_end_vpos at the end of
6230 int debug_end_pos
, debug_end_vpos
;
6232 /* Append a string to W->desired_matrix->method. FMT is a printf
6233 format string. A1...A9 are a supplement for a variable-length
6234 argument list. If trace_redisplay_p is non-zero also printf the
6235 resulting string to stderr. */
6238 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
6241 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
6244 char *method
= w
->desired_matrix
->method
;
6245 int len
= strlen (method
);
6246 int size
= sizeof w
->desired_matrix
->method
;
6247 int remaining
= size
- len
- 1;
6249 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
6250 if (len
&& remaining
)
6256 strncpy (method
+ len
, buffer
, remaining
);
6258 if (trace_redisplay_p
)
6259 fprintf (stderr
, "%p (%s): %s\n",
6261 ((BUFFERP (w
->buffer
)
6262 && STRINGP (XBUFFER (w
->buffer
)->name
))
6263 ? (char *) XSTRING (XBUFFER (w
->buffer
)->name
)->data
6268 #endif /* GLYPH_DEBUG */
6271 /* This counter is used to clear the face cache every once in a while
6272 in redisplay_internal. It is incremented for each redisplay.
6273 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
6276 #define CLEAR_FACE_CACHE_COUNT 10000
6277 static int clear_face_cache_count
;
6279 /* Record the previous terminal frame we displayed. */
6281 static struct frame
*previous_terminal_frame
;
6283 /* Non-zero while redisplay_internal is in progress. */
6288 /* Value is non-zero if all changes in window W, which displays
6289 current_buffer, are in the text between START and END. START is a
6290 buffer position, END is given as a distance from Z. Used in
6291 redisplay_internal for display optimization. */
6294 text_outside_line_unchanged_p (w
, start
, end
)
6298 int unchanged_p
= 1;
6300 /* If text or overlays have changed, see where. */
6301 if (XFASTINT (w
->last_modified
) < MODIFF
6302 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
6304 /* Gap in the line? */
6305 if (GPT
< start
|| Z
- GPT
< end
)
6308 /* Changes start in front of the line, or end after it? */
6310 && (beg_unchanged
< start
- 1
6311 || end_unchanged
< end
))
6314 /* If selective display, can't optimize if changes start at the
6315 beginning of the line. */
6317 && INTEGERP (current_buffer
->selective_display
)
6318 && XINT (current_buffer
->selective_display
) > 0
6319 && (beg_unchanged
< start
|| GPT
<= start
))
6327 /* Do a frame update, taking possible shortcuts into account. This is
6328 the main external entry point for redisplay.
6330 If the last redisplay displayed an echo area message and that message
6331 is no longer requested, we clear the echo area or bring back the
6332 mini-buffer if that is in use. */
6337 redisplay_internal (0);
6341 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
6342 response to any user action; therefore, we should preserve the echo
6343 area. (Actually, our caller does that job.) Perhaps in the future
6344 avoid recentering windows if it is not necessary; currently that
6345 causes some problems. */
6348 redisplay_internal (preserve_echo_area
)
6349 int preserve_echo_area
;
6351 struct window
*w
= XWINDOW (selected_window
);
6352 struct frame
*f
= XFRAME (w
->frame
);
6354 int must_finish
= 0;
6355 struct text_pos tlbufpos
, tlendpos
;
6356 int number_of_visible_frames
;
6358 /* Non-zero means redisplay has to consider all windows on all
6359 frames. Zero means, only selected_window is considered. */
6360 int consider_all_windows_p
;
6362 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
6364 /* No redisplay if running in batch mode or frame is not yet fully
6365 initialized, or redisplay is explicitly turned off by setting
6366 Vinhibit_redisplay. */
6368 || !NILP (Vinhibit_redisplay
)
6369 || !f
->glyphs_initialized_p
)
6372 /* The flag redisplay_performed_directly_p is set by
6373 direct_output_for_insert when it already did the whole screen
6374 update necessary. */
6375 if (redisplay_performed_directly_p
)
6377 redisplay_performed_directly_p
= 0;
6378 if (!hscroll_windows (selected_window
))
6382 #ifdef USE_X_TOOLKIT
6383 if (popup_activated ())
6393 /* If new fonts have been loaded that make a glyph matrix adjustment
6394 necessary, do it. */
6395 if (fonts_changed_p
)
6397 adjust_glyphs (NULL
);
6398 ++windows_or_buffers_changed
;
6399 fonts_changed_p
= 0;
6402 if (! FRAME_WINDOW_P (selected_frame
)
6403 && previous_terminal_frame
!= selected_frame
)
6405 /* Since frames on an ASCII terminal share the same display
6406 area, displaying a different frame means redisplay the whole
6408 windows_or_buffers_changed
++;
6409 SET_FRAME_GARBAGED (selected_frame
);
6410 XSETFRAME (Vterminal_frame
, selected_frame
);
6412 previous_terminal_frame
= selected_frame
;
6414 /* Set the visible flags for all frames. Do this before checking
6415 for resized or garbaged frames; they want to know if their frames
6416 are visible. See the comment in frame.h for
6417 FRAME_SAMPLE_VISIBILITY. */
6419 Lisp_Object tail
, frame
;
6421 number_of_visible_frames
= 0;
6423 FOR_EACH_FRAME (tail
, frame
)
6425 struct frame
*f
= XFRAME (frame
);
6427 FRAME_SAMPLE_VISIBILITY (f
);
6428 if (FRAME_VISIBLE_P (f
))
6429 ++number_of_visible_frames
;
6430 clear_desired_matrices (f
);
6434 /* Notice any pending interrupt request to change frame size. */
6435 do_pending_window_change ();
6437 /* Clear frames marked as garbaged. */
6440 /* Old redisplay called redraw_garbaged_frames here which in
6441 turn called redraw_frame which in turn called clear_frame.
6442 The call to clear_frame is a source of flickering. After
6443 checking the places where SET_FRAME_GARBAGED is called, I
6444 believe a clear_frame is not necessary. It should suffice in
6445 the new redisplay to invalidate all current matrices, and
6446 ensure a complete redisplay of all windows. */
6447 Lisp_Object tail
, frame
;
6449 FOR_EACH_FRAME (tail
, frame
)
6451 struct frame
*f
= XFRAME (frame
);
6453 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
6455 clear_current_matrices (f
);
6461 ++windows_or_buffers_changed
;
6464 /* Build menubar and toolbar items. */
6465 prepare_menu_bars ();
6467 if (windows_or_buffers_changed
)
6468 update_mode_lines
++;
6470 /* Detect case that we need to write or remove a star in the mode line. */
6471 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
6473 w
->update_mode_line
= Qt
;
6474 if (buffer_shared
> 1)
6475 update_mode_lines
++;
6478 /* If %c is in the mode line, update it if needed. */
6479 if (!NILP (w
->column_number_displayed
)
6480 /* This alternative quickly identifies a common case
6481 where no change is needed. */
6482 && !(PT
== XFASTINT (w
->last_point
)
6483 && XFASTINT (w
->last_modified
) >= MODIFF
6484 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
6485 && XFASTINT (w
->column_number_displayed
) != current_column ())
6486 w
->update_mode_line
= Qt
;
6488 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
6490 /* The variable buffer_shared is set in redisplay_window and
6491 indicates that we redisplay a buffer in different windows. See
6493 consider_all_windows_p
= update_mode_lines
|| buffer_shared
> 1;
6495 /* If specs for an arrow have changed, do thorough redisplay
6496 to ensure we remove any arrow that should no longer exist. */
6497 if (! EQ (COERCE_MARKER (Voverlay_arrow_position
), last_arrow_position
)
6498 || ! EQ (Voverlay_arrow_string
, last_arrow_string
))
6499 consider_all_windows_p
= windows_or_buffers_changed
= 1;
6501 /* Normally the message* functions will have already displayed and
6502 updated the echo area, but the frame may have been trashed, or
6503 the update may have been preempted, so display the echo area
6505 if (echo_area_glyphs
6506 || STRINGP (echo_area_message
)
6507 || previous_echo_glyphs
6508 || STRINGP (previous_echo_area_message
))
6510 echo_area_display (0);
6514 /* If showing the region, and mark has changed, we must redisplay
6515 the whole window. The assignment to this_line_start_pos prevents
6516 the optimization directly below this if-statement. */
6517 if (((!NILP (Vtransient_mark_mode
)
6518 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
6519 != !NILP (w
->region_showing
))
6520 || (!NILP (w
->region_showing
)
6521 && !EQ (w
->region_showing
,
6522 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
6523 CHARPOS (this_line_start_pos
) = 0;
6525 /* Optimize the case that only the line containing the cursor in the
6526 selected window has changed. Variables starting with this_ are
6527 set in display_line and record information about the line
6528 containing the cursor. */
6529 tlbufpos
= this_line_start_pos
;
6530 tlendpos
= this_line_end_pos
;
6531 if (!consider_all_windows_p
6532 && CHARPOS (tlbufpos
) > 0
6533 && NILP (w
->update_mode_line
)
6534 && !current_buffer
->clip_changed
6535 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
6536 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
6537 /* Make sure recorded data applies to current buffer, etc. */
6538 && this_line_buffer
== current_buffer
6539 && current_buffer
== XBUFFER (w
->buffer
)
6540 && NILP (w
->force_start
)
6541 /* Point must be on the line that we have info recorded about. */
6542 && PT
>= CHARPOS (tlbufpos
)
6543 && PT
<= Z
- CHARPOS (tlendpos
)
6544 /* All text outside that line, including its final newline,
6545 must be unchanged */
6546 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
6547 CHARPOS (tlendpos
)))
6549 if (CHARPOS (tlbufpos
) > BEGV
6550 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
6551 && (CHARPOS (tlbufpos
) == ZV
6552 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
6553 /* Former continuation line has disappeared by becoming empty */
6555 else if (XFASTINT (w
->last_modified
) < MODIFF
6556 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
6557 || MINI_WINDOW_P (w
))
6559 /* We have to handle the case of continuation around a
6560 wide-column character (See the comment in indent.c around
6563 For instance, in the following case:
6565 -------- Insert --------
6566 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
6567 J_I_ ==> J_I_ `^^' are cursors.
6571 As we have to redraw the line above, we should goto cancel. */
6574 int line_height_before
= this_line_pixel_height
;
6576 /* Note that start_display will handle the case that the
6577 line starting at tlbufpos is a continuation lines. */
6578 start_display (&it
, w
, tlbufpos
);
6580 /* Implementation note: It this still necessary? */
6581 if (it
.current_x
!= this_line_start_x
)
6584 TRACE ((stderr
, "trying display optimization 1\n"));
6585 w
->cursor
.vpos
= -1;
6586 overlay_arrow_seen
= 0;
6587 it
.vpos
= this_line_vpos
;
6588 it
.current_y
= this_line_y
;
6589 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
6592 /* If line contains point, is not continued,
6593 and ends at same distance from eob as before, we win */
6594 if (w
->cursor
.vpos
>= 0
6595 /* Line is not continued, otherwise this_line_start_pos
6596 would have been set to 0 in display_line. */
6597 && CHARPOS (this_line_start_pos
)
6598 /* Line ends as before. */
6599 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
6600 /* Line has same height as before. Otherwise other lines
6601 would have to be shifted up or down. */
6602 && this_line_pixel_height
== line_height_before
)
6604 /* If this is not the window's last line, we must adjust
6605 the charstarts of the lines below. */
6606 if (it
.current_y
< it
.last_visible_y
)
6608 struct glyph_row
*row
6609 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
6610 int delta
, delta_bytes
;
6612 if (Z
- CHARPOS (tlendpos
) == ZV
)
6614 /* This line ends at end of (accessible part of)
6615 buffer. There is no newline to count. */
6617 - CHARPOS (tlendpos
)
6618 - MATRIX_ROW_START_CHARPOS (row
));
6619 delta_bytes
= (Z_BYTE
6620 - BYTEPOS (tlendpos
)
6621 - MATRIX_ROW_START_BYTEPOS (row
));
6625 /* This line ends in a newline. Must take
6626 account of the newline and the rest of the
6627 text that follows. */
6629 - CHARPOS (tlendpos
)
6630 - MATRIX_ROW_START_CHARPOS (row
));
6631 delta_bytes
= (Z_BYTE
6632 - BYTEPOS (tlendpos
)
6633 - MATRIX_ROW_START_BYTEPOS (row
));
6636 increment_glyph_matrix_buffer_positions (w
->current_matrix
,
6638 w
->current_matrix
->nrows
,
6639 delta
, delta_bytes
);
6642 /* If this row displays text now but previously didn't,
6643 or vice versa, w->window_end_vpos may have to be
6645 if ((it
.glyph_row
- 1)->displays_text_p
)
6647 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
6648 XSETINT (w
->window_end_vpos
, this_line_vpos
);
6650 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
6651 && this_line_vpos
> 0)
6652 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
6653 w
->window_end_valid
= Qnil
;
6655 /* Update hint: No need to try to scroll in update_window. */
6656 w
->desired_matrix
->no_scrolling_p
= 1;
6659 *w
->desired_matrix
->method
= 0;
6660 debug_method_add (w
, "optimization 1");
6667 else if (/* Cursor position hasn't changed. */
6668 PT
== XFASTINT (w
->last_point
)
6669 /* Make sure the cursor was last displayed
6670 in this window. Otherwise we have to reposition it. */
6671 && 0 <= w
->cursor
.vpos
6672 && XINT (w
->height
) > w
->cursor
.vpos
)
6676 do_pending_window_change ();
6678 /* We used to always goto end_of_redisplay here, but this
6679 isn't enough if we have a blinking cursor. */
6680 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
6681 goto end_of_redisplay
;
6685 /* If highlighting the region, or if the cursor is in the echo area,
6686 then we can't just move the cursor. */
6687 else if (! (!NILP (Vtransient_mark_mode
)
6688 && !NILP (current_buffer
->mark_active
))
6689 && (w
== XWINDOW (current_buffer
->last_selected_window
)
6690 || highlight_nonselected_windows
)
6691 && NILP (w
->region_showing
)
6692 && !cursor_in_echo_area
)
6695 struct glyph_row
*row
;
6697 /* Skip from tlbufpos to PT and see where it is. Note that
6698 PT may be in invisible text. If so, we will end at the
6699 next visible position. */
6700 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
6701 NULL
, DEFAULT_FACE_ID
);
6702 it
.current_x
= this_line_start_x
;
6703 it
.current_y
= this_line_y
;
6704 it
.vpos
= this_line_vpos
;
6706 /* The call to move_it_to stops in front of PT, but
6707 moves over before-strings. */
6708 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
6710 if (it
.vpos
== this_line_vpos
6711 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
6714 xassert (this_line_vpos
== it
.vpos
);
6715 xassert (this_line_y
== it
.current_y
);
6716 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
6724 /* Text changed drastically or point moved off of line. */
6725 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
6728 CHARPOS (this_line_start_pos
) = 0;
6729 consider_all_windows_p
|= buffer_shared
> 1;
6730 ++clear_face_cache_count
;
6733 /* Build desired matrices. If consider_all_windows_p is non-zero,
6734 do it for all windows on all frames. Otherwise do it for
6735 selected_window, only. */
6737 if (consider_all_windows_p
)
6739 Lisp_Object tail
, frame
;
6741 /* Clear the face cache eventually. */
6742 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
6744 clear_face_cache (0);
6745 clear_face_cache_count
= 0;
6748 /* Recompute # windows showing selected buffer. This will be
6749 incremented each time such a window is displayed. */
6752 FOR_EACH_FRAME (tail
, frame
)
6754 struct frame
*f
= XFRAME (frame
);
6755 if (FRAME_WINDOW_P (f
) || f
== selected_frame
)
6757 /* Mark all the scroll bars to be removed; we'll redeem
6758 the ones we want when we redisplay their windows. */
6759 if (condemn_scroll_bars_hook
)
6760 (*condemn_scroll_bars_hook
) (f
);
6762 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
6763 redisplay_windows (FRAME_ROOT_WINDOW (f
));
6765 /* Any scroll bars which redisplay_windows should have
6766 nuked should now go away. */
6767 if (judge_scroll_bars_hook
)
6768 (*judge_scroll_bars_hook
) (f
);
6772 else if (FRAME_VISIBLE_P (selected_frame
)
6773 && !FRAME_OBSCURED_P (selected_frame
))
6774 redisplay_window (selected_window
, 1);
6777 /* Compare desired and current matrices, perform output. */
6781 /* If fonts changed, display again. */
6782 if (fonts_changed_p
)
6785 /* Prevent various kinds of signals during display update.
6786 stdio is not robust about handling signals,
6787 which can cause an apparent I/O error. */
6788 if (interrupt_input
)
6792 if (consider_all_windows_p
)
6798 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
6802 if (!FRAMEP (XCONS (tail
)->car
))
6805 f
= XFRAME (XCONS (tail
)->car
);
6807 if ((FRAME_WINDOW_P (f
) || f
== selected_frame
)
6808 && FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
6810 /* Mark all windows as to be updated. */
6811 set_window_update_flags (XWINDOW (f
->root_window
), 1);
6812 pause
|= update_frame (f
, 0, 0);
6815 if (hscroll_windows (f
->root_window
))
6818 mark_window_display_accurate (f
->root_window
, 1);
6819 if (frame_up_to_date_hook
!= 0)
6820 (*frame_up_to_date_hook
) (f
);
6827 if (FRAME_VISIBLE_P (selected_frame
)
6828 && !FRAME_OBSCURED_P (selected_frame
))
6830 XWINDOW (selected_window
)->must_be_updated_p
= 1;
6831 pause
= update_frame (selected_frame
, 0, 0);
6832 if (!pause
&& hscroll_windows (selected_window
))
6838 /* We may have called echo_area_display at the top of this
6839 function. If the echo area is on another frame, that may
6840 have put text on a frame other than the selected one, so the
6841 above call to update_frame would not have caught it. Catch
6844 Lisp_Object mini_window
;
6845 struct frame
*mini_frame
;
6847 mini_window
= FRAME_MINIBUF_WINDOW (selected_frame
);
6848 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6850 if (mini_frame
!= selected_frame
&& FRAME_WINDOW_P (mini_frame
))
6852 XWINDOW (mini_window
)->must_be_updated_p
= 1;
6853 pause
|= update_frame (mini_frame
, 0, 0);
6854 if (!pause
&& hscroll_windows (mini_window
))
6860 /* If display was paused because of pending input, make sure we do a
6861 thorough update the next time. */
6864 /* Prevent the optimization at the beginning of
6865 redisplay_internal that tries a single-line update of the
6866 line containing the cursor in the selected window. */
6867 CHARPOS (this_line_start_pos
) = 0;
6869 /* Let the overlay arrow be updated the next time. */
6870 if (!NILP (last_arrow_position
))
6872 last_arrow_position
= Qt
;
6873 last_arrow_string
= Qt
;
6876 /* If we pause after scrolling, some rows in the current
6877 matrices of some windows are not valid. */
6878 if (!WINDOW_FULL_WIDTH_P (w
)
6879 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
6880 update_mode_lines
= 1;
6883 /* Now text on frame agrees with windows, so put info into the
6884 windows for partial redisplay to follow. */
6887 register struct buffer
*b
= XBUFFER (w
->buffer
);
6889 unchanged_modified
= BUF_MODIFF (b
);
6890 overlay_unchanged_modified
= BUF_OVERLAY_MODIFF (b
);
6891 beg_unchanged
= BUF_GPT (b
) - BUF_BEG (b
);
6892 end_unchanged
= BUF_Z (b
) - BUF_GPT (b
);
6894 if (consider_all_windows_p
)
6895 mark_window_display_accurate (FRAME_ROOT_WINDOW (selected_frame
), 1);
6898 XSETFASTINT (w
->last_point
, BUF_PT (b
));
6899 w
->last_cursor
= w
->cursor
;
6900 w
->last_cursor_off_p
= w
->cursor_off_p
;
6902 b
->clip_changed
= 0;
6903 w
->update_mode_line
= Qnil
;
6904 XSETFASTINT (w
->last_modified
, BUF_MODIFF (b
));
6905 XSETFASTINT (w
->last_overlay_modified
, BUF_OVERLAY_MODIFF (b
));
6907 = (BUF_MODIFF (XBUFFER (w
->buffer
)) > BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
6910 /* Record if we are showing a region, so can make sure to
6911 update it fully at next redisplay. */
6912 w
->region_showing
= (!NILP (Vtransient_mark_mode
)
6913 && (w
== XWINDOW (current_buffer
->last_selected_window
)
6914 || highlight_nonselected_windows
)
6915 && !NILP (XBUFFER (w
->buffer
)->mark_active
)
6916 ? Fmarker_position (XBUFFER (w
->buffer
)->mark
)
6919 w
->window_end_valid
= w
->buffer
;
6920 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
6921 last_arrow_string
= Voverlay_arrow_string
;
6922 if (frame_up_to_date_hook
!= 0)
6923 (*frame_up_to_date_hook
) (selected_frame
);
6926 update_mode_lines
= 0;
6927 windows_or_buffers_changed
= 0;
6930 /* Start SIGIO interrupts coming again. Having them off during the
6931 code above makes it less likely one will discard output, but not
6932 impossible, since there might be stuff in the system buffer here.
6933 But it is much hairier to try to do anything about that. */
6934 if (interrupt_input
)
6938 /* If a frame has become visible which was not before, redisplay
6939 again, so that we display it. Expose events for such a frame
6940 (which it gets when becoming visible) don't call the parts of
6941 redisplay constructing glyphs, so simply exposing a frame won't
6942 display anything in this case. So, we have to display these
6943 frames here explicitly. */
6946 Lisp_Object tail
, frame
;
6949 FOR_EACH_FRAME (tail
, frame
)
6951 int this_is_visible
= 0;
6953 if (XFRAME (frame
)->visible
)
6954 this_is_visible
= 1;
6955 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
6956 if (XFRAME (frame
)->visible
)
6957 this_is_visible
= 1;
6959 if (this_is_visible
)
6963 if (new_count
!= number_of_visible_frames
)
6964 windows_or_buffers_changed
++;
6967 /* Change frame size now if a change is pending. */
6968 do_pending_window_change ();
6970 /* If we just did a pending size change, or have additional
6971 visible frames, redisplay again. */
6972 if (windows_or_buffers_changed
&& !pause
)
6977 if (--redisplaying_p
< 0)
6982 /* Redisplay, but leave alone any recent echo area message unless
6983 another message has been requested in its place.
6985 This is useful in situations where you need to redisplay but no
6986 user action has occurred, making it inappropriate for the message
6987 area to be cleared. See tracking_off and
6988 wait_reading_process_input for examples of these situations. */
6991 redisplay_preserve_echo_area ()
6993 if (!echo_area_glyphs
6994 && !STRINGP (echo_area_message
)
6995 && (previous_echo_glyphs
6996 || STRINGP (previous_echo_area_message
)))
6998 echo_area_glyphs
= previous_echo_glyphs
;
6999 echo_area_message
= previous_echo_area_message
;
7000 echo_area_glyphs_length
= previous_echo_glyphs_length
;
7001 redisplay_internal (1);
7002 echo_area_glyphs
= NULL
;
7003 echo_area_message
= Qnil
;
7006 redisplay_internal (1);
7010 /* Mark the display of windows in the window tree rooted at WINDOW as
7011 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
7012 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
7013 the next time redisplay_internal is called. */
7016 mark_window_display_accurate (window
, accurate_p
)
7022 for (; !NILP (window
); window
= w
->next
)
7024 w
= XWINDOW (window
);
7026 if (BUFFERP (w
->buffer
))
7028 struct buffer
*b
= XBUFFER (w
->buffer
);
7030 XSETFASTINT (w
->last_modified
,
7031 accurate_p
? BUF_MODIFF (b
) : 0);
7032 XSETFASTINT (w
->last_overlay_modified
,
7033 accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
7034 w
->last_had_star
= (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
)
7037 #if 0 /* I don't think this is necessary because display_line does it.
7039 /* Record if we are showing a region, so can make sure to
7040 update it fully at next redisplay. */
7042 = (!NILP (Vtransient_mark_mode
)
7043 && (w
== XWINDOW (current_buffer
->last_selected_window
)
7044 || highlight_nonselected_windows
)
7045 && (!NILP (b
->mark_active
)
7046 ? Fmarker_position (b
->mark
)
7052 b
->clip_changed
= 0;
7053 w
->last_cursor
= w
->cursor
;
7054 w
->last_cursor_off_p
= w
->cursor_off_p
;
7055 if (w
== XWINDOW (selected_window
))
7056 w
->last_point
= BUF_PT (b
);
7058 w
->last_point
= XMARKER (w
->pointm
)->charpos
;
7062 w
->window_end_valid
= w
->buffer
;
7063 w
->update_mode_line
= Qnil
;
7065 if (!NILP (w
->vchild
))
7066 mark_window_display_accurate (w
->vchild
, accurate_p
);
7067 if (!NILP (w
->hchild
))
7068 mark_window_display_accurate (w
->hchild
, accurate_p
);
7073 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
7074 last_arrow_string
= Voverlay_arrow_string
;
7078 /* Force a thorough redisplay the next time by setting
7079 last_arrow_position and last_arrow_string to t, which is
7080 unequal to any useful value of Voverlay_arrow_... */
7081 last_arrow_position
= Qt
;
7082 last_arrow_string
= Qt
;
7087 /* Return value in display table DP (Lisp_Char_Table *) for character
7088 C. Since a display table doesn't have any parent, we don't have to
7089 follow parent. Do not call this function directly but use the
7090 macro DISP_CHAR_VECTOR. */
7093 disp_char_vector (dp
, c
)
7094 struct Lisp_Char_Table
*dp
;
7100 if (SINGLE_BYTE_CHAR_P (c
))
7101 return (dp
->contents
[c
]);
7103 SPLIT_NON_ASCII_CHAR (c
, code
[0], code
[1], code
[2]);
7104 if (code
[0] != CHARSET_COMPOSITION
)
7108 else if (code
[2] < 32)
7112 /* Here, the possible range of code[0] (== charset ID) is
7113 128..max_charset. Since the top level char table contains data
7114 for multibyte characters after 256th element, we must increment
7115 code[0] by 128 to get a correct index. */
7117 code
[3] = -1; /* anchor */
7119 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
7121 val
= dp
->contents
[code
[i
]];
7122 if (!SUB_CHAR_TABLE_P (val
))
7123 return (NILP (val
) ? dp
->defalt
: val
);
7126 /* Here, val is a sub char table. We return the default value of
7128 return (dp
->defalt
);
7133 /***********************************************************************
7135 ***********************************************************************/
7137 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
7140 redisplay_windows (window
)
7143 while (!NILP (window
))
7145 struct window
*w
= XWINDOW (window
);
7147 if (!NILP (w
->hchild
))
7148 redisplay_windows (w
->hchild
);
7149 else if (!NILP (w
->vchild
))
7150 redisplay_windows (w
->vchild
);
7152 redisplay_window (window
, 0);
7159 /* Set cursor position of W. PT is assumed to be displayed in ROW.
7160 DELTA is the number of bytes by which positions recorded in ROW
7161 differ from current buffer positions. */
7164 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
7166 struct glyph_row
*row
;
7167 struct glyph_matrix
*matrix
;
7168 int delta
, delta_bytes
, dy
, dvpos
;
7170 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
7171 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
7173 int pt_old
= PT
- delta
;
7175 /* Skip over glyphs not having an object at the start of the row.
7176 These are special glyphs like truncation marks on terminal
7178 if (row
->displays_text_p
)
7181 && glyph
->charpos
< 0)
7183 x
+= glyph
->pixel_width
;
7189 && (!BUFFERP (glyph
->object
)
7190 || glyph
->charpos
< pt_old
))
7192 x
+= glyph
->pixel_width
;
7196 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7198 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
7199 w
->cursor
.y
= row
->y
+ dy
;
7201 if (w
== XWINDOW (selected_window
))
7203 if (!row
->continued_p
7204 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
7207 this_line_buffer
= XBUFFER (w
->buffer
);
7209 CHARPOS (this_line_start_pos
)
7210 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
7211 BYTEPOS (this_line_start_pos
)
7212 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
7214 CHARPOS (this_line_end_pos
)
7215 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
7216 BYTEPOS (this_line_end_pos
)
7217 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
7219 this_line_y
= w
->cursor
.y
;
7220 this_line_pixel_height
= row
->height
;
7221 this_line_vpos
= w
->cursor
.vpos
;
7222 this_line_start_x
= row
->x
;
7225 CHARPOS (this_line_start_pos
) = 0;
7230 /* Run window scroll functions, if any, for WINDOW with new window
7231 start STARTP. Sets the window start of WINDOW to that position. */
7233 static INLINE
struct text_pos
7234 run_window_scroll_functions (window
, startp
)
7236 struct text_pos startp
;
7238 struct window
*w
= XWINDOW (window
);
7239 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
7241 if (!NILP (Vwindow_scroll_functions
))
7243 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
7244 make_number (CHARPOS (startp
)));
7245 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
7252 /* Modify the desired matrix of window W and W->vscroll so that the
7253 line containing the cursor is fully visible. */
7256 make_cursor_line_fully_visible (w
)
7259 struct glyph_matrix
*matrix
;
7260 struct glyph_row
*row
;
7261 int top_line_height
;
7263 /* It's not always possible to find the cursor, e.g, when a window
7264 is full of overlay strings. Don't do anything in that case. */
7265 if (w
->cursor
.vpos
< 0)
7268 matrix
= w
->desired_matrix
;
7269 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
7271 /* If row->y == top y of window display area, the window isn't tall
7272 enough to display a single line. There is nothing we can do
7274 top_line_height
= WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
);
7275 if (row
->y
== top_line_height
)
7278 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
7280 int dy
= row
->height
- row
->visible_height
;
7283 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
7285 else if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w
, row
))
7287 int dy
= - (row
->height
- row
->visible_height
);
7290 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
7293 /* When we change the cursor y-position of the selected window,
7294 change this_line_y as well so that the display optimization for
7295 the cursor line of the selected window in redisplay_internal uses
7296 the correct y-position. */
7297 if (w
== XWINDOW (selected_window
))
7298 this_line_y
= w
->cursor
.y
;
7302 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
7303 non-zero means only WINDOW is redisplayed in redisplay_internal.
7304 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
7305 in redisplay_window to bring a partially visible line into view in
7306 the case that only the cursor has moved.
7310 1 if scrolling succeeded
7312 0 if scrolling didn't find point.
7314 -1 if new fonts have been loaded so that we must interrupt
7315 redisplay, adjust glyph matrices, and try again. */
7318 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
7319 scroll_step
, temp_scroll_step
)
7321 int just_this_one_p
;
7322 int scroll_conservatively
, scroll_step
;
7323 int temp_scroll_step
;
7325 struct window
*w
= XWINDOW (window
);
7326 struct frame
*f
= XFRAME (w
->frame
);
7327 struct text_pos scroll_margin_pos
;
7328 struct text_pos pos
;
7329 struct text_pos startp
;
7331 Lisp_Object window_end
;
7332 int this_scroll_margin
;
7335 int line_height
, rc
;
7336 int amount_to_scroll
= 0;
7337 Lisp_Object aggressive
;
7341 debug_method_add (w
, "try_scrolling");
7344 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
7346 /* Compute scroll margin height in pixels. We scroll when point is
7347 within this distance from the top or bottom of the window. */
7348 if (scroll_margin
> 0)
7350 this_scroll_margin
= min (scroll_margin
, XINT (w
->height
) / 4);
7351 this_scroll_margin
*= CANON_Y_UNIT (f
);
7354 this_scroll_margin
= 0;
7356 /* Compute how much we should try to scroll maximally to bring point
7359 scroll_max
= scroll_step
;
7360 else if (scroll_conservatively
)
7361 scroll_max
= scroll_conservatively
;
7362 else if (temp_scroll_step
)
7363 scroll_max
= temp_scroll_step
;
7364 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
7365 || NUMBERP (current_buffer
->scroll_up_aggressively
))
7366 /* We're trying to scroll because of aggressive scrolling
7367 but no scroll_step is set. Choose an arbitrary one. Maybe
7368 there should be a variable for this. */
7372 scroll_max
*= CANON_Y_UNIT (f
);
7374 /* Decide whether we have to scroll down. Start at the window end
7375 and move this_scroll_margin up to find the position of the scroll
7377 window_end
= Fwindow_end (window
, Qt
);
7378 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
7379 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
7380 if (this_scroll_margin
)
7382 start_display (&it
, w
, scroll_margin_pos
);
7383 move_it_vertically (&it
, - this_scroll_margin
);
7384 scroll_margin_pos
= it
.current
.pos
;
7387 if (PT
>= CHARPOS (scroll_margin_pos
))
7391 /* Point is in the scroll margin at the bottom of the window, or
7392 below. Compute a new window start that makes point visible. */
7394 /* Compute the distance from the scroll margin to PT.
7395 Give up if the distance is greater than scroll_max. */
7396 start_display (&it
, w
, scroll_margin_pos
);
7398 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
7399 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
7400 line_height
= (it
.max_ascent
+ it
.max_descent
7401 ? it
.max_ascent
+ it
.max_descent
7403 dy
= it
.current_y
+ line_height
- y0
;
7404 if (dy
> scroll_max
)
7407 /* Move the window start down. If scrolling conservatively,
7408 move it just enough down to make point visible. If
7409 scroll_step is set, move it down by scroll_step. */
7410 start_display (&it
, w
, startp
);
7412 if (scroll_conservatively
)
7413 amount_to_scroll
= dy
;
7414 else if (scroll_step
|| temp_scroll_step
)
7415 amount_to_scroll
= scroll_max
;
7418 aggressive
= current_buffer
->scroll_down_aggressively
;
7419 height
= (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w
)
7420 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
));
7421 if (NUMBERP (aggressive
))
7422 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
7425 if (amount_to_scroll
<= 0)
7428 move_it_vertically (&it
, amount_to_scroll
);
7429 startp
= it
.current
.pos
;
7433 /* See if point is inside the scroll margin at the top of the
7435 scroll_margin_pos
= startp
;
7436 if (this_scroll_margin
)
7438 start_display (&it
, w
, startp
);
7439 move_it_vertically (&it
, this_scroll_margin
);
7440 scroll_margin_pos
= it
.current
.pos
;
7443 if (PT
< CHARPOS (scroll_margin_pos
))
7445 /* Point is in the scroll margin at the top of the window or
7446 above what is displayed in the window. */
7449 /* Compute the vertical distance from PT to the scroll
7450 margin position. Give up if distance is greater than
7452 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
7453 start_display (&it
, w
, pos
);
7455 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
7456 it
.last_visible_y
, -1,
7457 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
7458 dy
= it
.current_y
- y0
;
7459 if (dy
> scroll_max
)
7462 /* Compute new window start. */
7463 start_display (&it
, w
, startp
);
7465 if (scroll_conservatively
)
7466 amount_to_scroll
= dy
;
7467 else if (scroll_step
|| temp_scroll_step
)
7468 amount_to_scroll
= scroll_max
;
7471 aggressive
= current_buffer
->scroll_up_aggressively
;
7472 height
= (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w
)
7473 - WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
));
7474 if (NUMBERP (aggressive
))
7475 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
7478 if (amount_to_scroll
<= 0)
7481 move_it_vertically (&it
, - amount_to_scroll
);
7482 startp
= it
.current
.pos
;
7486 /* Run window scroll functions. */
7487 startp
= run_window_scroll_functions (window
, startp
);
7489 /* Display the window. Give up if new fonts are loaded, or if point
7491 if (!try_window (window
, startp
))
7493 else if (w
->cursor
.vpos
< 0)
7495 clear_glyph_matrix (w
->desired_matrix
);
7500 /* Maybe forget recorded base line for line number display. */
7501 if (!just_this_one_p
7502 || current_buffer
->clip_changed
7503 || beg_unchanged
< CHARPOS (startp
))
7504 w
->base_line_number
= Qnil
;
7506 /* If cursor ends up on a partially visible line, shift display
7507 lines up or down. */
7508 make_cursor_line_fully_visible (w
);
7516 /* Compute a suitable window start for window W if display of W starts
7517 on a continuation line. Value is non-zero if a new window start
7520 The new window start will be computed, based on W's width, starting
7521 from the start of the continued line. It is the start of the
7522 screen line with the minimum distance from the old start W->start. */
7525 compute_window_start_on_continuation_line (w
)
7528 struct text_pos pos
, start_pos
;
7529 int window_start_changed_p
= 0;
7531 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
7533 /* If window start is on a continuation line... Window start may be
7534 < BEGV in case there's invisible text at the start of the
7535 buffer (M-x rmail, for example). */
7536 if (CHARPOS (start_pos
) > BEGV
7537 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
7540 struct glyph_row
*row
;
7542 /* Find the start of the continued line. This should be fast
7543 because scan_buffer is fast (newline cache). */
7544 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_TOP_LINE_P (w
) ? 1 : 0);
7545 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
7546 row
, DEFAULT_FACE_ID
);
7547 reseat_at_previous_visible_line_start (&it
);
7549 /* If the line start is "too far" away from the window start,
7550 say it takes too much time to compute a new window start. */
7551 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
7552 < XFASTINT (w
->height
) * XFASTINT (w
->width
))
7554 int min_distance
, distance
;
7556 /* Move forward by display lines to find the new window
7557 start. If window width was enlarged, the new start can
7558 be expected to be > the old start. If window width was
7559 decreased, the new window start will be < the old start.
7560 So, we're looking for the display line start with the
7561 minimum distance from the old window start. */
7562 pos
= it
.current
.pos
;
7563 min_distance
= INFINITY
;
7564 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
7565 distance
< min_distance
)
7567 min_distance
= distance
;
7568 pos
= it
.current
.pos
;
7569 move_it_by_lines (&it
, 1, 0);
7572 /* Set the window start there. */
7573 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
7574 window_start_changed_p
= 1;
7578 return window_start_changed_p
;
7582 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
7583 selected_window is redisplayed. */
7586 redisplay_window (window
, just_this_one_p
)
7588 int just_this_one_p
;
7590 struct window
*w
= XWINDOW (window
);
7591 struct frame
*f
= XFRAME (w
->frame
);
7592 struct buffer
*buffer
= XBUFFER (w
->buffer
);
7593 struct buffer
*old
= current_buffer
;
7594 struct text_pos lpoint
, opoint
, startp
;
7595 int update_mode_line
;
7598 /* Record it now because it's overwritten. */
7599 int current_matrix_up_to_date_p
= 0;
7600 int really_switched_buffer
= 0;
7601 int temp_scroll_step
= 0;
7602 int count
= specpdl_ptr
- specpdl
;
7604 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
7607 /* W must be a leaf window here. */
7608 xassert (!NILP (w
->buffer
));
7610 *w
->desired_matrix
->method
= 0;
7613 specbind (Qinhibit_point_motion_hooks
, Qt
);
7615 /* Has the mode line to be updated? */
7616 update_mode_line
= (!NILP (w
->update_mode_line
)
7617 || update_mode_lines
7618 || buffer
->clip_changed
);
7620 if (MINI_WINDOW_P (w
))
7622 if (w
== XWINDOW (echo_area_window
)
7623 && (echo_area_glyphs
7624 || STRINGP (echo_area_message
)))
7626 if (update_mode_line
)
7627 /* We may have to update a tty frame's menu bar or a
7628 toolbar. Example `M-x C-h C-h C-g'. */
7629 goto finish_menu_bars
;
7631 /* We've already displayed the echo area glyphs in this window. */
7632 goto finish_scroll_bars
;
7634 else if (w
!= XWINDOW (minibuf_window
))
7636 /* W is a mini-buffer window, but it's not the currently
7637 active one, so clear it. */
7638 int yb
= window_text_bottom_y (w
);
7639 struct glyph_row
*row
;
7642 for (y
= 0, row
= w
->desired_matrix
->rows
;
7644 y
+= row
->height
, ++row
)
7645 blank_row (w
, row
, y
);
7646 goto finish_scroll_bars
;
7650 /* Otherwise set up data on this window; select its buffer and point
7652 if (update_mode_line
)
7654 /* Really select the buffer, for the sake of buffer-local
7656 set_buffer_internal_1 (XBUFFER (w
->buffer
));
7657 really_switched_buffer
= 1;
7660 set_buffer_temp (XBUFFER (w
->buffer
));
7661 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
7663 current_matrix_up_to_date_p
7664 = (!NILP (w
->window_end_valid
)
7665 && !current_buffer
->clip_changed
7666 && XFASTINT (w
->last_modified
) >= MODIFF
7667 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
7669 /* When windows_or_buffers_changed is non-zero, we can't rely on
7670 the window end being valid, so set it to nil there. */
7671 if (windows_or_buffers_changed
)
7673 /* If window starts on a continuation line, maybe adjust the
7674 window start in case the window's width changed. */
7675 if (XMARKER (w
->start
)->buffer
== current_buffer
)
7676 compute_window_start_on_continuation_line (w
);
7678 w
->window_end_valid
= Qnil
;
7681 /* Some sanity checks. */
7682 CHECK_WINDOW_END (w
);
7683 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
7685 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
7688 /* If %c is in mode line, update it if needed. */
7689 if (!NILP (w
->column_number_displayed
)
7690 /* This alternative quickly identifies a common case
7691 where no change is needed. */
7692 && !(PT
== XFASTINT (w
->last_point
)
7693 && XFASTINT (w
->last_modified
) >= MODIFF
7694 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
7695 && XFASTINT (w
->column_number_displayed
) != current_column ())
7696 update_mode_line
= 1;
7698 /* Count number of windows showing the selected buffer. An indirect
7699 buffer counts as its base buffer. */
7700 if (!just_this_one_p
)
7702 struct buffer
*current_base
, *window_base
;
7703 current_base
= current_buffer
;
7704 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
7705 if (current_base
->base_buffer
)
7706 current_base
= current_base
->base_buffer
;
7707 if (window_base
->base_buffer
)
7708 window_base
= window_base
->base_buffer
;
7709 if (current_base
== window_base
)
7713 /* Point refers normally to the selected window. For any other
7714 window, set up appropriate value. */
7715 if (!EQ (window
, selected_window
))
7717 int new_pt
= XMARKER (w
->pointm
)->charpos
;
7718 int new_pt_byte
= marker_byte_position (w
->pointm
);
7722 new_pt_byte
= BEGV_BYTE
;
7723 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
7725 else if (new_pt
> (ZV
- 1))
7728 new_pt_byte
= ZV_BYTE
;
7729 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
7732 /* We don't use SET_PT so that the point-motion hooks don't run. */
7733 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
7736 /* If any of the character widths specified in the display table
7737 have changed, invalidate the width run cache. It's true that
7738 this may be a bit late to catch such changes, but the rest of
7739 redisplay goes (non-fatally) haywire when the display table is
7740 changed, so why should we worry about doing any better? */
7741 if (current_buffer
->width_run_cache
)
7743 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
7745 if (! disptab_matches_widthtab (disptab
,
7746 XVECTOR (current_buffer
->width_table
)))
7748 invalidate_region_cache (current_buffer
,
7749 current_buffer
->width_run_cache
,
7751 recompute_width_table (current_buffer
, disptab
);
7755 /* If window-start is screwed up, choose a new one. */
7756 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
7759 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
7761 /* If someone specified a new starting point but did not insist,
7762 check whether it can be used. */
7763 if (!NILP (w
->optional_new_start
))
7765 w
->optional_new_start
= Qnil
;
7766 /* This takes a mini-buffer prompt into account. */
7767 start_display (&it
, w
, startp
);
7768 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
7769 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
7770 if (IT_CHARPOS (it
) == PT
)
7771 w
->force_start
= Qt
;
7774 /* Handle case where place to start displaying has been specified,
7775 unless the specified location is outside the accessible range. */
7776 if (!NILP (w
->force_start
))
7778 w
->force_start
= Qnil
;
7780 w
->window_end_valid
= Qnil
;
7782 /* Forget any recorded base line for line number display. */
7783 if (!current_matrix_up_to_date_p
7784 || current_buffer
->clip_changed
)
7785 w
->base_line_number
= Qnil
;
7787 /* Redisplay the mode line. Select the buffer properly for that.
7788 Also, run the hook window-scroll-functions
7789 because we have scrolled. */
7790 /* Note, we do this after clearing force_start because
7791 if there's an error, it is better to forget about force_start
7792 than to get into an infinite loop calling the hook functions
7793 and having them get more errors. */
7794 if (!update_mode_line
7795 || ! NILP (Vwindow_scroll_functions
))
7797 if (!really_switched_buffer
)
7799 set_buffer_temp (old
);
7800 set_buffer_internal_1 (XBUFFER (w
->buffer
));
7801 really_switched_buffer
= 1;
7804 update_mode_line
= 1;
7805 w
->update_mode_line
= Qt
;
7806 startp
= run_window_scroll_functions (window
, startp
);
7809 XSETFASTINT (w
->last_modified
, 0);
7810 XSETFASTINT (w
->last_overlay_modified
, 0);
7811 if (CHARPOS (startp
) < BEGV
)
7812 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
7813 else if (CHARPOS (startp
) > ZV
)
7814 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
7816 /* Redisplay, then check if cursor has been set during the
7817 redisplay. Give up if new fonts were loaded. */
7818 if (!try_window (window
, startp
))
7820 w
->force_start
= Qt
;
7821 clear_glyph_matrix (w
->desired_matrix
);
7822 goto restore_buffers
;
7825 if (w
->cursor
.vpos
< 0)
7827 /* If point does not appear, or on a line that is not fully
7828 visible, move point so it does appear. The desired
7829 matrix has been built above, so we can use it. */
7830 int height
= window_box_height (w
) / 2;
7831 struct glyph_row
*row
= MATRIX_ROW (w
->desired_matrix
, 0);
7833 while (row
->y
< height
)
7836 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
7837 MATRIX_ROW_START_BYTEPOS (row
));
7839 if (w
!= XWINDOW (selected_window
))
7840 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
7841 else if (current_buffer
== old
)
7842 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
7844 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
7846 /* If we are highlighting the region, then we just changed
7847 the region, so redisplay to show it. */
7848 if (!NILP (Vtransient_mark_mode
)
7849 && !NILP (current_buffer
->mark_active
))
7851 clear_glyph_matrix (w
->desired_matrix
);
7852 if (!try_window (window
, startp
))
7853 goto restore_buffers
;
7857 make_cursor_line_fully_visible (w
);
7859 debug_method_add (w
, "forced window start");
7864 /* Handle case where text has not changed, only point, and it has
7865 not moved off the frame. */
7866 if (current_matrix_up_to_date_p
7867 /* Point may be in this window. */
7868 && PT
>= CHARPOS (startp
)
7869 /* If we don't check this, we are called to move the cursor in a
7870 horizontally split window with a current matrix that doesn't
7872 && !windows_or_buffers_changed
7873 /* Selective display hasn't changed. */
7874 && !current_buffer
->clip_changed
7875 /* If force-mode-line-update was called, really redisplay;
7876 that's how redisplay is forced after e.g. changing
7877 buffer-invisibility-spec. */
7878 && NILP (w
->update_mode_line
)
7879 /* Can't use this case if highlighting a region. When a
7880 region exists, cursor movement has to do more than just
7882 && !(!NILP (Vtransient_mark_mode
)
7883 && !NILP (current_buffer
->mark_active
))
7884 && NILP (w
->region_showing
)
7885 /* Right after splitting windows, last_point may be nil. */
7886 && INTEGERP (w
->last_point
)
7887 /* This code is not used for mini-buffer for the sake of the case
7888 of redisplaying to replace an echo area message; since in
7889 that case the mini-buffer contents per se are usually
7890 unchanged. This code is of no real use in the mini-buffer
7891 since the handling of this_line_start_pos, etc., in redisplay
7892 handles the same cases. */
7893 && !EQ (window
, minibuf_window
)
7894 /* When splitting windows or for new windows, it happens that
7895 redisplay is called with a nil window_end_vpos or one being
7896 larger than the window. This should really be fixed in
7897 window.c. I don't have this on my list, now, so we do
7898 approximately the same as the old redisplay code. --gerd. */
7899 && INTEGERP (w
->window_end_vpos
)
7900 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
7901 && (FRAME_WINDOW_P (f
)
7902 || !MARKERP (Voverlay_arrow_position
)
7903 || current_buffer
!= XMARKER (Voverlay_arrow_position
)->buffer
))
7905 int this_scroll_margin
;
7906 struct glyph_row
*row
;
7910 debug_method_add (w
, "cursor movement");
7913 /* Scroll if point within this distance from the top or bottom
7914 of the window. This is a pixel value. */
7915 this_scroll_margin
= max (0, scroll_margin
);
7916 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
7917 this_scroll_margin
*= CANON_Y_UNIT (f
);
7919 /* Start with the row the cursor was displayed during the last
7920 not paused redisplay. Give up if that row is not valid. */
7921 if (w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
7923 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
7924 if (row
->mode_line_p
)
7926 if (!row
->enabled_p
)
7930 if (PT
> XFASTINT (w
->last_point
))
7932 /* Point has moved forward. */
7933 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
7935 while ((MATRIX_ROW_END_CHARPOS (row
) < PT
7936 /* The end position of a row equals the start
7937 position of the next row. If PT is there, we
7938 would rather display it in the next line, except
7939 when this line ends in ZV. */
7940 || (MATRIX_ROW_END_CHARPOS (row
) == PT
7941 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)
7942 || !row
->ends_at_zv_p
)))
7943 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
7945 xassert (row
->enabled_p
);
7949 /* If within the scroll margin, scroll. Note that
7950 MATRIX_ROW_BOTTOM_Y gives the pixel position at which the
7951 next line would be drawn, and that this_scroll_margin can
7953 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
7954 || PT
> MATRIX_ROW_END_CHARPOS (row
)
7955 /* Line is completely visible last line in window and PT
7956 is to be set in the next line. */
7957 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
7958 && PT
== MATRIX_ROW_END_CHARPOS (row
)
7959 && !row
->ends_at_zv_p
7960 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
7963 else if (PT
< XFASTINT (w
->last_point
))
7965 /* Cursor has to be moved backward. Note that PT >=
7966 CHARPOS (startp) because of the outer if-statement. */
7967 while (!row
->mode_line_p
7968 && (MATRIX_ROW_START_CHARPOS (row
) > PT
7969 || (MATRIX_ROW_START_CHARPOS (row
) == PT
7970 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
7971 && (row
->y
> this_scroll_margin
7972 || CHARPOS (startp
) == BEGV
))
7974 xassert (row
->enabled_p
);
7978 /* Consider the following case: Window starts at BEGV, there
7979 is invisible, intangible text at BEGV, so that display
7980 starts at some point START > BEGV. It can happen that
7981 we are called with PT somewhere between BEGV and START.
7982 Try to handle that case. */
7983 if (row
< w
->current_matrix
->rows
7984 || row
->mode_line_p
)
7986 row
= w
->current_matrix
->rows
;
7987 if (row
->mode_line_p
)
7991 /* Due to newlines in overlay strings, we may have to skip
7992 forward over overlay strings. */
7993 while (MATRIX_ROW_END_CHARPOS (row
) == PT
7994 && MATRIX_ROW_ENDS_IN_OVERLAY_STRING_P (row
)
7995 && !row
->ends_at_zv_p
)
7998 /* If within the scroll margin, scroll. */
7999 if (row
->y
< this_scroll_margin
8000 && CHARPOS (startp
) != BEGV
)
8004 /* if PT is not in the glyph row, give up. */
8005 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
8006 || PT
> MATRIX_ROW_END_CHARPOS (row
))
8009 /* If we end up in a partially visible line, let's make it fully
8010 visible. This can be done most easily by using the existing
8012 if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
8014 temp_scroll_step
= 1;
8020 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
8024 /* If current starting point was originally the beginning of a line
8025 but no longer is, find a new starting point. */
8026 else if (!NILP (w
->start_at_line_beg
)
8027 && !(CHARPOS (startp
) <= BEGV
8028 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
8031 debug_method_add (w
, "recenter 1");
8036 /* Try scrolling with try_window_id. */
8037 else if (!windows_or_buffers_changed
8038 /* Window must be either use window-based redisplay or
8040 && (FRAME_WINDOW_P (f
)
8041 || ((line_ins_del_ok
&& WINDOW_FULL_WIDTH_P (w
))
8042 && just_this_one_p
))
8043 && !MINI_WINDOW_P (w
)
8044 /* Point is not known NOT to appear in window. */
8045 && PT
>= CHARPOS (startp
)
8046 && XFASTINT (w
->last_modified
)
8047 /* Window is not hscrolled. */
8048 && XFASTINT (w
->hscroll
) == 0
8049 /* Selective display has not changed. */
8050 && !current_buffer
->clip_changed
8051 /* Current matrix is up to date. */
8052 && !NILP (w
->window_end_valid
)
8053 /* Can't use this case if highlighting a region because
8054 a cursor movement will do more than just set the cursor. */
8055 && !(!NILP (Vtransient_mark_mode
)
8056 && !NILP (current_buffer
->mark_active
))
8057 && NILP (w
->region_showing
)
8058 /* Overlay arrow position and string not changed. */
8059 && EQ (last_arrow_position
, COERCE_MARKER (Voverlay_arrow_position
))
8060 && EQ (last_arrow_string
, Voverlay_arrow_string
)
8061 /* Value is > 0 if update has been done, it is -1 if we
8062 know that the same window start will not work. It is 0
8063 if unsuccessful for some other reason. */
8064 && (tem
= try_window_id (w
)) != 0)
8067 debug_method_add (w
, "try_window_id");
8070 if (fonts_changed_p
)
8071 goto restore_buffers
;
8074 /* Otherwise try_window_id has returned -1 which means that we
8075 don't want the alternative below this comment to execute. */
8077 else if (CHARPOS (startp
) >= BEGV
8078 && CHARPOS (startp
) <= ZV
8079 && PT
>= CHARPOS (startp
)
8080 && (CHARPOS (startp
) < ZV
8081 /* Avoid starting at end of buffer. */
8082 || CHARPOS (startp
) == BEGV
8083 || (XFASTINT (w
->last_modified
) >= MODIFF
8084 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
8087 debug_method_add (w
, "same window start");
8090 /* Try to redisplay starting at same place as before.
8091 If point has not moved off frame, accept the results. */
8092 if (!current_matrix_up_to_date_p
8093 /* Don't use try_window_reusing_current_matrix in this case
8094 because it can have changed the buffer. */
8095 || !NILP (Vwindow_scroll_functions
)
8096 || MINI_WINDOW_P (w
)
8097 || !try_window_reusing_current_matrix (w
))
8099 IF_DEBUG (debug_method_add (w
, "1"));
8100 try_window (window
, startp
);
8103 if (fonts_changed_p
)
8104 goto restore_buffers
;
8106 if (w
->cursor
.vpos
>= 0)
8108 if (!just_this_one_p
8109 || current_buffer
->clip_changed
8110 || beg_unchanged
< CHARPOS (startp
))
8111 /* Forget any recorded base line for line number display. */
8112 w
->base_line_number
= Qnil
;
8114 make_cursor_line_fully_visible (w
);
8118 clear_glyph_matrix (w
->desired_matrix
);
8123 XSETFASTINT (w
->last_modified
, 0);
8124 XSETFASTINT (w
->last_overlay_modified
, 0);
8126 /* Redisplay the mode line. Select the buffer properly for that. */
8127 if (!update_mode_line
)
8129 if (!really_switched_buffer
)
8131 set_buffer_temp (old
);
8132 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8133 really_switched_buffer
= 1;
8135 update_mode_line
= 1;
8136 w
->update_mode_line
= Qt
;
8139 /* Try to scroll by specified few lines. */
8140 if ((scroll_conservatively
8143 || NUMBERP (current_buffer
->scroll_up_aggressively
)
8144 || NUMBERP (current_buffer
->scroll_down_aggressively
))
8145 && !current_buffer
->clip_changed
8146 && CHARPOS (startp
) >= BEGV
8147 && CHARPOS (startp
) <= ZV
)
8149 /* The function returns -1 if new fonts were loaded, 1 if
8150 successful, 0 if not successful. */
8151 int rc
= try_scrolling (window
, just_this_one_p
,
8152 scroll_conservatively
,
8158 goto restore_buffers
;
8161 /* Finally, just choose place to start which centers point */
8166 debug_method_add (w
, "recenter");
8169 /* w->vscroll = 0; */
8171 /* Forget any previously recorded base line for line number display. */
8172 if (!current_matrix_up_to_date_p
8173 || current_buffer
->clip_changed
)
8174 w
->base_line_number
= Qnil
;
8176 /* Move backward half the height of the window. */
8177 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
8178 it
.current_y
= it
.last_visible_y
;
8179 move_it_vertically_backward (&it
, it
.last_visible_y
/ 2);
8180 xassert (IT_CHARPOS (it
) >= BEGV
);
8182 /* The function move_it_vertically_backward may move over more
8183 than the specified y-distance. If it->w is small, e.g. a
8184 mini-buffer window, we may end up in front of the window's
8185 display area. Start displaying at the start of the line
8186 containing PT in this case. */
8187 if (it
.current_y
<= 0)
8189 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
8190 move_it_vertically (&it
, 0);
8191 xassert (IT_CHARPOS (it
) <= PT
);
8195 it
.current_x
= it
.hpos
= 0;
8197 /* Set startp here explicitly in case that helps avoid an infinite loop
8198 in case the window-scroll-functions functions get errors. */
8199 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
8201 /* Run scroll hooks. */
8202 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
8204 /* Redisplay the window. */
8205 if (!current_matrix_up_to_date_p
8206 || windows_or_buffers_changed
8207 /* Don't use try_window_reusing_current_matrix in this case
8208 because it can have changed the buffer. */
8209 || !NILP (Vwindow_scroll_functions
)
8211 || MINI_WINDOW_P (w
)
8212 || !try_window_reusing_current_matrix (w
))
8213 try_window (window
, startp
);
8215 /* If new fonts have been loaded (due to fontsets), give up. We
8216 have to start a new redisplay since we need to re-adjust glyph
8218 if (fonts_changed_p
)
8219 goto restore_buffers
;
8221 /* If cursor did not appear assume that the middle of the window is
8222 in the first line of the window. Do it again with the next line.
8223 (Imagine a window of height 100, displaying two lines of height
8224 60. Moving back 50 from it->last_visible_y will end in the first
8226 if (w
->cursor
.vpos
< 0)
8228 if (!NILP (w
->window_end_valid
)
8229 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
8231 clear_glyph_matrix (w
->desired_matrix
);
8232 move_it_by_lines (&it
, 1, 0);
8233 try_window (window
, it
.current
.pos
);
8235 else if (PT
< IT_CHARPOS (it
))
8237 clear_glyph_matrix (w
->desired_matrix
);
8238 move_it_by_lines (&it
, -1, 0);
8239 try_window (window
, it
.current
.pos
);
8243 /* Not much we can do about it. */
8247 /* Consider the following case: Window starts at BEGV, there is
8248 invisible, intangible text at BEGV, so that display starts at
8249 some point START > BEGV. It can happen that we are called with
8250 PT somewhere between BEGV and START. Try to handle that case. */
8251 if (w
->cursor
.vpos
< 0)
8253 struct glyph_row
*row
= w
->current_matrix
->rows
;
8254 if (row
->mode_line_p
)
8256 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
8259 make_cursor_line_fully_visible (w
);
8261 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
8262 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
8263 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
8268 /* Display the mode line, if we must. */
8269 if ((update_mode_line
8270 /* If window not full width, must redo its mode line
8271 if (a) the window to its side is being redone and
8272 (b) we do a frame-based redisplay. This is a consequence
8273 of how inverted lines are drawn in frame-based redisplay. */
8274 || (!just_this_one_p
8275 && !FRAME_WINDOW_P (f
)
8276 && !WINDOW_FULL_WIDTH_P (w
))
8277 /* Line number to display. */
8278 || INTEGERP (w
->base_line_pos
)
8279 /* Column number is displayed and different from the one displayed. */
8280 || (!NILP (w
->column_number_displayed
)
8281 && XFASTINT (w
->column_number_displayed
) != current_column ()))
8282 /* This means that the window has a mode line. */
8283 && (WINDOW_WANTS_MODELINE_P (w
)
8284 || WINDOW_WANTS_TOP_LINE_P (w
)))
8286 display_mode_lines (w
);
8288 /* If mode line height has changed, arrange for a thorough
8289 immediate redisplay using the correct mode line height. */
8290 if (WINDOW_WANTS_MODELINE_P (w
)
8291 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
8293 fonts_changed_p
= 1;
8294 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
8295 = DESIRED_MODE_LINE_HEIGHT (w
);
8298 /* If top line height has changed, arrange for a thorough
8299 immediate redisplay using the correct mode line height. */
8300 if (WINDOW_WANTS_TOP_LINE_P (w
)
8301 && CURRENT_TOP_LINE_HEIGHT (w
) != DESIRED_TOP_LINE_HEIGHT (w
))
8303 fonts_changed_p
= 1;
8304 MATRIX_TOP_LINE_ROW (w
->current_matrix
)->height
8305 = DESIRED_TOP_LINE_HEIGHT (w
);
8308 if (fonts_changed_p
)
8309 goto restore_buffers
;
8312 if (!line_number_displayed
8313 && !BUFFERP (w
->base_line_pos
))
8315 w
->base_line_pos
= Qnil
;
8316 w
->base_line_number
= Qnil
;
8321 /* When we reach a frame's selected window, redo the frame's menu bar. */
8322 if (update_mode_line
8323 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
8325 int redisplay_menu_p
= 0;
8327 if (FRAME_WINDOW_P (f
))
8329 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
8330 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
8332 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
8336 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
8338 if (redisplay_menu_p
)
8339 display_menu_bar (w
);
8341 #ifdef HAVE_WINDOW_SYSTEM
8342 if (WINDOWP (f
->toolbar_window
)
8343 && (FRAME_TOOLBAR_LINES (f
) > 0
8344 || auto_resize_toolbars_p
))
8345 redisplay_toolbar (f
);
8351 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8353 int start
, end
, whole
;
8355 /* Calculate the start and end positions for the current window.
8356 At some point, it would be nice to choose between scrollbars
8357 which reflect the whole buffer size, with special markers
8358 indicating narrowing, and scrollbars which reflect only the
8361 Note that mini-buffers sometimes aren't displaying any text. */
8362 if (! MINI_WINDOW_P (w
)
8363 || (w
== XWINDOW (minibuf_window
)
8364 && !echo_area_glyphs
8365 && !STRINGP (echo_area_message
)))
8368 start
= marker_position (w
->start
) - BEGV
;
8369 /* I don't think this is guaranteed to be right. For the
8370 moment, we'll pretend it is. */
8371 end
= (Z
- XFASTINT (w
->window_end_pos
)) - BEGV
;
8375 if (whole
< (end
- start
))
8376 whole
= end
- start
;
8379 start
= end
= whole
= 0;
8381 /* Indicate what this scroll bar ought to be displaying now. */
8382 (*set_vertical_scroll_bar_hook
) (w
, end
- start
, whole
, start
);
8384 /* Note that we actually used the scroll bar attached to this
8385 window, so it shouldn't be deleted at the end of redisplay. */
8386 (*redeem_scroll_bar_hook
) (w
);
8391 /* Restore current_buffer and value of point in it. */
8392 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
8393 if (really_switched_buffer
)
8394 set_buffer_internal_1 (old
);
8396 set_buffer_temp (old
);
8397 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
8399 unbind_to (count
, Qnil
);
8403 /* Build the complete desired matrix of WINDOW with a window start
8404 buffer position POS. Value is non-zero if successful. It is zero
8405 if fonts were loaded during redisplay which makes re-adjusting
8406 glyph matrices necessary. */
8409 try_window (window
, pos
)
8411 struct text_pos pos
;
8413 struct window
*w
= XWINDOW (window
);
8415 struct glyph_row
*last_text_row
= NULL
;
8417 /* Make POS the new window start. */
8418 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
8420 /* Mark cursor position as unknown. No overlay arrow seen. */
8421 w
->cursor
.vpos
= -1;
8422 overlay_arrow_seen
= 0;
8424 /* Initialize iterator and info to start at POS. */
8425 start_display (&it
, w
, pos
);
8427 /* Display all lines of W. */
8428 while (it
.current_y
< it
.last_visible_y
)
8430 if (display_line (&it
))
8431 last_text_row
= it
.glyph_row
- 1;
8432 if (fonts_changed_p
)
8436 /* If bottom moved off end of frame, change mode line percentage. */
8437 if (XFASTINT (w
->window_end_pos
) <= 0
8438 && Z
!= IT_CHARPOS (it
))
8439 w
->update_mode_line
= Qt
;
8441 /* Set window_end_pos to the offset of the last character displayed
8442 on the window from the end of current_buffer. Set
8443 window_end_vpos to its row number. */
8446 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
8447 w
->window_end_bytepos
8448 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
8449 XSETFASTINT (w
->window_end_pos
,
8450 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
8451 XSETFASTINT (w
->window_end_vpos
,
8452 MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
8453 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
8458 w
->window_end_bytepos
= 0;
8459 XSETFASTINT (w
->window_end_pos
, 0);
8460 XSETFASTINT (w
->window_end_vpos
, 0);
8463 /* But that is not valid info until redisplay finishes. */
8464 w
->window_end_valid
= Qnil
;
8470 /************************************************************************
8471 Window redisplay reusing current matrix when buffer has not changed
8472 ************************************************************************/
8474 /* Try redisplay of window W showing an unchanged buffer with a
8475 different window start than the last time it was displayed by
8476 reusing its current matrix. Value is non-zero if successful.
8477 W->start is the new window start. */
8480 try_window_reusing_current_matrix (w
)
8483 struct frame
*f
= XFRAME (w
->frame
);
8484 struct glyph_row
*row
, *bottom_row
;
8487 struct text_pos start
, new_start
;
8488 int nrows_scrolled
, i
;
8489 struct glyph_row
*last_text_row
;
8490 struct glyph_row
*last_reused_text_row
;
8491 struct glyph_row
*start_row
;
8492 int start_vpos
, min_y
, max_y
;
8494 /* Right now this function doesn't handle terminal frames. */
8495 if (!FRAME_WINDOW_P (f
))
8498 /* Can't do this if region may have changed. */
8499 if ((!NILP (Vtransient_mark_mode
)
8500 && !NILP (current_buffer
->mark_active
))
8501 || !NILP (w
->region_showing
))
8504 /* If top-line visibility has changed, give up. */
8505 if (WINDOW_WANTS_TOP_LINE_P (w
)
8506 != MATRIX_TOP_LINE_ROW (w
->current_matrix
)->mode_line_p
)
8509 /* Give up if old or new display is scrolled vertically. We could
8510 make this function handle this, but right now it doesn't. */
8511 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8512 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
8515 /* The variable new_start now holds the new window start. The old
8516 start `start' can be determined from the current matrix. */
8517 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
8518 start
= start_row
->start
.pos
;
8519 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
8521 /* Clear the desired matrix for the display below. */
8522 clear_glyph_matrix (w
->desired_matrix
);
8524 if (CHARPOS (new_start
) <= CHARPOS (start
))
8528 IF_DEBUG (debug_method_add (w
, "twu1"));
8530 /* Display up to a row that can be reused. The variable
8531 last_text_row is set to the last row displayed that displays
8533 start_display (&it
, w
, new_start
);
8534 first_row_y
= it
.current_y
;
8535 w
->cursor
.vpos
= -1;
8536 last_text_row
= last_reused_text_row
= NULL
;
8537 while (it
.current_y
< it
.last_visible_y
8538 && IT_CHARPOS (it
) < CHARPOS (start
)
8539 && !fonts_changed_p
)
8540 if (display_line (&it
))
8541 last_text_row
= it
.glyph_row
- 1;
8543 /* A value of current_y < last_visible_y means that we stopped
8544 at the previous window start, which in turn means that we
8545 have at least one reusable row. */
8546 if (it
.current_y
< it
.last_visible_y
)
8548 nrows_scrolled
= it
.vpos
;
8550 /* Find PT if not already found in the lines displayed. */
8551 if (w
->cursor
.vpos
< 0)
8553 int dy
= it
.current_y
- first_row_y
;
8555 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8556 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
8558 if (PT
>= MATRIX_ROW_START_CHARPOS (row
)
8559 && PT
< MATRIX_ROW_END_CHARPOS (row
))
8561 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
8562 dy
, nrows_scrolled
);
8566 if (MATRIX_ROW_BOTTOM_Y (row
) + dy
>= it
.last_visible_y
)
8572 /* Give up if point was not found. This shouldn't
8573 happen often; not more often than with try_window
8575 if (w
->cursor
.vpos
< 0)
8577 clear_glyph_matrix (w
->desired_matrix
);
8582 /* Scroll the display. Do it before the current matrix is
8583 changed. The problem here is that update has not yet
8584 run, i.e. part of the current matrix is not up to date.
8585 scroll_run_hook will clear the cursor, and use the
8586 current matrix to get the height of the row the cursor is
8588 run
.current_y
= first_row_y
;
8589 run
.desired_y
= it
.current_y
;
8590 run
.height
= it
.last_visible_y
- it
.current_y
;
8594 rif
->update_window_begin_hook (w
);
8595 rif
->scroll_run_hook (w
, &run
);
8596 rif
->update_window_end_hook (w
, 0);
8600 /* Shift current matrix down by nrows_scrolled lines. */
8601 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
8602 rotate_matrix (w
->current_matrix
,
8604 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
8607 /* Disable lines not reused. */
8608 for (i
= 0; i
< it
.vpos
; ++i
)
8609 MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
= 0;
8611 /* Re-compute Y positions. */
8612 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
) + nrows_scrolled
;
8613 min_y
= WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
);
8614 max_y
= it
.last_visible_y
;
8615 while (row
< bottom_row
)
8617 row
->y
= it
.current_y
;
8620 row
->visible_height
= row
->height
- (min_y
- row
->y
);
8621 else if (row
->y
+ row
->height
> max_y
)
8623 = row
->height
- (row
->y
+ row
->height
- max_y
);
8625 row
->visible_height
= row
->height
;
8627 it
.current_y
+= row
->height
;
8630 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
8631 last_reused_text_row
= row
;
8632 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
8638 /* Update window_end_pos etc.; last_reused_text_row is the last
8639 reused row from the current matrix containing text, if any.
8640 The value of last_text_row is the last displayed line
8642 if (last_reused_text_row
)
8644 w
->window_end_bytepos
8645 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
8646 XSETFASTINT (w
->window_end_pos
,
8647 Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
8648 XSETFASTINT (w
->window_end_vpos
,
8649 MATRIX_ROW_VPOS (last_reused_text_row
,
8650 w
->current_matrix
));
8652 else if (last_text_row
)
8654 w
->window_end_bytepos
8655 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
8656 XSETFASTINT (w
->window_end_pos
,
8657 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
8658 XSETFASTINT (w
->window_end_vpos
,
8659 MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
8663 /* This window must be completely empty. */
8664 w
->window_end_bytepos
= 0;
8665 XSETFASTINT (w
->window_end_pos
, 0);
8666 XSETFASTINT (w
->window_end_vpos
, 0);
8668 w
->window_end_valid
= Qnil
;
8670 /* Update hint: don't try scrolling again in update_window. */
8671 w
->desired_matrix
->no_scrolling_p
= 1;
8674 debug_method_add (w
, "try_window_reusing_current_matrix 1");
8678 else if (CHARPOS (new_start
) > CHARPOS (start
))
8680 struct glyph_row
*pt_row
, *row
;
8681 struct glyph_row
*first_reusable_row
;
8682 struct glyph_row
*first_row_to_display
;
8684 int yb
= window_text_bottom_y (w
);
8686 IF_DEBUG (debug_method_add (w
, "twu2"));
8688 /* Find the row starting at new_start, if there is one. Don't
8689 reuse a partially visible line at the end. */
8690 first_reusable_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8691 while (first_reusable_row
->enabled_p
8692 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
8693 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
8694 < CHARPOS (new_start
)))
8695 ++first_reusable_row
;
8697 /* Give up if there is no row to reuse. */
8698 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
8699 || !first_reusable_row
->enabled_p
)
8702 /* The row we found must start at new_start, or else something
8704 xassert (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
8705 == CHARPOS (new_start
));
8707 /* We can reuse fully visible rows beginning with
8708 first_reusable_row to the end of the window. Set
8709 first_row_to_display to the first row that cannot be reused.
8710 Set pt_row to the row containing point, if there is any. */
8711 first_row_to_display
= first_reusable_row
;
8713 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
)
8715 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
8716 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
8717 pt_row
= first_row_to_display
;
8719 ++first_row_to_display
;
8722 /* Start displaying at the start of first_row_to_display. */
8723 xassert (first_row_to_display
->y
< yb
);
8724 init_to_row_start (&it
, w
, first_row_to_display
);
8725 nrows_scrolled
= MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
);
8726 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
8728 it
.current_y
= first_row_to_display
->y
- first_reusable_row
->y
;
8730 /* Display lines beginning with first_row_to_display in the
8731 desired matrix. Set last_text_row to the last row displayed
8732 that displays text. */
8733 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
8735 w
->cursor
.vpos
= -1;
8736 last_text_row
= NULL
;
8737 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
8738 if (display_line (&it
))
8739 last_text_row
= it
.glyph_row
- 1;
8741 /* Give up If point isn't in a row displayed or reused. */
8742 if (w
->cursor
.vpos
< 0)
8744 clear_glyph_matrix (w
->desired_matrix
);
8748 /* If point is in a reused row, adjust y and vpos of the cursor
8752 w
->cursor
.vpos
-= MATRIX_ROW_VPOS (first_reusable_row
,
8754 w
->cursor
.y
-= first_reusable_row
->y
;
8757 /* Scroll the display. */
8758 run
.current_y
= first_reusable_row
->y
;
8759 run
.desired_y
= WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
);
8760 run
.height
= it
.last_visible_y
- run
.current_y
;
8763 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8765 rif
->update_window_begin_hook (w
);
8766 rif
->scroll_run_hook (w
, &run
);
8767 rif
->update_window_end_hook (w
, 0);
8771 /* Adjust Y positions of reused rows. */
8772 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
8773 row
= first_reusable_row
;
8774 dy
= first_reusable_row
->y
;
8775 min_y
= WINDOW_DISPLAY_TOP_LINE_HEIGHT (w
);
8776 max_y
= it
.last_visible_y
;
8777 while (row
< first_row_to_display
)
8781 row
->visible_height
= row
->height
- (min_y
- row
->y
);
8782 else if (row
->y
+ row
->height
> max_y
)
8784 = row
->height
- (row
->y
+ row
->height
- max_y
);
8786 row
->visible_height
= row
->height
;
8790 /* Disable rows not reused. */
8791 while (row
< bottom_row
)
8797 /* Scroll the current matrix. */
8798 xassert (nrows_scrolled
> 0);
8799 rotate_matrix (w
->current_matrix
,
8801 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
8804 /* Adjust window end. A null value of last_text_row means that
8805 the window end is in reused rows which in turn means that
8806 only its vpos can have changed. */
8809 w
->window_end_bytepos
8810 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
8811 XSETFASTINT (w
->window_end_pos
,
8812 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
8813 XSETFASTINT (w
->window_end_vpos
,
8814 MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
8818 XSETFASTINT (w
->window_end_vpos
,
8819 XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
8822 w
->window_end_valid
= Qnil
;
8823 w
->desired_matrix
->no_scrolling_p
= 1;
8826 debug_method_add (w
, "try_window_reusing_current_matrix 2");
8836 /************************************************************************
8837 Window redisplay reusing current matrix when buffer has changed
8838 ************************************************************************/
8840 static struct glyph_row
*get_last_unchanged_at_beg_row
P_ ((struct window
*));
8841 static struct glyph_row
*get_first_unchanged_at_end_row
P_ ((struct window
*,
8843 static struct glyph_row
*
8844 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
8845 struct glyph_row
*));
8848 /* Return the last row in MATRIX displaying text. If row START is
8849 non-null, start searching with that row. IT gives the dimensions
8850 of the display. Value is null if matrix is empty; otherwise it is
8851 a pointer to the row found. */
8853 static struct glyph_row
*
8854 find_last_row_displaying_text (matrix
, it
, start
)
8855 struct glyph_matrix
*matrix
;
8857 struct glyph_row
*start
;
8859 struct glyph_row
*row
, *row_found
;
8861 /* Set row_found to the last row in IT->w's current matrix
8862 displaying text. The loop looks funny but think of partially
8865 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
8866 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
8868 xassert (row
->enabled_p
);
8870 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
8879 /* Return the last row in the current matrix of W that is not affected
8880 by changes at the start of current_buffer that occurred since the
8881 last time W was redisplayed. Value is null if no such row exists.
8883 The global variable beg_unchanged has to contain the number of
8884 bytes unchanged at the start of current_buffer. BEG +
8885 beg_unchanged is the buffer position of the first changed byte in
8886 current_buffer. Characters at positions < BEG + beg_unchanged are
8887 at the same buffer positions as they were when the current matrix
8890 static struct glyph_row
*
8891 get_last_unchanged_at_beg_row (w
)
8894 int first_changed_pos
= BEG
+ beg_unchanged
;
8895 struct glyph_row
*row
;
8896 struct glyph_row
*row_found
= NULL
;
8897 int yb
= window_text_bottom_y (w
);
8899 /* Find the last row displaying unchanged text. */
8900 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8901 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
8902 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
8904 if (/* If row ends before first_changed_pos, it is unchanged,
8905 except in some case. */
8906 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
8907 /* When row ends in ZV and we write at ZV it is not
8909 && !row
->ends_at_zv_p
8910 /* When first_changed_pos is the end of a continued line,
8911 row is not unchanged because it may be no longer
8913 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
8914 && row
->continued_p
))
8917 /* Stop if last visible row. */
8918 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
8928 /* Find the first glyph row in the current matrix of W that is not
8929 affected by changes at the end of current_buffer since the last
8930 time the window was redisplayed. Return in *DELTA the number of
8931 bytes by which buffer positions in unchanged text at the end of
8932 current_buffer must be adjusted. Value is null if no such row
8933 exists, i.e. all rows are affected by changes.
8935 The global variable end_unchanged is assumed to contain the number
8936 of unchanged bytes at the end of current_buffer. The buffer
8937 position of the last changed byte in current_buffer is then Z -
8940 static struct glyph_row
*
8941 get_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
8943 int *delta
, *delta_bytes
;
8945 struct glyph_row
*row
;
8946 struct glyph_row
*row_found
= NULL
;
8948 *delta
= *delta_bytes
= 0;
8950 /* A value of window_end_pos >= end_unchanged means that the window
8951 end is in the range of changed text. If so, there is no
8952 unchanged row at the end of W's current matrix. */
8953 xassert (!NILP (w
->window_end_valid
));
8954 if (XFASTINT (w
->window_end_pos
) >= end_unchanged
)
8957 /* Set row to the last row in W's current matrix displaying text. */
8958 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
8960 /* End vpos should always be on text, except in an entirely empty
8962 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
8963 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0);
8965 /* If matrix is entirely empty, no unchanged row exists. */
8966 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
8968 /* The value of row is the last glyph row in the matrix having a
8969 meaningful buffer position in it. The end position of row
8970 corresponds to window_end_pos. This allows us to translate
8971 buffer positions in the current matrix to current buffer
8972 positions for characters not in changed text. */
8973 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
8974 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
8975 int last_unchanged_pos
, last_unchanged_pos_old
;
8976 struct glyph_row
*first_text_row
8977 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8980 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
8982 /* Set last_unchanged_pos to the buffer position of the last
8983 character in the buffer that has not been changed. Z is the
8984 index + 1 of the last byte in current_buffer, i.e. by
8985 subtracting end_unchanged we get the index of the last
8986 unchanged character, and we have to add BEG to get its buffer
8988 last_unchanged_pos
= Z
- end_unchanged
+ BEG
;
8989 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
8991 /* Search backward from ROW for a row displaying a line that
8992 starts at a minimum position >= last_unchanged_pos_old. */
8993 while (row
>= first_text_row
)
8995 xassert (row
->enabled_p
);
8996 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (row
));
8998 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
9004 xassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
9009 /* Make sure that glyph rows in the current matrix of window W
9010 reference the same glyph memory as corresponding rows in the
9011 frame's frame matrix. This function is called after scrolling W's
9012 current matrix on a terminal frame in try_window_id and
9013 try_window_reusing_current_matrix. */
9016 sync_frame_with_window_matrix_rows (w
)
9019 struct frame
*f
= XFRAME (w
->frame
);
9020 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
9022 /* Preconditions: W must be a leaf window and full-width. Its frame
9023 must have a frame matrix. */
9024 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
9025 xassert (WINDOW_FULL_WIDTH_P (w
));
9026 xassert (!FRAME_WINDOW_P (f
));
9028 /* If W is a full-width window, glyph pointers in W's current matrix
9029 have, by definition, to be the same as glyph pointers in the
9030 corresponding frame matrix. */
9031 window_row
= w
->current_matrix
->rows
;
9032 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
9033 frame_row
= f
->current_matrix
->rows
+ XFASTINT (w
->top
);
9034 while (window_row
< window_row_end
)
9037 for (area
= LEFT_MARGIN_AREA
; area
<= LAST_AREA
; ++area
)
9038 frame_row
->glyphs
[area
] = window_row
->glyphs
[area
];
9039 ++window_row
, ++frame_row
;
9044 /* Try to redisplay window W by reusing its existing display. W's
9045 current matrix must be up to date when this function is called,
9046 i.e. window_end_valid must not be nil.
9050 1 if display has been updated
9051 0 if otherwise unsuccessful
9052 -1 if redisplay with same window start is known not to succeed
9054 The following steps are performed:
9056 1. Find the last row in the current matrix of W that is not
9057 affected by changes at the start of current_buffer. If no such row
9060 2. Find the first row in W's current matrix that is not affected by
9061 changes at the end of current_buffer. Maybe there is no such row.
9063 3. Display lines beginning with the row + 1 found in step 1 to the
9064 row found in step 2 or, if step 2 didn't find a row, to the end of
9067 4. If cursor is not known to appear on the window, give up.
9069 5. If display stopped at the row found in step 2, scroll the
9070 display and current matrix as needed.
9072 6. Maybe display some lines at the end of W, if we must. This can
9073 happen under various circumstances, like a partially visible line
9074 becoming fully visible, or because newly displayed lines are displayed
9075 in smaller font sizes.
9077 7. Update W's window end information. */
9079 /* Check that window end is what we expect it to be. */
9085 struct frame
*f
= XFRAME (w
->frame
);
9086 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
9087 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
9088 struct glyph_row
*last_unchanged_at_beg_row
;
9089 struct glyph_row
*first_unchanged_at_end_row
;
9090 struct glyph_row
*row
;
9091 struct glyph_row
*bottom_row
;
9094 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
9095 struct text_pos start_pos
;
9097 int first_unchanged_at_end_vpos
= 0;
9098 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
9099 struct text_pos start
;
9101 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
9103 /* Check pre-conditions. Window end must be valid, otherwise
9104 the current matrix would not be up to date. */
9105 xassert (!NILP (w
->window_end_valid
));
9106 xassert (FRAME_WINDOW_P (XFRAME (w
->frame
))
9107 || (line_ins_del_ok
&& WINDOW_FULL_WIDTH_P (w
)));
9109 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
9110 only if buffer has really changed. The reason is that the gap is
9111 initially at Z for freshly visited files. The code below would
9112 set end_unchanged to 0 in that case. */
9113 if (MODIFF
> SAVE_MODIFF
)
9115 if (GPT
- BEG
< beg_unchanged
)
9116 beg_unchanged
= GPT
- BEG
;
9117 if (Z
- GPT
< end_unchanged
)
9118 end_unchanged
= Z
- GPT
;
9121 /* If window starts after a line end, and the last change is in
9122 front of that newline, then changes don't affect the display.
9123 This case happens with stealth-fontification. */
9124 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
9125 if (CHARPOS (start
) > BEGV
9126 && Z
- end_unchanged
< CHARPOS (start
) - 1
9127 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n'
9128 && PT
< MATRIX_ROW_END_CHARPOS (row
))
9130 /* We have to update window end positions because the buffer's
9131 size has changed. */
9133 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
9134 w
->window_end_bytepos
9135 = make_number (Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
));
9139 /* Return quickly if changes are all below what is displayed in the
9140 window, and if PT is in the window. */
9141 if (beg_unchanged
> MATRIX_ROW_END_CHARPOS (row
)
9142 && PT
< MATRIX_ROW_END_CHARPOS (row
))
9144 /* We have to update window end positions because the buffer's
9145 size has changed. */
9147 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
9148 w
->window_end_bytepos
9149 = make_number (Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
));
9153 /* Check that window start agrees with the start of the first glyph
9154 row in its current matrix. Check this after we know the window
9155 start is not in changed text, otherwise positions would not be
9157 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
9158 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
9161 /* Remember beg_unchanged and end_unchanged for debugging purposes. */
9162 IF_DEBUG (debug_beg_unchanged
= beg_unchanged
;
9163 debug_end_unchanged
= end_unchanged
);
9165 /* Compute the position at which we have to start displaying new
9166 lines. Some of the lines at the top of the window might be
9167 reusable because they are not displaying changed text. Find the
9168 last row in W's current matrix not affected by changes at the
9169 start of current_buffer. Value is null if changes start in the
9170 first line of window. */
9171 last_unchanged_at_beg_row
= get_last_unchanged_at_beg_row (w
);
9172 if (last_unchanged_at_beg_row
)
9174 init_to_row_end (&it
, w
, last_unchanged_at_beg_row
);
9175 start_pos
= it
.current
.pos
;
9177 /* Start displaying new lines in the desired matrix at the same
9178 vpos we would use in the current matrix, i.e. below
9179 last_unchanged_at_beg_row. */
9180 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
9182 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
9183 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
9185 xassert (it
.hpos
== 0 && it
.current_x
== 0);
9189 /* There are no reusable lines at the start of the window.
9190 Start displaying in the first line. */
9191 start_display (&it
, w
, start
);
9192 start_pos
= it
.current
.pos
;
9195 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
9196 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
9198 /* Find the first row that is not affected by changes at the end of
9199 the buffer. Value will be null if there is no unchanged row, in
9200 which case we must redisplay to the end of the window. delta
9201 will be set to the value by which buffer positions beginning with
9202 first_unchanged_at_end_row have to be adjusted due to text
9204 first_unchanged_at_end_row
9205 = get_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
9206 IF_DEBUG (debug_delta
= delta
);
9207 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
9209 /* Set stop_pos to the buffer position up to which we will have to
9210 display new lines. If first_unchanged_at_end_row != NULL, this
9211 is the buffer position of the start of the line displayed in that
9212 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
9213 that we don't stop at a buffer position. */
9215 if (first_unchanged_at_end_row
)
9217 xassert (last_unchanged_at_beg_row
== NULL
9218 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
9220 /* If this is a continuation line, move forward to the next one
9221 that isn't. Changes in lines above affect this line.
9222 Caution: this may move first_unchanged_at_end_row to a row
9223 not displaying text. */
9224 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
9225 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
9226 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
9227 < it
.last_visible_y
))
9228 ++first_unchanged_at_end_row
;
9230 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
9231 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
9232 >= it
.last_visible_y
))
9233 first_unchanged_at_end_row
= NULL
;
9236 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
9238 first_unchanged_at_end_vpos
9239 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
9240 xassert (stop_pos
>= Z
- end_unchanged
);
9243 else if (last_unchanged_at_beg_row
== NULL
)
9249 /* Either there is no unchanged row at the end, or the one we have
9250 now displays text. This is a necessary condition for the window
9251 end pos calculation at the end of this function. */
9252 xassert (first_unchanged_at_end_row
== NULL
9253 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
9255 debug_last_unchanged_at_beg_vpos
9256 = (last_unchanged_at_beg_row
9257 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
9259 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
9261 #endif /* GLYPH_DEBUG != 0 */
9264 /* Display new lines. Set last_text_row to the last new line
9265 displayed which has text on it, i.e. might end up as being the
9266 line where the window_end_vpos is. */
9267 w
->cursor
.vpos
= -1;
9268 last_text_row
= NULL
;
9269 overlay_arrow_seen
= 0;
9270 while (it
.current_y
< it
.last_visible_y
9272 && (first_unchanged_at_end_row
== NULL
9273 || IT_CHARPOS (it
) < stop_pos
))
9275 if (display_line (&it
))
9276 last_text_row
= it
.glyph_row
- 1;
9279 if (fonts_changed_p
)
9283 /* Compute differences in buffer positions, y-positions etc. for
9284 lines reused at the bottom of the window. Compute what we can
9286 if (first_unchanged_at_end_row
)
9289 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
9291 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
9292 run
.current_y
= first_unchanged_at_end_row
->y
;
9293 run
.desired_y
= run
.current_y
+ dy
;
9294 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
9297 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
9298 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
9301 /* Find the cursor if not already found. We have to decide whether
9302 PT will appear on this window (it sometimes doesn't, but this is
9303 not a very frequent case.) This decision has to be made before
9304 the current matrix is altered. A value of cursor.vpos < 0 means
9305 that PT is either in one of the lines beginning at
9306 first_unchanged_at_end_row or below the window. Don't care for
9307 lines that might be displayed later at the window end; as
9308 mentioned, this is not a frequent case. */
9309 if (w
->cursor
.vpos
< 0)
9311 int last_y
= min (it
.last_visible_y
, it
.last_visible_y
+ dy
);
9313 /* Cursor in unchanged rows at the top? */
9314 if (PT
< CHARPOS (start_pos
)
9315 && last_unchanged_at_beg_row
)
9317 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
9318 while (row
<= last_unchanged_at_beg_row
9319 && MATRIX_ROW_END_CHARPOS (row
) <= PT
)
9321 xassert (row
<= last_unchanged_at_beg_row
);
9322 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
9325 /* Start from first_unchanged_at_end_row looking for PT. */
9326 else if (first_unchanged_at_end_row
)
9328 row
= first_unchanged_at_end_row
;
9329 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
9331 if (PT
- delta
>= MATRIX_ROW_START_CHARPOS (row
)
9332 && PT
- delta
< MATRIX_ROW_END_CHARPOS (row
))
9334 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
9335 delta_bytes
, dy
, dvpos
);
9338 else if (MATRIX_ROW_BOTTOM_Y (row
) >= last_y
)
9344 /* Give up if cursor was not found. */
9345 if (w
->cursor
.vpos
< 0)
9347 clear_glyph_matrix (w
->desired_matrix
);
9352 /* Don't let the cursor end in the scroll margins. */
9354 int this_scroll_margin
, cursor_height
;
9356 this_scroll_margin
= max (0, scroll_margin
);
9357 this_scroll_margin
= min (this_scroll_margin
,
9358 XFASTINT (w
->height
) / 4);
9359 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
9360 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
9362 if ((w
->cursor
.y
< this_scroll_margin
9363 && CHARPOS (start
) > BEGV
)
9364 /* Don't take scroll margin into account at the bottom because
9365 old redisplay didn't do it either. */
9366 || w
->cursor
.y
+ cursor_height
> it
.last_visible_y
)
9368 w
->cursor
.vpos
= -1;
9369 clear_glyph_matrix (w
->desired_matrix
);
9374 /* Scroll the display. Do it before changing the current matrix so
9375 that xterm.c doesn't get confused about where the cursor glyph is
9381 if (FRAME_WINDOW_P (f
))
9383 rif
->update_window_begin_hook (w
);
9384 rif
->scroll_run_hook (w
, &run
);
9385 rif
->update_window_end_hook (w
, 0);
9389 /* Terminal frame. In this case, dvpos gives the number of
9390 lines to scroll by; dvpos < 0 means scroll up. */
9391 int first_unchanged_at_end_vpos
9392 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
9393 int from
= XFASTINT (w
->top
) + first_unchanged_at_end_vpos
;
9394 int end
= XFASTINT (w
->top
) + window_internal_height (w
);
9396 /* Perform the operation on the screen. */
9399 /* Scroll last_unchanged_at_beg_row to the end of the
9400 window down dvpos lines. */
9401 set_terminal_window (end
);
9403 /* On dumb terminals delete dvpos lines at the end
9404 before inserting dvpos empty lines. */
9405 if (!scroll_region_ok
)
9406 ins_del_lines (end
- dvpos
, -dvpos
);
9408 /* Insert dvpos empty lines in front of
9409 last_unchanged_at_beg_row. */
9410 ins_del_lines (from
, dvpos
);
9414 /* Scroll up last_unchanged_at_beg_vpos to the end of
9415 the window to last_unchanged_at_beg_vpos - |dvpos|. */
9416 set_terminal_window (end
);
9418 /* Delete dvpos lines in front of
9419 last_unchanged_at_beg_vpos. ins_del_lines will set
9420 the cursor to the given vpos and emit |dvpos| delete
9422 ins_del_lines (from
+ dvpos
, dvpos
);
9424 /* On a dumb terminal insert dvpos empty lines at the
9426 if (!scroll_region_ok
)
9427 ins_del_lines (end
+ dvpos
, -dvpos
);
9430 set_terminal_window (0);
9436 /* Shift reused rows of the current matrix to the right position. */
9439 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
9440 bottom_vpos
, dvpos
);
9441 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
9446 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
9447 bottom_vpos
, dvpos
);
9448 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
9449 first_unchanged_at_end_vpos
+ dvpos
, 0);
9452 /* For frame-based redisplay, make sure that current frame and window
9453 matrix are in sync with respect to glyph memory. */
9454 if (!FRAME_WINDOW_P (f
))
9455 sync_frame_with_window_matrix_rows (w
);
9457 /* Adjust buffer positions in reused rows. */
9459 increment_glyph_matrix_buffer_positions (current_matrix
,
9460 first_unchanged_at_end_vpos
+ dvpos
,
9461 bottom_vpos
, delta
, delta_bytes
);
9463 /* Adjust Y positions. */
9465 shift_glyph_matrix (w
, current_matrix
,
9466 first_unchanged_at_end_vpos
+ dvpos
,
9469 if (first_unchanged_at_end_row
)
9470 first_unchanged_at_end_row
+= dvpos
;
9472 /* If scrolling up, there may be some lines to display at the end of
9474 last_text_row_at_end
= NULL
;
9477 /* Set last_row to the glyph row in the current matrix where the
9478 window end line is found. It has been moved up or down in
9479 the matrix by dvpos. */
9480 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
9481 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
9483 /* If last_row is the window end line, it should display text. */
9484 xassert (last_row
->displays_text_p
);
9486 /* If window end line was partially visible before, begin
9487 displaying at that line. Otherwise begin displaying with the
9488 line following it. */
9489 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
9491 init_to_row_start (&it
, w
, last_row
);
9492 it
.vpos
= last_vpos
;
9493 it
.current_y
= last_row
->y
;
9497 init_to_row_end (&it
, w
, last_row
);
9498 it
.vpos
= 1 + last_vpos
;
9499 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
9503 /* We may start in a continuation line. If so, we have to get
9504 the right continuation_lines_width and current_x. */
9505 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
9506 it
.hpos
= it
.current_x
= 0;
9508 /* Display the rest of the lines at the window end. */
9509 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
9510 while (it
.current_y
< it
.last_visible_y
9511 && !fonts_changed_p
)
9513 /* Is it always sure that the display agrees with lines in
9514 the current matrix? I don't think so, so we mark rows
9515 displayed invalid in the current matrix by setting their
9516 enabled_p flag to zero. */
9517 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
9518 if (display_line (&it
))
9519 last_text_row_at_end
= it
.glyph_row
- 1;
9523 /* Update window_end_pos and window_end_vpos. */
9524 if (first_unchanged_at_end_row
9525 && first_unchanged_at_end_row
->y
< it
.last_visible_y
9526 && !last_text_row_at_end
)
9528 /* Window end line if one of the preserved rows from the current
9529 matrix. Set row to the last row displaying text in current
9530 matrix starting at first_unchanged_at_end_row, after
9532 xassert (first_unchanged_at_end_row
->displays_text_p
);
9533 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
9534 first_unchanged_at_end_row
);
9535 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
9537 XSETFASTINT (w
->window_end_pos
, Z
- MATRIX_ROW_END_CHARPOS (row
));
9538 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
9539 XSETFASTINT (w
->window_end_vpos
,
9540 MATRIX_ROW_VPOS (row
, w
->current_matrix
));
9542 else if (last_text_row_at_end
)
9544 XSETFASTINT (w
->window_end_pos
,
9545 Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
9546 w
->window_end_bytepos
9547 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
9548 XSETFASTINT (w
->window_end_vpos
,
9549 MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
9551 else if (last_text_row
)
9553 /* We have displayed either to the end of the window or at the
9554 end of the window, i.e. the last row with text is to be found
9555 in the desired matrix. */
9556 XSETFASTINT (w
->window_end_pos
,
9557 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
9558 w
->window_end_bytepos
9559 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
9560 XSETFASTINT (w
->window_end_vpos
,
9561 MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
9563 else if (first_unchanged_at_end_row
== NULL
9564 && last_text_row
== NULL
9565 && last_text_row_at_end
== NULL
)
9567 /* Displayed to end of window, but no line containing text was
9568 displayed. Lines were deleted at the end of the window. */
9570 int top_line_p
= WINDOW_WANTS_TOP_LINE_P (w
) ? 1 : 0;
9572 for (vpos
= XFASTINT (w
->window_end_vpos
); vpos
> 0; --vpos
)
9573 if ((w
->desired_matrix
->rows
[vpos
+ top_line_p
].enabled_p
9574 && w
->desired_matrix
->rows
[vpos
+ top_line_p
].displays_text_p
)
9575 || (!w
->desired_matrix
->rows
[vpos
+ top_line_p
].enabled_p
9576 && w
->current_matrix
->rows
[vpos
+ top_line_p
].displays_text_p
))
9579 w
->window_end_vpos
= make_number (vpos
);
9584 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
9585 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
9587 /* Record that display has not been completed. */
9588 w
->window_end_valid
= Qnil
;
9589 w
->desired_matrix
->no_scrolling_p
= 1;
9595 /***********************************************************************
9596 More debugging support
9597 ***********************************************************************/
9601 void dump_glyph_row
P_ ((struct glyph_matrix
*, int, int));
9602 static void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
9605 /* Dump the contents of glyph matrix MATRIX on stderr. If
9606 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
9609 dump_glyph_matrix (matrix
, with_glyphs_p
)
9610 struct glyph_matrix
*matrix
;
9614 for (i
= 0; i
< matrix
->nrows
; ++i
)
9615 dump_glyph_row (matrix
, i
, with_glyphs_p
);
9619 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
9620 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
9623 dump_glyph_row (matrix
, vpos
, with_glyphs_p
)
9624 struct glyph_matrix
*matrix
;
9625 int vpos
, with_glyphs_p
;
9627 struct glyph_row
*row
;
9629 if (vpos
< 0 || vpos
>= matrix
->nrows
)
9632 row
= MATRIX_ROW (matrix
, vpos
);
9634 fprintf (stderr
, "Row Start End Used oEI><O\\CTZF X Y W\n");
9635 fprintf (stderr
, "=============================================\n");
9637 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d\n",
9639 MATRIX_ROW_START_CHARPOS (row
),
9640 MATRIX_ROW_END_CHARPOS (row
),
9641 row
->used
[TEXT_AREA
],
9642 row
->contains_overlapping_glyphs_p
,
9645 row
->truncated_on_left_p
,
9646 row
->truncated_on_right_p
,
9647 row
->overlay_arrow_p
,
9649 MATRIX_ROW_CONTINUATION_LINE_P (row
),
9650 row
->displays_text_p
,
9656 fprintf (stderr
, "%9d %5d\n", row
->start
.overlay_string_index
,
9657 row
->end
.overlay_string_index
);
9658 fprintf (stderr
, "%9d %5d\n",
9659 CHARPOS (row
->start
.string_pos
),
9660 CHARPOS (row
->end
.string_pos
));
9661 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
9662 row
->end
.dpvec_index
);
9666 struct glyph
*glyph
, *glyph_end
;
9667 int prev_had_glyphs_p
;
9669 glyph
= row
->glyphs
[TEXT_AREA
];
9670 glyph_end
= glyph
+ row
->used
[TEXT_AREA
];
9672 /* Glyph for a line end in text. */
9673 if (glyph
== glyph_end
&& glyph
->charpos
> 0)
9676 if (glyph
< glyph_end
)
9678 fprintf (stderr
, " Glyph Type Pos W Code C Face LR\n");
9679 prev_had_glyphs_p
= 1;
9682 prev_had_glyphs_p
= 0;
9684 while (glyph
< glyph_end
)
9686 if (glyph
->type
== CHAR_GLYPH
)
9689 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9690 glyph
- row
->glyphs
[TEXT_AREA
],
9695 (glyph
->u
.ch
.code
< 0x80 && glyph
->u
.ch
.code
>= ' '
9698 glyph
->u
.ch
.face_id
,
9699 glyph
->left_box_line_p
,
9700 glyph
->right_box_line_p
);
9702 else if (glyph
->type
== STRETCH_GLYPH
)
9705 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9706 glyph
- row
->glyphs
[TEXT_AREA
],
9712 glyph
->u
.stretch
.face_id
,
9713 glyph
->left_box_line_p
,
9714 glyph
->right_box_line_p
);
9716 else if (glyph
->type
== IMAGE_GLYPH
)
9719 " %5d %4c %6d %3d 0x%05x %c %4d %1.1d%1.1d\n",
9720 glyph
- row
->glyphs
[TEXT_AREA
],
9726 glyph
->u
.img
.face_id
,
9727 glyph
->left_box_line_p
,
9728 glyph
->right_box_line_p
);
9736 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
9737 Sdump_glyph_matrix
, 0, 1, "p",
9738 "Dump the current matrix of the selected window to stderr.\n\
9739 Shows contents of glyph row structures. With non-nil optional\n\
9740 parameter WITH-GLYPHS-P, dump glyphs as well.")
9743 struct window
*w
= XWINDOW (selected_window
);
9744 struct buffer
*buffer
= XBUFFER (w
->buffer
);
9746 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
9747 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
9748 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
9749 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
9750 fprintf (stderr
, "=============================================\n");
9751 dump_glyph_matrix (w
->current_matrix
, !NILP (with_glyphs_p
));
9756 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 1, "",
9757 "Dump glyph row ROW to stderr.")
9761 CHECK_NUMBER (row
, 0);
9762 dump_glyph_row (XWINDOW (selected_window
)->current_matrix
, XINT (row
), 1);
9767 DEFUN ("dump-toolbar-row", Fdump_toolbar_row
, Sdump_toolbar_row
,
9771 struct glyph_matrix
*m
= (XWINDOW (selected_frame
->toolbar_window
)
9773 dump_glyph_row (m
, 0, 1);
9778 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle
,
9779 Strace_redisplay_toggle
, 0, 0, "",
9780 "Toggle tracing of redisplay.")
9783 trace_redisplay_p
= !trace_redisplay_p
;
9788 #endif /* GLYPH_DEBUG */
9792 /***********************************************************************
9793 Building Desired Matrix Rows
9794 ***********************************************************************/
9796 /* Return a temporary glyph row holding the glyphs of an overlay
9797 arrow. Only used for non-window-redisplay windows. */
9799 static struct glyph_row
*
9800 get_overlay_arrow_glyph_row (w
)
9803 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9804 struct buffer
*buffer
= XBUFFER (w
->buffer
);
9805 struct buffer
*old
= current_buffer
;
9806 unsigned char *arrow_string
= XSTRING (Voverlay_arrow_string
)->data
;
9807 int arrow_len
= XSTRING (Voverlay_arrow_string
)->size
;
9808 unsigned char *arrow_end
= arrow_string
+ arrow_len
;
9812 int n_glyphs_before
;
9814 set_buffer_temp (buffer
);
9815 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
9816 it
.glyph_row
->used
[TEXT_AREA
] = 0;
9817 SET_TEXT_POS (it
.position
, 0, 0);
9819 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
9821 while (p
< arrow_end
)
9823 Lisp_Object face
, ilisp
;
9825 /* Get the next character. */
9827 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
9829 it
.c
= *p
, it
.len
= 1;
9833 XSETFASTINT (ilisp
, p
- arrow_string
);
9834 face
= Fget_text_property (ilisp
, Qface
, Voverlay_arrow_string
);
9835 it
.face_id
= compute_char_face (f
, it
.c
, face
);
9837 /* Compute its width, get its glyphs. */
9838 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
9839 PRODUCE_GLYPHS (&it
);
9841 /* If this character doesn't fit any more in the line, we have
9842 to remove some glyphs. */
9843 if (it
.current_x
> it
.last_visible_x
)
9845 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
9850 set_buffer_temp (old
);
9851 return it
.glyph_row
;
9855 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
9856 glyphs are only inserted for terminal frames since we can't really
9857 win with truncation glyphs when partially visible glyphs are
9858 involved. Which glyphs to insert is determined by
9859 produce_special_glyphs. */
9862 insert_left_trunc_glyphs (it
)
9865 struct it truncate_it
;
9866 struct glyph
*from
, *end
, *to
, *toend
;
9868 xassert (!FRAME_WINDOW_P (it
->f
));
9870 /* Get the truncation glyphs. */
9872 truncate_it
.charset
= -1;
9873 truncate_it
.current_x
= 0;
9874 truncate_it
.face_id
= DEFAULT_FACE_ID
;
9875 truncate_it
.glyph_row
= &scratch_glyph_row
;
9876 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
9877 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
9878 truncate_it
.object
= 0;
9879 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
9881 /* Overwrite glyphs from IT with truncation glyphs. */
9882 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
9883 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
9884 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
9885 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
9890 /* There may be padding glyphs left over. Remove them. */
9892 while (from
< toend
&& CHAR_GLYPH_PADDING_P (*from
))
9894 while (from
< toend
)
9897 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
9901 /* Compute the pixel height and width of IT->glyph_row.
9903 Most of the time, ascent and height of a display line will be equal
9904 to the max_ascent and max_height values of the display iterator
9905 structure. This is not the case if
9907 1. We hit ZV without displaying anything. In this case, max_ascent
9908 and max_height will be zero.
9910 2. We have some glyphs that don't contribute to the line height.
9911 (The glyph row flag contributes_to_line_height_p is for future
9914 The first case is easily covered by using default values because in
9915 these cases, the line height does not really matter, except that it
9916 must not be zero. */
9919 compute_line_metrics (it
)
9922 struct glyph_row
*row
= it
->glyph_row
;
9925 if (FRAME_WINDOW_P (it
->f
))
9927 int i
, top_line_height
;
9929 /* The line may consist of one space only, that was added to
9930 place the cursor on it. If so, the row's height hasn't been
9932 if (row
->height
== 0)
9934 if (it
->max_ascent
+ it
->max_descent
== 0)
9935 it
->max_descent
= it
->max_phys_descent
= CANON_Y_UNIT (it
->f
);
9936 row
->ascent
= it
->max_ascent
;
9937 row
->height
= it
->max_ascent
+ it
->max_descent
;
9938 row
->phys_ascent
= it
->max_phys_ascent
;
9939 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
9942 /* Compute the width of this line. */
9943 row
->pixel_width
= row
->x
;
9944 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
9945 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
9947 xassert (row
->pixel_width
>= 0);
9948 xassert (row
->ascent
>= 0 && row
->height
> 0);
9950 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
9951 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
9953 /* If first line's physical ascent is larger than its logical
9954 ascent, use the physical ascent, and make the row taller.
9955 This makes accented characters fully visible. */
9956 if (row
== it
->w
->desired_matrix
->rows
9957 && row
->phys_ascent
> row
->ascent
)
9959 row
->height
+= row
->phys_ascent
- row
->ascent
;
9960 row
->ascent
= row
->phys_ascent
;
9963 /* Compute how much of the line is visible. */
9964 row
->visible_height
= row
->height
;
9966 top_line_height
= WINDOW_DISPLAY_TOP_LINE_HEIGHT (it
->w
);
9967 if (row
->y
< top_line_height
)
9968 row
->visible_height
-= top_line_height
- row
->y
;
9971 int max_y
= WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it
->w
);
9972 if (row
->y
+ row
->height
> max_y
)
9973 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
9978 row
->pixel_width
= row
->used
[TEXT_AREA
];
9979 row
->ascent
= row
->phys_ascent
= 0;
9980 row
->height
= row
->phys_height
= row
->visible_height
= 1;
9983 /* Compute a hash code for this row. */
9985 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
9986 for (i
= 0; i
< row
->used
[area
]; ++i
)
9987 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
9988 + row
->glyphs
[area
][i
].u
.val
9989 + (row
->glyphs
[area
][i
].type
<< 2));
9991 it
->max_ascent
= it
->max_descent
= 0;
9992 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
9996 /* Append one space to the glyph row of iterator IT if doing a
9997 window-based redisplay. DEFAULT_FACE_P non-zero means let the
9998 space have the default face, otherwise let it have the same face as
9999 IT->face_id. This function is called to make sure that there is
10000 always one glyph at the end of a glyph row that the cursor can be
10001 set on under window-systems. (If there weren't such a glyph we
10002 would not know how wide and tall the cursor should be displayed). */
10005 append_space (it
, default_face_p
)
10007 int default_face_p
;
10009 if (FRAME_WINDOW_P (it
->f
))
10011 int n
= it
->glyph_row
->used
[TEXT_AREA
];
10013 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
10014 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
10016 /* Save some values that must not be changed. */
10017 int saved_x
= it
->current_x
;
10018 struct text_pos saved_pos
;
10019 int saved_what
= it
->what
;
10020 int saved_face_id
= it
->face_id
;
10021 int saved_charset
= it
->charset
;
10022 Lisp_Object saved_object
;
10024 saved_object
= it
->object
;
10025 saved_pos
= it
->position
;
10027 it
->what
= IT_CHARACTER
;
10028 bzero (&it
->position
, sizeof it
->position
);
10032 it
->charset
= CHARSET_ASCII
;
10034 if (default_face_p
)
10035 it
->face_id
= DEFAULT_FACE_ID
;
10036 if (it
->multibyte_p
)
10037 it
->face_id
= FACE_FOR_CHARSET (it
->f
, it
->face_id
, CHARSET_ASCII
);
10039 it
->face_id
= FACE_FOR_CHARSET (it
->f
, it
->face_id
, -1);
10041 PRODUCE_GLYPHS (it
);
10043 it
->current_x
= saved_x
;
10044 it
->object
= saved_object
;
10045 it
->position
= saved_pos
;
10046 it
->what
= saved_what
;
10047 it
->face_id
= saved_face_id
;
10048 it
->charset
= saved_charset
;
10054 /* Extend the face of the last glyph in the text area of IT->glyph_row
10055 to the end of the display line. Called from display_line.
10056 If the glyph row is empty, add a space glyph to it so that we
10057 know the face to draw. Set the glyph row flag fill_line_p. */
10060 extend_face_to_end_of_line (it
)
10064 struct frame
*f
= it
->f
;
10066 /* If line is already filled, do nothing. */
10067 if (it
->current_x
>= it
->last_visible_x
)
10070 /* Face extension extends the background and box of IT->face_id
10071 to the end of the line. If the background equals the background
10072 of the frame, we haven't to do anything. */
10073 face
= FACE_FROM_ID (f
, it
->face_id
);
10074 if (FRAME_WINDOW_P (f
)
10075 && face
->box
== FACE_NO_BOX
10076 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
10080 /* Set the glyph row flag indicating that the face of the last glyph
10081 in the text area has to be drawn to the end of the text area. */
10082 it
->glyph_row
->fill_line_p
= 1;
10084 /* If current charset of IT is not ASCII, make sure we have the
10085 ASCII face. This will be automatically undone the next time
10086 get_next_display_element returns a character from a different
10087 charset. Note that the charset will always be ASCII in unibyte
10089 if (it
->charset
!= CHARSET_ASCII
)
10091 it
->charset
= CHARSET_ASCII
;
10092 it
->face_id
= FACE_FOR_CHARSET (f
, it
->face_id
, CHARSET_ASCII
);
10095 if (FRAME_WINDOW_P (f
))
10097 /* If the row is empty, add a space with the current face of IT,
10098 so that we know which face to draw. */
10099 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
10101 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
10102 it
->glyph_row
->glyphs
[TEXT_AREA
][0].u
.ch
.face_id
= it
->face_id
;
10103 it
->glyph_row
->used
[TEXT_AREA
] = 1;
10108 /* Save some values that must not be changed. */
10109 int saved_x
= it
->current_x
;
10110 struct text_pos saved_pos
;
10111 Lisp_Object saved_object
;
10112 int saved_what
= it
->what
;
10114 saved_object
= it
->object
;
10115 saved_pos
= it
->position
;
10117 it
->what
= IT_CHARACTER
;
10118 bzero (&it
->position
, sizeof it
->position
);
10123 PRODUCE_GLYPHS (it
);
10125 while (it
->current_x
<= it
->last_visible_x
)
10126 PRODUCE_GLYPHS (it
);
10128 /* Don't count these blanks really. It would let us insert a left
10129 truncation glyph below and make us set the cursor on them, maybe. */
10130 it
->current_x
= saved_x
;
10131 it
->object
= saved_object
;
10132 it
->position
= saved_pos
;
10133 it
->what
= saved_what
;
10138 /* Value is non-zero if text starting at CHARPOS in current_buffer is
10139 trailing whitespace. */
10142 trailing_whitespace_p (charpos
)
10145 int bytepos
= CHAR_TO_BYTE (charpos
);
10148 while (bytepos
< ZV_BYTE
10149 && (c
= FETCH_CHAR (bytepos
),
10150 c
== ' ' || c
== '\t'))
10153 return bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r';
10157 /* Highlight trailing whitespace, if any, in ROW. */
10160 highlight_trailing_whitespace (f
, row
)
10162 struct glyph_row
*row
;
10164 int used
= row
->used
[TEXT_AREA
];
10168 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
10169 struct glyph
*glyph
= start
+ used
- 1;
10171 /* Skip over the space glyph inserted to display the
10172 cursor at the end of a line. */
10173 if (glyph
->type
== CHAR_GLYPH
10174 && glyph
->u
.ch
.code
== ' '
10175 && glyph
->object
== 0)
10178 /* If last glyph is a space or stretch, and it's trailing
10179 whitespace, set the face of all trailing whitespace glyphs in
10180 IT->glyph_row to `trailing-whitespace'. */
10182 && BUFFERP (glyph
->object
)
10183 && (glyph
->type
== STRETCH_GLYPH
10184 || (glyph
->type
== CHAR_GLYPH
10185 && glyph
->u
.ch
.code
== ' '))
10186 && trailing_whitespace_p (glyph
->charpos
))
10188 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
,
10191 while (glyph
>= start
10192 && BUFFERP (glyph
->object
)
10193 && (glyph
->type
== STRETCH_GLYPH
10194 || (glyph
->type
== CHAR_GLYPH
10195 && glyph
->u
.ch
.code
== ' ')))
10197 if (glyph
->type
== STRETCH_GLYPH
)
10198 glyph
->u
.stretch
.face_id
= face_id
;
10200 glyph
->u
.ch
.face_id
= face_id
;
10209 /* Construct the glyph row IT->glyph_row in the desired matrix of
10210 IT->w from text at the current position of IT. See dispextern.h
10211 for an overview of struct it. Value is non-zero if
10212 IT->glyph_row displays text, as opposed to a line displaying ZV
10219 struct glyph_row
*row
= it
->glyph_row
;
10221 /* We always start displaying at hpos zero even if hscrolled. */
10222 xassert (it
->hpos
== 0 && it
->current_x
== 0);
10224 /* We must not display in a row that's not a text row. */
10225 xassert (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
10226 < it
->w
->desired_matrix
->nrows
);
10228 /* Is IT->w showing the region? */
10229 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
10231 /* Clear the result glyph row and enable it. */
10232 prepare_desired_row (row
);
10234 row
->y
= it
->current_y
;
10235 row
->start
= it
->current
;
10236 row
->continuation_lines_width
= it
->continuation_lines_width
;
10237 row
->displays_text_p
= 1;
10239 /* Arrange the overlays nicely for our purposes. Usually, we call
10240 display_line on only one line at a time, in which case this
10241 can't really hurt too much, or we call it on lines which appear
10242 one after another in the buffer, in which case all calls to
10243 recenter_overlay_lists but the first will be pretty cheap. */
10244 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
10246 #if NO_PROMPT_IN_BUFFER
10247 /* Show mini-buffer prompt, if at the beginning of a mini-buffer
10249 if (MINI_WINDOW_P (it
->w
)
10250 && MATRIX_ROW_START_CHARPOS (row
) == BEG
10253 if (NILP (minibuf_prompt
))
10254 minibuf_prompt_width
= minibuf_prompt_pixel_width
= 0;
10257 /* We would like to truncate the prompt a little bit before
10258 the right margin of the window, so that user input can
10259 start on the first line. Set max_x to this position. */
10260 int max_x
= (it
->last_visible_x
- 4 * CANON_X_UNIT (it
->f
));
10262 /* We use a temporary iterator different from IT so that
10263 IT's settings are not overwritten when displaying
10269 /* Display the prompt. Set minibuf_prompt_width to the
10270 number of glyphs generated for the prompt, set
10271 minibuf_prompt_pixel_width to its width in pixels. */
10272 xassert (it
->current_x
== 0);
10273 display_string (NULL
, minibuf_prompt
, Qnil
, 0, 0, &ti
,
10275 minibuf_prompt_width
= ti
.hpos
;
10276 minibuf_prompt_pixel_width
= ti
.current_x
;
10278 /* Transfer pixel and hpos information to IT. */
10279 it
->hpos
= ti
.hpos
;
10280 it
->current_x
= ti
.current_x
;
10283 #endif /* NO_PROMPT_IN_BUFFER */
10285 /* Move over display elements that are not visible because we are
10286 hscrolled. This may stop at an x-position < IT->first_visible_x
10287 if the first glyph is partially visible or if we hit a line end. */
10288 if (it
->current_x
< it
->first_visible_x
)
10289 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
10290 MOVE_TO_POS
| MOVE_TO_X
);
10292 /* Get the initial row height. This is either the height of the
10293 text hscrolled, if there is any, or zero. */
10294 row
->ascent
= it
->max_ascent
;
10295 row
->height
= it
->max_ascent
+ it
->max_descent
;
10296 row
->phys_ascent
= it
->max_phys_ascent
;
10297 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
10299 /* Loop generating characters. The loop is left with IT on the next
10300 character to display. */
10303 int n_glyphs_before
, hpos_before
, x_before
;
10306 /* Retrieve the next thing to display. Value is zero if end of
10308 if (!get_next_display_element (it
))
10310 /* Maybe add a space at the end of this line that is used to
10311 display the cursor there under X. */
10312 append_space (it
, 1);
10314 /* The position -1 below indicates a blank line not
10315 corresponding to any text, as opposed to an empty line
10316 corresponding to a line end. */
10317 if (row
->used
[TEXT_AREA
] <= 1)
10319 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
10320 row
->displays_text_p
= 0;
10322 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
))
10323 row
->indicate_empty_line_p
= 1;
10326 it
->continuation_lines_width
= 0;
10327 row
->ends_at_zv_p
= 1;
10331 /* Now, get the metrics of what we want to display. This also
10332 generates glyphs in `row' (which is IT->glyph_row). */
10333 n_glyphs_before
= row
->used
[TEXT_AREA
];
10335 PRODUCE_GLYPHS (it
);
10337 /* If this display element was in marginal areas, continue with
10339 if (it
->area
!= TEXT_AREA
)
10341 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
10342 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
10343 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
10344 row
->phys_height
= max (row
->phys_height
,
10345 it
->max_phys_ascent
+ it
->max_phys_descent
);
10346 set_iterator_to_next (it
);
10350 /* Does the display element fit on the line? If we truncate
10351 lines, we should draw past the right edge of the window. If
10352 we don't truncate, we want to stop so that we can display the
10353 continuation glyph before the right margin. If lines are
10354 continued, there are two possible strategies for characters
10355 resulting in more than 1 glyph (e.g. tabs): Display as many
10356 glyphs as possible in this line and leave the rest for the
10357 continuation line, or display the whole element in the next
10358 line. Original redisplay did the former, so we do it also. */
10359 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
10360 hpos_before
= it
->hpos
;
10364 && it
->current_x
< it
->last_visible_x
)
10367 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
10368 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
10369 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
10370 row
->phys_height
= max (row
->phys_height
,
10371 it
->max_phys_ascent
+ it
->max_phys_descent
);
10372 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
10373 row
->x
= x
- it
->first_visible_x
;
10378 struct glyph
*glyph
;
10380 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
10382 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
10383 new_x
= x
+ glyph
->pixel_width
;
10385 if (/* Lines are continued. */
10386 !it
->truncate_lines_p
10387 && (/* Glyph doesn't fit on the line. */
10388 new_x
> it
->last_visible_x
10389 /* Or it fits exactly on a window system frame. */
10390 || (new_x
== it
->last_visible_x
10391 && FRAME_WINDOW_P (it
->f
))))
10393 /* End of a continued line. */
10396 || (new_x
== it
->last_visible_x
10397 && FRAME_WINDOW_P (it
->f
)))
10399 /* Current glyph fits exactly on the line. We
10400 must continue the line because we can't draw
10401 the cursor after the glyph. */
10402 row
->continued_p
= 1;
10403 it
->current_x
= new_x
;
10404 it
->continuation_lines_width
+= new_x
;
10406 if (i
== nglyphs
- 1)
10407 set_iterator_to_next (it
);
10411 /* Display element draws past the right edge of
10412 the window. Restore positions to values
10413 before the element. The next line starts
10414 with current_x before the glyph that could
10415 not be displayed, so that TAB works right. */
10416 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
10418 /* Display continuation glyphs. */
10419 if (!FRAME_WINDOW_P (it
->f
))
10420 produce_special_glyphs (it
, IT_CONTINUATION
);
10421 row
->continued_p
= 1;
10424 it
->continuation_lines_width
+= x
;
10428 else if (new_x
> it
->first_visible_x
)
10430 /* Increment number of glyphs actually displayed. */
10433 if (x
< it
->first_visible_x
)
10434 /* Glyph is partially visible, i.e. row starts at
10435 negative X position. */
10436 row
->x
= x
- it
->first_visible_x
;
10440 /* Glyph is completely off the left margin of the
10441 window. This should not happen because of the
10442 move_it_in_display_line at the start of
10448 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
10449 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
10450 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
10451 row
->phys_height
= max (row
->phys_height
,
10452 it
->max_phys_ascent
+ it
->max_phys_descent
);
10454 /* End of this display line if row is continued. */
10455 if (row
->continued_p
)
10459 /* Is this a line end? If yes, we're also done, after making
10460 sure that a non-default face is extended up to the right
10461 margin of the window. */
10462 if (ITERATOR_AT_END_OF_LINE_P (it
))
10464 int used_before
= row
->used
[TEXT_AREA
];
10466 /* Add a space at the end of the line that is used to
10467 display the cursor there. */
10468 append_space (it
, 0);
10470 /* Extend the face to the end of the line. */
10471 extend_face_to_end_of_line (it
);
10473 /* Make sure we have the position. */
10474 if (used_before
== 0)
10475 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
10477 /* Consume the line end. This skips over invisible lines. */
10478 set_iterator_to_next (it
);
10479 it
->continuation_lines_width
= 0;
10483 /* Proceed with next display element. Note that this skips
10484 over lines invisible because of selective display. */
10485 set_iterator_to_next (it
);
10487 /* If we truncate lines, we are done when the last displayed
10488 glyphs reach past the right margin of the window. */
10489 if (it
->truncate_lines_p
10490 && (FRAME_WINDOW_P (it
->f
)
10491 ? (it
->current_x
>= it
->last_visible_x
)
10492 : (it
->current_x
> it
->last_visible_x
)))
10494 /* Maybe add truncation glyphs. */
10495 if (!FRAME_WINDOW_P (it
->f
))
10497 --it
->glyph_row
->used
[TEXT_AREA
];
10498 produce_special_glyphs (it
, IT_TRUNCATION
);
10501 row
->truncated_on_right_p
= 1;
10502 it
->continuation_lines_width
= 0;
10503 reseat_at_next_visible_line_start (it
, 0);
10504 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
10505 it
->hpos
= hpos_before
;
10506 it
->current_x
= x_before
;
10511 /* If line is not empty and hscrolled, maybe insert truncation glyphs
10512 at the left window margin. */
10513 if (it
->first_visible_x
10514 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
10516 if (!FRAME_WINDOW_P (it
->f
))
10517 insert_left_trunc_glyphs (it
);
10518 row
->truncated_on_left_p
= 1;
10521 /* If the start of this line is the overlay arrow-position, then
10522 mark this glyph row as the one containing the overlay arrow.
10523 This is clearly a mess with variable size fonts. It would be
10524 better to let it be displayed like cursors under X. */
10525 if (MARKERP (Voverlay_arrow_position
)
10526 && current_buffer
== XMARKER (Voverlay_arrow_position
)->buffer
10527 && (MATRIX_ROW_START_CHARPOS (row
)
10528 == marker_position (Voverlay_arrow_position
))
10529 && STRINGP (Voverlay_arrow_string
)
10530 && ! overlay_arrow_seen
)
10532 /* Overlay arrow in window redisplay is a bitmap. */
10533 if (!FRAME_WINDOW_P (it
->f
))
10535 struct glyph_row
*arrow_row
= get_overlay_arrow_glyph_row (it
->w
);
10536 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
10537 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
10538 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
10539 struct glyph
*p2
, *end
;
10541 /* Copy the arrow glyphs. */
10542 while (glyph
< arrow_end
)
10545 /* Throw away padding glyphs. */
10547 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
10548 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
10554 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
10558 overlay_arrow_seen
= 1;
10559 row
->overlay_arrow_p
= 1;
10562 /* Compute pixel dimensions of this line. */
10563 compute_line_metrics (it
);
10565 /* Remember the position at which this line ends. */
10566 row
->end
= it
->current
;
10568 /* Maybe set the cursor. If you change this, it's probably a good
10569 idea to also change the code in redisplay_window for cursor
10570 movement in an unchanged window. */
10571 if (it
->w
->cursor
.vpos
< 0
10572 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
10573 && MATRIX_ROW_END_CHARPOS (row
) >= PT
10574 && !(MATRIX_ROW_END_CHARPOS (row
) == PT
10575 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)
10576 || !row
->ends_at_zv_p
)))
10577 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
10579 /* Highlight trailing whitespace. */
10580 if (it
->show_trailing_whitespace_p
)
10581 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
10583 /* Prepare for the next line. This line starts horizontally at (X
10584 HPOS) = (0 0). Vertical positions are incremented. As a
10585 convenience for the caller, IT->glyph_row is set to the next
10587 it
->current_x
= it
->hpos
= 0;
10588 it
->current_y
+= row
->height
;
10591 return row
->displays_text_p
;
10596 /***********************************************************************
10598 ***********************************************************************/
10600 /* Redisplay the menu bar in the frame for window W.
10602 The menu bar of X frames that don't have X toolkit support is
10603 displayed in a special window W->frame->menu_bar_window.
10605 The menu bar of terminal frames is treated specially as far as
10606 glyph matrices are concerned. Menu bar lines are not part of
10607 windows, so the update is done directly on the frame matrix rows
10608 for the menu bar. */
10611 display_menu_bar (w
)
10614 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10619 /* Don't do all this for graphical frames. */
10621 if (!NILP (Vwindow_system
))
10624 #ifdef USE_X_TOOLKIT
10629 #ifdef USE_X_TOOLKIT
10630 xassert (!FRAME_WINDOW_P (f
));
10631 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MODE_LINE_FACE_ID
);
10632 it
.first_visible_x
= 0;
10633 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
10634 #else /* not USE_X_TOOLKIT */
10635 if (FRAME_WINDOW_P (f
))
10637 /* Menu bar lines are displayed in the desired matrix of the
10638 dummy window menu_bar_window. */
10639 struct window
*menu_w
;
10640 xassert (WINDOWP (f
->menu_bar_window
));
10641 menu_w
= XWINDOW (f
->menu_bar_window
);
10642 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
10643 MODE_LINE_FACE_ID
);
10644 it
.first_visible_x
= 0;
10645 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
10649 /* This is a TTY frame, i.e. character hpos/vpos are used as
10651 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
10652 MODE_LINE_FACE_ID
);
10653 it
.first_visible_x
= 0;
10654 it
.last_visible_x
= FRAME_WIDTH (f
);
10656 #endif /* not USE_X_TOOLKIT */
10658 /* Clear all rows of the menu bar. */
10659 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
10661 struct glyph_row
*row
= it
.glyph_row
+ i
;
10662 clear_glyph_row (row
);
10663 row
->enabled_p
= 1;
10664 row
->full_width_p
= 1;
10667 /* Make the first line of the menu bar appear in reverse video. */
10668 it
.glyph_row
->inverse_p
= mode_line_inverse_video
!= 0;
10670 /* Display all items of the menu bar. */
10671 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
10672 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
10674 Lisp_Object string
;
10676 /* Stop at nil string. */
10677 string
= XVECTOR (items
)->contents
[i
+ 1];
10681 /* Remember where item was displayed. */
10682 XSETFASTINT (XVECTOR (items
)->contents
[i
+ 3], it
.hpos
);
10684 /* Display the item, pad with one space. */
10685 if (it
.current_x
< it
.last_visible_x
)
10686 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
10687 XSTRING (string
)->size
+ 1, 0, 0, -1);
10690 /* Fill out the line with spaces. */
10691 if (it
.current_x
< it
.last_visible_x
)
10692 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
10694 /* Compute the total height of the lines. */
10695 compute_line_metrics (&it
);
10700 /***********************************************************************
10702 ***********************************************************************/
10704 /* Display the mode and/or top line of window W. */
10707 display_mode_lines (w
)
10710 /* These will be set while the mode line specs are processed. */
10711 line_number_displayed
= 0;
10712 w
->column_number_displayed
= Qnil
;
10714 if (WINDOW_WANTS_MODELINE_P (w
))
10715 display_mode_line (w
, MODE_LINE_FACE_ID
, current_buffer
->mode_line_format
);
10717 if (WINDOW_WANTS_TOP_LINE_P (w
))
10718 display_mode_line (w
, TOP_LINE_FACE_ID
, current_buffer
->top_line_format
);
10722 /* Display mode or top line of window W. FACE_ID specifies which line
10723 to display; it is either MODE_LINE_FACE_ID or TOP_LINE_FACE_ID.
10724 FORMAT is the mode line format to display. */
10727 display_mode_line (w
, face_id
, format
)
10729 enum face_id face_id
;
10730 Lisp_Object format
;
10735 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
10736 prepare_desired_row (it
.glyph_row
);
10738 /* Temporarily make frame's keyboard the current kboard so that
10739 kboard-local variables in the mode_line_format will get the right
10741 push_frame_kboard (it
.f
);
10742 display_mode_element (&it
, 0, 0, 0, format
);
10743 pop_frame_kboard ();
10745 /* Fill up with spaces. */
10746 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
10748 compute_line_metrics (&it
);
10749 it
.glyph_row
->full_width_p
= 1;
10750 it
.glyph_row
->mode_line_p
= 1;
10751 it
.glyph_row
->inverse_p
= mode_line_inverse_video
!= 0;
10752 it
.glyph_row
->continued_p
= 0;
10753 it
.glyph_row
->truncated_on_left_p
= 0;
10754 it
.glyph_row
->truncated_on_right_p
= 0;
10756 /* Make a 3D mode-line have a shadow at its right end. */
10757 face
= FACE_FROM_ID (it
.f
, face_id
);
10758 extend_face_to_end_of_line (&it
);
10759 if (face
->box
!= FACE_NO_BOX
)
10761 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
10762 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
10763 last
->right_box_line_p
= 1;
10768 /* Contribute ELT to the mode line for window IT->w. How it
10769 translates into text depends on its data type.
10771 IT describes the display environment in which we display, as usual.
10773 DEPTH is the depth in recursion. It is used to prevent
10774 infinite recursion here.
10776 FIELD_WIDTH is the number of characters the display of ELT should
10777 occupy in the mode line, and PRECISION is the maximum number of
10778 characters to display from ELT's representation. See
10779 display_string for details. *
10781 Returns the hpos of the end of the text generated by ELT. */
10784 display_mode_element (it
, depth
, field_width
, precision
, elt
)
10787 int field_width
, precision
;
10790 int n
= 0, field
, prec
;
10798 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
10802 /* A string: output it and check for %-constructs within it. */
10804 unsigned char *this = XSTRING (elt
)->data
;
10805 unsigned char *lisp_string
= this;
10807 while ((precision
<= 0 || n
< precision
)
10809 && (frame_title_ptr
10810 || it
->current_x
< it
->last_visible_x
))
10812 unsigned char *last
= this;
10814 /* Advance to end of string or next format specifier. */
10815 while ((c
= *this++) != '\0' && c
!= '%')
10818 if (this - 1 != last
)
10820 /* Output to end of string or up to '%'. Field width
10821 is length of string. Don't output more than
10822 PRECISION allows us. */
10823 prec
= --this - last
;
10824 if (precision
> 0 && prec
> precision
- n
)
10825 prec
= precision
- n
;
10827 if (frame_title_ptr
)
10828 n
+= store_frame_title (last
, prec
, prec
);
10830 n
+= display_string (NULL
, elt
, Qnil
, 0, last
- lisp_string
,
10831 it
, 0, prec
, 0, -1);
10833 else /* c == '%' */
10835 unsigned char *percent_position
= this;
10837 /* Get the specified minimum width. Zero means
10840 while ((c
= *this++) >= '0' && c
<= '9')
10841 field
= field
* 10 + c
- '0';
10843 /* Don't pad beyond the total padding allowed. */
10844 if (field_width
- n
> 0 && field
> field_width
- n
)
10845 field
= field_width
- n
;
10847 /* Note that either PRECISION <= 0 or N < PRECISION. */
10848 prec
= precision
- n
;
10851 n
+= display_mode_element (it
, depth
, field
, prec
,
10852 Vglobal_mode_string
);
10855 unsigned char *spec
10856 = decode_mode_spec (it
->w
, c
, field
, prec
);
10858 if (frame_title_ptr
)
10859 n
+= store_frame_title (spec
, field
, prec
);
10863 = it
->glyph_row
->used
[TEXT_AREA
];
10865 = percent_position
- XSTRING (elt
)->data
;
10867 = display_string (spec
, Qnil
, elt
, charpos
, 0, it
,
10868 field
, prec
, 0, -1);
10870 /* Assign to the glyphs written above the
10871 string where the `%x' came from, position
10875 struct glyph
*glyph
10876 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
10880 for (i
= 0; i
< nwritten
; ++i
)
10882 glyph
[i
].object
= elt
;
10883 glyph
[i
].charpos
= charpos
;
10896 /* A symbol: process the value of the symbol recursively
10897 as if it appeared here directly. Avoid error if symbol void.
10898 Special case: if value of symbol is a string, output the string
10901 register Lisp_Object tem
;
10902 tem
= Fboundp (elt
);
10905 tem
= Fsymbol_value (elt
);
10906 /* If value is a string, output that string literally:
10907 don't check for % within it. */
10910 prec
= XSTRING (tem
)->size
;
10911 if (precision
> 0 && prec
> precision
- n
)
10912 prec
= precision
- n
;
10913 if (frame_title_ptr
)
10914 n
+= store_frame_title (XSTRING (tem
)->data
, -1, prec
);
10916 n
+= display_string (NULL
, tem
, Qnil
, 0, 0, it
,
10919 else if (!EQ (tem
, elt
))
10921 /* Give up right away for nil or t. */
10931 register Lisp_Object car
, tem
;
10933 /* A cons cell: three distinct cases.
10934 If first element is a string or a cons, process all the elements
10935 and effectively concatenate them.
10936 If first element is a negative number, truncate displaying cdr to
10937 at most that many characters. If positive, pad (with spaces)
10938 to at least that many characters.
10939 If first element is a symbol, process the cadr or caddr recursively
10940 according to whether the symbol's value is non-nil or nil. */
10941 car
= XCONS (elt
)->car
;
10942 if (EQ (car
, QCeval
) && CONSP (XCDR (elt
)))
10944 /* An element of the form (:eval FORM) means evaluate FORM
10945 and use the result as mode line elements. */
10946 struct gcpro gcpro1
;
10949 spec
= eval_form (XCAR (XCDR (elt
)));
10951 n
+= display_mode_element (it
, depth
, field_width
- n
,
10952 precision
- n
, spec
);
10955 else if (SYMBOLP (car
))
10957 tem
= Fboundp (car
);
10958 elt
= XCONS (elt
)->cdr
;
10961 /* elt is now the cdr, and we know it is a cons cell.
10962 Use its car if CAR has a non-nil value. */
10965 tem
= Fsymbol_value (car
);
10967 { elt
= XCONS (elt
)->car
; goto tail_recurse
; }
10969 /* Symbol's value is nil (or symbol is unbound)
10970 Get the cddr of the original list
10971 and if possible find the caddr and use that. */
10972 elt
= XCONS (elt
)->cdr
;
10975 else if (!CONSP (elt
))
10977 elt
= XCONS (elt
)->car
;
10980 else if (INTEGERP (car
))
10982 register int lim
= XINT (car
);
10983 elt
= XCONS (elt
)->cdr
;
10986 /* Negative int means reduce maximum width. */
10987 if (precision
<= 0)
10990 precision
= min (precision
, -lim
);
10994 /* Padding specified. Don't let it be more than
10995 current maximum. */
10997 lim
= min (precision
, lim
);
10999 /* If that's more padding than already wanted, queue it.
11000 But don't reduce padding already specified even if
11001 that is beyond the current truncation point. */
11002 field_width
= max (lim
, field_width
);
11006 else if (STRINGP (car
) || CONSP (car
))
11008 register int limit
= 50;
11009 /* Limit is to protect against circular lists. */
11012 && (precision
<= 0 || n
< precision
))
11014 n
+= display_mode_element (it
, depth
, field_width
- n
,
11015 precision
- n
, XCONS (elt
)->car
);
11016 elt
= XCONS (elt
)->cdr
;
11024 if (frame_title_ptr
)
11025 n
+= store_frame_title ("*invalid*", 0, precision
- n
);
11027 n
+= display_string ("*invalid*", Qnil
, Qnil
, 0, 0, it
, 0,
11028 precision
- n
, 0, 0);
11032 /* Pad to FIELD_WIDTH. */
11033 if (field_width
> 0 && n
< field_width
)
11035 if (frame_title_ptr
)
11036 n
+= store_frame_title ("", field_width
- n
, 0);
11038 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
11046 /* Write a null-terminated, right justified decimal representation of
11047 the positive integer D to BUF using a minimal field width WIDTH. */
11050 pint2str (buf
, width
, d
)
11051 register char *buf
;
11052 register int width
;
11055 register char *p
= buf
;
11063 *p
++ = d
% 10 + '0';
11068 for (width
-= (int) (p
- buf
); width
> 0; --width
)
11079 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
11080 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
11081 type of CODING_SYSTEM. Return updated pointer into BUF. */
11083 static unsigned char invalid_eol_type
[] = "(*invalid*)";
11086 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
11087 Lisp_Object coding_system
;
11088 register char *buf
;
11092 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
11093 unsigned char *eol_str
;
11095 /* The EOL conversion we are using. */
11096 Lisp_Object eoltype
;
11098 val
= coding_system
;
11100 if (NILP (val
)) /* Not yet decided. */
11105 eoltype
= eol_mnemonic_undecided
;
11106 /* Don't mention EOL conversion if it isn't decided. */
11110 Lisp_Object eolvalue
;
11112 eolvalue
= Fget (coding_system
, Qeol_type
);
11114 while (!NILP (val
) && SYMBOLP (val
))
11116 val
= Fget (val
, Qcoding_system
);
11117 if (NILP (eolvalue
))
11118 eolvalue
= Fget (val
, Qeol_type
);
11122 *buf
++ = XFASTINT (XVECTOR (val
)->contents
[1]);
11126 /* The EOL conversion that is normal on this system. */
11128 if (NILP (eolvalue
)) /* Not yet decided. */
11129 eoltype
= eol_mnemonic_undecided
;
11130 else if (VECTORP (eolvalue
)) /* Not yet decided. */
11131 eoltype
= eol_mnemonic_undecided
;
11132 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
11133 eoltype
= (XFASTINT (eolvalue
) == 0
11134 ? eol_mnemonic_unix
11135 : (XFASTINT (eolvalue
) == 1
11136 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
11142 /* Mention the EOL conversion if it is not the usual one. */
11143 if (STRINGP (eoltype
))
11145 eol_str
= XSTRING (eoltype
)->data
;
11146 eol_str_len
= XSTRING (eoltype
)->size
;
11148 else if (INTEGERP (eoltype
)
11149 && CHAR_VALID_P (XINT (eoltype
), 0))
11151 int c
= XINT (eoltype
);
11152 unsigned char work
[4];
11154 eol_str_len
= CHAR_STRING (XINT (eoltype
), work
, eol_str
);
11158 eol_str
= invalid_eol_type
;
11159 eol_str_len
= sizeof (invalid_eol_type
) - 1;
11161 bcopy (eol_str
, buf
, eol_str_len
);
11162 buf
+= eol_str_len
;
11168 /* Return a string for the output of a mode line %-spec for window W,
11169 generated by character C. PRECISION >= 0 means don't return a
11170 string longer than that value. FIELD_WIDTH > 0 means pad the
11171 string returned with spaces to that value. */
11173 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
11176 decode_mode_spec (w
, c
, field_width
, precision
)
11179 int field_width
, precision
;
11182 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11183 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
11184 struct buffer
*b
= XBUFFER (w
->buffer
);
11191 if (!NILP (b
->read_only
))
11193 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
11198 /* This differs from %* only for a modified read-only buffer. */
11199 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
11201 if (!NILP (b
->read_only
))
11206 /* This differs from %* in ignoring read-only-ness. */
11207 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
11219 if (command_loop_level
> 5)
11221 p
= decode_mode_spec_buf
;
11222 for (i
= 0; i
< command_loop_level
; i
++)
11225 return decode_mode_spec_buf
;
11233 if (command_loop_level
> 5)
11235 p
= decode_mode_spec_buf
;
11236 for (i
= 0; i
< command_loop_level
; i
++)
11239 return decode_mode_spec_buf
;
11246 /* Let lots_of_dashes be a string of infinite length. */
11247 if (field_width
<= 0
11248 || field_width
> sizeof (lots_of_dashes
))
11250 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
11251 decode_mode_spec_buf
[i
] = '-';
11252 decode_mode_spec_buf
[i
] = '\0';
11253 return decode_mode_spec_buf
;
11256 return lots_of_dashes
;
11265 int col
= current_column ();
11266 XSETFASTINT (w
->column_number_displayed
, col
);
11267 pint2str (decode_mode_spec_buf
, field_width
, col
);
11268 return decode_mode_spec_buf
;
11272 /* %F displays the frame name. */
11273 if (!NILP (f
->title
))
11274 return (char *) XSTRING (f
->title
)->data
;
11275 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
11276 return (char *) XSTRING (f
->name
)->data
;
11285 int startpos
= XMARKER (w
->start
)->charpos
;
11286 int startpos_byte
= marker_byte_position (w
->start
);
11287 int line
, linepos
, linepos_byte
, topline
;
11289 int height
= XFASTINT (w
->height
);
11291 /* If we decided that this buffer isn't suitable for line numbers,
11292 don't forget that too fast. */
11293 if (EQ (w
->base_line_pos
, w
->buffer
))
11295 /* But do forget it, if the window shows a different buffer now. */
11296 else if (BUFFERP (w
->base_line_pos
))
11297 w
->base_line_pos
= Qnil
;
11299 /* If the buffer is very big, don't waste time. */
11300 if (BUF_ZV (b
) - BUF_BEGV (b
) > line_number_display_limit
)
11302 w
->base_line_pos
= Qnil
;
11303 w
->base_line_number
= Qnil
;
11307 if (!NILP (w
->base_line_number
)
11308 && !NILP (w
->base_line_pos
)
11309 && XFASTINT (w
->base_line_pos
) <= startpos
)
11311 line
= XFASTINT (w
->base_line_number
);
11312 linepos
= XFASTINT (w
->base_line_pos
);
11313 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
11318 linepos
= BUF_BEGV (b
);
11319 linepos_byte
= BUF_BEGV_BYTE (b
);
11322 /* Count lines from base line to window start position. */
11323 nlines
= display_count_lines (linepos
, linepos_byte
,
11327 topline
= nlines
+ line
;
11329 /* Determine a new base line, if the old one is too close
11330 or too far away, or if we did not have one.
11331 "Too close" means it's plausible a scroll-down would
11332 go back past it. */
11333 if (startpos
== BUF_BEGV (b
))
11335 XSETFASTINT (w
->base_line_number
, topline
);
11336 XSETFASTINT (w
->base_line_pos
, BUF_BEGV (b
));
11338 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
11339 || linepos
== BUF_BEGV (b
))
11341 int limit
= BUF_BEGV (b
);
11342 int limit_byte
= BUF_BEGV_BYTE (b
);
11344 int distance
= (height
* 2 + 30) * 200;
11346 if (startpos
- distance
> limit
)
11348 limit
= startpos
- distance
;
11349 limit_byte
= CHAR_TO_BYTE (limit
);
11352 nlines
= display_count_lines (startpos
, startpos_byte
,
11354 - (height
* 2 + 30),
11356 /* If we couldn't find the lines we wanted within
11357 200 chars per line,
11358 give up on line numbers for this window. */
11359 if (position
== limit_byte
&& limit
== startpos
- distance
)
11361 w
->base_line_pos
= w
->buffer
;
11362 w
->base_line_number
= Qnil
;
11366 XSETFASTINT (w
->base_line_number
, topline
- nlines
);
11367 XSETFASTINT (w
->base_line_pos
, BYTE_TO_CHAR (position
));
11370 /* Now count lines from the start pos to point. */
11371 nlines
= display_count_lines (startpos
, startpos_byte
,
11372 PT_BYTE
, PT
, &junk
);
11374 /* Record that we did display the line number. */
11375 line_number_displayed
= 1;
11377 /* Make the string to show. */
11378 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
11379 return decode_mode_spec_buf
;
11382 char* p
= decode_mode_spec_buf
;
11383 int pad
= field_width
- 2;
11388 return decode_mode_spec_buf
;
11394 obj
= b
->mode_name
;
11398 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
11404 int pos
= marker_position (w
->start
);
11405 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
11407 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
11409 if (pos
<= BUF_BEGV (b
))
11414 else if (pos
<= BUF_BEGV (b
))
11418 if (total
> 1000000)
11419 /* Do it differently for a large value, to avoid overflow. */
11420 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
11422 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
11423 /* We can't normally display a 3-digit number,
11424 so get us a 2-digit number that is close. */
11427 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
11428 return decode_mode_spec_buf
;
11432 /* Display percentage of size above the bottom of the screen. */
11435 int toppos
= marker_position (w
->start
);
11436 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
11437 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
11439 if (botpos
>= BUF_ZV (b
))
11441 if (toppos
<= BUF_BEGV (b
))
11448 if (total
> 1000000)
11449 /* Do it differently for a large value, to avoid overflow. */
11450 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
11452 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
11453 /* We can't normally display a 3-digit number,
11454 so get us a 2-digit number that is close. */
11457 if (toppos
<= BUF_BEGV (b
))
11458 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
11460 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
11461 return decode_mode_spec_buf
;
11466 /* status of process */
11467 obj
= Fget_buffer_process (w
->buffer
);
11469 return "no process";
11470 #ifdef subprocesses
11471 obj
= Fsymbol_name (Fprocess_status (obj
));
11475 case 't': /* indicate TEXT or BINARY */
11476 #ifdef MODE_LINE_BINARY_TEXT
11477 return MODE_LINE_BINARY_TEXT (b
);
11483 /* coding-system (not including end-of-line format) */
11485 /* coding-system (including end-of-line type) */
11487 int eol_flag
= (c
== 'Z');
11488 char *p
= decode_mode_spec_buf
;
11490 if (! FRAME_WINDOW_P (f
))
11492 /* No need to mention EOL here--the terminal never needs
11493 to do EOL conversion. */
11494 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
11495 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
11497 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
11500 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
11501 #ifdef subprocesses
11502 obj
= Fget_buffer_process (Fcurrent_buffer ());
11503 if (PROCESSP (obj
))
11505 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
11507 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
11510 #endif /* subprocesses */
11513 return decode_mode_spec_buf
;
11518 return (char *) XSTRING (obj
)->data
;
11524 /* Count up to COUNT lines starting from START / START_BYTE.
11525 But don't go beyond LIMIT_BYTE.
11526 Return the number of lines thus found (always nonnegative).
11528 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
11531 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
11532 int start
, start_byte
, limit_byte
, count
;
11535 register unsigned char *cursor
;
11536 unsigned char *base
;
11538 register int ceiling
;
11539 register unsigned char *ceiling_addr
;
11540 int orig_count
= count
;
11542 /* If we are not in selective display mode,
11543 check only for newlines. */
11544 int selective_display
= (!NILP (current_buffer
->selective_display
)
11545 && !INTEGERP (current_buffer
->selective_display
));
11549 while (start_byte
< limit_byte
)
11551 ceiling
= BUFFER_CEILING_OF (start_byte
);
11552 ceiling
= min (limit_byte
- 1, ceiling
);
11553 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
11554 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
11557 if (selective_display
)
11558 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
11561 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
11564 if (cursor
!= ceiling_addr
)
11568 start_byte
+= cursor
- base
+ 1;
11569 *byte_pos_ptr
= start_byte
;
11573 if (++cursor
== ceiling_addr
)
11579 start_byte
+= cursor
- base
;
11584 while (start_byte
> limit_byte
)
11586 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
11587 ceiling
= max (limit_byte
, ceiling
);
11588 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
11589 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
11592 if (selective_display
)
11593 while (--cursor
!= ceiling_addr
11594 && *cursor
!= '\n' && *cursor
!= 015)
11597 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
11600 if (cursor
!= ceiling_addr
)
11604 start_byte
+= cursor
- base
+ 1;
11605 *byte_pos_ptr
= start_byte
;
11606 /* When scanning backwards, we should
11607 not count the newline posterior to which we stop. */
11608 return - orig_count
- 1;
11614 /* Here we add 1 to compensate for the last decrement
11615 of CURSOR, which took it past the valid range. */
11616 start_byte
+= cursor
- base
+ 1;
11620 *byte_pos_ptr
= limit_byte
;
11623 return - orig_count
+ count
;
11624 return orig_count
- count
;
11630 /***********************************************************************
11632 ***********************************************************************/
11634 /* Display a NUL-terminated string, starting with index START.
11636 If STRING is non-null, display that C string. Otherwise, the Lisp
11637 string LISP_STRING is displayed.
11639 If FACE_STRING is not nil, FACE_STRING_POS is a position in
11640 FACE_STRING. Display STRING or LISP_STRING with the face at
11641 FACE_STRING_POS in FACE_STRING:
11643 Display the string in the environment given by IT, but use the
11644 standard display table, temporarily.
11646 FIELD_WIDTH is the minimum number of output glyphs to produce.
11647 If STRING has fewer characters than FIELD_WIDTH, pad to the right
11648 with spaces. If STRING has more characters, more than FIELD_WIDTH
11649 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
11651 PRECISION is the maximum number of characters to output from
11652 STRING. PRECISION < 0 means don't truncate the string.
11654 This is roughly equivalent to printf format specifiers:
11656 FIELD_WIDTH PRECISION PRINTF
11657 ----------------------------------------
11663 MULTIBYTE zero means do not display multibyte chars, > 0 means do
11664 display them, and < 0 means obey the current buffer's value of
11665 enable_multibyte_characters.
11667 Value is the number of glyphs produced. */
11670 display_string (string
, lisp_string
, face_string
, face_string_pos
,
11671 start
, it
, field_width
, precision
, max_x
, multibyte
)
11672 unsigned char *string
;
11673 Lisp_Object lisp_string
;
11676 int field_width
, precision
, max_x
;
11679 int hpos_at_start
= it
->hpos
;
11680 int saved_face_id
= it
->face_id
;
11681 struct glyph_row
*row
= it
->glyph_row
;
11683 /* Initialize the iterator IT for iteration over STRING beginning
11684 with index START. We assume that IT may be modified here (which
11685 means that display_line has to do something when displaying a
11686 mini-buffer prompt, which it does). */
11687 reseat_to_string (it
, string
, lisp_string
, start
,
11688 precision
, field_width
, multibyte
);
11690 /* If displaying STRING, set up the face of the iterator
11691 from LISP_STRING, if that's given. */
11692 if (STRINGP (face_string
))
11698 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
11699 0, it
->region_beg_charpos
,
11700 it
->region_end_charpos
,
11701 &endptr
, it
->base_face_id
);
11702 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
11703 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
11706 /* Set max_x to the maximum allowed X position. Don't let it go
11707 beyond the right edge of the window. */
11709 max_x
= it
->last_visible_x
;
11711 max_x
= min (max_x
, it
->last_visible_x
);
11713 /* Skip over display elements that are not visible. because IT->w is
11715 if (it
->current_x
< it
->first_visible_x
)
11716 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
11717 MOVE_TO_POS
| MOVE_TO_X
);
11719 row
->ascent
= it
->max_ascent
;
11720 row
->height
= it
->max_ascent
+ it
->max_descent
;
11721 row
->phys_ascent
= it
->max_phys_ascent
;
11722 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
11724 /* This condition is for the case that we are called with current_x
11725 past last_visible_x. */
11726 while (it
->current_x
< max_x
)
11728 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
11730 /* Get the next display element. */
11731 if (!get_next_display_element (it
))
11734 /* Produce glyphs. */
11735 x_before
= it
->current_x
;
11736 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
11737 PRODUCE_GLYPHS (it
);
11739 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
11742 while (i
< nglyphs
)
11744 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
11746 if (!it
->truncate_lines_p
11747 && x
+ glyph
->pixel_width
> max_x
)
11749 /* End of continued line or max_x reached. */
11750 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
11754 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
11756 /* Glyph is at least partially visible. */
11758 if (x
< it
->first_visible_x
)
11759 it
->glyph_row
->x
= x
- it
->first_visible_x
;
11763 /* Glyph is off the left margin of the display area.
11764 Should not happen. */
11768 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
11769 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
11770 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
11771 row
->phys_height
= max (row
->phys_height
,
11772 it
->max_phys_ascent
+ it
->max_phys_descent
);
11773 x
+= glyph
->pixel_width
;
11777 /* Stop if max_x reached. */
11781 /* Stop at line ends. */
11782 if (ITERATOR_AT_END_OF_LINE_P (it
))
11784 it
->continuation_lines_width
= 0;
11788 set_iterator_to_next (it
);
11790 /* Stop if truncating at the right edge. */
11791 if (it
->truncate_lines_p
11792 && it
->current_x
>= it
->last_visible_x
)
11794 /* Add truncation mark, but don't do it if the line is
11795 truncated at a padding space. */
11796 if (IT_CHARPOS (*it
) < it
->string_nchars
)
11798 if (!FRAME_WINDOW_P (it
->f
))
11799 produce_special_glyphs (it
, IT_TRUNCATION
);
11800 it
->glyph_row
->truncated_on_right_p
= 1;
11806 /* Maybe insert a truncation at the left. */
11807 if (it
->first_visible_x
11808 && IT_CHARPOS (*it
) > 0)
11810 if (!FRAME_WINDOW_P (it
->f
))
11811 insert_left_trunc_glyphs (it
);
11812 it
->glyph_row
->truncated_on_left_p
= 1;
11815 it
->face_id
= saved_face_id
;
11817 /* Value is number of columns displayed. */
11818 return it
->hpos
- hpos_at_start
;
11823 /* This is like a combination of memq and assq. Return 1 if PROPVAL
11824 appears as an element of LIST or as the car of an element of LIST.
11825 If PROPVAL is a list, compare each element against LIST in that
11826 way, and return 1 if any element of PROPVAL is found in LIST.
11827 Otherwise return 0. This function cannot quit. */
11830 invisible_p (propval
, list
)
11831 register Lisp_Object propval
;
11834 register Lisp_Object tail
, proptail
;
11835 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
11837 register Lisp_Object tem
;
11838 tem
= XCONS (tail
)->car
;
11839 if (EQ (propval
, tem
))
11841 if (CONSP (tem
) && EQ (propval
, XCONS (tem
)->car
))
11844 if (CONSP (propval
))
11845 for (proptail
= propval
; CONSP (proptail
);
11846 proptail
= XCONS (proptail
)->cdr
)
11848 Lisp_Object propelt
;
11849 propelt
= XCONS (proptail
)->car
;
11850 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
11852 register Lisp_Object tem
;
11853 tem
= XCONS (tail
)->car
;
11854 if (EQ (propelt
, tem
))
11856 if (CONSP (tem
) && EQ (propelt
, XCONS (tem
)->car
))
11864 /* Return 1 if PROPVAL appears as the car of an element of LIST and
11865 the cdr of that element is non-nil. If PROPVAL is a list, check
11866 each element of PROPVAL in that way, and the first time some
11867 element is found, return 1 if the cdr of that element is non-nil.
11868 Otherwise return 0. This function cannot quit. */
11871 invisible_ellipsis_p (propval
, list
)
11872 register Lisp_Object propval
;
11875 register Lisp_Object tail
, proptail
;
11876 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
11878 register Lisp_Object tem
;
11879 tem
= XCONS (tail
)->car
;
11880 if (CONSP (tem
) && EQ (propval
, XCONS (tem
)->car
))
11881 return ! NILP (XCONS (tem
)->cdr
);
11883 if (CONSP (propval
))
11884 for (proptail
= propval
; CONSP (proptail
);
11885 proptail
= XCONS (proptail
)->cdr
)
11887 Lisp_Object propelt
;
11888 propelt
= XCONS (proptail
)->car
;
11889 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
11891 register Lisp_Object tem
;
11892 tem
= XCONS (tail
)->car
;
11893 if (CONSP (tem
) && EQ (propelt
, XCONS (tem
)->car
))
11894 return ! NILP (XCONS (tem
)->cdr
);
11902 /***********************************************************************
11904 ***********************************************************************/
11909 echo_area_message
= previous_echo_area_message
= Qnil
;
11910 staticpro (&echo_area_message
);
11911 staticpro (&previous_echo_area_message
);
11913 staticpro (&Qinhibit_redisplay
);
11914 Qinhibit_redisplay
= intern ("inhibit-redisplay");
11917 defsubr (&Sdump_glyph_matrix
);
11918 defsubr (&Sdump_glyph_row
);
11919 defsubr (&Sdump_toolbar_row
);
11920 defsubr (&Strace_redisplay_toggle
);
11923 staticpro (&Qmenu_bar_update_hook
);
11924 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
11926 staticpro (&Qoverriding_terminal_local_map
);
11927 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
11929 staticpro (&Qoverriding_local_map
);
11930 Qoverriding_local_map
= intern ("overriding-local-map");
11932 staticpro (&Qwindow_scroll_functions
);
11933 Qwindow_scroll_functions
= intern ("window-scroll-functions");
11935 staticpro (&Qredisplay_end_trigger_functions
);
11936 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
11938 staticpro (&Qinhibit_point_motion_hooks
);
11939 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
11941 staticpro (&Qdisplay
);
11942 Qdisplay
= intern ("display");
11943 staticpro (&Qleft_margin
);
11944 Qspace_width
= intern ("space-width");
11945 staticpro (&Qspace_width
);
11946 Qheight
= intern ("height");
11947 staticpro (&Qheight
);
11948 Qraise
= intern ("raise");
11949 staticpro (&Qraise
);
11950 Qspace
= intern ("space");
11951 staticpro (&Qspace
);
11952 Qleft_margin
= intern ("left-margin");
11953 staticpro (&Qright_margin
);
11954 Qright_margin
= intern ("right-margin");
11955 Qalign_to
= intern ("align-to");
11956 staticpro (&Qalign_to
);
11957 QCalign_to
= intern (":align-to");
11958 staticpro (&QCalign_to
);
11959 Qwidth
= intern ("width");
11960 staticpro (&Qwidth
);
11961 Qrelative_width
= intern ("relative-width");
11962 staticpro (&Qrelative_width
);
11963 QCrelative_width
= intern (":relative-width");
11964 staticpro (&QCrelative_width
);
11965 QCrelative_height
= intern (":relative-height");
11966 staticpro (&QCrelative_height
);
11967 QCeval
= intern (":eval");
11968 staticpro (&QCeval
);
11969 QCwhen
= intern (":when");
11970 staticpro (&QCwhen
);
11971 Qfontified
= intern ("fontified");
11972 staticpro (&Qfontified
);
11973 Qfontification_functions
= intern ("fontification-functions");
11974 staticpro (&Qfontification_functions
);
11975 Qshow_trailing_whitespace
= intern ("show-trailing-whitespace");
11976 staticpro (&Qshow_trailing_whitespace
);
11977 Qtrailing_whitespace
= intern ("trailing-whitespace");
11978 staticpro (&Qtrailing_whitespace
);
11979 Qimage
= intern ("image");
11980 staticpro (&Qimage
);
11982 staticpro (&last_arrow_position
);
11983 staticpro (&last_arrow_string
);
11984 last_arrow_position
= Qnil
;
11985 last_arrow_string
= Qnil
;
11987 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
11988 "Non-nil means don't actually do any redisplay.\n\
11989 This is used for internal purposes.");
11990 Vinhibit_redisplay
= Qnil
;
11992 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
11993 "String (or mode line construct) included (normally) in `mode-line-format'.");
11994 Vglobal_mode_string
= Qnil
;
11996 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
11997 "Marker for where to display an arrow on top of the buffer text.\n\
11998 This must be the beginning of a line in order to work.\n\
11999 See also `overlay-arrow-string'.");
12000 Voverlay_arrow_position
= Qnil
;
12002 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
12003 "String to display as an arrow. See also `overlay-arrow-position'.");
12004 Voverlay_arrow_string
= Qnil
;
12006 DEFVAR_INT ("scroll-step", &scroll_step
,
12007 "*The number of lines to try scrolling a window by when point moves out.\n\
12008 If that fails to bring point back on frame, point is centered instead.\n\
12009 If this is zero, point is always centered after it moves off frame.");
12011 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
12012 "*Scroll up to this many lines, to bring point back on screen.");
12013 scroll_conservatively
= 0;
12015 DEFVAR_INT ("scroll-margin", &scroll_margin
,
12016 "*Number of lines of margin at the top and bottom of a window.\n\
12017 Recenter the window whenever point gets within this many lines\n\
12018 of the top or bottom of the window.");
12022 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, "Don't ask");
12025 DEFVAR_BOOL ("truncate-partial-width-windows",
12026 &truncate_partial_width_windows
,
12027 "*Non-nil means truncate lines in all windows less than full frame wide.");
12028 truncate_partial_width_windows
= 1;
12030 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
12031 "*Non-nil means use inverse video for the mode line.");
12032 mode_line_inverse_video
= 1;
12034 DEFVAR_INT ("line-number-display-limit", &line_number_display_limit
,
12035 "*Maximum buffer size for which line number should be displayed.\n\
12036 If the buffer is bigger than this, the line number does not appear\n\
12037 in the mode line.");
12038 line_number_display_limit
= 1000000;
12040 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
12041 "*Non-nil means highlight region even in nonselected windows.");
12042 highlight_nonselected_windows
= 0;
12044 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
12045 "Non-nil if more than one frame is visible on this display.\n\
12046 Minibuffer-only frames don't count, but iconified frames do.\n\
12047 This variable is not guaranteed to be accurate except while processing\n\
12048 `frame-title-format' and `icon-title-format'.");
12050 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
12051 "Template for displaying the title bar of visible frames.\n\
12052 \(Assuming the window manager supports this feature.)\n\
12053 This variable has the same structure as `mode-line-format' (which see),\n\
12054 and is used only on frames for which no explicit name has been set\n\
12055 \(see `modify-frame-parameters').");
12056 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
12057 "Template for displaying the title bar of an iconified frame.\n\
12058 \(Assuming the window manager supports this feature.)\n\
12059 This variable has the same structure as `mode-line-format' (which see),\n\
12060 and is used only on frames for which no explicit name has been set\n\
12061 \(see `modify-frame-parameters').");
12063 = Vframe_title_format
12064 = Fcons (intern ("multiple-frames"),
12065 Fcons (build_string ("%b"),
12066 Fcons (Fcons (build_string (""),
12067 Fcons (intern ("invocation-name"),
12068 Fcons (build_string ("@"),
12069 Fcons (intern ("system-name"),
12073 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
12074 "Maximum number of lines to keep in the message log buffer.\n\
12075 If nil, disable message logging. If t, log messages but don't truncate\n\
12076 the buffer when it becomes large.");
12077 XSETFASTINT (Vmessage_log_max
, 50);
12079 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
12080 "Functions called before redisplay, if window sizes have changed.\n\
12081 The value should be a list of functions that take one argument.\n\
12082 Just before redisplay, for each frame, if any of its windows have changed\n\
12083 size since the last redisplay, or have been split or deleted,\n\
12084 all the functions in the list are called, with the frame as argument.");
12085 Vwindow_size_change_functions
= Qnil
;
12087 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
12088 "List of Functions to call before redisplaying a window with scrolling.\n\
12089 Each function is called with two arguments, the window\n\
12090 and its new display-start position. Note that the value of `window-end'\n\
12091 is not valid when these functions are called.");
12092 Vwindow_scroll_functions
= Qnil
;
12094 DEFVAR_BOOL ("auto-resize-toolbars", &auto_resize_toolbars_p
,
12095 "*Non-nil means automatically resize toolbars.\n\
12096 This increases a toolbar's height if not all toolbar items are visible.\n\
12097 It decreases a toolbar's height when it would display blank lines\n\
12099 auto_resize_toolbars_p
= 1;
12101 DEFVAR_BOOL ("auto-raise-toolbar-buttons", &auto_raise_toolbar_buttons_p
,
12102 "*Non-nil means raise toolbar buttons when the mouse moves over them.");
12103 auto_raise_toolbar_buttons_p
= 1;
12105 DEFVAR_INT ("toolbar-button-margin", &toolbar_button_margin
,
12106 "*Margin around toolbar buttons in pixels.");
12107 toolbar_button_margin
= 1;
12109 DEFVAR_INT ("toolbar-button-relief", &toolbar_button_relief
,
12110 "Relief thickness of toolbar buttons.");
12111 toolbar_button_relief
= 3;
12113 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
12114 "List of functions to call to fontify regions of text.\n\
12115 Each function is called with one argument POS. Functions must\n\
12116 fontify a region starting at POS in the current buffer, and give\n\
12117 fontified regions the property `fontified'.\n\
12118 This variable automatically becomes buffer-local when set.");
12119 Vfontification_functions
= Qnil
;
12120 Fmake_local_variable (Qfontification_functions
);
12122 DEFVAR_BOOL ("unibyte-display-via-language-environment",
12123 &unibyte_display_via_language_environment
,
12124 "*Non-nil means display unibyte text according to language environment.\n\
12125 Specifically this means that unibyte non-ASCII characters\n\
12126 are displayed by converting them to the equivalent multibyte characters\n\
12127 according to the current language environment. As a result, they are\n\
12128 displayed according to the current fontset.");
12129 unibyte_display_via_language_environment
= 0;
12133 /* Initialize this module when Emacs starts. */
12138 Lisp_Object root_window
;
12139 struct window
*mini_w
;
12141 CHARPOS (this_line_start_pos
) = 0;
12143 mini_w
= XWINDOW (minibuf_window
);
12144 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
12146 echo_area_glyphs
= 0;
12147 previous_echo_glyphs
= 0;
12148 echo_area_message
= previous_echo_area_message
= Qnil
;
12150 if (!noninteractive
)
12152 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
12155 XSETFASTINT (XWINDOW (root_window
)->top
, FRAME_TOP_MARGIN (f
));
12156 set_window_height (root_window
,
12157 FRAME_HEIGHT (f
) - 1 - FRAME_TOP_MARGIN (f
),
12159 XSETFASTINT (mini_w
->top
, FRAME_HEIGHT (f
) - 1);
12160 set_window_height (minibuf_window
, 1, 0);
12162 XSETFASTINT (XWINDOW (root_window
)->width
, FRAME_WIDTH (f
));
12163 XSETFASTINT (mini_w
->width
, FRAME_WIDTH (f
));
12165 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
12166 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
12167 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
12169 /* The default ellipsis glyphs `...'. */
12170 for (i
= 0; i
< 3; ++i
)
12171 XSETFASTINT (default_invis_vector
[i
], '.');
12174 #ifdef HAVE_WINDOW_SYSTEM
12176 /* Allocate the buffer for frame titles. */
12178 frame_title_buf
= (char *) xmalloc (size
);
12179 frame_title_buf_end
= frame_title_buf
+ size
;
12180 frame_title_ptr
= NULL
;
12182 #endif /* HAVE_WINDOW_SYSTEM */