1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 99, 2000
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. */
173 #include "keyboard.h"
176 #include "termchar.h"
177 #include "dispextern.h"
181 #include "commands.h"
184 #include "termhooks.h"
185 #include "intervals.h"
188 #include "region-cache.h"
191 #ifdef HAVE_X_WINDOWS
201 #define min(a, b) ((a) < (b) ? (a) : (b))
202 #define max(a, b) ((a) > (b) ? (a) : (b))
204 #define INFINITY 10000000
206 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
207 extern void set_frame_menubar
P_ ((struct frame
*f
, int, int));
208 extern int pending_menu_activation
;
211 extern int interrupt_input
;
212 extern int command_loop_level
;
214 extern int minibuffer_auto_raise
;
216 extern Lisp_Object Qface
;
218 extern Lisp_Object Voverriding_local_map
;
219 extern Lisp_Object Voverriding_local_map_menu_flag
;
220 extern Lisp_Object Qmenu_item
;
222 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
223 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
224 Lisp_Object Qredisplay_end_trigger_functions
;
225 Lisp_Object Qinhibit_point_motion_hooks
;
226 Lisp_Object QCeval
, Qwhen
, QCfile
, QCdata
;
227 Lisp_Object Qfontified
;
228 Lisp_Object Qgrow_only
;
230 /* Functions called to fontify regions of text. */
232 Lisp_Object Vfontification_functions
;
233 Lisp_Object Qfontification_functions
;
235 /* Non-zero means draw tool bar buttons raised when the mouse moves
238 int auto_raise_tool_bar_buttons_p
;
240 /* Margin around tool bar buttons in pixels. */
242 int tool_bar_button_margin
;
244 /* Thickness of shadow to draw around tool bar buttons. */
246 int tool_bar_button_relief
;
248 /* Non-zero means automatically resize tool-bars so that all tool-bar
249 items are visible, and no blank lines remain. */
251 int auto_resize_tool_bars_p
;
253 /* Non-nil means don't actually do any redisplay. */
255 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
257 /* Names of text properties relevant for redisplay. */
259 Lisp_Object Qdisplay
, Qrelative_width
, Qalign_to
;
260 extern Lisp_Object Qface
, Qinvisible
, Qimage
, Qwidth
;
262 /* Symbols used in text property values. */
264 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
265 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
267 extern Lisp_Object Qheight
;
269 /* Non-nil means highlight trailing whitespace. */
271 Lisp_Object Vshow_trailing_whitespace
;
273 /* Name of the face used to highlight trailing whitespace. */
275 Lisp_Object Qtrailing_whitespace
;
277 /* The symbol `image' which is the car of the lists used to represent
282 /* Non-zero means print newline to stdout before next mini-buffer
285 int noninteractive_need_newline
;
287 /* Non-zero means print newline to message log before next message. */
289 static int message_log_need_newline
;
292 /* The buffer position of the first character appearing entirely or
293 partially on the line of the selected window which contains the
294 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
295 redisplay optimization in redisplay_internal. */
297 static struct text_pos this_line_start_pos
;
299 /* Number of characters past the end of the line above, including the
300 terminating newline. */
302 static struct text_pos this_line_end_pos
;
304 /* The vertical positions and the height of this line. */
306 static int this_line_vpos
;
307 static int this_line_y
;
308 static int this_line_pixel_height
;
310 /* X position at which this display line starts. Usually zero;
311 negative if first character is partially visible. */
313 static int this_line_start_x
;
315 /* Buffer that this_line_.* variables are referring to. */
317 static struct buffer
*this_line_buffer
;
319 /* Nonzero means truncate lines in all windows less wide than the
322 int truncate_partial_width_windows
;
324 /* A flag to control how to display unibyte 8-bit character. */
326 int unibyte_display_via_language_environment
;
328 /* Nonzero means we have more than one non-mini-buffer-only frame.
329 Not guaranteed to be accurate except while parsing
330 frame-title-format. */
334 Lisp_Object Vglobal_mode_string
;
336 /* Marker for where to display an arrow on top of the buffer text. */
338 Lisp_Object Voverlay_arrow_position
;
340 /* String to display for the arrow. Only used on terminal frames. */
342 Lisp_Object Voverlay_arrow_string
;
344 /* Values of those variables at last redisplay. However, if
345 Voverlay_arrow_position is a marker, last_arrow_position is its
346 numerical position. */
348 static Lisp_Object last_arrow_position
, last_arrow_string
;
350 /* Like mode-line-format, but for the title bar on a visible frame. */
352 Lisp_Object Vframe_title_format
;
354 /* Like mode-line-format, but for the title bar on an iconified frame. */
356 Lisp_Object Vicon_title_format
;
358 /* List of functions to call when a window's size changes. These
359 functions get one arg, a frame on which one or more windows' sizes
362 static Lisp_Object Vwindow_size_change_functions
;
364 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
366 /* Nonzero if overlay arrow has been displayed once in this window. */
368 static int overlay_arrow_seen
;
370 /* Nonzero means highlight the region even in nonselected windows. */
372 int highlight_nonselected_windows
;
374 /* If cursor motion alone moves point off frame, try scrolling this
375 many lines up or down if that will bring it back. */
377 static int scroll_step
;
379 /* Non-0 means scroll just far enough to bring point back on the
380 screen, when appropriate. */
382 static int scroll_conservatively
;
384 /* Recenter the window whenever point gets within this many lines of
385 the top or bottom of the window. This value is translated into a
386 pixel value by multiplying it with CANON_Y_UNIT, which means that
387 there is really a fixed pixel height scroll margin. */
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 /* Zero means display the mode-line/header-line/menu-bar in the default face
402 (this slightly odd definition is for compatibility with previous versions
403 of emacs), non-zero means display them using their respective faces.
405 This variable is deprecated. */
407 int mode_line_inverse_video
;
409 /* Prompt to display in front of the mini-buffer contents. */
411 Lisp_Object minibuf_prompt
;
413 /* Width of current mini-buffer prompt. Only set after display_line
414 of the line that contains the prompt. */
416 int minibuf_prompt_width
;
417 int minibuf_prompt_pixel_width
;
419 /* This is the window where the echo area message was displayed. It
420 is always a mini-buffer window, but it may not be the same window
421 currently active as a mini-buffer. */
423 Lisp_Object echo_area_window
;
425 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
426 pushes the current message and the value of
427 message_enable_multibyte on the stack, the function restore_message
428 pops the stack and displays MESSAGE again. */
430 Lisp_Object Vmessage_stack
;
432 /* Nonzero means multibyte characters were enabled when the echo area
433 message was specified. */
435 int message_enable_multibyte
;
437 /* True if we should redraw the mode lines on the next redisplay. */
439 int update_mode_lines
;
441 /* Nonzero if window sizes or contents have changed since last
442 redisplay that finished */
444 int windows_or_buffers_changed
;
446 /* Nonzero after display_mode_line if %l was used and it displayed a
449 int line_number_displayed
;
451 /* Maximum buffer size for which to display line numbers. */
453 Lisp_Object Vline_number_display_limit
;
455 /* line width to consider when repostioning for line number display */
457 static int line_number_display_limit_width
;
459 /* Number of lines to keep in the message log buffer. t means
460 infinite. nil means don't log at all. */
462 Lisp_Object Vmessage_log_max
;
464 /* The name of the *Messages* buffer, a string. */
466 static Lisp_Object Vmessages_buffer_name
;
468 /* Current, index 0, and last displayed echo area message. Either
469 buffers from echo_buffers, or nil to indicate no message. */
471 Lisp_Object echo_area_buffer
[2];
473 /* The buffers referenced from echo_area_buffer. */
475 static Lisp_Object echo_buffer
[2];
477 /* A vector saved used in with_area_buffer to reduce consing. */
479 static Lisp_Object Vwith_echo_area_save_vector
;
481 /* Non-zero means display_echo_area should display the last echo area
482 message again. Set by redisplay_preserve_echo_area. */
484 static int display_last_displayed_message_p
;
486 /* Nonzero if echo area is being used by print; zero if being used by
489 int message_buf_print
;
491 /* Maximum height for resizing mini-windows. Either a float
492 specifying a fraction of the available height, or an integer
493 specifying a number of lines. */
495 Lisp_Object Vmax_mini_window_height
;
497 /* Non-zero means messages should be displayed with truncated
498 lines instead of being continued. */
500 int message_truncate_lines
;
501 Lisp_Object Qmessage_truncate_lines
;
503 /* Non-zero means we want a hollow cursor in windows that are not
504 selected. Zero means there's no cursor in such windows. */
506 int cursor_in_non_selected_windows
;
508 /* A scratch glyph row with contents used for generating truncation
509 glyphs. Also used in direct_output_for_insert. */
511 #define MAX_SCRATCH_GLYPHS 100
512 struct glyph_row scratch_glyph_row
;
513 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
515 /* Ascent and height of the last line processed by move_it_to. */
517 static int last_max_ascent
, last_height
;
519 /* Non-zero if there's a help-echo in the echo area. */
521 int help_echo_showing_p
;
523 /* If >= 0, computed, exact values of mode-line and header-line height
524 to use in the macros CURRENT_MODE_LINE_HEIGHT and
525 CURRENT_HEADER_LINE_HEIGHT. */
527 int current_mode_line_height
, current_header_line_height
;
529 /* The maximum distance to look ahead for text properties. Values
530 that are too small let us call compute_char_face and similar
531 functions too often which is expensive. Values that are too large
532 let us call compute_char_face and alike too often because we
533 might not be interested in text properties that far away. */
535 #define TEXT_PROP_DISTANCE_LIMIT 100
539 /* Non-zero means print traces of redisplay if compiled with
542 int trace_redisplay_p
;
544 #endif /* GLYPH_DEBUG */
546 #ifdef DEBUG_TRACE_MOVE
547 /* Non-zero means trace with TRACE_MOVE to stderr. */
550 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
552 #define TRACE_MOVE(x) (void) 0
555 /* Non-zero means automatically scroll windows horizontally to make
558 int automatic_hscrolling_p
;
560 /* A list of symbols, one for each supported image type. */
562 Lisp_Object Vimage_types
;
564 /* The variable `resize-mini-windows'. If nil, don't resize
565 mini-windows. If t, always resize them to fit the text they
566 display. If `grow-only', let mini-windows grow only until they
569 Lisp_Object Vresize_mini_windows
;
571 /* Value returned from text property handlers (see below). */
576 HANDLED_RECOMPUTE_PROPS
,
577 HANDLED_OVERLAY_STRING_CONSUMED
,
581 /* A description of text properties that redisplay is interested
586 /* The name of the property. */
589 /* A unique index for the property. */
592 /* A handler function called to set up iterator IT from the property
593 at IT's current position. Value is used to steer handle_stop. */
594 enum prop_handled (*handler
) P_ ((struct it
*it
));
597 static enum prop_handled handle_face_prop
P_ ((struct it
*));
598 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
599 static enum prop_handled handle_display_prop
P_ ((struct it
*));
600 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
601 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
602 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
604 /* Properties handled by iterators. */
606 static struct props it_props
[] =
608 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
609 /* Handle `face' before `display' because some sub-properties of
610 `display' need to know the face. */
611 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
612 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
613 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
614 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
618 /* Value is the position described by X. If X is a marker, value is
619 the marker_position of X. Otherwise, value is X. */
621 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
623 /* Enumeration returned by some move_it_.* functions internally. */
627 /* Not used. Undefined value. */
630 /* Move ended at the requested buffer position or ZV. */
631 MOVE_POS_MATCH_OR_ZV
,
633 /* Move ended at the requested X pixel position. */
636 /* Move within a line ended at the end of a line that must be
640 /* Move within a line ended at the end of a line that would
641 be displayed truncated. */
644 /* Move within a line ended at a line end. */
650 /* Function prototypes. */
652 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
653 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
654 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
655 static int invisible_text_between_p
P_ ((struct it
*, int, int));
656 static int next_element_from_ellipsis
P_ ((struct it
*));
657 static void pint2str
P_ ((char *, int, int));
658 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
660 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
661 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
662 static void store_frame_title_char
P_ ((char));
663 static int store_frame_title
P_ ((unsigned char *, int, int));
664 static void x_consider_frame_title
P_ ((Lisp_Object
));
665 static void handle_stop
P_ ((struct it
*));
666 static int tool_bar_lines_needed
P_ ((struct frame
*));
667 static int single_display_prop_intangible_p
P_ ((Lisp_Object
));
668 static void ensure_echo_area_buffers
P_ ((void));
669 static struct glyph_row
*row_containing_pos
P_ ((struct window
*, int,
671 struct glyph_row
*));
672 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
673 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
674 static int with_echo_area_buffer
P_ ((struct window
*, int,
675 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
676 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
677 static void clear_garbaged_frames
P_ ((void));
678 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
679 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
680 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
681 static int display_echo_area
P_ ((struct window
*));
682 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
683 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
684 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
685 static int string_char_and_length
P_ ((unsigned char *, int, int *));
686 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
688 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
689 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
690 static void insert_left_trunc_glyphs
P_ ((struct it
*));
691 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*));
692 static void extend_face_to_end_of_line
P_ ((struct it
*));
693 static int append_space
P_ ((struct it
*, int));
694 static void make_cursor_line_fully_visible
P_ ((struct window
*));
695 static int try_scrolling
P_ ((Lisp_Object
, int, int, int, int));
696 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
697 static int trailing_whitespace_p
P_ ((int));
698 static int message_log_check_duplicate
P_ ((int, int, int, int));
699 int invisible_p
P_ ((Lisp_Object
, Lisp_Object
));
700 int invisible_ellipsis_p
P_ ((Lisp_Object
, Lisp_Object
));
701 static void push_it
P_ ((struct it
*));
702 static void pop_it
P_ ((struct it
*));
703 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
704 static void redisplay_internal
P_ ((int));
705 static int echo_area_display
P_ ((int));
706 static void redisplay_windows
P_ ((Lisp_Object
));
707 static void redisplay_window
P_ ((Lisp_Object
, int));
708 static void update_menu_bar
P_ ((struct frame
*, int));
709 static int try_window_reusing_current_matrix
P_ ((struct window
*));
710 static int try_window_id
P_ ((struct window
*));
711 static int display_line
P_ ((struct it
*));
712 static int display_mode_lines
P_ ((struct window
*));
713 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
714 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
));
715 static char *decode_mode_spec
P_ ((struct window
*, int, int, int));
716 static void display_menu_bar
P_ ((struct window
*));
717 static int display_count_lines
P_ ((int, int, int, int, int *));
718 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
719 int, int, struct it
*, int, int, int, int));
720 static void compute_line_metrics
P_ ((struct it
*));
721 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
722 static int get_overlay_strings
P_ ((struct it
*));
723 static void next_overlay_string
P_ ((struct it
*));
724 static void reseat
P_ ((struct it
*, struct text_pos
, int));
725 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
726 static void back_to_previous_visible_line_start
P_ ((struct it
*));
727 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
728 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
729 static int next_element_from_display_vector
P_ ((struct it
*));
730 static int next_element_from_string
P_ ((struct it
*));
731 static int next_element_from_c_string
P_ ((struct it
*));
732 static int next_element_from_buffer
P_ ((struct it
*));
733 static int next_element_from_composition
P_ ((struct it
*));
734 static int next_element_from_image
P_ ((struct it
*));
735 static int next_element_from_stretch
P_ ((struct it
*));
736 static void load_overlay_strings
P_ ((struct it
*));
737 static void init_from_display_pos
P_ ((struct it
*, struct window
*,
738 struct display_pos
*));
739 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
740 Lisp_Object
, int, int, int, int));
741 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
743 void move_it_vertically_backward
P_ ((struct it
*, int));
744 static void init_to_row_start
P_ ((struct it
*, struct window
*,
745 struct glyph_row
*));
746 static void init_to_row_end
P_ ((struct it
*, struct window
*,
747 struct glyph_row
*));
748 static void back_to_previous_line_start
P_ ((struct it
*));
749 static int forward_to_next_line_start
P_ ((struct it
*, int *));
750 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
752 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
753 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
754 static int number_of_chars
P_ ((unsigned char *, int));
755 static void compute_stop_pos
P_ ((struct it
*));
756 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
758 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
759 static int next_overlay_change
P_ ((int));
760 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
761 Lisp_Object
, struct text_pos
*));
763 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
764 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
766 #ifdef HAVE_WINDOW_SYSTEM
768 static void update_tool_bar
P_ ((struct frame
*, int));
769 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
770 static int redisplay_tool_bar
P_ ((struct frame
*));
771 static void display_tool_bar_line
P_ ((struct it
*));
773 #endif /* HAVE_WINDOW_SYSTEM */
776 /***********************************************************************
777 Window display dimensions
778 ***********************************************************************/
780 /* Return the window-relative maximum y + 1 for glyph rows displaying
781 text in window W. This is the height of W minus the height of a
782 mode line, if any. */
785 window_text_bottom_y (w
)
788 struct frame
*f
= XFRAME (w
->frame
);
789 int height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
791 if (WINDOW_WANTS_MODELINE_P (w
))
792 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
797 /* Return the pixel width of display area AREA of window W. AREA < 0
798 means return the total width of W, not including bitmap areas to
799 the left and right of the window. */
802 window_box_width (w
, area
)
806 struct frame
*f
= XFRAME (w
->frame
);
807 int width
= XFASTINT (w
->width
);
809 if (!w
->pseudo_window_p
)
811 width
-= FRAME_SCROLL_BAR_WIDTH (f
) + FRAME_FLAGS_AREA_COLS (f
);
813 if (area
== TEXT_AREA
)
815 if (INTEGERP (w
->left_margin_width
))
816 width
-= XFASTINT (w
->left_margin_width
);
817 if (INTEGERP (w
->right_margin_width
))
818 width
-= XFASTINT (w
->right_margin_width
);
820 else if (area
== LEFT_MARGIN_AREA
)
821 width
= (INTEGERP (w
->left_margin_width
)
822 ? XFASTINT (w
->left_margin_width
) : 0);
823 else if (area
== RIGHT_MARGIN_AREA
)
824 width
= (INTEGERP (w
->right_margin_width
)
825 ? XFASTINT (w
->right_margin_width
) : 0);
828 return width
* CANON_X_UNIT (f
);
832 /* Return the pixel height of the display area of window W, not
833 including mode lines of W, if any.. */
836 window_box_height (w
)
839 struct frame
*f
= XFRAME (w
->frame
);
840 int height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
842 xassert (height
>= 0);
844 if (WINDOW_WANTS_MODELINE_P (w
))
845 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
847 if (WINDOW_WANTS_HEADER_LINE_P (w
))
848 height
-= CURRENT_HEADER_LINE_HEIGHT (w
);
854 /* Return the frame-relative coordinate of the left edge of display
855 area AREA of window W. AREA < 0 means return the left edge of the
856 whole window, to the right of any bitmap area at the left side of
860 window_box_left (w
, area
)
864 struct frame
*f
= XFRAME (w
->frame
);
865 int x
= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
867 if (!w
->pseudo_window_p
)
869 x
+= (WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
)
870 + FRAME_LEFT_FLAGS_AREA_WIDTH (f
));
872 if (area
== TEXT_AREA
)
873 x
+= window_box_width (w
, LEFT_MARGIN_AREA
);
874 else if (area
== RIGHT_MARGIN_AREA
)
875 x
+= (window_box_width (w
, LEFT_MARGIN_AREA
)
876 + window_box_width (w
, TEXT_AREA
));
883 /* Return the frame-relative coordinate of the right edge of display
884 area AREA of window W. AREA < 0 means return the left edge of the
885 whole window, to the left of any bitmap area at the right side of
889 window_box_right (w
, area
)
893 return window_box_left (w
, area
) + window_box_width (w
, area
);
897 /* Get the bounding box of the display area AREA of window W, without
898 mode lines, in frame-relative coordinates. AREA < 0 means the
899 whole window, not including bitmap areas to the left and right of
900 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
901 coordinates of the upper-left corner of the box. Return in
902 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
905 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
908 int *box_x
, *box_y
, *box_width
, *box_height
;
910 struct frame
*f
= XFRAME (w
->frame
);
912 *box_width
= window_box_width (w
, area
);
913 *box_height
= window_box_height (w
);
914 *box_x
= window_box_left (w
, area
);
915 *box_y
= (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
)
916 + XFASTINT (w
->top
) * CANON_Y_UNIT (f
));
917 if (WINDOW_WANTS_HEADER_LINE_P (w
))
918 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
922 /* Get the bounding box of the display area AREA of window W, without
923 mode lines. AREA < 0 means the whole window, not including bitmap
924 areas to the left and right of the window. Return in *TOP_LEFT_X
925 and TOP_LEFT_Y the frame-relative pixel coordinates of the
926 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
927 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
931 window_box_edges (w
, area
, top_left_x
, top_left_y
,
932 bottom_right_x
, bottom_right_y
)
935 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
937 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
939 *bottom_right_x
+= *top_left_x
;
940 *bottom_right_y
+= *top_left_y
;
945 /***********************************************************************
947 ***********************************************************************/
949 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
950 1 if POS is visible and the line containing POS is fully visible.
951 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
952 and header-lines heights. */
955 pos_visible_p (w
, charpos
, fully
, exact_mode_line_heights_p
)
957 int charpos
, *fully
, exact_mode_line_heights_p
;
962 struct buffer
*old_buffer
= NULL
;
964 if (XBUFFER (w
->buffer
) != current_buffer
)
966 old_buffer
= current_buffer
;
967 set_buffer_internal_1 (XBUFFER (w
->buffer
));
970 *fully
= visible_p
= 0;
971 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
973 /* Compute exact mode line heights, if requested. */
974 if (exact_mode_line_heights_p
)
976 if (WINDOW_WANTS_MODELINE_P (w
))
977 current_mode_line_height
978 = display_mode_line (w
, MODE_LINE_FACE_ID
,
979 current_buffer
->mode_line_format
);
981 if (WINDOW_WANTS_HEADER_LINE_P (w
))
982 current_header_line_height
983 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
984 current_buffer
->header_line_format
);
987 start_display (&it
, w
, top
);
988 move_it_to (&it
, charpos
, 0, it
.last_visible_y
, -1,
989 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
991 if (IT_CHARPOS (it
) == charpos
)
993 int line_height
, line_bottom_y
;
994 int line_top_y
= it
.current_y
;
995 int window_top_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
997 line_height
= it
.max_ascent
+ it
.max_descent
;
998 if (line_height
== 0)
1001 line_height
= last_height
;
1002 else if (charpos
< ZV
)
1004 move_it_by_lines (&it
, 1, 1);
1005 line_height
= (it
.max_ascent
|| it
.max_descent
1006 ? it
.max_ascent
+ it
.max_descent
1011 /* Use the default character height. */
1012 it
.what
= IT_CHARACTER
;
1015 PRODUCE_GLYPHS (&it
);
1016 line_height
= it
.ascent
+ it
.descent
;
1019 line_bottom_y
= line_top_y
+ line_height
;
1021 if (line_top_y
< window_top_y
)
1022 visible_p
= line_bottom_y
> window_top_y
;
1023 else if (line_top_y
< it
.last_visible_y
)
1026 *fully
= line_bottom_y
<= it
.last_visible_y
;
1029 else if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
> it
.last_visible_y
)
1031 move_it_by_lines (&it
, 1, 0);
1032 if (charpos
< IT_CHARPOS (it
))
1040 set_buffer_internal_1 (old_buffer
);
1042 current_header_line_height
= current_mode_line_height
= -1;
1047 /* Return the next character from STR which is MAXLEN bytes long.
1048 Return in *LEN the length of the character. This is like
1049 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1050 we find one, we return a `?', but with the length of the invalid
1054 string_char_and_length (str
, maxlen
, len
)
1060 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1061 if (!CHAR_VALID_P (c
, 1))
1062 /* We may not change the length here because other places in Emacs
1063 don't use this function, i.e. they silently accept invalid
1072 /* Given a position POS containing a valid character and byte position
1073 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1075 static struct text_pos
1076 string_pos_nchars_ahead (pos
, string
, nchars
)
1077 struct text_pos pos
;
1081 xassert (STRINGP (string
) && nchars
>= 0);
1083 if (STRING_MULTIBYTE (string
))
1085 int rest
= STRING_BYTES (XSTRING (string
)) - BYTEPOS (pos
);
1086 unsigned char *p
= XSTRING (string
)->data
+ BYTEPOS (pos
);
1091 string_char_and_length (p
, rest
, &len
);
1092 p
+= len
, rest
-= len
;
1093 xassert (rest
>= 0);
1095 BYTEPOS (pos
) += len
;
1099 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1105 /* Value is the text position, i.e. character and byte position,
1106 for character position CHARPOS in STRING. */
1108 static INLINE
struct text_pos
1109 string_pos (charpos
, string
)
1113 struct text_pos pos
;
1114 xassert (STRINGP (string
));
1115 xassert (charpos
>= 0);
1116 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1121 /* Value is a text position, i.e. character and byte position, for
1122 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1123 means recognize multibyte characters. */
1125 static struct text_pos
1126 c_string_pos (charpos
, s
, multibyte_p
)
1131 struct text_pos pos
;
1133 xassert (s
!= NULL
);
1134 xassert (charpos
>= 0);
1138 int rest
= strlen (s
), len
;
1140 SET_TEXT_POS (pos
, 0, 0);
1143 string_char_and_length (s
, rest
, &len
);
1144 s
+= len
, rest
-= len
;
1145 xassert (rest
>= 0);
1147 BYTEPOS (pos
) += len
;
1151 SET_TEXT_POS (pos
, charpos
, charpos
);
1157 /* Value is the number of characters in C string S. MULTIBYTE_P
1158 non-zero means recognize multibyte characters. */
1161 number_of_chars (s
, multibyte_p
)
1169 int rest
= strlen (s
), len
;
1170 unsigned char *p
= (unsigned char *) s
;
1172 for (nchars
= 0; rest
> 0; ++nchars
)
1174 string_char_and_length (p
, rest
, &len
);
1175 rest
-= len
, p
+= len
;
1179 nchars
= strlen (s
);
1185 /* Compute byte position NEWPOS->bytepos corresponding to
1186 NEWPOS->charpos. POS is a known position in string STRING.
1187 NEWPOS->charpos must be >= POS.charpos. */
1190 compute_string_pos (newpos
, pos
, string
)
1191 struct text_pos
*newpos
, pos
;
1194 xassert (STRINGP (string
));
1195 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1197 if (STRING_MULTIBYTE (string
))
1198 *newpos
= string_pos_nchars_ahead (pos
, string
,
1199 CHARPOS (*newpos
) - CHARPOS (pos
));
1201 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1206 /***********************************************************************
1207 Lisp form evaluation
1208 ***********************************************************************/
1210 /* Error handler for safe_eval and safe_call. */
1213 safe_eval_handler (arg
)
1216 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1221 /* Evaluate SEXPR and return the result, or nil if something went
1228 int count
= BINDING_STACK_SIZE ();
1229 struct gcpro gcpro1
;
1233 specbind (Qinhibit_redisplay
, Qt
);
1234 val
= internal_condition_case_1 (Feval
, sexpr
, Qerror
, safe_eval_handler
);
1236 return unbind_to (count
, val
);
1240 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1241 Return the result, or nil if something went wrong. */
1244 safe_call (nargs
, args
)
1248 int count
= BINDING_STACK_SIZE ();
1250 struct gcpro gcpro1
;
1253 gcpro1
.nvars
= nargs
;
1254 specbind (Qinhibit_redisplay
, Qt
);
1255 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qerror
,
1258 return unbind_to (count
, val
);
1262 /* Call function FN with one argument ARG.
1263 Return the result, or nil if something went wrong. */
1266 safe_call1 (fn
, arg
)
1267 Lisp_Object fn
, arg
;
1269 Lisp_Object args
[2];
1272 return safe_call (2, args
);
1277 /***********************************************************************
1279 ***********************************************************************/
1283 /* Define CHECK_IT to perform sanity checks on iterators.
1284 This is for debugging. It is too slow to do unconditionally. */
1290 if (it
->method
== next_element_from_string
)
1292 xassert (STRINGP (it
->string
));
1293 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1295 else if (it
->method
== next_element_from_buffer
)
1297 /* Check that character and byte positions agree. */
1298 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1302 xassert (it
->current
.dpvec_index
>= 0);
1304 xassert (it
->current
.dpvec_index
< 0);
1307 #define CHECK_IT(IT) check_it ((IT))
1311 #define CHECK_IT(IT) (void) 0
1318 /* Check that the window end of window W is what we expect it
1319 to be---the last row in the current matrix displaying text. */
1322 check_window_end (w
)
1325 if (!MINI_WINDOW_P (w
)
1326 && !NILP (w
->window_end_valid
))
1328 struct glyph_row
*row
;
1329 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1330 XFASTINT (w
->window_end_vpos
)),
1332 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1333 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1337 #define CHECK_WINDOW_END(W) check_window_end ((W))
1339 #else /* not GLYPH_DEBUG */
1341 #define CHECK_WINDOW_END(W) (void) 0
1343 #endif /* not GLYPH_DEBUG */
1347 /***********************************************************************
1348 Iterator initialization
1349 ***********************************************************************/
1351 /* Initialize IT for displaying current_buffer in window W, starting
1352 at character position CHARPOS. CHARPOS < 0 means that no buffer
1353 position is specified which is useful when the iterator is assigned
1354 a position later. BYTEPOS is the byte position corresponding to
1355 CHARPOS. BYTEPOS <= 0 means compute it from CHARPOS.
1357 If ROW is not null, calls to produce_glyphs with IT as parameter
1358 will produce glyphs in that row.
1360 BASE_FACE_ID is the id of a base face to use. It must be one of
1361 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID or
1362 HEADER_LINE_FACE_ID for displaying mode lines, or TOOL_BAR_FACE_ID for
1363 displaying the tool-bar.
1365 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID or
1366 HEADER_LINE_FACE_ID, the iterator will be initialized to use the
1367 corresponding mode line glyph row of the desired matrix of W. */
1370 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
1373 int charpos
, bytepos
;
1374 struct glyph_row
*row
;
1375 enum face_id base_face_id
;
1377 int highlight_region_p
;
1379 /* Some precondition checks. */
1380 xassert (w
!= NULL
&& it
!= NULL
);
1381 xassert (charpos
< 0 || (charpos
> 0 && charpos
<= ZV
));
1383 /* If face attributes have been changed since the last redisplay,
1384 free realized faces now because they depend on face definitions
1385 that might have changed. */
1386 if (face_change_count
)
1388 face_change_count
= 0;
1389 free_all_realized_faces (Qnil
);
1392 /* Use one of the mode line rows of W's desired matrix if
1396 if (base_face_id
== MODE_LINE_FACE_ID
)
1397 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
1398 else if (base_face_id
== HEADER_LINE_FACE_ID
)
1399 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
1403 bzero (it
, sizeof *it
);
1404 it
->current
.overlay_string_index
= -1;
1405 it
->current
.dpvec_index
= -1;
1406 it
->base_face_id
= base_face_id
;
1408 /* The window in which we iterate over current_buffer: */
1409 XSETWINDOW (it
->window
, w
);
1411 it
->f
= XFRAME (w
->frame
);
1413 /* Extra space between lines (on window systems only). */
1414 if (base_face_id
== DEFAULT_FACE_ID
1415 && FRAME_WINDOW_P (it
->f
))
1417 if (NATNUMP (current_buffer
->extra_line_spacing
))
1418 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
1419 else if (it
->f
->extra_line_spacing
> 0)
1420 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
1423 /* If realized faces have been removed, e.g. because of face
1424 attribute changes of named faces, recompute them. */
1425 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
1426 recompute_basic_faces (it
->f
);
1428 /* Current value of the `space-width', and 'height' properties. */
1429 it
->space_width
= Qnil
;
1430 it
->font_height
= Qnil
;
1432 /* Are control characters displayed as `^C'? */
1433 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
1435 /* -1 means everything between a CR and the following line end
1436 is invisible. >0 means lines indented more than this value are
1438 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
1439 ? XFASTINT (current_buffer
->selective_display
)
1440 : (!NILP (current_buffer
->selective_display
)
1442 it
->selective_display_ellipsis_p
1443 = !NILP (current_buffer
->selective_display_ellipses
);
1445 /* Display table to use. */
1446 it
->dp
= window_display_table (w
);
1448 /* Are multibyte characters enabled in current_buffer? */
1449 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
1451 /* Non-zero if we should highlight the region. */
1453 = (!NILP (Vtransient_mark_mode
)
1454 && !NILP (current_buffer
->mark_active
)
1455 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
1457 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
1458 start and end of a visible region in window IT->w. Set both to
1459 -1 to indicate no region. */
1460 if (highlight_region_p
1461 /* Maybe highlight only in selected window. */
1462 && (/* Either show region everywhere. */
1463 highlight_nonselected_windows
1464 /* Or show region in the selected window. */
1465 || w
== XWINDOW (selected_window
)
1466 /* Or show the region if we are in the mini-buffer and W is
1467 the window the mini-buffer refers to. */
1468 || (MINI_WINDOW_P (XWINDOW (selected_window
))
1469 && w
== XWINDOW (Vminibuf_scroll_window
))))
1471 int charpos
= marker_position (current_buffer
->mark
);
1472 it
->region_beg_charpos
= min (PT
, charpos
);
1473 it
->region_end_charpos
= max (PT
, charpos
);
1476 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
1478 /* Get the position at which the redisplay_end_trigger hook should
1479 be run, if it is to be run at all. */
1480 if (MARKERP (w
->redisplay_end_trigger
)
1481 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
1482 it
->redisplay_end_trigger_charpos
1483 = marker_position (w
->redisplay_end_trigger
);
1484 else if (INTEGERP (w
->redisplay_end_trigger
))
1485 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
1487 /* Correct bogus values of tab_width. */
1488 it
->tab_width
= XINT (current_buffer
->tab_width
);
1489 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
1492 /* Are lines in the display truncated? */
1493 it
->truncate_lines_p
1494 = (base_face_id
!= DEFAULT_FACE_ID
1495 || XINT (it
->w
->hscroll
)
1496 || (truncate_partial_width_windows
1497 && !WINDOW_FULL_WIDTH_P (it
->w
))
1498 || !NILP (current_buffer
->truncate_lines
));
1500 /* Get dimensions of truncation and continuation glyphs. These are
1501 displayed as bitmaps under X, so we don't need them for such
1503 if (!FRAME_WINDOW_P (it
->f
))
1505 if (it
->truncate_lines_p
)
1507 /* We will need the truncation glyph. */
1508 xassert (it
->glyph_row
== NULL
);
1509 produce_special_glyphs (it
, IT_TRUNCATION
);
1510 it
->truncation_pixel_width
= it
->pixel_width
;
1514 /* We will need the continuation glyph. */
1515 xassert (it
->glyph_row
== NULL
);
1516 produce_special_glyphs (it
, IT_CONTINUATION
);
1517 it
->continuation_pixel_width
= it
->pixel_width
;
1520 /* Reset these values to zero becaue the produce_special_glyphs
1521 above has changed them. */
1522 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
1523 it
->phys_ascent
= it
->phys_descent
= 0;
1526 /* Set this after getting the dimensions of truncation and
1527 continuation glyphs, so that we don't produce glyphs when calling
1528 produce_special_glyphs, above. */
1529 it
->glyph_row
= row
;
1530 it
->area
= TEXT_AREA
;
1532 /* Get the dimensions of the display area. The display area
1533 consists of the visible window area plus a horizontally scrolled
1534 part to the left of the window. All x-values are relative to the
1535 start of this total display area. */
1536 if (base_face_id
!= DEFAULT_FACE_ID
)
1538 /* Mode lines, menu bar in terminal frames. */
1539 it
->first_visible_x
= 0;
1540 it
->last_visible_x
= XFASTINT (w
->width
) * CANON_X_UNIT (it
->f
);
1545 = XFASTINT (it
->w
->hscroll
) * CANON_X_UNIT (it
->f
);
1546 it
->last_visible_x
= (it
->first_visible_x
1547 + window_box_width (w
, TEXT_AREA
));
1549 /* If we truncate lines, leave room for the truncator glyph(s) at
1550 the right margin. Otherwise, leave room for the continuation
1551 glyph(s). Truncation and continuation glyphs are not inserted
1552 for window-based redisplay. */
1553 if (!FRAME_WINDOW_P (it
->f
))
1555 if (it
->truncate_lines_p
)
1556 it
->last_visible_x
-= it
->truncation_pixel_width
;
1558 it
->last_visible_x
-= it
->continuation_pixel_width
;
1561 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
1562 it
->current_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
1565 /* Leave room for a border glyph. */
1566 if (!FRAME_WINDOW_P (it
->f
)
1567 && !WINDOW_RIGHTMOST_P (it
->w
))
1568 it
->last_visible_x
-= 1;
1570 it
->last_visible_y
= window_text_bottom_y (w
);
1572 /* For mode lines and alike, arrange for the first glyph having a
1573 left box line if the face specifies a box. */
1574 if (base_face_id
!= DEFAULT_FACE_ID
)
1578 it
->face_id
= base_face_id
;
1580 /* If we have a boxed mode line, make the first character appear
1581 with a left box line. */
1582 face
= FACE_FROM_ID (it
->f
, base_face_id
);
1583 if (face
->box
!= FACE_NO_BOX
)
1584 it
->start_of_box_run_p
= 1;
1587 /* If a buffer position was specified, set the iterator there,
1588 getting overlays and face properties from that position. */
1591 it
->end_charpos
= ZV
;
1593 IT_CHARPOS (*it
) = charpos
;
1595 /* Compute byte position if not specified. */
1597 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
1599 IT_BYTEPOS (*it
) = bytepos
;
1601 /* Compute faces etc. */
1602 reseat (it
, it
->current
.pos
, 1);
1609 /* Initialize IT for the display of window W with window start POS. */
1612 start_display (it
, w
, pos
)
1615 struct text_pos pos
;
1617 int start_at_line_beg_p
;
1618 struct glyph_row
*row
;
1619 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
1622 row
= w
->desired_matrix
->rows
+ first_vpos
;
1623 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
1624 first_y
= it
->current_y
;
1626 /* If window start is not at a line start, move back to the line
1627 start. This makes sure that we take continuation lines into
1629 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
1630 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
1631 if (!start_at_line_beg_p
)
1632 reseat_at_previous_visible_line_start (it
);
1634 /* If window start is not at a line start, skip forward to POS to
1635 get the correct continuation_lines_width and current_x. */
1636 if (!start_at_line_beg_p
)
1638 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
1640 /* If lines are continued, this line may end in the middle of a
1641 multi-glyph character (e.g. a control character displayed as
1642 \003, or in the middle of an overlay string). In this case
1643 move_it_to above will not have taken us to the start of
1644 the continuation line but to the end of the continued line. */
1645 if (!it
->truncate_lines_p
)
1647 if (it
->current_x
> 0)
1649 if (it
->current
.dpvec_index
>= 0
1650 || it
->current
.overlay_string_index
>= 0)
1652 set_iterator_to_next (it
, 1);
1653 move_it_in_display_line_to (it
, -1, -1, 0);
1656 it
->continuation_lines_width
+= it
->current_x
;
1659 /* We're starting a new display line, not affected by the
1660 height of the continued line, so clear the appropriate
1661 fields in the iterator structure. */
1662 it
->max_ascent
= it
->max_descent
= 0;
1663 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
1666 it
->current_y
= first_y
;
1668 it
->current_x
= it
->hpos
= 0;
1671 #if 0 /* Don't assert the following because start_display is sometimes
1672 called intentionally with a window start that is not at a
1673 line start. Please leave this code in as a comment. */
1675 /* Window start should be on a line start, now. */
1676 xassert (it
->continuation_lines_width
1677 || IT_CHARPOS (it
) == BEGV
1678 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
1683 /* Initialize IT for stepping through current_buffer in window W,
1684 starting at position POS that includes overlay string and display
1685 vector/ control character translation position information. */
1688 init_from_display_pos (it
, w
, pos
)
1691 struct display_pos
*pos
;
1693 /* Keep in mind: the call to reseat in init_iterator skips invisible
1694 text, so we might end up at a position different from POS. This
1695 is only a problem when POS is a row start after a newline and an
1696 overlay starts there with an after-string, and the overlay has an
1697 invisible property. Since we don't skip invisible text in
1698 display_line and elsewhere immediately after consuming the
1699 newline before the row start, such a POS will not be in a string,
1700 but the call to init_iterator below will move us to the
1702 init_iterator (it
, w
, CHARPOS (pos
->pos
), BYTEPOS (pos
->pos
),
1703 NULL
, DEFAULT_FACE_ID
);
1705 /* If position is within an overlay string, set up IT to
1706 the right overlay string. */
1707 if (pos
->overlay_string_index
>= 0)
1711 /* We already have the first chunk of overlay strings in
1712 IT->overlay_strings. Load more until the one for
1713 pos->overlay_string_index is in IT->overlay_strings. */
1714 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
1716 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
1717 it
->current
.overlay_string_index
= 0;
1720 load_overlay_strings (it
);
1721 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
1725 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
1726 relative_index
= (it
->current
.overlay_string_index
1727 % OVERLAY_STRING_CHUNK_SIZE
);
1728 it
->string
= it
->overlay_strings
[relative_index
];
1729 xassert (STRINGP (it
->string
));
1730 it
->current
.string_pos
= pos
->string_pos
;
1731 it
->method
= next_element_from_string
;
1733 else if (it
->current
.overlay_string_index
>= 0)
1735 /* If POS says we're already after an overlay string ending at
1736 POS, make sure to pop the iterator because it will be in
1737 front of that overlay string. When POS is ZV, we've thereby
1738 also ``processed'' overlay strings at ZV. */
1740 it
->current
.overlay_string_index
= -1;
1741 it
->method
= next_element_from_buffer
;
1742 if (CHARPOS (pos
->pos
) == ZV
)
1743 it
->overlay_strings_at_end_processed_p
= 1;
1746 if (CHARPOS (pos
->string_pos
) >= 0)
1748 /* Recorded position is not in an overlay string, but in another
1749 string. This can only be a string from a `display' property.
1750 IT should already be filled with that string. */
1751 it
->current
.string_pos
= pos
->string_pos
;
1752 xassert (STRINGP (it
->string
));
1755 /* Restore position in display vector translations or control
1756 character translations. */
1757 if (pos
->dpvec_index
>= 0)
1759 /* This fills IT->dpvec. */
1760 get_next_display_element (it
);
1761 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
1762 it
->current
.dpvec_index
= pos
->dpvec_index
;
1769 /* Initialize IT for stepping through current_buffer in window W
1770 starting at ROW->start. */
1773 init_to_row_start (it
, w
, row
)
1776 struct glyph_row
*row
;
1778 init_from_display_pos (it
, w
, &row
->start
);
1779 it
->continuation_lines_width
= row
->continuation_lines_width
;
1784 /* Initialize IT for stepping through current_buffer in window W
1785 starting in the line following ROW, i.e. starting at ROW->end. */
1788 init_to_row_end (it
, w
, row
)
1791 struct glyph_row
*row
;
1793 init_from_display_pos (it
, w
, &row
->end
);
1795 if (row
->continued_p
)
1796 it
->continuation_lines_width
= (row
->continuation_lines_width
1797 + row
->pixel_width
);
1804 /***********************************************************************
1806 ***********************************************************************/
1808 /* Called when IT reaches IT->stop_charpos. Handle text property and
1809 overlay changes. Set IT->stop_charpos to the next position where
1816 enum prop_handled handled
;
1817 int handle_overlay_change_p
= 1;
1821 it
->current
.dpvec_index
= -1;
1825 handled
= HANDLED_NORMALLY
;
1827 /* Call text property handlers. */
1828 for (p
= it_props
; p
->handler
; ++p
)
1830 handled
= p
->handler (it
);
1832 if (handled
== HANDLED_RECOMPUTE_PROPS
)
1834 else if (handled
== HANDLED_RETURN
)
1836 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
1837 handle_overlay_change_p
= 0;
1840 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
1842 /* Don't check for overlay strings below when set to deliver
1843 characters from a display vector. */
1844 if (it
->method
== next_element_from_display_vector
)
1845 handle_overlay_change_p
= 0;
1847 /* Handle overlay changes. */
1848 if (handle_overlay_change_p
)
1849 handled
= handle_overlay_change (it
);
1851 /* Determine where to stop next. */
1852 if (handled
== HANDLED_NORMALLY
)
1853 compute_stop_pos (it
);
1856 while (handled
== HANDLED_RECOMPUTE_PROPS
);
1860 /* Compute IT->stop_charpos from text property and overlay change
1861 information for IT's current position. */
1864 compute_stop_pos (it
)
1867 register INTERVAL iv
, next_iv
;
1868 Lisp_Object object
, limit
, position
;
1870 /* If nowhere else, stop at the end. */
1871 it
->stop_charpos
= it
->end_charpos
;
1873 if (STRINGP (it
->string
))
1875 /* Strings are usually short, so don't limit the search for
1877 object
= it
->string
;
1879 XSETFASTINT (position
, IT_STRING_CHARPOS (*it
));
1885 /* If next overlay change is in front of the current stop pos
1886 (which is IT->end_charpos), stop there. Note: value of
1887 next_overlay_change is point-max if no overlay change
1889 charpos
= next_overlay_change (IT_CHARPOS (*it
));
1890 if (charpos
< it
->stop_charpos
)
1891 it
->stop_charpos
= charpos
;
1893 /* If showing the region, we have to stop at the region
1894 start or end because the face might change there. */
1895 if (it
->region_beg_charpos
> 0)
1897 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
1898 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
1899 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
1900 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
1903 /* Set up variables for computing the stop position from text
1904 property changes. */
1905 XSETBUFFER (object
, current_buffer
);
1906 XSETFASTINT (limit
, IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
1907 XSETFASTINT (position
, IT_CHARPOS (*it
));
1911 /* Get the interval containing IT's position. Value is a null
1912 interval if there isn't such an interval. */
1913 iv
= validate_interval_range (object
, &position
, &position
, 0);
1914 if (!NULL_INTERVAL_P (iv
))
1916 Lisp_Object values_here
[LAST_PROP_IDX
];
1919 /* Get properties here. */
1920 for (p
= it_props
; p
->handler
; ++p
)
1921 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
1923 /* Look for an interval following iv that has different
1925 for (next_iv
= next_interval (iv
);
1926 (!NULL_INTERVAL_P (next_iv
)
1928 || XFASTINT (limit
) > next_iv
->position
));
1929 next_iv
= next_interval (next_iv
))
1931 for (p
= it_props
; p
->handler
; ++p
)
1933 Lisp_Object new_value
;
1935 new_value
= textget (next_iv
->plist
, *p
->name
);
1936 if (!EQ (values_here
[p
->idx
], new_value
))
1944 if (!NULL_INTERVAL_P (next_iv
))
1946 if (INTEGERP (limit
)
1947 && next_iv
->position
>= XFASTINT (limit
))
1948 /* No text property change up to limit. */
1949 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
1951 /* Text properties change in next_iv. */
1952 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
1956 xassert (STRINGP (it
->string
)
1957 || (it
->stop_charpos
>= BEGV
1958 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
1962 /* Return the position of the next overlay change after POS in
1963 current_buffer. Value is point-max if no overlay change
1964 follows. This is like `next-overlay-change' but doesn't use
1968 next_overlay_change (pos
)
1973 Lisp_Object
*overlays
;
1977 /* Get all overlays at the given position. */
1979 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
1980 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
1981 if (noverlays
> len
)
1984 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
1985 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
1988 /* If any of these overlays ends before endpos,
1989 use its ending point instead. */
1990 for (i
= 0; i
< noverlays
; ++i
)
1995 oend
= OVERLAY_END (overlays
[i
]);
1996 oendpos
= OVERLAY_POSITION (oend
);
1997 endpos
= min (endpos
, oendpos
);
2005 /***********************************************************************
2007 ***********************************************************************/
2009 /* Handle changes in the `fontified' property of the current buffer by
2010 calling hook functions from Qfontification_functions to fontify
2013 static enum prop_handled
2014 handle_fontified_prop (it
)
2017 Lisp_Object prop
, pos
;
2018 enum prop_handled handled
= HANDLED_NORMALLY
;
2020 /* Get the value of the `fontified' property at IT's current buffer
2021 position. (The `fontified' property doesn't have a special
2022 meaning in strings.) If the value is nil, call functions from
2023 Qfontification_functions. */
2024 if (!STRINGP (it
->string
)
2026 && !NILP (Vfontification_functions
)
2027 && !NILP (Vrun_hooks
)
2028 && (pos
= make_number (IT_CHARPOS (*it
)),
2029 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2032 int count
= BINDING_STACK_SIZE ();
2035 val
= Vfontification_functions
;
2036 specbind (Qfontification_functions
, Qnil
);
2037 specbind (Qafter_change_functions
, Qnil
);
2039 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2040 safe_call1 (val
, pos
);
2043 Lisp_Object globals
, fn
;
2044 struct gcpro gcpro1
, gcpro2
;
2047 GCPRO2 (val
, globals
);
2049 for (; CONSP (val
); val
= XCDR (val
))
2055 /* A value of t indicates this hook has a local
2056 binding; it means to run the global binding too.
2057 In a global value, t should not occur. If it
2058 does, we must ignore it to avoid an endless
2060 for (globals
= Fdefault_value (Qfontification_functions
);
2062 globals
= XCDR (globals
))
2064 fn
= XCAR (globals
);
2066 safe_call1 (fn
, pos
);
2070 safe_call1 (fn
, pos
);
2076 unbind_to (count
, Qnil
);
2078 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2079 something. This avoids an endless loop if they failed to
2080 fontify the text for which reason ever. */
2081 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2082 handled
= HANDLED_RECOMPUTE_PROPS
;
2090 /***********************************************************************
2092 ***********************************************************************/
2094 /* Set up iterator IT from face properties at its current position.
2095 Called from handle_stop. */
2097 static enum prop_handled
2098 handle_face_prop (it
)
2101 int new_face_id
, next_stop
;
2103 if (!STRINGP (it
->string
))
2106 = face_at_buffer_position (it
->w
,
2108 it
->region_beg_charpos
,
2109 it
->region_end_charpos
,
2112 + TEXT_PROP_DISTANCE_LIMIT
),
2115 /* Is this a start of a run of characters with box face?
2116 Caveat: this can be called for a freshly initialized
2117 iterator; face_id is -1 is this case. We know that the new
2118 face will not change until limit, i.e. if the new face has a
2119 box, all characters up to limit will have one. But, as
2120 usual, we don't know whether limit is really the end. */
2121 if (new_face_id
!= it
->face_id
)
2123 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2125 /* If new face has a box but old face has not, this is
2126 the start of a run of characters with box, i.e. it has
2127 a shadow on the left side. The value of face_id of the
2128 iterator will be -1 if this is the initial call that gets
2129 the face. In this case, we have to look in front of IT's
2130 position and see whether there is a face != new_face_id. */
2131 it
->start_of_box_run_p
2132 = (new_face
->box
!= FACE_NO_BOX
2133 && (it
->face_id
>= 0
2134 || IT_CHARPOS (*it
) == BEG
2135 || new_face_id
!= face_before_it_pos (it
)));
2136 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2142 = face_at_string_position (it
->w
,
2144 IT_STRING_CHARPOS (*it
),
2145 (it
->current
.overlay_string_index
>= 0
2148 it
->region_beg_charpos
,
2149 it
->region_end_charpos
,
2153 #if 0 /* This shouldn't be neccessary. Let's check it. */
2154 /* If IT is used to display a mode line we would really like to
2155 use the mode line face instead of the frame's default face. */
2156 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
2157 && new_face_id
== DEFAULT_FACE_ID
)
2158 new_face_id
= MODE_LINE_FACE_ID
;
2161 /* Is this a start of a run of characters with box? Caveat:
2162 this can be called for a freshly allocated iterator; face_id
2163 is -1 is this case. We know that the new face will not
2164 change until the next check pos, i.e. if the new face has a
2165 box, all characters up to that position will have a
2166 box. But, as usual, we don't know whether that position
2167 is really the end. */
2168 if (new_face_id
!= it
->face_id
)
2170 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2171 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2173 /* If new face has a box but old face hasn't, this is the
2174 start of a run of characters with box, i.e. it has a
2175 shadow on the left side. */
2176 it
->start_of_box_run_p
2177 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
2178 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2182 it
->face_id
= new_face_id
;
2183 return HANDLED_NORMALLY
;
2187 /* Compute the face one character before or after the current position
2188 of IT. BEFORE_P non-zero means get the face in front of IT's
2189 position. Value is the id of the face. */
2192 face_before_or_after_it_pos (it
, before_p
)
2197 int next_check_charpos
;
2198 struct text_pos pos
;
2200 xassert (it
->s
== NULL
);
2202 if (STRINGP (it
->string
))
2204 /* No face change past the end of the string (for the case
2205 we are padding with spaces). No face change before the
2207 if (IT_STRING_CHARPOS (*it
) >= XSTRING (it
->string
)->size
2208 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
2211 /* Set pos to the position before or after IT's current position. */
2213 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
2215 /* For composition, we must check the character after the
2217 pos
= (it
->what
== IT_COMPOSITION
2218 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
2219 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
2221 /* Get the face for ASCII, or unibyte. */
2223 = face_at_string_position (it
->w
,
2226 (it
->current
.overlay_string_index
>= 0
2229 it
->region_beg_charpos
,
2230 it
->region_end_charpos
,
2231 &next_check_charpos
,
2234 /* Correct the face for charsets different from ASCII. Do it
2235 for the multibyte case only. The face returned above is
2236 suitable for unibyte text if IT->string is unibyte. */
2237 if (STRING_MULTIBYTE (it
->string
))
2239 unsigned char *p
= XSTRING (it
->string
)->data
+ BYTEPOS (pos
);
2240 int rest
= STRING_BYTES (XSTRING (it
->string
)) - BYTEPOS (pos
);
2242 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
2244 c
= string_char_and_length (p
, rest
, &len
);
2245 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
2250 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
2251 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
2254 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
2255 pos
= it
->current
.pos
;
2258 DEC_TEXT_POS (pos
, it
->multibyte_p
);
2261 if (it
->what
== IT_COMPOSITION
)
2262 /* For composition, we must check the position after the
2264 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
2266 INC_TEXT_POS (pos
, it
->multibyte_p
);
2268 /* Determine face for CHARSET_ASCII, or unibyte. */
2269 face_id
= face_at_buffer_position (it
->w
,
2271 it
->region_beg_charpos
,
2272 it
->region_end_charpos
,
2273 &next_check_charpos
,
2276 /* Correct the face for charsets different from ASCII. Do it
2277 for the multibyte case only. The face returned above is
2278 suitable for unibyte text if current_buffer is unibyte. */
2279 if (it
->multibyte_p
)
2281 int c
= FETCH_MULTIBYTE_CHAR (CHARPOS (pos
));
2282 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
2283 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
2292 /***********************************************************************
2294 ***********************************************************************/
2296 /* Set up iterator IT from invisible properties at its current
2297 position. Called from handle_stop. */
2299 static enum prop_handled
2300 handle_invisible_prop (it
)
2303 enum prop_handled handled
= HANDLED_NORMALLY
;
2305 if (STRINGP (it
->string
))
2307 extern Lisp_Object Qinvisible
;
2308 Lisp_Object prop
, end_charpos
, limit
, charpos
;
2310 /* Get the value of the invisible text property at the
2311 current position. Value will be nil if there is no such
2313 XSETFASTINT (charpos
, IT_STRING_CHARPOS (*it
));
2314 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
2317 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
2319 handled
= HANDLED_RECOMPUTE_PROPS
;
2321 /* Get the position at which the next change of the
2322 invisible text property can be found in IT->string.
2323 Value will be nil if the property value is the same for
2324 all the rest of IT->string. */
2325 XSETINT (limit
, XSTRING (it
->string
)->size
);
2326 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
2329 /* Text at current position is invisible. The next
2330 change in the property is at position end_charpos.
2331 Move IT's current position to that position. */
2332 if (INTEGERP (end_charpos
)
2333 && XFASTINT (end_charpos
) < XFASTINT (limit
))
2335 struct text_pos old
;
2336 old
= it
->current
.string_pos
;
2337 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
2338 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
2342 /* The rest of the string is invisible. If this is an
2343 overlay string, proceed with the next overlay string
2344 or whatever comes and return a character from there. */
2345 if (it
->current
.overlay_string_index
>= 0)
2347 next_overlay_string (it
);
2348 /* Don't check for overlay strings when we just
2349 finished processing them. */
2350 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
2354 struct Lisp_String
*s
= XSTRING (it
->string
);
2355 IT_STRING_CHARPOS (*it
) = s
->size
;
2356 IT_STRING_BYTEPOS (*it
) = STRING_BYTES (s
);
2363 int visible_p
, newpos
, next_stop
;
2364 Lisp_Object pos
, prop
;
2366 /* First of all, is there invisible text at this position? */
2367 XSETFASTINT (pos
, IT_CHARPOS (*it
));
2368 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
2370 /* If we are on invisible text, skip over it. */
2371 if (TEXT_PROP_MEANS_INVISIBLE (prop
)
2372 && IT_CHARPOS (*it
) < it
->end_charpos
)
2374 /* Record whether we have to display an ellipsis for the
2376 int display_ellipsis_p
2377 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop
);
2379 handled
= HANDLED_RECOMPUTE_PROPS
;
2381 /* Loop skipping over invisible text. The loop is left at
2382 ZV or with IT on the first char being visible again. */
2385 /* Try to skip some invisible text. Return value is the
2386 position reached which can be equal to IT's position
2387 if there is nothing invisible here. This skips both
2388 over invisible text properties and overlays with
2389 invisible property. */
2390 newpos
= skip_invisible (IT_CHARPOS (*it
),
2391 &next_stop
, ZV
, it
->window
);
2393 /* If we skipped nothing at all we weren't at invisible
2394 text in the first place. If everything to the end of
2395 the buffer was skipped, end the loop. */
2396 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
2400 /* We skipped some characters but not necessarily
2401 all there are. Check if we ended up on visible
2402 text. Fget_char_property returns the property of
2403 the char before the given position, i.e. if we
2404 get visible_p = 1, this means that the char at
2405 newpos is visible. */
2406 XSETFASTINT (pos
, newpos
);
2407 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
2408 visible_p
= !TEXT_PROP_MEANS_INVISIBLE (prop
);
2411 /* If we ended up on invisible text, proceed to
2412 skip starting with next_stop. */
2414 IT_CHARPOS (*it
) = next_stop
;
2418 /* The position newpos is now either ZV or on visible text. */
2419 IT_CHARPOS (*it
) = newpos
;
2420 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
2422 /* Maybe return `...' next for the end of the invisible text. */
2423 if (display_ellipsis_p
)
2426 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
2428 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
2429 it
->dpvec
= v
->contents
;
2430 it
->dpend
= v
->contents
+ v
->size
;
2434 /* Default `...'. */
2435 it
->dpvec
= default_invis_vector
;
2436 it
->dpend
= default_invis_vector
+ 3;
2439 /* The ellipsis display does not replace the display of
2440 the character at the new position. Indicate this by
2441 setting IT->dpvec_char_len to zero. */
2442 it
->dpvec_char_len
= 0;
2444 it
->current
.dpvec_index
= 0;
2445 it
->method
= next_element_from_display_vector
;
2455 /***********************************************************************
2457 ***********************************************************************/
2459 /* Set up iterator IT from `display' property at its current position.
2460 Called from handle_stop. */
2462 static enum prop_handled
2463 handle_display_prop (it
)
2466 Lisp_Object prop
, object
;
2467 struct text_pos
*position
;
2468 int space_or_image_found_p
;
2470 if (STRINGP (it
->string
))
2472 object
= it
->string
;
2473 position
= &it
->current
.string_pos
;
2478 position
= &it
->current
.pos
;
2481 /* Reset those iterator values set from display property values. */
2482 it
->font_height
= Qnil
;
2483 it
->space_width
= Qnil
;
2486 /* We don't support recursive `display' properties, i.e. string
2487 values that have a string `display' property, that have a string
2488 `display' property etc. */
2489 if (!it
->string_from_display_prop_p
)
2490 it
->area
= TEXT_AREA
;
2492 prop
= Fget_char_property (make_number (position
->charpos
),
2495 return HANDLED_NORMALLY
;
2497 space_or_image_found_p
= 0;
2499 && CONSP (XCAR (prop
))
2500 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
2502 /* A list of sub-properties. */
2503 while (CONSP (prop
))
2505 if (handle_single_display_prop (it
, XCAR (prop
), object
, position
))
2506 space_or_image_found_p
= 1;
2510 else if (VECTORP (prop
))
2513 for (i
= 0; i
< XVECTOR (prop
)->size
; ++i
)
2514 if (handle_single_display_prop (it
, XVECTOR (prop
)->contents
[i
],
2516 space_or_image_found_p
= 1;
2520 if (handle_single_display_prop (it
, prop
, object
, position
))
2521 space_or_image_found_p
= 1;
2524 return space_or_image_found_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
2528 /* Value is the position of the end of the `display' property starting
2529 at START_POS in OBJECT. */
2531 static struct text_pos
2532 display_prop_end (it
, object
, start_pos
)
2535 struct text_pos start_pos
;
2538 struct text_pos end_pos
;
2540 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
2541 Qdisplay
, object
, Qnil
);
2542 CHARPOS (end_pos
) = XFASTINT (end
);
2543 if (STRINGP (object
))
2544 compute_string_pos (&end_pos
, start_pos
, it
->string
);
2546 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
2552 /* Set up IT from a single `display' sub-property value PROP. OBJECT
2553 is the object in which the `display' property was found. *POSITION
2554 is the position at which it was found.
2556 If PROP is a `space' or `image' sub-property, set *POSITION to the
2557 end position of the `display' property.
2559 Value is non-zero if a `space' or `image' property value was found. */
2562 handle_single_display_prop (it
, prop
, object
, position
)
2566 struct text_pos
*position
;
2569 int space_or_image_found_p
= 0;
2572 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
2573 evaluated. If the result is nil, VALUE is ignored. */
2575 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
2584 if (!NILP (form
) && !EQ (form
, Qt
))
2586 struct gcpro gcpro1
;
2587 struct text_pos end_pos
, pt
;
2590 end_pos
= display_prop_end (it
, object
, *position
);
2592 /* Temporarily set point to the end position, and then evaluate
2593 the form. This makes `(eolp)' work as FORM. */
2594 if (BUFFERP (object
))
2597 BYTEPOS (pt
) = PT_BYTE
;
2598 TEMP_SET_PT_BOTH (CHARPOS (end_pos
), BYTEPOS (end_pos
));
2601 form
= safe_eval (form
);
2603 if (BUFFERP (object
))
2604 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
2612 && EQ (XCAR (prop
), Qheight
)
2613 && CONSP (XCDR (prop
)))
2615 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2618 /* `(height HEIGHT)'. */
2619 it
->font_height
= XCAR (XCDR (prop
));
2620 if (!NILP (it
->font_height
))
2622 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2623 int new_height
= -1;
2625 if (CONSP (it
->font_height
)
2626 && (EQ (XCAR (it
->font_height
), Qplus
)
2627 || EQ (XCAR (it
->font_height
), Qminus
))
2628 && CONSP (XCDR (it
->font_height
))
2629 && INTEGERP (XCAR (XCDR (it
->font_height
))))
2631 /* `(+ N)' or `(- N)' where N is an integer. */
2632 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
2633 if (EQ (XCAR (it
->font_height
), Qplus
))
2635 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
2637 else if (FUNCTIONP (it
->font_height
))
2639 /* Call function with current height as argument.
2640 Value is the new height. */
2642 height
= safe_call1 (it
->font_height
,
2643 face
->lface
[LFACE_HEIGHT_INDEX
]);
2644 if (NUMBERP (height
))
2645 new_height
= XFLOATINT (height
);
2647 else if (NUMBERP (it
->font_height
))
2649 /* Value is a multiple of the canonical char height. */
2652 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
2653 new_height
= (XFLOATINT (it
->font_height
)
2654 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
2658 /* Evaluate IT->font_height with `height' bound to the
2659 current specified height to get the new height. */
2661 int count
= BINDING_STACK_SIZE ();
2663 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
2664 value
= safe_eval (it
->font_height
);
2665 unbind_to (count
, Qnil
);
2667 if (NUMBERP (value
))
2668 new_height
= XFLOATINT (value
);
2672 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
2675 else if (CONSP (prop
)
2676 && EQ (XCAR (prop
), Qspace_width
)
2677 && CONSP (XCDR (prop
)))
2679 /* `(space_width WIDTH)'. */
2680 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2683 value
= XCAR (XCDR (prop
));
2684 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
2685 it
->space_width
= value
;
2687 else if (CONSP (prop
)
2688 && EQ (XCAR (prop
), Qraise
)
2689 && CONSP (XCDR (prop
)))
2691 /* `(raise FACTOR)'. */
2692 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
2695 #ifdef HAVE_WINDOW_SYSTEM
2696 value
= XCAR (XCDR (prop
));
2697 if (NUMBERP (value
))
2699 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2700 it
->voffset
= - (XFLOATINT (value
)
2701 * (FONT_HEIGHT (face
->font
)));
2703 #endif /* HAVE_WINDOW_SYSTEM */
2705 else if (!it
->string_from_display_prop_p
)
2707 /* `((margin left-margin) VALUE)' or `((margin right-margin)
2708 VALUE) or `((margin nil) VALUE)' or VALUE. */
2709 Lisp_Object location
, value
;
2710 struct text_pos start_pos
;
2713 /* Characters having this form of property are not displayed, so
2714 we have to find the end of the property. */
2715 start_pos
= *position
;
2716 *position
= display_prop_end (it
, object
, start_pos
);
2719 /* Let's stop at the new position and assume that all
2720 text properties change there. */
2721 it
->stop_charpos
= position
->charpos
;
2723 location
= Qunbound
;
2724 if (CONSP (prop
) && CONSP (XCAR (prop
)))
2728 value
= XCDR (prop
);
2730 value
= XCAR (value
);
2733 if (EQ (XCAR (tem
), Qmargin
)
2734 && (tem
= XCDR (tem
),
2735 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
2737 || EQ (tem
, Qleft_margin
)
2738 || EQ (tem
, Qright_margin
))))
2742 if (EQ (location
, Qunbound
))
2748 #ifdef HAVE_WINDOW_SYSTEM
2749 if (FRAME_TERMCAP_P (it
->f
))
2750 valid_p
= STRINGP (value
);
2752 valid_p
= (STRINGP (value
)
2753 || (CONSP (value
) && EQ (XCAR (value
), Qspace
))
2754 || valid_image_p (value
));
2755 #else /* not HAVE_WINDOW_SYSTEM */
2756 valid_p
= STRINGP (value
);
2757 #endif /* not HAVE_WINDOW_SYSTEM */
2759 if ((EQ (location
, Qleft_margin
)
2760 || EQ (location
, Qright_margin
)
2764 space_or_image_found_p
= 1;
2766 /* Save current settings of IT so that we can restore them
2767 when we are finished with the glyph property value. */
2770 if (NILP (location
))
2771 it
->area
= TEXT_AREA
;
2772 else if (EQ (location
, Qleft_margin
))
2773 it
->area
= LEFT_MARGIN_AREA
;
2775 it
->area
= RIGHT_MARGIN_AREA
;
2777 if (STRINGP (value
))
2780 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
2781 it
->current
.overlay_string_index
= -1;
2782 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
2783 it
->end_charpos
= it
->string_nchars
2784 = XSTRING (it
->string
)->size
;
2785 it
->method
= next_element_from_string
;
2786 it
->stop_charpos
= 0;
2787 it
->string_from_display_prop_p
= 1;
2789 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
2791 it
->method
= next_element_from_stretch
;
2793 it
->current
.pos
= it
->position
= start_pos
;
2795 #ifdef HAVE_WINDOW_SYSTEM
2798 it
->what
= IT_IMAGE
;
2799 it
->image_id
= lookup_image (it
->f
, value
);
2800 it
->position
= start_pos
;
2801 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
2802 it
->method
= next_element_from_image
;
2804 /* Say that we haven't consumed the characters with
2805 `display' property yet. The call to pop_it in
2806 set_iterator_to_next will clean this up. */
2807 *position
= start_pos
;
2809 #endif /* HAVE_WINDOW_SYSTEM */
2812 /* Invalid property or property not supported. Restore
2813 the position to what it was before. */
2814 *position
= start_pos
;
2817 return space_or_image_found_p
;
2821 /* Check if PROP is a display sub-property value whose text should be
2822 treated as intangible. */
2825 single_display_prop_intangible_p (prop
)
2828 /* Skip over `when FORM'. */
2829 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
2840 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
2841 we don't need to treat text as intangible. */
2842 if (EQ (XCAR (prop
), Qmargin
))
2850 || EQ (XCAR (prop
), Qleft_margin
)
2851 || EQ (XCAR (prop
), Qright_margin
))
2855 return CONSP (prop
) && EQ (XCAR (prop
), Qimage
);
2859 /* Check if PROP is a display property value whose text should be
2860 treated as intangible. */
2863 display_prop_intangible_p (prop
)
2867 && CONSP (XCAR (prop
))
2868 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
2870 /* A list of sub-properties. */
2871 while (CONSP (prop
))
2873 if (single_display_prop_intangible_p (XCAR (prop
)))
2878 else if (VECTORP (prop
))
2880 /* A vector of sub-properties. */
2882 for (i
= 0; i
< XVECTOR (prop
)->size
; ++i
)
2883 if (single_display_prop_intangible_p (XVECTOR (prop
)->contents
[i
]))
2887 return single_display_prop_intangible_p (prop
);
2893 /***********************************************************************
2894 `composition' property
2895 ***********************************************************************/
2897 /* Set up iterator IT from `composition' property at its current
2898 position. Called from handle_stop. */
2900 static enum prop_handled
2901 handle_composition_prop (it
)
2904 Lisp_Object prop
, string
;
2905 int pos
, pos_byte
, end
;
2906 enum prop_handled handled
= HANDLED_NORMALLY
;
2908 if (STRINGP (it
->string
))
2910 pos
= IT_STRING_CHARPOS (*it
);
2911 pos_byte
= IT_STRING_BYTEPOS (*it
);
2912 string
= it
->string
;
2916 pos
= IT_CHARPOS (*it
);
2917 pos_byte
= IT_BYTEPOS (*it
);
2921 /* If there's a valid composition and point is not inside of the
2922 composition (in the case that the composition is from the current
2923 buffer), draw a glyph composed from the composition components. */
2924 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
2925 && COMPOSITION_VALID_P (pos
, end
, prop
)
2926 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
2928 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
2932 it
->method
= next_element_from_composition
;
2934 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
2935 /* For a terminal, draw only the first character of the
2937 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
2938 it
->len
= (STRINGP (it
->string
)
2939 ? string_char_to_byte (it
->string
, end
)
2940 : CHAR_TO_BYTE (end
)) - pos_byte
;
2941 it
->stop_charpos
= end
;
2942 handled
= HANDLED_RETURN
;
2951 /***********************************************************************
2953 ***********************************************************************/
2955 /* The following structure is used to record overlay strings for
2956 later sorting in load_overlay_strings. */
2958 struct overlay_entry
2960 Lisp_Object overlay
;
2967 /* Set up iterator IT from overlay strings at its current position.
2968 Called from handle_stop. */
2970 static enum prop_handled
2971 handle_overlay_change (it
)
2974 if (!STRINGP (it
->string
) && get_overlay_strings (it
))
2975 return HANDLED_RECOMPUTE_PROPS
;
2977 return HANDLED_NORMALLY
;
2981 /* Set up the next overlay string for delivery by IT, if there is an
2982 overlay string to deliver. Called by set_iterator_to_next when the
2983 end of the current overlay string is reached. If there are more
2984 overlay strings to display, IT->string and
2985 IT->current.overlay_string_index are set appropriately here.
2986 Otherwise IT->string is set to nil. */
2989 next_overlay_string (it
)
2992 ++it
->current
.overlay_string_index
;
2993 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
2995 /* No more overlay strings. Restore IT's settings to what
2996 they were before overlay strings were processed, and
2997 continue to deliver from current_buffer. */
2999 xassert (it
->stop_charpos
>= BEGV
3000 && it
->stop_charpos
<= it
->end_charpos
);
3002 it
->current
.overlay_string_index
= -1;
3003 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
3004 it
->n_overlay_strings
= 0;
3005 it
->method
= next_element_from_buffer
;
3007 /* If we're at the end of the buffer, record that we have
3008 processed the overlay strings there already, so that
3009 next_element_from_buffer doesn't try it again. */
3010 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
3011 it
->overlay_strings_at_end_processed_p
= 1;
3015 /* There are more overlay strings to process. If
3016 IT->current.overlay_string_index has advanced to a position
3017 where we must load IT->overlay_strings with more strings, do
3019 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
3021 if (it
->current
.overlay_string_index
&& i
== 0)
3022 load_overlay_strings (it
);
3024 /* Initialize IT to deliver display elements from the overlay
3026 it
->string
= it
->overlay_strings
[i
];
3027 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3028 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
3029 it
->method
= next_element_from_string
;
3030 it
->stop_charpos
= 0;
3037 /* Compare two overlay_entry structures E1 and E2. Used as a
3038 comparison function for qsort in load_overlay_strings. Overlay
3039 strings for the same position are sorted so that
3041 1. All after-strings come in front of before-strings, except
3042 when they come from the same overlay.
3044 2. Within after-strings, strings are sorted so that overlay strings
3045 from overlays with higher priorities come first.
3047 2. Within before-strings, strings are sorted so that overlay
3048 strings from overlays with higher priorities come last.
3050 Value is analogous to strcmp. */
3054 compare_overlay_entries (e1
, e2
)
3057 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
3058 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
3061 if (entry1
->after_string_p
!= entry2
->after_string_p
)
3063 /* Let after-strings appear in front of before-strings if
3064 they come from different overlays. */
3065 if (EQ (entry1
->overlay
, entry2
->overlay
))
3066 result
= entry1
->after_string_p
? 1 : -1;
3068 result
= entry1
->after_string_p
? -1 : 1;
3070 else if (entry1
->after_string_p
)
3071 /* After-strings sorted in order of decreasing priority. */
3072 result
= entry2
->priority
- entry1
->priority
;
3074 /* Before-strings sorted in order of increasing priority. */
3075 result
= entry1
->priority
- entry2
->priority
;
3081 /* Load the vector IT->overlay_strings with overlay strings from IT's
3082 current buffer position. Set IT->n_overlays to the total number of
3083 overlay strings found.
3085 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
3086 a time. On entry into load_overlay_strings,
3087 IT->current.overlay_string_index gives the number of overlay
3088 strings that have already been loaded by previous calls to this
3091 IT->add_overlay_start contains an additional overlay start
3092 position to consider for taking overlay strings from, if non-zero.
3093 This position comes into play when the overlay has an `invisible'
3094 property, and both before and after-strings. When we've skipped to
3095 the end of the overlay, because of its `invisible' property, we
3096 nevertheless want its before-string to appear.
3097 IT->add_overlay_start will contain the overlay start position
3100 Overlay strings are sorted so that after-string strings come in
3101 front of before-string strings. Within before and after-strings,
3102 strings are sorted by overlay priority. See also function
3103 compare_overlay_entries. */
3106 load_overlay_strings (it
)
3109 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
3110 Lisp_Object ov
, overlay
, window
, str
, invisible
;
3113 int n
= 0, i
, j
, invis_p
;
3114 struct overlay_entry
*entries
3115 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
3116 int charpos
= IT_CHARPOS (*it
);
3118 /* Append the overlay string STRING of overlay OVERLAY to vector
3119 `entries' which has size `size' and currently contains `n'
3120 elements. AFTER_P non-zero means STRING is an after-string of
3122 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
3125 Lisp_Object priority; \
3129 int new_size = 2 * size; \
3130 struct overlay_entry *old = entries; \
3132 (struct overlay_entry *) alloca (new_size \
3133 * sizeof *entries); \
3134 bcopy (old, entries, size * sizeof *entries); \
3138 entries[n].string = (STRING); \
3139 entries[n].overlay = (OVERLAY); \
3140 priority = Foverlay_get ((OVERLAY), Qpriority); \
3141 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
3142 entries[n].after_string_p = (AFTER_P); \
3147 /* Process overlay before the overlay center. */
3148 for (ov
= current_buffer
->overlays_before
; CONSP (ov
); ov
= XCDR (ov
))
3150 overlay
= XCAR (ov
);
3151 xassert (OVERLAYP (overlay
));
3152 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
3153 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
3158 /* Skip this overlay if it doesn't start or end at IT's current
3160 if (end
!= charpos
&& start
!= charpos
)
3163 /* Skip this overlay if it doesn't apply to IT->w. */
3164 window
= Foverlay_get (overlay
, Qwindow
);
3165 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
3168 /* If the text ``under'' the overlay is invisible, both before-
3169 and after-strings from this overlay are visible; start and
3170 end position are indistinguishable. */
3171 invisible
= Foverlay_get (overlay
, Qinvisible
);
3172 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
3174 /* If overlay has a non-empty before-string, record it. */
3175 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
3176 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
3177 && XSTRING (str
)->size
)
3178 RECORD_OVERLAY_STRING (overlay
, str
, 0);
3180 /* If overlay has a non-empty after-string, record it. */
3181 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
3182 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
3183 && XSTRING (str
)->size
)
3184 RECORD_OVERLAY_STRING (overlay
, str
, 1);
3187 /* Process overlays after the overlay center. */
3188 for (ov
= current_buffer
->overlays_after
; CONSP (ov
); ov
= XCDR (ov
))
3190 overlay
= XCAR (ov
);
3191 xassert (OVERLAYP (overlay
));
3192 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
3193 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
3195 if (start
> charpos
)
3198 /* Skip this overlay if it doesn't start or end at IT's current
3200 if (end
!= charpos
&& start
!= charpos
)
3203 /* Skip this overlay if it doesn't apply to IT->w. */
3204 window
= Foverlay_get (overlay
, Qwindow
);
3205 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
3208 /* If the text ``under'' the overlay is invisible, it has a zero
3209 dimension, and both before- and after-strings apply. */
3210 invisible
= Foverlay_get (overlay
, Qinvisible
);
3211 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
3213 /* If overlay has a non-empty before-string, record it. */
3214 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
3215 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
3216 && XSTRING (str
)->size
)
3217 RECORD_OVERLAY_STRING (overlay
, str
, 0);
3219 /* If overlay has a non-empty after-string, record it. */
3220 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
3221 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
3222 && XSTRING (str
)->size
)
3223 RECORD_OVERLAY_STRING (overlay
, str
, 1);
3226 #undef RECORD_OVERLAY_STRING
3230 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
3232 /* Record the total number of strings to process. */
3233 it
->n_overlay_strings
= n
;
3235 /* IT->current.overlay_string_index is the number of overlay strings
3236 that have already been consumed by IT. Copy some of the
3237 remaining overlay strings to IT->overlay_strings. */
3239 j
= it
->current
.overlay_string_index
;
3240 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
3241 it
->overlay_strings
[i
++] = entries
[j
++].string
;
3247 /* Get the first chunk of overlay strings at IT's current buffer
3248 position. Value is non-zero if at least one overlay string was
3252 get_overlay_strings (it
)
3255 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
3256 process. This fills IT->overlay_strings with strings, and sets
3257 IT->n_overlay_strings to the total number of strings to process.
3258 IT->pos.overlay_string_index has to be set temporarily to zero
3259 because load_overlay_strings needs this; it must be set to -1
3260 when no overlay strings are found because a zero value would
3261 indicate a position in the first overlay string. */
3262 it
->current
.overlay_string_index
= 0;
3263 load_overlay_strings (it
);
3265 /* If we found overlay strings, set up IT to deliver display
3266 elements from the first one. Otherwise set up IT to deliver
3267 from current_buffer. */
3268 if (it
->n_overlay_strings
)
3270 /* Make sure we know settings in current_buffer, so that we can
3271 restore meaningful values when we're done with the overlay
3273 compute_stop_pos (it
);
3274 xassert (it
->face_id
>= 0);
3276 /* Save IT's settings. They are restored after all overlay
3277 strings have been processed. */
3278 xassert (it
->sp
== 0);
3281 /* Set up IT to deliver display elements from the first overlay
3283 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3284 it
->stop_charpos
= 0;
3285 it
->string
= it
->overlay_strings
[0];
3286 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3287 xassert (STRINGP (it
->string
));
3288 it
->method
= next_element_from_string
;
3293 it
->current
.overlay_string_index
= -1;
3294 it
->method
= next_element_from_buffer
;
3299 /* Value is non-zero if we found at least one overlay string. */
3300 return STRINGP (it
->string
);
3305 /***********************************************************************
3306 Saving and restoring state
3307 ***********************************************************************/
3309 /* Save current settings of IT on IT->stack. Called, for example,
3310 before setting up IT for an overlay string, to be able to restore
3311 IT's settings to what they were after the overlay string has been
3318 struct iterator_stack_entry
*p
;
3320 xassert (it
->sp
< 2);
3321 p
= it
->stack
+ it
->sp
;
3323 p
->stop_charpos
= it
->stop_charpos
;
3324 xassert (it
->face_id
>= 0);
3325 p
->face_id
= it
->face_id
;
3326 p
->string
= it
->string
;
3327 p
->pos
= it
->current
;
3328 p
->end_charpos
= it
->end_charpos
;
3329 p
->string_nchars
= it
->string_nchars
;
3331 p
->multibyte_p
= it
->multibyte_p
;
3332 p
->space_width
= it
->space_width
;
3333 p
->font_height
= it
->font_height
;
3334 p
->voffset
= it
->voffset
;
3335 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
3340 /* Restore IT's settings from IT->stack. Called, for example, when no
3341 more overlay strings must be processed, and we return to delivering
3342 display elements from a buffer, or when the end of a string from a
3343 `display' property is reached and we return to delivering display
3344 elements from an overlay string, or from a buffer. */
3350 struct iterator_stack_entry
*p
;
3352 xassert (it
->sp
> 0);
3354 p
= it
->stack
+ it
->sp
;
3355 it
->stop_charpos
= p
->stop_charpos
;
3356 it
->face_id
= p
->face_id
;
3357 it
->string
= p
->string
;
3358 it
->current
= p
->pos
;
3359 it
->end_charpos
= p
->end_charpos
;
3360 it
->string_nchars
= p
->string_nchars
;
3362 it
->multibyte_p
= p
->multibyte_p
;
3363 it
->space_width
= p
->space_width
;
3364 it
->font_height
= p
->font_height
;
3365 it
->voffset
= p
->voffset
;
3366 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
3371 /***********************************************************************
3373 ***********************************************************************/
3375 /* Set IT's current position to the previous line start. */
3378 back_to_previous_line_start (it
)
3381 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
3382 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
3386 /* Move IT to the next line start.
3388 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
3389 we skipped over part of the text (as opposed to moving the iterator
3390 continuously over the text). Otherwise, don't change the value
3393 Newlines may come from buffer text, overlay strings, or strings
3394 displayed via the `display' property. That's the reason we can't
3395 simply use find_next_newline_no_quit.
3397 Note that this function may not skip over invisible text that is so
3398 because of text properties and immediately follows a newline. If
3399 it would, function reseat_at_next_visible_line_start, when called
3400 from set_iterator_to_next, would effectively make invisible
3401 characters following a newline part of the wrong glyph row, which
3402 leads to wrong cursor motion. */
3405 forward_to_next_line_start (it
, skipped_p
)
3409 int old_selective
, newline_found_p
, n
;
3410 const int MAX_NEWLINE_DISTANCE
= 500;
3412 /* If already on a newline, just consume it to avoid unintended
3413 skipping over invisible text below. */
3414 if (it
->what
== IT_CHARACTER
&& it
->c
== '\n')
3416 set_iterator_to_next (it
, 0);
3420 /* Don't handle selective display in the following. It's (a)
3421 unnecessary because it's done by the caller, and (b) leads to an
3422 infinite recursion because next_element_from_ellipsis indirectly
3423 calls this function. */
3424 old_selective
= it
->selective
;
3427 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
3428 from buffer text. */
3429 n
= newline_found_p
= 0;
3430 while (n
< MAX_NEWLINE_DISTANCE
3431 && get_next_display_element (it
)
3432 && !newline_found_p
)
3434 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
3435 set_iterator_to_next (it
, 0);
3436 if (!STRINGP (it
->string
))
3440 /* If we didn't find a newline near enough, see if we can use a
3442 if (!newline_found_p
&& n
== MAX_NEWLINE_DISTANCE
)
3444 int start
= IT_CHARPOS (*it
);
3445 int limit
= find_next_newline_no_quit (start
, 1);
3448 xassert (!STRINGP (it
->string
));
3450 /* If there isn't any `display' property in sight, and no
3451 overlays, we can just use the position of the newline in
3453 if (it
->stop_charpos
>= limit
3454 || ((pos
= Fnext_single_property_change (make_number (start
),
3456 Qnil
, make_number (limit
)),
3458 && next_overlay_change (start
) == ZV
))
3460 IT_CHARPOS (*it
) = limit
;
3461 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
3462 *skipped_p
= newline_found_p
= 1;
3466 while (get_next_display_element (it
)
3467 && !newline_found_p
)
3469 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
3470 set_iterator_to_next (it
, 0);
3475 it
->selective
= old_selective
;
3476 return newline_found_p
;
3480 /* Set IT's current position to the previous visible line start. Skip
3481 invisible text that is so either due to text properties or due to
3482 selective display. Caution: this does not change IT->current_x and
3486 back_to_previous_visible_line_start (it
)
3491 /* Go back one newline if not on BEGV already. */
3492 if (IT_CHARPOS (*it
) > BEGV
)
3493 back_to_previous_line_start (it
);
3495 /* Move over lines that are invisible because of selective display
3496 or text properties. */
3497 while (IT_CHARPOS (*it
) > BEGV
3502 /* If selective > 0, then lines indented more than that values
3504 if (it
->selective
> 0
3505 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
3512 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
3513 Qinvisible
, it
->window
);
3514 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
3518 /* Back one more newline if the current one is invisible. */
3520 back_to_previous_line_start (it
);
3523 xassert (IT_CHARPOS (*it
) >= BEGV
);
3524 xassert (IT_CHARPOS (*it
) == BEGV
3525 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
3530 /* Reseat iterator IT at the previous visible line start. Skip
3531 invisible text that is so either due to text properties or due to
3532 selective display. At the end, update IT's overlay information,
3533 face information etc. */
3536 reseat_at_previous_visible_line_start (it
)
3539 back_to_previous_visible_line_start (it
);
3540 reseat (it
, it
->current
.pos
, 1);
3545 /* Reseat iterator IT on the next visible line start in the current
3546 buffer. ON_NEWLINE_P non-zero means position IT on the newline
3547 preceding the line start. Skip over invisible text that is so
3548 because of selective display. Compute faces, overlays etc at the
3549 new position. Note that this function does not skip over text that
3550 is invisible because of text properties. */
3553 reseat_at_next_visible_line_start (it
, on_newline_p
)
3557 int newline_found_p
, skipped_p
= 0;
3559 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
3561 /* Skip over lines that are invisible because they are indented
3562 more than the value of IT->selective. */
3563 if (it
->selective
> 0)
3564 while (IT_CHARPOS (*it
) < ZV
3565 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
3567 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
3569 /* Position on the newline if that's what's requested. */
3570 if (on_newline_p
&& newline_found_p
)
3572 if (STRINGP (it
->string
))
3574 if (IT_STRING_CHARPOS (*it
) > 0)
3576 --IT_STRING_CHARPOS (*it
);
3577 --IT_STRING_BYTEPOS (*it
);
3580 else if (IT_CHARPOS (*it
) > BEGV
)
3584 reseat (it
, it
->current
.pos
, 0);
3588 reseat (it
, it
->current
.pos
, 0);
3595 /***********************************************************************
3596 Changing an iterator's position
3597 ***********************************************************************/
3599 /* Change IT's current position to POS in current_buffer. If FORCE_P
3600 is non-zero, always check for text properties at the new position.
3601 Otherwise, text properties are only looked up if POS >=
3602 IT->check_charpos of a property. */
3605 reseat (it
, pos
, force_p
)
3607 struct text_pos pos
;
3610 int original_pos
= IT_CHARPOS (*it
);
3612 reseat_1 (it
, pos
, 0);
3614 /* Determine where to check text properties. Avoid doing it
3615 where possible because text property lookup is very expensive. */
3617 || CHARPOS (pos
) > it
->stop_charpos
3618 || CHARPOS (pos
) < original_pos
)
3625 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
3626 IT->stop_pos to POS, also. */
3629 reseat_1 (it
, pos
, set_stop_p
)
3631 struct text_pos pos
;
3634 /* Don't call this function when scanning a C string. */
3635 xassert (it
->s
== NULL
);
3637 /* POS must be a reasonable value. */
3638 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
3640 it
->current
.pos
= it
->position
= pos
;
3641 XSETBUFFER (it
->object
, current_buffer
);
3643 it
->current
.dpvec_index
= -1;
3644 it
->current
.overlay_string_index
= -1;
3645 IT_STRING_CHARPOS (*it
) = -1;
3646 IT_STRING_BYTEPOS (*it
) = -1;
3648 it
->method
= next_element_from_buffer
;
3652 it
->stop_charpos
= CHARPOS (pos
);
3656 /* Set up IT for displaying a string, starting at CHARPOS in window W.
3657 If S is non-null, it is a C string to iterate over. Otherwise,
3658 STRING gives a Lisp string to iterate over.
3660 If PRECISION > 0, don't return more then PRECISION number of
3661 characters from the string.
3663 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
3664 characters have been returned. FIELD_WIDTH < 0 means an infinite
3667 MULTIBYTE = 0 means disable processing of multibyte characters,
3668 MULTIBYTE > 0 means enable it,
3669 MULTIBYTE < 0 means use IT->multibyte_p.
3671 IT must be initialized via a prior call to init_iterator before
3672 calling this function. */
3675 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
3680 int precision
, field_width
, multibyte
;
3682 /* No region in strings. */
3683 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
3685 /* No text property checks performed by default, but see below. */
3686 it
->stop_charpos
= -1;
3688 /* Set iterator position and end position. */
3689 bzero (&it
->current
, sizeof it
->current
);
3690 it
->current
.overlay_string_index
= -1;
3691 it
->current
.dpvec_index
= -1;
3692 xassert (charpos
>= 0);
3694 /* Use the setting of MULTIBYTE if specified. */
3696 it
->multibyte_p
= multibyte
> 0;
3700 xassert (STRINGP (string
));
3701 it
->string
= string
;
3703 it
->end_charpos
= it
->string_nchars
= XSTRING (string
)->size
;
3704 it
->method
= next_element_from_string
;
3705 it
->current
.string_pos
= string_pos (charpos
, string
);
3712 /* Note that we use IT->current.pos, not it->current.string_pos,
3713 for displaying C strings. */
3714 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
3715 if (it
->multibyte_p
)
3717 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
3718 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
3722 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
3723 it
->end_charpos
= it
->string_nchars
= strlen (s
);
3726 it
->method
= next_element_from_c_string
;
3729 /* PRECISION > 0 means don't return more than PRECISION characters
3731 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
3732 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
3734 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
3735 characters have been returned. FIELD_WIDTH == 0 means don't pad,
3736 FIELD_WIDTH < 0 means infinite field width. This is useful for
3737 padding with `-' at the end of a mode line. */
3738 if (field_width
< 0)
3739 field_width
= INFINITY
;
3740 if (field_width
> it
->end_charpos
- charpos
)
3741 it
->end_charpos
= charpos
+ field_width
;
3743 /* Use the standard display table for displaying strings. */
3744 if (DISP_TABLE_P (Vstandard_display_table
))
3745 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
3747 it
->stop_charpos
= charpos
;
3753 /***********************************************************************
3755 ***********************************************************************/
3757 /* Load IT's display element fields with information about the next
3758 display element from the current position of IT. Value is zero if
3759 end of buffer (or C string) is reached. */
3762 get_next_display_element (it
)
3765 /* Non-zero means that we found an display element. Zero means that
3766 we hit the end of what we iterate over. Performance note: the
3767 function pointer `method' used here turns out to be faster than
3768 using a sequence of if-statements. */
3769 int success_p
= (*it
->method
) (it
);
3771 if (it
->what
== IT_CHARACTER
)
3773 /* Map via display table or translate control characters.
3774 IT->c, IT->len etc. have been set to the next character by
3775 the function call above. If we have a display table, and it
3776 contains an entry for IT->c, translate it. Don't do this if
3777 IT->c itself comes from a display table, otherwise we could
3778 end up in an infinite recursion. (An alternative could be to
3779 count the recursion depth of this function and signal an
3780 error when a certain maximum depth is reached.) Is it worth
3782 if (success_p
&& it
->dpvec
== NULL
)
3787 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
3790 struct Lisp_Vector
*v
= XVECTOR (dv
);
3792 /* Return the first character from the display table
3793 entry, if not empty. If empty, don't display the
3794 current character. */
3797 it
->dpvec_char_len
= it
->len
;
3798 it
->dpvec
= v
->contents
;
3799 it
->dpend
= v
->contents
+ v
->size
;
3800 it
->current
.dpvec_index
= 0;
3801 it
->method
= next_element_from_display_vector
;
3804 success_p
= get_next_display_element (it
);
3807 /* Translate control characters into `\003' or `^C' form.
3808 Control characters coming from a display table entry are
3809 currently not translated because we use IT->dpvec to hold
3810 the translation. This could easily be changed but I
3811 don't believe that it is worth doing.
3813 Non-printable multibyte characters are also translated
3815 else if ((it
->c
< ' '
3816 && (it
->area
!= TEXT_AREA
3817 || (it
->c
!= '\n' && it
->c
!= '\t')))
3820 || !CHAR_PRINTABLE_P (it
->c
))
3822 /* IT->c is a control character which must be displayed
3823 either as '\003' or as `^C' where the '\\' and '^'
3824 can be defined in the display table. Fill
3825 IT->ctl_chars with glyphs for what we have to
3826 display. Then, set IT->dpvec to these glyphs. */
3829 if (it
->c
< 128 && it
->ctl_arrow_p
)
3831 /* Set IT->ctl_chars[0] to the glyph for `^'. */
3833 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
3834 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
3835 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
3837 g
= FAST_MAKE_GLYPH ('^', 0);
3838 XSETINT (it
->ctl_chars
[0], g
);
3840 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
3841 XSETINT (it
->ctl_chars
[1], g
);
3843 /* Set up IT->dpvec and return first character from it. */
3844 it
->dpvec_char_len
= it
->len
;
3845 it
->dpvec
= it
->ctl_chars
;
3846 it
->dpend
= it
->dpvec
+ 2;
3847 it
->current
.dpvec_index
= 0;
3848 it
->method
= next_element_from_display_vector
;
3849 get_next_display_element (it
);
3853 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
3858 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
3860 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
3861 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
3862 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
3864 escape_glyph
= FAST_MAKE_GLYPH ('\\', 0);
3866 if (SINGLE_BYTE_CHAR_P (it
->c
))
3867 str
[0] = it
->c
, len
= 1;
3869 len
= CHAR_STRING (it
->c
, str
);
3871 for (i
= 0; i
< len
; i
++)
3873 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
3874 /* Insert three more glyphs into IT->ctl_chars for
3875 the octal display of the character. */
3876 g
= FAST_MAKE_GLYPH (((str
[i
] >> 6) & 7) + '0', 0);
3877 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
3878 g
= FAST_MAKE_GLYPH (((str
[i
] >> 3) & 7) + '0', 0);
3879 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
3880 g
= FAST_MAKE_GLYPH ((str
[i
] & 7) + '0', 0);
3881 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
3884 /* Set up IT->dpvec and return the first character
3886 it
->dpvec_char_len
= it
->len
;
3887 it
->dpvec
= it
->ctl_chars
;
3888 it
->dpend
= it
->dpvec
+ len
* 4;
3889 it
->current
.dpvec_index
= 0;
3890 it
->method
= next_element_from_display_vector
;
3891 get_next_display_element (it
);
3896 /* Adjust face id for a multibyte character. There are no
3897 multibyte character in unibyte text. */
3900 && FRAME_WINDOW_P (it
->f
))
3902 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3903 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
3907 /* Is this character the last one of a run of characters with
3908 box? If yes, set IT->end_of_box_run_p to 1. */
3915 it
->end_of_box_run_p
3916 = ((face_id
= face_after_it_pos (it
),
3917 face_id
!= it
->face_id
)
3918 && (face
= FACE_FROM_ID (it
->f
, face_id
),
3919 face
->box
== FACE_NO_BOX
));
3922 /* Value is 0 if end of buffer or string reached. */
3927 /* Move IT to the next display element.
3929 RESEAT_P non-zero means if called on a newline in buffer text,
3930 skip to the next visible line start.
3932 Functions get_next_display_element and set_iterator_to_next are
3933 separate because I find this arrangement easier to handle than a
3934 get_next_display_element function that also increments IT's
3935 position. The way it is we can first look at an iterator's current
3936 display element, decide whether it fits on a line, and if it does,
3937 increment the iterator position. The other way around we probably
3938 would either need a flag indicating whether the iterator has to be
3939 incremented the next time, or we would have to implement a
3940 decrement position function which would not be easy to write. */
3943 set_iterator_to_next (it
, reseat_p
)
3947 /* Reset flags indicating start and end of a sequence of characters
3948 with box. Reset them at the start of this function because
3949 moving the iterator to a new position might set them. */
3950 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
3952 if (it
->method
== next_element_from_buffer
)
3954 /* The current display element of IT is a character from
3955 current_buffer. Advance in the buffer, and maybe skip over
3956 invisible lines that are so because of selective display. */
3957 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
3958 reseat_at_next_visible_line_start (it
, 0);
3961 xassert (it
->len
!= 0);
3962 IT_BYTEPOS (*it
) += it
->len
;
3963 IT_CHARPOS (*it
) += 1;
3964 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
3967 else if (it
->method
== next_element_from_composition
)
3969 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
3970 if (STRINGP (it
->string
))
3972 IT_STRING_BYTEPOS (*it
) += it
->len
;
3973 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
3974 it
->method
= next_element_from_string
;
3975 goto consider_string_end
;
3979 IT_BYTEPOS (*it
) += it
->len
;
3980 IT_CHARPOS (*it
) += it
->cmp_len
;
3981 it
->method
= next_element_from_buffer
;
3984 else if (it
->method
== next_element_from_c_string
)
3986 /* Current display element of IT is from a C string. */
3987 IT_BYTEPOS (*it
) += it
->len
;
3988 IT_CHARPOS (*it
) += 1;
3990 else if (it
->method
== next_element_from_display_vector
)
3992 /* Current display element of IT is from a display table entry.
3993 Advance in the display table definition. Reset it to null if
3994 end reached, and continue with characters from buffers/
3996 ++it
->current
.dpvec_index
;
3998 /* Restore face of the iterator to what they were before the
3999 display vector entry (these entries may contain faces). */
4000 it
->face_id
= it
->saved_face_id
;
4002 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
4005 it
->method
= next_element_from_c_string
;
4006 else if (STRINGP (it
->string
))
4007 it
->method
= next_element_from_string
;
4009 it
->method
= next_element_from_buffer
;
4012 it
->current
.dpvec_index
= -1;
4014 /* Skip over characters which were displayed via IT->dpvec. */
4015 if (it
->dpvec_char_len
< 0)
4016 reseat_at_next_visible_line_start (it
, 1);
4017 else if (it
->dpvec_char_len
> 0)
4019 it
->len
= it
->dpvec_char_len
;
4020 set_iterator_to_next (it
, reseat_p
);
4024 else if (it
->method
== next_element_from_string
)
4026 /* Current display element is a character from a Lisp string. */
4027 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
4028 IT_STRING_BYTEPOS (*it
) += it
->len
;
4029 IT_STRING_CHARPOS (*it
) += 1;
4031 consider_string_end
:
4033 if (it
->current
.overlay_string_index
>= 0)
4035 /* IT->string is an overlay string. Advance to the
4036 next, if there is one. */
4037 if (IT_STRING_CHARPOS (*it
) >= XSTRING (it
->string
)->size
)
4038 next_overlay_string (it
);
4042 /* IT->string is not an overlay string. If we reached
4043 its end, and there is something on IT->stack, proceed
4044 with what is on the stack. This can be either another
4045 string, this time an overlay string, or a buffer. */
4046 if (IT_STRING_CHARPOS (*it
) == XSTRING (it
->string
)->size
4050 if (!STRINGP (it
->string
))
4051 it
->method
= next_element_from_buffer
;
4055 else if (it
->method
== next_element_from_image
4056 || it
->method
== next_element_from_stretch
)
4058 /* The position etc with which we have to proceed are on
4059 the stack. The position may be at the end of a string,
4060 if the `display' property takes up the whole string. */
4063 if (STRINGP (it
->string
))
4065 it
->method
= next_element_from_string
;
4066 goto consider_string_end
;
4069 it
->method
= next_element_from_buffer
;
4072 /* There are no other methods defined, so this should be a bug. */
4075 xassert (it
->method
!= next_element_from_string
4076 || (STRINGP (it
->string
)
4077 && IT_STRING_CHARPOS (*it
) >= 0));
4081 /* Load IT's display element fields with information about the next
4082 display element which comes from a display table entry or from the
4083 result of translating a control character to one of the forms `^C'
4084 or `\003'. IT->dpvec holds the glyphs to return as characters. */
4087 next_element_from_display_vector (it
)
4091 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
4093 /* Remember the current face id in case glyphs specify faces.
4094 IT's face is restored in set_iterator_to_next. */
4095 it
->saved_face_id
= it
->face_id
;
4097 if (INTEGERP (*it
->dpvec
)
4098 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
4103 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
4104 it
->c
= FAST_GLYPH_CHAR (g
);
4105 it
->len
= CHAR_BYTES (it
->c
);
4107 /* The entry may contain a face id to use. Such a face id is
4108 the id of a Lisp face, not a realized face. A face id of
4109 zero means no face is specified. */
4110 lface_id
= FAST_GLYPH_FACE (g
);
4113 /* The function returns -1 if lface_id is invalid. */
4114 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
4116 it
->face_id
= face_id
;
4120 /* Display table entry is invalid. Return a space. */
4121 it
->c
= ' ', it
->len
= 1;
4123 /* Don't change position and object of the iterator here. They are
4124 still the values of the character that had this display table
4125 entry or was translated, and that's what we want. */
4126 it
->what
= IT_CHARACTER
;
4131 /* Load IT with the next display element from Lisp string IT->string.
4132 IT->current.string_pos is the current position within the string.
4133 If IT->current.overlay_string_index >= 0, the Lisp string is an
4137 next_element_from_string (it
)
4140 struct text_pos position
;
4142 xassert (STRINGP (it
->string
));
4143 xassert (IT_STRING_CHARPOS (*it
) >= 0);
4144 position
= it
->current
.string_pos
;
4146 /* Time to check for invisible text? */
4147 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
4148 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
4152 /* Since a handler may have changed IT->method, we must
4154 return get_next_display_element (it
);
4157 if (it
->current
.overlay_string_index
>= 0)
4159 /* Get the next character from an overlay string. In overlay
4160 strings, There is no field width or padding with spaces to
4162 if (IT_STRING_CHARPOS (*it
) >= XSTRING (it
->string
)->size
)
4167 else if (STRING_MULTIBYTE (it
->string
))
4169 int remaining
= (STRING_BYTES (XSTRING (it
->string
))
4170 - IT_STRING_BYTEPOS (*it
));
4171 unsigned char *s
= (XSTRING (it
->string
)->data
4172 + IT_STRING_BYTEPOS (*it
));
4173 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
4177 it
->c
= XSTRING (it
->string
)->data
[IT_STRING_BYTEPOS (*it
)];
4183 /* Get the next character from a Lisp string that is not an
4184 overlay string. Such strings come from the mode line, for
4185 example. We may have to pad with spaces, or truncate the
4186 string. See also next_element_from_c_string. */
4187 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
4192 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
4194 /* Pad with spaces. */
4195 it
->c
= ' ', it
->len
= 1;
4196 CHARPOS (position
) = BYTEPOS (position
) = -1;
4198 else if (STRING_MULTIBYTE (it
->string
))
4200 int maxlen
= (STRING_BYTES (XSTRING (it
->string
))
4201 - IT_STRING_BYTEPOS (*it
));
4202 unsigned char *s
= (XSTRING (it
->string
)->data
4203 + IT_STRING_BYTEPOS (*it
));
4204 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
4208 it
->c
= XSTRING (it
->string
)->data
[IT_STRING_BYTEPOS (*it
)];
4213 /* Record what we have and where it came from. Note that we store a
4214 buffer position in IT->position although it could arguably be a
4216 it
->what
= IT_CHARACTER
;
4217 it
->object
= it
->string
;
4218 it
->position
= position
;
4223 /* Load IT with next display element from C string IT->s.
4224 IT->string_nchars is the maximum number of characters to return
4225 from the string. IT->end_charpos may be greater than
4226 IT->string_nchars when this function is called, in which case we
4227 may have to return padding spaces. Value is zero if end of string
4228 reached, including padding spaces. */
4231 next_element_from_c_string (it
)
4237 it
->what
= IT_CHARACTER
;
4238 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
4241 /* IT's position can be greater IT->string_nchars in case a field
4242 width or precision has been specified when the iterator was
4244 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
4246 /* End of the game. */
4250 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
4252 /* Pad with spaces. */
4253 it
->c
= ' ', it
->len
= 1;
4254 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
4256 else if (it
->multibyte_p
)
4258 /* Implementation note: The calls to strlen apparently aren't a
4259 performance problem because there is no noticeable performance
4260 difference between Emacs running in unibyte or multibyte mode. */
4261 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
4262 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
4266 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
4272 /* Set up IT to return characters from an ellipsis, if appropriate.
4273 The definition of the ellipsis glyphs may come from a display table
4274 entry. This function Fills IT with the first glyph from the
4275 ellipsis if an ellipsis is to be displayed. */
4278 next_element_from_ellipsis (it
)
4281 if (it
->selective_display_ellipsis_p
)
4283 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
4285 /* Use the display table definition for `...'. Invalid glyphs
4286 will be handled by the method returning elements from dpvec. */
4287 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
4288 it
->dpvec_char_len
= it
->len
;
4289 it
->dpvec
= v
->contents
;
4290 it
->dpend
= v
->contents
+ v
->size
;
4291 it
->current
.dpvec_index
= 0;
4292 it
->method
= next_element_from_display_vector
;
4296 /* Use default `...' which is stored in default_invis_vector. */
4297 it
->dpvec_char_len
= it
->len
;
4298 it
->dpvec
= default_invis_vector
;
4299 it
->dpend
= default_invis_vector
+ 3;
4300 it
->current
.dpvec_index
= 0;
4301 it
->method
= next_element_from_display_vector
;
4306 it
->method
= next_element_from_buffer
;
4307 reseat_at_next_visible_line_start (it
, 1);
4310 return get_next_display_element (it
);
4314 /* Deliver an image display element. The iterator IT is already
4315 filled with image information (done in handle_display_prop). Value
4320 next_element_from_image (it
)
4323 it
->what
= IT_IMAGE
;
4328 /* Fill iterator IT with next display element from a stretch glyph
4329 property. IT->object is the value of the text property. Value is
4333 next_element_from_stretch (it
)
4336 it
->what
= IT_STRETCH
;
4341 /* Load IT with the next display element from current_buffer. Value
4342 is zero if end of buffer reached. IT->stop_charpos is the next
4343 position at which to stop and check for text properties or buffer
4347 next_element_from_buffer (it
)
4352 /* Check this assumption, otherwise, we would never enter the
4353 if-statement, below. */
4354 xassert (IT_CHARPOS (*it
) >= BEGV
4355 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
4357 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
4359 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
4361 int overlay_strings_follow_p
;
4363 /* End of the game, except when overlay strings follow that
4364 haven't been returned yet. */
4365 if (it
->overlay_strings_at_end_processed_p
)
4366 overlay_strings_follow_p
= 0;
4369 it
->overlay_strings_at_end_processed_p
= 1;
4370 overlay_strings_follow_p
= get_overlay_strings (it
);
4373 if (overlay_strings_follow_p
)
4374 success_p
= get_next_display_element (it
);
4378 it
->position
= it
->current
.pos
;
4385 return get_next_display_element (it
);
4390 /* No face changes, overlays etc. in sight, so just return a
4391 character from current_buffer. */
4394 /* Maybe run the redisplay end trigger hook. Performance note:
4395 This doesn't seem to cost measurable time. */
4396 if (it
->redisplay_end_trigger_charpos
4398 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
4399 run_redisplay_end_trigger_hook (it
);
4401 /* Get the next character, maybe multibyte. */
4402 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
4403 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
4405 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
4406 - IT_BYTEPOS (*it
));
4407 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
4410 it
->c
= *p
, it
->len
= 1;
4412 /* Record what we have and where it came from. */
4413 it
->what
= IT_CHARACTER
;;
4414 it
->object
= it
->w
->buffer
;
4415 it
->position
= it
->current
.pos
;
4417 /* Normally we return the character found above, except when we
4418 really want to return an ellipsis for selective display. */
4423 /* A value of selective > 0 means hide lines indented more
4424 than that number of columns. */
4425 if (it
->selective
> 0
4426 && IT_CHARPOS (*it
) + 1 < ZV
4427 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
4428 IT_BYTEPOS (*it
) + 1,
4431 success_p
= next_element_from_ellipsis (it
);
4432 it
->dpvec_char_len
= -1;
4435 else if (it
->c
== '\r' && it
->selective
== -1)
4437 /* A value of selective == -1 means that everything from the
4438 CR to the end of the line is invisible, with maybe an
4439 ellipsis displayed for it. */
4440 success_p
= next_element_from_ellipsis (it
);
4441 it
->dpvec_char_len
= -1;
4446 /* Value is zero if end of buffer reached. */
4447 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
4452 /* Run the redisplay end trigger hook for IT. */
4455 run_redisplay_end_trigger_hook (it
)
4458 Lisp_Object args
[3];
4460 /* IT->glyph_row should be non-null, i.e. we should be actually
4461 displaying something, or otherwise we should not run the hook. */
4462 xassert (it
->glyph_row
);
4464 /* Set up hook arguments. */
4465 args
[0] = Qredisplay_end_trigger_functions
;
4466 args
[1] = it
->window
;
4467 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
4468 it
->redisplay_end_trigger_charpos
= 0;
4470 /* Since we are *trying* to run these functions, don't try to run
4471 them again, even if they get an error. */
4472 it
->w
->redisplay_end_trigger
= Qnil
;
4473 Frun_hook_with_args (3, args
);
4475 /* Notice if it changed the face of the character we are on. */
4476 handle_face_prop (it
);
4480 /* Deliver a composition display element. The iterator IT is already
4481 filled with composition information (done in
4482 handle_composition_prop). Value is always 1. */
4485 next_element_from_composition (it
)
4488 it
->what
= IT_COMPOSITION
;
4489 it
->position
= (STRINGP (it
->string
)
4490 ? it
->current
.string_pos
4497 /***********************************************************************
4498 Moving an iterator without producing glyphs
4499 ***********************************************************************/
4501 /* Move iterator IT to a specified buffer or X position within one
4502 line on the display without producing glyphs.
4504 Begin to skip at IT's current position. Skip to TO_CHARPOS or TO_X
4505 whichever is reached first.
4507 TO_CHARPOS <= 0 means no TO_CHARPOS is specified.
4509 TO_X < 0 means that no TO_X is specified. TO_X is normally a value
4510 0 <= TO_X <= IT->last_visible_x. This means in particular, that
4511 TO_X includes the amount by which a window is horizontally
4516 MOVE_POS_MATCH_OR_ZV
4517 - when TO_POS or ZV was reached.
4520 -when TO_X was reached before TO_POS or ZV were reached.
4523 - when we reached the end of the display area and the line must
4527 - when we reached the end of the display area and the line is
4531 - when we stopped at a line end, i.e. a newline or a CR and selective
4534 static enum move_it_result
4535 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
4537 int to_charpos
, to_x
, op
;
4539 enum move_it_result result
= MOVE_UNDEFINED
;
4540 struct glyph_row
*saved_glyph_row
;
4542 /* Don't produce glyphs in produce_glyphs. */
4543 saved_glyph_row
= it
->glyph_row
;
4544 it
->glyph_row
= NULL
;
4548 int x
, i
, ascent
= 0, descent
= 0;
4550 /* Stop when ZV or TO_CHARPOS reached. */
4551 if (!get_next_display_element (it
)
4552 || ((op
& MOVE_TO_POS
) != 0
4553 && BUFFERP (it
->object
)
4554 && IT_CHARPOS (*it
) >= to_charpos
))
4556 result
= MOVE_POS_MATCH_OR_ZV
;
4560 /* The call to produce_glyphs will get the metrics of the
4561 display element IT is loaded with. We record in x the
4562 x-position before this display element in case it does not
4566 /* Remember the line height so far in case the next element doesn't
4568 if (!it
->truncate_lines_p
)
4570 ascent
= it
->max_ascent
;
4571 descent
= it
->max_descent
;
4574 PRODUCE_GLYPHS (it
);
4576 if (it
->area
!= TEXT_AREA
)
4578 set_iterator_to_next (it
, 1);
4582 /* The number of glyphs we get back in IT->nglyphs will normally
4583 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
4584 character on a terminal frame, or (iii) a line end. For the
4585 second case, IT->nglyphs - 1 padding glyphs will be present
4586 (on X frames, there is only one glyph produced for a
4587 composite character.
4589 The behavior implemented below means, for continuation lines,
4590 that as many spaces of a TAB as fit on the current line are
4591 displayed there. For terminal frames, as many glyphs of a
4592 multi-glyph character are displayed in the current line, too.
4593 This is what the old redisplay code did, and we keep it that
4594 way. Under X, the whole shape of a complex character must
4595 fit on the line or it will be completely displayed in the
4598 Note that both for tabs and padding glyphs, all glyphs have
4602 /* More than one glyph or glyph doesn't fit on line. All
4603 glyphs have the same width. */
4604 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
4607 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
4609 new_x
= x
+ single_glyph_width
;
4611 /* We want to leave anything reaching TO_X to the caller. */
4612 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
4615 result
= MOVE_X_REACHED
;
4618 else if (/* Lines are continued. */
4619 !it
->truncate_lines_p
4620 && (/* And glyph doesn't fit on the line. */
4621 new_x
> it
->last_visible_x
4622 /* Or it fits exactly and we're on a window
4624 || (new_x
== it
->last_visible_x
4625 && FRAME_WINDOW_P (it
->f
))))
4627 if (/* IT->hpos == 0 means the very first glyph
4628 doesn't fit on the line, e.g. a wide image. */
4630 || (new_x
== it
->last_visible_x
4631 && FRAME_WINDOW_P (it
->f
)))
4634 it
->current_x
= new_x
;
4635 if (i
== it
->nglyphs
- 1)
4636 set_iterator_to_next (it
, 1);
4641 it
->max_ascent
= ascent
;
4642 it
->max_descent
= descent
;
4645 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
4647 result
= MOVE_LINE_CONTINUED
;
4650 else if (new_x
> it
->first_visible_x
)
4652 /* Glyph is visible. Increment number of glyphs that
4653 would be displayed. */
4658 /* Glyph is completely off the left margin of the display
4659 area. Nothing to do. */
4663 if (result
!= MOVE_UNDEFINED
)
4666 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
4668 /* Stop when TO_X specified and reached. This check is
4669 necessary here because of lines consisting of a line end,
4670 only. The line end will not produce any glyphs and we
4671 would never get MOVE_X_REACHED. */
4672 xassert (it
->nglyphs
== 0);
4673 result
= MOVE_X_REACHED
;
4677 /* Is this a line end? If yes, we're done. */
4678 if (ITERATOR_AT_END_OF_LINE_P (it
))
4680 result
= MOVE_NEWLINE_OR_CR
;
4684 /* The current display element has been consumed. Advance
4686 set_iterator_to_next (it
, 1);
4688 /* Stop if lines are truncated and IT's current x-position is
4689 past the right edge of the window now. */
4690 if (it
->truncate_lines_p
4691 && it
->current_x
>= it
->last_visible_x
)
4693 result
= MOVE_LINE_TRUNCATED
;
4698 /* Restore the iterator settings altered at the beginning of this
4700 it
->glyph_row
= saved_glyph_row
;
4705 /* Move IT forward to a specified buffer position TO_CHARPOS, TO_X,
4706 TO_Y, TO_VPOS. OP is a bit-mask that specifies where to stop. See
4707 the description of enum move_operation_enum.
4709 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
4710 screen line, this function will set IT to the next position >
4714 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
4716 int to_charpos
, to_x
, to_y
, to_vpos
;
4719 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
4725 if (op
& MOVE_TO_VPOS
)
4727 /* If no TO_CHARPOS and no TO_X specified, stop at the
4728 start of the line TO_VPOS. */
4729 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
4731 if (it
->vpos
== to_vpos
)
4737 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
4741 /* TO_VPOS >= 0 means stop at TO_X in the line at
4742 TO_VPOS, or at TO_POS, whichever comes first. */
4743 if (it
->vpos
== to_vpos
)
4749 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
4751 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
4756 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
4758 /* We have reached TO_X but not in the line we want. */
4759 skip
= move_it_in_display_line_to (it
, to_charpos
,
4761 if (skip
== MOVE_POS_MATCH_OR_ZV
)
4769 else if (op
& MOVE_TO_Y
)
4771 struct it it_backup
;
4773 /* TO_Y specified means stop at TO_X in the line containing
4774 TO_Y---or at TO_CHARPOS if this is reached first. The
4775 problem is that we can't really tell whether the line
4776 contains TO_Y before we have completely scanned it, and
4777 this may skip past TO_X. What we do is to first scan to
4780 If TO_X is not specified, use a TO_X of zero. The reason
4781 is to make the outcome of this function more predictable.
4782 If we didn't use TO_X == 0, we would stop at the end of
4783 the line which is probably not what a caller would expect
4785 skip
= move_it_in_display_line_to (it
, to_charpos
,
4789 | (op
& MOVE_TO_POS
)));
4791 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
4792 if (skip
== MOVE_POS_MATCH_OR_ZV
)
4798 /* If TO_X was reached, we would like to know whether TO_Y
4799 is in the line. This can only be said if we know the
4800 total line height which requires us to scan the rest of
4802 if (skip
== MOVE_X_REACHED
)
4805 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
4806 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
4808 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
4811 /* Now, decide whether TO_Y is in this line. */
4812 line_height
= it
->max_ascent
+ it
->max_descent
;
4813 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
4815 if (to_y
>= it
->current_y
4816 && to_y
< it
->current_y
+ line_height
)
4818 if (skip
== MOVE_X_REACHED
)
4819 /* If TO_Y is in this line and TO_X was reached above,
4820 we scanned too far. We have to restore IT's settings
4821 to the ones before skipping. */
4825 else if (skip
== MOVE_X_REACHED
)
4828 if (skip
== MOVE_POS_MATCH_OR_ZV
)
4836 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
4840 case MOVE_POS_MATCH_OR_ZV
:
4844 case MOVE_NEWLINE_OR_CR
:
4845 set_iterator_to_next (it
, 1);
4846 it
->continuation_lines_width
= 0;
4849 case MOVE_LINE_TRUNCATED
:
4850 it
->continuation_lines_width
= 0;
4851 reseat_at_next_visible_line_start (it
, 0);
4852 if ((op
& MOVE_TO_POS
) != 0
4853 && IT_CHARPOS (*it
) > to_charpos
)
4860 case MOVE_LINE_CONTINUED
:
4861 it
->continuation_lines_width
+= it
->current_x
;
4868 /* Reset/increment for the next run. */
4869 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
4870 it
->current_x
= it
->hpos
= 0;
4871 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
4873 last_height
= it
->max_ascent
+ it
->max_descent
;
4874 last_max_ascent
= it
->max_ascent
;
4875 it
->max_ascent
= it
->max_descent
= 0;
4880 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
4884 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
4886 If DY > 0, move IT backward at least that many pixels. DY = 0
4887 means move IT backward to the preceding line start or BEGV. This
4888 function may move over more than DY pixels if IT->current_y - DY
4889 ends up in the middle of a line; in this case IT->current_y will be
4890 set to the top of the line moved to. */
4893 move_it_vertically_backward (it
, dy
)
4897 int nlines
, h
, line_height
;
4899 int start_pos
= IT_CHARPOS (*it
);
4903 /* Estimate how many newlines we must move back. */
4904 nlines
= max (1, dy
/ CANON_Y_UNIT (it
->f
));
4906 /* Set the iterator's position that many lines back. */
4907 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
4908 back_to_previous_visible_line_start (it
);
4910 /* Reseat the iterator here. When moving backward, we don't want
4911 reseat to skip forward over invisible text, set up the iterator
4912 to deliver from overlay strings at the new position etc. So,
4913 use reseat_1 here. */
4914 reseat_1 (it
, it
->current
.pos
, 1);
4916 /* We are now surely at a line start. */
4917 it
->current_x
= it
->hpos
= 0;
4919 /* Move forward and see what y-distance we moved. First move to the
4920 start of the next line so that we get its height. We need this
4921 height to be able to tell whether we reached the specified
4924 it2
.max_ascent
= it2
.max_descent
= 0;
4925 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
4926 MOVE_TO_POS
| MOVE_TO_VPOS
);
4927 xassert (IT_CHARPOS (*it
) >= BEGV
);
4928 line_height
= it2
.max_ascent
+ it2
.max_descent
;
4930 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
4931 xassert (IT_CHARPOS (*it
) >= BEGV
);
4932 h
= it2
.current_y
- it
->current_y
;
4933 nlines
= it2
.vpos
- it
->vpos
;
4935 /* Correct IT's y and vpos position. */
4941 /* DY == 0 means move to the start of the screen line. The
4942 value of nlines is > 0 if continuation lines were involved. */
4944 move_it_by_lines (it
, nlines
, 1);
4945 xassert (IT_CHARPOS (*it
) <= start_pos
);
4949 /* The y-position we try to reach. Note that h has been
4950 subtracted in front of the if-statement. */
4951 int target_y
= it
->current_y
+ h
- dy
;
4953 /* If we did not reach target_y, try to move further backward if
4954 we can. If we moved too far backward, try to move forward. */
4955 if (target_y
< it
->current_y
4956 && IT_CHARPOS (*it
) > BEGV
)
4958 move_it_vertically (it
, target_y
- it
->current_y
);
4959 xassert (IT_CHARPOS (*it
) >= BEGV
);
4961 else if (target_y
>= it
->current_y
+ line_height
4962 && IT_CHARPOS (*it
) < ZV
)
4964 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
4965 xassert (IT_CHARPOS (*it
) >= BEGV
);
4971 /* Move IT by a specified amount of pixel lines DY. DY negative means
4972 move backwards. DY = 0 means move to start of screen line. At the
4973 end, IT will be on the start of a screen line. */
4976 move_it_vertically (it
, dy
)
4981 move_it_vertically_backward (it
, -dy
);
4984 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
4985 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
4986 MOVE_TO_POS
| MOVE_TO_Y
);
4987 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
4989 /* If buffer ends in ZV without a newline, move to the start of
4990 the line to satisfy the post-condition. */
4991 if (IT_CHARPOS (*it
) == ZV
4992 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
4993 move_it_by_lines (it
, 0, 0);
4998 /* Return non-zero if some text between buffer positions START_CHARPOS
4999 and END_CHARPOS is invisible. IT->window is the window for text
5003 invisible_text_between_p (it
, start_charpos
, end_charpos
)
5005 int start_charpos
, end_charpos
;
5007 Lisp_Object prop
, limit
;
5008 int invisible_found_p
;
5010 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
5012 /* Is text at START invisible? */
5013 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
5015 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
5016 invisible_found_p
= 1;
5019 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
5021 make_number (end_charpos
));
5022 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
5025 return invisible_found_p
;
5029 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
5030 negative means move up. DVPOS == 0 means move to the start of the
5031 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
5032 NEED_Y_P is zero, IT->current_y will be left unchanged.
5034 Further optimization ideas: If we would know that IT->f doesn't use
5035 a face with proportional font, we could be faster for
5036 truncate-lines nil. */
5039 move_it_by_lines (it
, dvpos
, need_y_p
)
5041 int dvpos
, need_y_p
;
5043 struct position pos
;
5045 if (!FRAME_WINDOW_P (it
->f
))
5047 struct text_pos textpos
;
5049 /* We can use vmotion on frames without proportional fonts. */
5050 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
5051 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
5052 reseat (it
, textpos
, 1);
5053 it
->vpos
+= pos
.vpos
;
5054 it
->current_y
+= pos
.vpos
;
5056 else if (dvpos
== 0)
5058 /* DVPOS == 0 means move to the start of the screen line. */
5059 move_it_vertically_backward (it
, 0);
5060 xassert (it
->current_x
== 0 && it
->hpos
== 0);
5064 /* If there are no continuation lines, and if there is no
5065 selective display, try the simple method of moving forward
5066 DVPOS newlines, then see where we are. */
5067 if (!need_y_p
&& it
->truncate_lines_p
&& it
->selective
== 0)
5069 int shortage
= 0, charpos
;
5071 if (FETCH_BYTE (IT_BYTEPOS (*it
) == '\n'))
5072 charpos
= IT_CHARPOS (*it
) + 1;
5074 charpos
= scan_buffer ('\n', IT_CHARPOS (*it
), 0, dvpos
,
5077 if (!invisible_text_between_p (it
, IT_CHARPOS (*it
), charpos
))
5079 struct text_pos pos
;
5080 CHARPOS (pos
) = charpos
;
5081 BYTEPOS (pos
) = CHAR_TO_BYTE (charpos
);
5082 reseat (it
, pos
, 1);
5083 it
->vpos
+= dvpos
- shortage
;
5084 it
->hpos
= it
->current_x
= 0;
5089 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
5094 int start_charpos
, i
;
5096 /* If there are no continuation lines, and if there is no
5097 selective display, try the simple method of moving backward
5099 if (!need_y_p
&& it
->truncate_lines_p
&& it
->selective
== 0)
5102 int charpos
= IT_CHARPOS (*it
);
5103 int bytepos
= IT_BYTEPOS (*it
);
5105 /* If in the middle of a line, go to its start. */
5106 if (charpos
> BEGV
&& FETCH_BYTE (bytepos
- 1) != '\n')
5108 charpos
= find_next_newline_no_quit (charpos
, -1);
5109 bytepos
= CHAR_TO_BYTE (charpos
);
5112 if (charpos
== BEGV
)
5114 struct text_pos pos
;
5115 CHARPOS (pos
) = charpos
;
5116 BYTEPOS (pos
) = bytepos
;
5117 reseat (it
, pos
, 1);
5118 it
->hpos
= it
->current_x
= 0;
5123 charpos
= scan_buffer ('\n', charpos
- 1, 0, dvpos
, &shortage
, 0);
5124 if (!invisible_text_between_p (it
, charpos
, IT_CHARPOS (*it
)))
5126 struct text_pos pos
;
5127 CHARPOS (pos
) = charpos
;
5128 BYTEPOS (pos
) = CHAR_TO_BYTE (charpos
);
5129 reseat (it
, pos
, 1);
5130 it
->vpos
+= dvpos
+ (shortage
? shortage
- 1 : 0);
5131 it
->hpos
= it
->current_x
= 0;
5137 /* Go back -DVPOS visible lines and reseat the iterator there. */
5138 start_charpos
= IT_CHARPOS (*it
);
5139 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
5140 back_to_previous_visible_line_start (it
);
5141 reseat (it
, it
->current
.pos
, 1);
5142 it
->current_x
= it
->hpos
= 0;
5144 /* Above call may have moved too far if continuation lines
5145 are involved. Scan forward and see if it did. */
5147 it2
.vpos
= it2
.current_y
= 0;
5148 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
5149 it
->vpos
-= it2
.vpos
;
5150 it
->current_y
-= it2
.current_y
;
5151 it
->current_x
= it
->hpos
= 0;
5153 /* If we moved too far, move IT some lines forward. */
5154 if (it2
.vpos
> -dvpos
)
5156 int delta
= it2
.vpos
+ dvpos
;
5157 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
5164 /***********************************************************************
5166 ***********************************************************************/
5169 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
5173 add_to_log (format
, arg1
, arg2
)
5175 Lisp_Object arg1
, arg2
;
5177 Lisp_Object args
[3];
5178 Lisp_Object msg
, fmt
;
5181 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
5184 GCPRO4 (fmt
, msg
, arg1
, arg2
);
5186 args
[0] = fmt
= build_string (format
);
5189 msg
= Fformat (3, args
);
5191 len
= STRING_BYTES (XSTRING (msg
)) + 1;
5192 buffer
= (char *) alloca (len
);
5193 strcpy (buffer
, XSTRING (msg
)->data
);
5195 message_dolog (buffer
, len
- 1, 1, 0);
5200 /* Output a newline in the *Messages* buffer if "needs" one. */
5203 message_log_maybe_newline ()
5205 if (message_log_need_newline
)
5206 message_dolog ("", 0, 1, 0);
5210 /* Add a string M of length LEN to the message log, optionally
5211 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
5212 nonzero, means interpret the contents of M as multibyte. This
5213 function calls low-level routines in order to bypass text property
5214 hooks, etc. which might not be safe to run. */
5217 message_dolog (m
, len
, nlflag
, multibyte
)
5219 int len
, nlflag
, multibyte
;
5221 if (!NILP (Vmessage_log_max
))
5223 struct buffer
*oldbuf
;
5224 Lisp_Object oldpoint
, oldbegv
, oldzv
;
5225 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
5226 int point_at_end
= 0;
5228 Lisp_Object old_deactivate_mark
, tem
;
5229 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
5231 old_deactivate_mark
= Vdeactivate_mark
;
5232 oldbuf
= current_buffer
;
5233 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
5234 current_buffer
->undo_list
= Qt
;
5236 oldpoint
= Fpoint_marker ();
5237 oldbegv
= Fpoint_min_marker ();
5238 oldzv
= Fpoint_max_marker ();
5239 GCPRO4 (oldpoint
, oldbegv
, oldzv
, old_deactivate_mark
);
5247 BEGV_BYTE
= BEG_BYTE
;
5250 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
5252 /* Insert the string--maybe converting multibyte to single byte
5253 or vice versa, so that all the text fits the buffer. */
5255 && NILP (current_buffer
->enable_multibyte_characters
))
5258 unsigned char work
[1];
5260 /* Convert a multibyte string to single-byte
5261 for the *Message* buffer. */
5262 for (i
= 0; i
< len
; i
+= nbytes
)
5264 c
= string_char_and_length (m
+ i
, len
- i
, &nbytes
);
5265 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
5267 : multibyte_char_to_unibyte (c
, Qnil
));
5268 insert_1_both (work
, 1, 1, 1, 0, 0);
5271 else if (! multibyte
5272 && ! NILP (current_buffer
->enable_multibyte_characters
))
5275 unsigned char *msg
= (unsigned char *) m
;
5276 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
5277 /* Convert a single-byte string to multibyte
5278 for the *Message* buffer. */
5279 for (i
= 0; i
< len
; i
++)
5281 c
= unibyte_char_to_multibyte (msg
[i
]);
5282 nbytes
= CHAR_STRING (c
, str
);
5283 insert_1_both (str
, 1, nbytes
, 1, 0, 0);
5287 insert_1 (m
, len
, 1, 0, 0);
5291 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
5292 insert_1 ("\n", 1, 1, 0, 0);
5294 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
5296 this_bol_byte
= PT_BYTE
;
5300 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
5302 prev_bol_byte
= PT_BYTE
;
5304 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
5305 this_bol
, this_bol_byte
);
5308 del_range_both (prev_bol
, prev_bol_byte
,
5309 this_bol
, this_bol_byte
, 0);
5315 /* If you change this format, don't forget to also
5316 change message_log_check_duplicate. */
5317 sprintf (dupstr
, " [%d times]", dup
);
5318 duplen
= strlen (dupstr
);
5319 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
5320 insert_1 (dupstr
, duplen
, 1, 0, 1);
5325 if (NATNUMP (Vmessage_log_max
))
5327 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
5328 -XFASTINT (Vmessage_log_max
) - 1, 0);
5329 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
5332 BEGV
= XMARKER (oldbegv
)->charpos
;
5333 BEGV_BYTE
= marker_byte_position (oldbegv
);
5342 ZV
= XMARKER (oldzv
)->charpos
;
5343 ZV_BYTE
= marker_byte_position (oldzv
);
5347 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
5349 /* We can't do Fgoto_char (oldpoint) because it will run some
5351 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
5352 XMARKER (oldpoint
)->bytepos
);
5355 free_marker (oldpoint
);
5356 free_marker (oldbegv
);
5357 free_marker (oldzv
);
5359 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
5360 set_buffer_internal (oldbuf
);
5362 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
5363 message_log_need_newline
= !nlflag
;
5364 Vdeactivate_mark
= old_deactivate_mark
;
5369 /* We are at the end of the buffer after just having inserted a newline.
5370 (Note: We depend on the fact we won't be crossing the gap.)
5371 Check to see if the most recent message looks a lot like the previous one.
5372 Return 0 if different, 1 if the new one should just replace it, or a
5373 value N > 1 if we should also append " [N times]". */
5376 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
5377 int prev_bol
, this_bol
;
5378 int prev_bol_byte
, this_bol_byte
;
5381 int len
= Z_BYTE
- 1 - this_bol_byte
;
5383 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
5384 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
5386 for (i
= 0; i
< len
; i
++)
5388 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
5396 if (*p1
++ == ' ' && *p1
++ == '[')
5399 while (*p1
>= '0' && *p1
<= '9')
5400 n
= n
* 10 + *p1
++ - '0';
5401 if (strncmp (p1
, " times]\n", 8) == 0)
5408 /* Display an echo area message M with a specified length of LEN
5409 chars. The string may include null characters. If M is 0, clear
5410 out any existing message, and let the mini-buffer text show through.
5412 The buffer M must continue to exist until after the echo area gets
5413 cleared or some other message gets displayed there. This means do
5414 not pass text that is stored in a Lisp string; do not pass text in
5415 a buffer that was alloca'd. */
5418 message2 (m
, len
, multibyte
)
5423 /* First flush out any partial line written with print. */
5424 message_log_maybe_newline ();
5426 message_dolog (m
, len
, 1, multibyte
);
5427 message2_nolog (m
, len
, multibyte
);
5431 /* The non-logging counterpart of message2. */
5434 message2_nolog (m
, len
, multibyte
)
5438 struct frame
*sf
= SELECTED_FRAME ();
5439 message_enable_multibyte
= multibyte
;
5443 if (noninteractive_need_newline
)
5444 putc ('\n', stderr
);
5445 noninteractive_need_newline
= 0;
5447 fwrite (m
, len
, 1, stderr
);
5448 if (cursor_in_echo_area
== 0)
5449 fprintf (stderr
, "\n");
5452 /* A null message buffer means that the frame hasn't really been
5453 initialized yet. Error messages get reported properly by
5454 cmd_error, so this must be just an informative message; toss it. */
5455 else if (INTERACTIVE
5456 && sf
->glyphs_initialized_p
5457 && FRAME_MESSAGE_BUF (sf
))
5459 Lisp_Object mini_window
;
5462 /* Get the frame containing the mini-buffer
5463 that the selected frame is using. */
5464 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
5465 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
5467 FRAME_SAMPLE_VISIBILITY (f
);
5468 if (FRAME_VISIBLE_P (sf
)
5469 && ! FRAME_VISIBLE_P (f
))
5470 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
5474 set_message (m
, Qnil
, len
, multibyte
);
5475 if (minibuffer_auto_raise
)
5476 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
5479 clear_message (1, 1);
5481 do_pending_window_change (0);
5482 echo_area_display (1);
5483 do_pending_window_change (0);
5484 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
5485 (*frame_up_to_date_hook
) (f
);
5490 /* Display an echo area message M with a specified length of NBYTES
5491 bytes. The string may include null characters. If M is not a
5492 string, clear out any existing message, and let the mini-buffer
5493 text show through. */
5496 message3 (m
, nbytes
, multibyte
)
5501 struct gcpro gcpro1
;
5505 /* First flush out any partial line written with print. */
5506 message_log_maybe_newline ();
5508 message_dolog (XSTRING (m
)->data
, nbytes
, 1, multibyte
);
5509 message3_nolog (m
, nbytes
, multibyte
);
5515 /* The non-logging version of message3. */
5518 message3_nolog (m
, nbytes
, multibyte
)
5520 int nbytes
, multibyte
;
5522 struct frame
*sf
= SELECTED_FRAME ();
5523 message_enable_multibyte
= multibyte
;
5527 if (noninteractive_need_newline
)
5528 putc ('\n', stderr
);
5529 noninteractive_need_newline
= 0;
5531 fwrite (XSTRING (m
)->data
, nbytes
, 1, stderr
);
5532 if (cursor_in_echo_area
== 0)
5533 fprintf (stderr
, "\n");
5536 /* A null message buffer means that the frame hasn't really been
5537 initialized yet. Error messages get reported properly by
5538 cmd_error, so this must be just an informative message; toss it. */
5539 else if (INTERACTIVE
5540 && sf
->glyphs_initialized_p
5541 && FRAME_MESSAGE_BUF (sf
))
5543 Lisp_Object mini_window
;
5547 /* Get the frame containing the mini-buffer
5548 that the selected frame is using. */
5549 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
5550 frame
= XWINDOW (mini_window
)->frame
;
5553 FRAME_SAMPLE_VISIBILITY (f
);
5554 if (FRAME_VISIBLE_P (sf
)
5555 && !FRAME_VISIBLE_P (f
))
5556 Fmake_frame_visible (frame
);
5558 if (STRINGP (m
) && XSTRING (m
)->size
)
5560 set_message (NULL
, m
, nbytes
, multibyte
);
5561 if (minibuffer_auto_raise
)
5562 Fraise_frame (frame
);
5565 clear_message (1, 1);
5567 do_pending_window_change (0);
5568 echo_area_display (1);
5569 do_pending_window_change (0);
5570 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
5571 (*frame_up_to_date_hook
) (f
);
5576 /* Display a null-terminated echo area message M. If M is 0, clear
5577 out any existing message, and let the mini-buffer text show through.
5579 The buffer M must continue to exist until after the echo area gets
5580 cleared or some other message gets displayed there. Do not pass
5581 text that is stored in a Lisp string. Do not pass text in a buffer
5582 that was alloca'd. */
5588 message2 (m
, (m
? strlen (m
) : 0), 0);
5592 /* The non-logging counterpart of message1. */
5598 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
5601 /* Display a message M which contains a single %s
5602 which gets replaced with STRING. */
5605 message_with_string (m
, string
, log
)
5614 if (noninteractive_need_newline
)
5615 putc ('\n', stderr
);
5616 noninteractive_need_newline
= 0;
5617 fprintf (stderr
, m
, XSTRING (string
)->data
);
5618 if (cursor_in_echo_area
== 0)
5619 fprintf (stderr
, "\n");
5623 else if (INTERACTIVE
)
5625 /* The frame whose minibuffer we're going to display the message on.
5626 It may be larger than the selected frame, so we need
5627 to use its buffer, not the selected frame's buffer. */
5628 Lisp_Object mini_window
;
5629 struct frame
*f
, *sf
= SELECTED_FRAME ();
5631 /* Get the frame containing the minibuffer
5632 that the selected frame is using. */
5633 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
5634 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
5636 /* A null message buffer means that the frame hasn't really been
5637 initialized yet. Error messages get reported properly by
5638 cmd_error, so this must be just an informative message; toss it. */
5639 if (FRAME_MESSAGE_BUF (f
))
5643 a
[0] = (char *) XSTRING (string
)->data
;
5645 len
= doprnt (FRAME_MESSAGE_BUF (f
),
5646 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
5649 message2 (FRAME_MESSAGE_BUF (f
), len
,
5650 STRING_MULTIBYTE (string
));
5652 message2_nolog (FRAME_MESSAGE_BUF (f
), len
,
5653 STRING_MULTIBYTE (string
));
5655 /* Print should start at the beginning of the message
5656 buffer next time. */
5657 message_buf_print
= 0;
5663 /* Dump an informative message to the minibuf. If M is 0, clear out
5664 any existing message, and let the mini-buffer text show through. */
5668 message (m
, a1
, a2
, a3
)
5670 EMACS_INT a1
, a2
, a3
;
5676 if (noninteractive_need_newline
)
5677 putc ('\n', stderr
);
5678 noninteractive_need_newline
= 0;
5679 fprintf (stderr
, m
, a1
, a2
, a3
);
5680 if (cursor_in_echo_area
== 0)
5681 fprintf (stderr
, "\n");
5685 else if (INTERACTIVE
)
5687 /* The frame whose mini-buffer we're going to display the message
5688 on. It may be larger than the selected frame, so we need to
5689 use its buffer, not the selected frame's buffer. */
5690 Lisp_Object mini_window
;
5691 struct frame
*f
, *sf
= SELECTED_FRAME ();
5693 /* Get the frame containing the mini-buffer
5694 that the selected frame is using. */
5695 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
5696 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
5698 /* A null message buffer means that the frame hasn't really been
5699 initialized yet. Error messages get reported properly by
5700 cmd_error, so this must be just an informative message; toss
5702 if (FRAME_MESSAGE_BUF (f
))
5713 len
= doprnt (FRAME_MESSAGE_BUF (f
),
5714 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
5716 len
= doprnt (FRAME_MESSAGE_BUF (f
),
5717 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
5719 #endif /* NO_ARG_ARRAY */
5721 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
5726 /* Print should start at the beginning of the message
5727 buffer next time. */
5728 message_buf_print
= 0;
5734 /* The non-logging version of message. */
5737 message_nolog (m
, a1
, a2
, a3
)
5739 EMACS_INT a1
, a2
, a3
;
5741 Lisp_Object old_log_max
;
5742 old_log_max
= Vmessage_log_max
;
5743 Vmessage_log_max
= Qnil
;
5744 message (m
, a1
, a2
, a3
);
5745 Vmessage_log_max
= old_log_max
;
5749 /* Display the current message in the current mini-buffer. This is
5750 only called from error handlers in process.c, and is not time
5756 if (!NILP (echo_area_buffer
[0]))
5759 string
= Fcurrent_message ();
5760 message3 (string
, XSTRING (string
)->size
,
5761 !NILP (current_buffer
->enable_multibyte_characters
));
5766 /* Make sure echo area buffers in echo_buffers[] are life. If they
5767 aren't, make new ones. */
5770 ensure_echo_area_buffers ()
5774 for (i
= 0; i
< 2; ++i
)
5775 if (!BUFFERP (echo_buffer
[i
])
5776 || NILP (XBUFFER (echo_buffer
[i
])->name
))
5779 Lisp_Object old_buffer
;
5782 old_buffer
= echo_buffer
[i
];
5783 sprintf (name
, " *Echo Area %d*", i
);
5784 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
5785 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
5787 for (j
= 0; j
< 2; ++j
)
5788 if (EQ (old_buffer
, echo_area_buffer
[j
]))
5789 echo_area_buffer
[j
] = echo_buffer
[i
];
5794 /* Call FN with args A1..A4 with either the current or last displayed
5795 echo_area_buffer as current buffer.
5797 WHICH zero means use the current message buffer
5798 echo_area_buffer[0]. If that is nil, choose a suitable buffer
5799 from echo_buffer[] and clear it.
5801 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
5802 suitable buffer from echo_buffer[] and clear it.
5804 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
5805 that the current message becomes the last displayed one, make
5806 choose a suitable buffer for echo_area_buffer[0], and clear it.
5808 Value is what FN returns. */
5811 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
5814 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
5820 int this_one
, the_other
, clear_buffer_p
, rc
;
5821 int count
= BINDING_STACK_SIZE ();
5823 /* If buffers aren't life, make new ones. */
5824 ensure_echo_area_buffers ();
5829 this_one
= 0, the_other
= 1;
5831 this_one
= 1, the_other
= 0;
5834 this_one
= 0, the_other
= 1;
5837 /* We need a fresh one in case the current echo buffer equals
5838 the one containing the last displayed echo area message. */
5839 if (!NILP (echo_area_buffer
[this_one
])
5840 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
5841 echo_area_buffer
[this_one
] = Qnil
;
5844 /* Choose a suitable buffer from echo_buffer[] is we don't
5846 if (NILP (echo_area_buffer
[this_one
]))
5848 echo_area_buffer
[this_one
]
5849 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
5850 ? echo_buffer
[the_other
]
5851 : echo_buffer
[this_one
]);
5855 buffer
= echo_area_buffer
[this_one
];
5857 record_unwind_protect (unwind_with_echo_area_buffer
,
5858 with_echo_area_buffer_unwind_data (w
));
5860 /* Make the echo area buffer current. Note that for display
5861 purposes, it is not necessary that the displayed window's buffer
5862 == current_buffer, except for text property lookup. So, let's
5863 only set that buffer temporarily here without doing a full
5864 Fset_window_buffer. We must also change w->pointm, though,
5865 because otherwise an assertions in unshow_buffer fails, and Emacs
5867 set_buffer_internal_1 (XBUFFER (buffer
));
5871 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
5874 current_buffer
->undo_list
= Qt
;
5875 current_buffer
->read_only
= Qnil
;
5877 if (clear_buffer_p
&& Z
> BEG
)
5880 xassert (BEGV
>= BEG
);
5881 xassert (ZV
<= Z
&& ZV
>= BEGV
);
5883 rc
= fn (a1
, a2
, a3
, a4
);
5885 xassert (BEGV
>= BEG
);
5886 xassert (ZV
<= Z
&& ZV
>= BEGV
);
5888 unbind_to (count
, Qnil
);
5893 /* Save state that should be preserved around the call to the function
5894 FN called in with_echo_area_buffer. */
5897 with_echo_area_buffer_unwind_data (w
)
5903 /* Reduce consing by keeping one vector in
5904 Vwith_echo_area_save_vector. */
5905 vector
= Vwith_echo_area_save_vector
;
5906 Vwith_echo_area_save_vector
= Qnil
;
5909 vector
= Fmake_vector (make_number (7), Qnil
);
5911 XSETBUFFER (XVECTOR (vector
)->contents
[i
], current_buffer
); ++i
;
5912 XVECTOR (vector
)->contents
[i
++] = Vdeactivate_mark
;
5913 XVECTOR (vector
)->contents
[i
++] = make_number (windows_or_buffers_changed
);
5917 XSETWINDOW (XVECTOR (vector
)->contents
[i
], w
); ++i
;
5918 XVECTOR (vector
)->contents
[i
++] = w
->buffer
;
5919 XVECTOR (vector
)->contents
[i
++]
5920 = make_number (XMARKER (w
->pointm
)->charpos
);
5921 XVECTOR (vector
)->contents
[i
++]
5922 = make_number (XMARKER (w
->pointm
)->bytepos
);
5928 XVECTOR (vector
)->contents
[i
++] = Qnil
;
5931 xassert (i
== XVECTOR (vector
)->size
);
5936 /* Restore global state from VECTOR which was created by
5937 with_echo_area_buffer_unwind_data. */
5940 unwind_with_echo_area_buffer (vector
)
5945 set_buffer_internal_1 (XBUFFER (XVECTOR (vector
)->contents
[i
])); ++i
;
5946 Vdeactivate_mark
= XVECTOR (vector
)->contents
[i
]; ++i
;
5947 windows_or_buffers_changed
= XFASTINT (XVECTOR (vector
)->contents
[i
]); ++i
;
5949 if (WINDOWP (XVECTOR (vector
)->contents
[i
]))
5952 Lisp_Object buffer
, charpos
, bytepos
;
5954 w
= XWINDOW (XVECTOR (vector
)->contents
[i
]); ++i
;
5955 buffer
= XVECTOR (vector
)->contents
[i
]; ++i
;
5956 charpos
= XVECTOR (vector
)->contents
[i
]; ++i
;
5957 bytepos
= XVECTOR (vector
)->contents
[i
]; ++i
;
5960 set_marker_both (w
->pointm
, buffer
,
5961 XFASTINT (charpos
), XFASTINT (bytepos
));
5964 Vwith_echo_area_save_vector
= vector
;
5969 /* Set up the echo area for use by print functions. MULTIBYTE_P
5970 non-zero means we will print multibyte. */
5973 setup_echo_area_for_printing (multibyte_p
)
5976 ensure_echo_area_buffers ();
5978 if (!message_buf_print
)
5980 /* A message has been output since the last time we printed.
5981 Choose a fresh echo area buffer. */
5982 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
5983 echo_area_buffer
[0] = echo_buffer
[1];
5985 echo_area_buffer
[0] = echo_buffer
[0];
5987 /* Switch to that buffer and clear it. */
5988 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
5991 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
5993 /* Set up the buffer for the multibyteness we need. */
5995 != !NILP (current_buffer
->enable_multibyte_characters
))
5996 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
5998 /* Raise the frame containing the echo area. */
5999 if (minibuffer_auto_raise
)
6001 struct frame
*sf
= SELECTED_FRAME ();
6002 Lisp_Object mini_window
;
6003 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6004 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6007 message_log_maybe_newline ();
6008 message_buf_print
= 1;
6012 if (NILP (echo_area_buffer
[0]))
6014 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
6015 echo_area_buffer
[0] = echo_buffer
[1];
6017 echo_area_buffer
[0] = echo_buffer
[0];
6020 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
6021 /* Someone switched buffers between print requests. */
6022 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
6027 /* Display an echo area message in window W. Value is non-zero if W's
6028 height is changed. If display_last_displayed_message_p is
6029 non-zero, display the message that was last displayed, otherwise
6030 display the current message. */
6033 display_echo_area (w
)
6036 int i
, no_message_p
, window_height_changed_p
, count
;
6038 /* Temporarily disable garbage collections while displaying the echo
6039 area. This is done because a GC can print a message itself.
6040 That message would modify the echo area buffer's contents while a
6041 redisplay of the buffer is going on, and seriously confuse
6043 count
= inhibit_garbage_collection ();
6045 /* If there is no message, we must call display_echo_area_1
6046 nevertheless because it resizes the window. But we will have to
6047 reset the echo_area_buffer in question to nil at the end because
6048 with_echo_area_buffer will sets it to an empty buffer. */
6049 i
= display_last_displayed_message_p
? 1 : 0;
6050 no_message_p
= NILP (echo_area_buffer
[i
]);
6052 window_height_changed_p
6053 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
6054 display_echo_area_1
,
6055 (EMACS_INT
) w
, Qnil
, 0, 0);
6058 echo_area_buffer
[i
] = Qnil
;
6060 unbind_to (count
, Qnil
);
6061 return window_height_changed_p
;
6065 /* Helper for display_echo_area. Display the current buffer which
6066 contains the current echo area message in window W, a mini-window,
6067 a pointer to which is passed in A1. A2..A4 are currently not used.
6068 Change the height of W so that all of the message is displayed.
6069 Value is non-zero if height of W was changed. */
6072 display_echo_area_1 (a1
, a2
, a3
, a4
)
6077 struct window
*w
= (struct window
*) a1
;
6079 struct text_pos start
;
6080 int window_height_changed_p
= 0;
6082 /* Do this before displaying, so that we have a large enough glyph
6083 matrix for the display. */
6084 window_height_changed_p
= resize_mini_window (w
, 0);
6087 clear_glyph_matrix (w
->desired_matrix
);
6088 XSETWINDOW (window
, w
);
6089 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
6090 try_window (window
, start
);
6092 return window_height_changed_p
;
6096 /* Resize the echo area window to exactly the size needed for the
6097 currently displayed message, if there is one. */
6100 resize_echo_area_axactly ()
6102 if (BUFFERP (echo_area_buffer
[0])
6103 && WINDOWP (echo_area_window
))
6105 struct window
*w
= XWINDOW (echo_area_window
);
6108 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
6109 (EMACS_INT
) w
, Qnil
, 0, 0);
6112 ++windows_or_buffers_changed
;
6113 ++update_mode_lines
;
6114 redisplay_internal (0);
6120 /* Callback function for with_echo_area_buffer, when used from
6121 resize_echo_area_axactly. A1 contains a pointer to the window to
6122 resize, A2 to A4 are not used. Value is what resize_mini_window
6126 resize_mini_window_1 (a1
, a2
, a3
, a4
)
6131 return resize_mini_window ((struct window
*) a1
, 1);
6135 /* Resize mini-window W to fit the size of its contents. EXACT:P
6136 means size the window exactly to the size needed. Otherwise, it's
6137 only enlarged until W's buffer is empty. Value is non-zero if
6138 the window height has been changed. */
6141 resize_mini_window (w
, exact_p
)
6145 struct frame
*f
= XFRAME (w
->frame
);
6146 int window_height_changed_p
= 0;
6148 xassert (MINI_WINDOW_P (w
));
6150 /* Nil means don't try to resize. */
6151 if (NILP (Vresize_mini_windows
)
6152 || (FRAME_X_P (f
) && f
->output_data
.x
== NULL
))
6155 if (!FRAME_MINIBUF_ONLY_P (f
))
6158 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
6159 int total_height
= XFASTINT (root
->height
) + XFASTINT (w
->height
);
6160 int height
, max_height
;
6161 int unit
= CANON_Y_UNIT (f
);
6162 struct text_pos start
;
6163 struct buffer
*old_current_buffer
= NULL
;
6165 if (current_buffer
!= XBUFFER (w
->buffer
))
6167 old_current_buffer
= current_buffer
;
6168 set_buffer_internal (XBUFFER (w
->buffer
));
6171 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
6173 /* Compute the max. number of lines specified by the user. */
6174 if (FLOATP (Vmax_mini_window_height
))
6175 max_height
= XFLOATINT (Vmax_mini_window_height
) * total_height
;
6176 else if (INTEGERP (Vmax_mini_window_height
))
6177 max_height
= XINT (Vmax_mini_window_height
);
6179 max_height
= total_height
/ 4;
6181 /* Correct that max. height if it's bogus. */
6182 max_height
= max (1, max_height
);
6183 max_height
= min (total_height
, max_height
);
6185 /* Find out the height of the text in the window. */
6186 if (it
.truncate_lines_p
)
6191 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
6192 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
6193 height
= it
.current_y
+ last_height
;
6195 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
6196 height
-= it
.extra_line_spacing
;
6197 height
= (height
+ unit
- 1) / unit
;
6200 /* Compute a suitable window start. */
6201 if (height
> max_height
)
6203 height
= max_height
;
6204 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
6205 move_it_vertically_backward (&it
, (height
- 1) * unit
);
6206 start
= it
.current
.pos
;
6209 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
6210 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
6212 if (EQ (Vresize_mini_windows
, Qgrow_only
))
6214 /* Let it grow only, until we display an empty message, in which
6215 case the window shrinks again. */
6216 if (height
> XFASTINT (w
->height
))
6218 int old_height
= XFASTINT (w
->height
);
6219 freeze_window_starts (f
, 1);
6220 grow_mini_window (w
, height
- XFASTINT (w
->height
));
6221 window_height_changed_p
= XFASTINT (w
->height
) != old_height
;
6223 else if (height
< XFASTINT (w
->height
)
6224 && (exact_p
|| BEGV
== ZV
))
6226 int old_height
= XFASTINT (w
->height
);
6227 freeze_window_starts (f
, 0);
6228 shrink_mini_window (w
);
6229 window_height_changed_p
= XFASTINT (w
->height
) != old_height
;
6234 /* Always resize to exact size needed. */
6235 if (height
> XFASTINT (w
->height
))
6237 int old_height
= XFASTINT (w
->height
);
6238 freeze_window_starts (f
, 1);
6239 grow_mini_window (w
, height
- XFASTINT (w
->height
));
6240 window_height_changed_p
= XFASTINT (w
->height
) != old_height
;
6242 else if (height
< XFASTINT (w
->height
))
6244 int old_height
= XFASTINT (w
->height
);
6245 freeze_window_starts (f
, 0);
6246 shrink_mini_window (w
);
6250 freeze_window_starts (f
, 1);
6251 grow_mini_window (w
, height
- XFASTINT (w
->height
));
6254 window_height_changed_p
= XFASTINT (w
->height
) != old_height
;
6258 if (old_current_buffer
)
6259 set_buffer_internal (old_current_buffer
);
6262 return window_height_changed_p
;
6266 /* Value is the current message, a string, or nil if there is no
6274 if (NILP (echo_area_buffer
[0]))
6278 with_echo_area_buffer (0, 0, current_message_1
,
6279 (EMACS_INT
) &msg
, Qnil
, 0, 0);
6281 echo_area_buffer
[0] = Qnil
;
6289 current_message_1 (a1
, a2
, a3
, a4
)
6294 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
6297 *msg
= make_buffer_string (BEG
, Z
, 1);
6304 /* Push the current message on Vmessage_stack for later restauration
6305 by restore_message. Value is non-zero if the current message isn't
6306 empty. This is a relatively infrequent operation, so it's not
6307 worth optimizing. */
6313 msg
= current_message ();
6314 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
6315 return STRINGP (msg
);
6319 /* Restore message display from the top of Vmessage_stack. */
6326 xassert (CONSP (Vmessage_stack
));
6327 msg
= XCAR (Vmessage_stack
);
6329 message3_nolog (msg
, STRING_BYTES (XSTRING (msg
)), STRING_MULTIBYTE (msg
));
6331 message3_nolog (msg
, 0, 0);
6335 /* Pop the top-most entry off Vmessage_stack. */
6340 xassert (CONSP (Vmessage_stack
));
6341 Vmessage_stack
= XCDR (Vmessage_stack
);
6345 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
6346 exits. If the stack is not empty, we have a missing pop_message
6350 check_message_stack ()
6352 if (!NILP (Vmessage_stack
))
6357 /* Truncate to NCHARS what will be displayed in the echo area the next
6358 time we display it---but don't redisplay it now. */
6361 truncate_echo_area (nchars
)
6365 echo_area_buffer
[0] = Qnil
;
6366 /* A null message buffer means that the frame hasn't really been
6367 initialized yet. Error messages get reported properly by
6368 cmd_error, so this must be just an informative message; toss it. */
6369 else if (!noninteractive
6371 && !NILP (echo_area_buffer
[0]))
6373 struct frame
*sf
= SELECTED_FRAME ();
6374 if (FRAME_MESSAGE_BUF (sf
))
6375 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
6380 /* Helper function for truncate_echo_area. Truncate the current
6381 message to at most NCHARS characters. */
6384 truncate_message_1 (nchars
, a2
, a3
, a4
)
6389 if (BEG
+ nchars
< Z
)
6390 del_range (BEG
+ nchars
, Z
);
6392 echo_area_buffer
[0] = Qnil
;
6397 /* Set the current message to a substring of S or STRING.
6399 If STRING is a Lisp string, set the message to the first NBYTES
6400 bytes from STRING. NBYTES zero means use the whole string. If
6401 STRING is multibyte, the message will be displayed multibyte.
6403 If S is not null, set the message to the first LEN bytes of S. LEN
6404 zero means use the whole string. MULTIBYTE_P non-zero means S is
6405 multibyte. Display the message multibyte in that case. */
6408 set_message (s
, string
, nbytes
, multibyte_p
)
6413 message_enable_multibyte
6414 = ((s
&& multibyte_p
)
6415 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
6417 with_echo_area_buffer (0, -1, set_message_1
,
6418 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
6419 message_buf_print
= 0;
6420 help_echo_showing_p
= 0;
6424 /* Helper function for set_message. Arguments have the same meaning
6425 as there, with A1 corresponding to S and A2 corresponding to STRING
6426 This function is called with the echo area buffer being
6430 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
6433 EMACS_INT nbytes
, multibyte_p
;
6435 char *s
= (char *) a1
;
6436 Lisp_Object string
= a2
;
6440 /* Change multibyteness of the echo buffer appropriately. */
6441 if (message_enable_multibyte
6442 != !NILP (current_buffer
->enable_multibyte_characters
))
6443 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
6445 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
6447 /* Insert new message at BEG. */
6448 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
6450 if (STRINGP (string
))
6455 nbytes
= XSTRING (string
)->size_byte
;
6456 nchars
= string_byte_to_char (string
, nbytes
);
6458 /* This function takes care of single/multibyte conversion. We
6459 just have to ensure that the echo area buffer has the right
6460 setting of enable_multibyte_characters. */
6461 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
6466 nbytes
= strlen (s
);
6468 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
6470 /* Convert from multi-byte to single-byte. */
6472 unsigned char work
[1];
6474 /* Convert a multibyte string to single-byte. */
6475 for (i
= 0; i
< nbytes
; i
+= n
)
6477 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
6478 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6480 : multibyte_char_to_unibyte (c
, Qnil
));
6481 insert_1_both (work
, 1, 1, 1, 0, 0);
6484 else if (!multibyte_p
6485 && !NILP (current_buffer
->enable_multibyte_characters
))
6487 /* Convert from single-byte to multi-byte. */
6489 unsigned char *msg
= (unsigned char *) s
;
6490 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6492 /* Convert a single-byte string to multibyte. */
6493 for (i
= 0; i
< nbytes
; i
++)
6495 c
= unibyte_char_to_multibyte (msg
[i
]);
6496 n
= CHAR_STRING (c
, str
);
6497 insert_1_both (str
, 1, n
, 1, 0, 0);
6501 insert_1 (s
, nbytes
, 1, 0, 0);
6508 /* Clear messages. CURRENT_P non-zero means clear the current
6509 message. LAST_DISPLAYED_P non-zero means clear the message
6513 clear_message (current_p
, last_displayed_p
)
6514 int current_p
, last_displayed_p
;
6517 echo_area_buffer
[0] = Qnil
;
6519 if (last_displayed_p
)
6520 echo_area_buffer
[1] = Qnil
;
6522 message_buf_print
= 0;
6525 /* Clear garbaged frames.
6527 This function is used where the old redisplay called
6528 redraw_garbaged_frames which in turn called redraw_frame which in
6529 turn called clear_frame. The call to clear_frame was a source of
6530 flickering. I believe a clear_frame is not necessary. It should
6531 suffice in the new redisplay to invalidate all current matrices,
6532 and ensure a complete redisplay of all windows. */
6535 clear_garbaged_frames ()
6539 Lisp_Object tail
, frame
;
6541 FOR_EACH_FRAME (tail
, frame
)
6543 struct frame
*f
= XFRAME (frame
);
6545 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
6547 clear_current_matrices (f
);
6553 ++windows_or_buffers_changed
;
6558 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
6559 is non-zero update selected_frame. Value is non-zero if the
6560 mini-windows height has been changed. */
6563 echo_area_display (update_frame_p
)
6566 Lisp_Object mini_window
;
6569 int window_height_changed_p
= 0;
6570 struct frame
*sf
= SELECTED_FRAME ();
6572 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6573 w
= XWINDOW (mini_window
);
6574 f
= XFRAME (WINDOW_FRAME (w
));
6576 /* Don't display if frame is invisible or not yet initialized. */
6577 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
6580 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
6582 #ifdef HAVE_WINDOW_SYSTEM
6583 /* When Emacs starts, selected_frame may be a visible terminal
6584 frame, even if we run under a window system. If we let this
6585 through, a message would be displayed on the terminal. */
6586 if (EQ (selected_frame
, Vterminal_frame
)
6587 && !NILP (Vwindow_system
))
6589 #endif /* HAVE_WINDOW_SYSTEM */
6592 /* Redraw garbaged frames. */
6594 clear_garbaged_frames ();
6596 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
6598 echo_area_window
= mini_window
;
6599 window_height_changed_p
= display_echo_area (w
);
6600 w
->must_be_updated_p
= 1;
6602 /* Update the display, unless called from redisplay_internal.
6603 Also don't update the screen during redisplay itself. The
6604 update will happen at the end of redisplay, and an update
6605 here could cause confusion. */
6606 if (update_frame_p
&& !redisplaying_p
)
6610 /* If the display update has been interrupted by pending
6611 input, update mode lines in the frame. Due to the
6612 pending input, it might have been that redisplay hasn't
6613 been called, so that mode lines above the echo area are
6614 garbaged. This looks odd, so we prevent it here. */
6615 if (!display_completed
)
6616 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
6618 if (window_height_changed_p
)
6620 /* Must update other windows. */
6621 windows_or_buffers_changed
= 1;
6622 redisplay_internal (0);
6624 else if (FRAME_WINDOW_P (f
) && n
== 0)
6626 /* Window configuration is the same as before.
6627 Can do with a display update of the echo area,
6628 unless we displayed some mode lines. */
6629 update_single_window (w
, 1);
6630 rif
->flush_display (f
);
6633 update_frame (f
, 1, 1);
6636 else if (!EQ (mini_window
, selected_window
))
6637 windows_or_buffers_changed
++;
6639 /* Last displayed message is now the current message. */
6640 echo_area_buffer
[1] = echo_area_buffer
[0];
6642 /* Prevent redisplay optimization in redisplay_internal by resetting
6643 this_line_start_pos. This is done because the mini-buffer now
6644 displays the message instead of its buffer text. */
6645 if (EQ (mini_window
, selected_window
))
6646 CHARPOS (this_line_start_pos
) = 0;
6648 return window_height_changed_p
;
6653 /***********************************************************************
6655 ***********************************************************************/
6658 #ifdef HAVE_WINDOW_SYSTEM
6660 /* A buffer for constructing frame titles in it; allocated from the
6661 heap in init_xdisp and resized as needed in store_frame_title_char. */
6663 static char *frame_title_buf
;
6665 /* The buffer's end, and a current output position in it. */
6667 static char *frame_title_buf_end
;
6668 static char *frame_title_ptr
;
6671 /* Store a single character C for the frame title in frame_title_buf.
6672 Re-allocate frame_title_buf if necessary. */
6675 store_frame_title_char (c
)
6678 /* If output position has reached the end of the allocated buffer,
6679 double the buffer's size. */
6680 if (frame_title_ptr
== frame_title_buf_end
)
6682 int len
= frame_title_ptr
- frame_title_buf
;
6683 int new_size
= 2 * len
* sizeof *frame_title_buf
;
6684 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
6685 frame_title_buf_end
= frame_title_buf
+ new_size
;
6686 frame_title_ptr
= frame_title_buf
+ len
;
6689 *frame_title_ptr
++ = c
;
6693 /* Store part of a frame title in frame_title_buf, beginning at
6694 frame_title_ptr. STR is the string to store. Do not copy more
6695 than PRECISION number of bytes from STR; PRECISION <= 0 means copy
6696 the whole string. Pad with spaces until FIELD_WIDTH number of
6697 characters have been copied; FIELD_WIDTH <= 0 means don't pad.
6698 Called from display_mode_element when it is used to build a frame
6702 store_frame_title (str
, field_width
, precision
)
6704 int field_width
, precision
;
6708 /* Copy at most PRECISION chars from STR. */
6709 while ((precision
<= 0 || n
< precision
)
6712 store_frame_title_char (*str
++);
6716 /* Fill up with spaces until FIELD_WIDTH reached. */
6717 while (field_width
> 0
6720 store_frame_title_char (' ');
6728 /* Set the title of FRAME, if it has changed. The title format is
6729 Vicon_title_format if FRAME is iconified, otherwise it is
6730 frame_title_format. */
6733 x_consider_frame_title (frame
)
6736 struct frame
*f
= XFRAME (frame
);
6738 if (FRAME_WINDOW_P (f
)
6739 || FRAME_MINIBUF_ONLY_P (f
)
6740 || f
->explicit_name
)
6742 /* Do we have more than one visible frame on this X display? */
6745 struct buffer
*obuf
;
6749 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
6751 struct frame
*tf
= XFRAME (XCAR (tail
));
6754 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
6755 && !FRAME_MINIBUF_ONLY_P (tf
)
6756 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
6760 /* Set global variable indicating that multiple frames exist. */
6761 multiple_frames
= CONSP (tail
);
6763 /* Switch to the buffer of selected window of the frame. Set up
6764 frame_title_ptr so that display_mode_element will output into it;
6765 then display the title. */
6766 obuf
= current_buffer
;
6767 Fset_buffer (XWINDOW (f
->selected_window
)->buffer
);
6768 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
6769 frame_title_ptr
= frame_title_buf
;
6770 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
6771 NULL
, DEFAULT_FACE_ID
);
6772 len
= display_mode_element (&it
, 0, -1, -1, fmt
);
6773 frame_title_ptr
= NULL
;
6774 set_buffer_internal (obuf
);
6776 /* Set the title only if it's changed. This avoids consing in
6777 the common case where it hasn't. (If it turns out that we've
6778 already wasted too much time by walking through the list with
6779 display_mode_element, then we might need to optimize at a
6780 higher level than this.) */
6781 if (! STRINGP (f
->name
)
6782 || STRING_BYTES (XSTRING (f
->name
)) != len
6783 || bcmp (frame_title_buf
, XSTRING (f
->name
)->data
, len
) != 0)
6784 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
6788 #else /* not HAVE_WINDOW_SYSTEM */
6790 #define frame_title_ptr ((char *)0)
6791 #define store_frame_title(str, mincol, maxcol) 0
6793 #endif /* not HAVE_WINDOW_SYSTEM */
6798 /***********************************************************************
6800 ***********************************************************************/
6803 /* Prepare for redisplay by updating menu-bar item lists when
6804 appropriate. This can call eval. */
6807 prepare_menu_bars ()
6810 struct gcpro gcpro1
, gcpro2
;
6812 struct frame
*tooltip_frame
;
6814 #ifdef HAVE_X_WINDOWS
6815 tooltip_frame
= tip_frame
;
6817 tooltip_frame
= NULL
;
6820 /* Update all frame titles based on their buffer names, etc. We do
6821 this before the menu bars so that the buffer-menu will show the
6822 up-to-date frame titles. */
6823 #ifdef HAVE_WINDOW_SYSTEM
6824 if (windows_or_buffers_changed
|| update_mode_lines
)
6826 Lisp_Object tail
, frame
;
6828 FOR_EACH_FRAME (tail
, frame
)
6831 if (f
!= tooltip_frame
6832 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
6833 x_consider_frame_title (frame
);
6836 #endif /* HAVE_WINDOW_SYSTEM */
6838 /* Update the menu bar item lists, if appropriate. This has to be
6839 done before any actual redisplay or generation of display lines. */
6840 all_windows
= (update_mode_lines
6841 || buffer_shared
> 1
6842 || windows_or_buffers_changed
);
6845 Lisp_Object tail
, frame
;
6846 int count
= BINDING_STACK_SIZE ();
6848 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
6850 FOR_EACH_FRAME (tail
, frame
)
6854 /* Ignore tooltip frame. */
6855 if (f
== tooltip_frame
)
6858 /* If a window on this frame changed size, report that to
6859 the user and clear the size-change flag. */
6860 if (FRAME_WINDOW_SIZES_CHANGED (f
))
6862 Lisp_Object functions
;
6864 /* Clear flag first in case we get an error below. */
6865 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
6866 functions
= Vwindow_size_change_functions
;
6867 GCPRO2 (tail
, functions
);
6869 while (CONSP (functions
))
6871 call1 (XCAR (functions
), frame
);
6872 functions
= XCDR (functions
);
6878 update_menu_bar (f
, 0);
6879 #ifdef HAVE_WINDOW_SYSTEM
6880 update_tool_bar (f
, 0);
6885 unbind_to (count
, Qnil
);
6889 struct frame
*sf
= SELECTED_FRAME ();
6890 update_menu_bar (sf
, 1);
6891 #ifdef HAVE_WINDOW_SYSTEM
6892 update_tool_bar (sf
, 1);
6896 /* Motif needs this. See comment in xmenu.c. Turn it off when
6897 pending_menu_activation is not defined. */
6898 #ifdef USE_X_TOOLKIT
6899 pending_menu_activation
= 0;
6904 /* Update the menu bar item list for frame F. This has to be done
6905 before we start to fill in any display lines, because it can call
6908 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
6911 update_menu_bar (f
, save_match_data
)
6913 int save_match_data
;
6916 register struct window
*w
;
6918 window
= FRAME_SELECTED_WINDOW (f
);
6919 w
= XWINDOW (window
);
6921 if (update_mode_lines
)
6922 w
->update_mode_line
= Qt
;
6924 if (FRAME_WINDOW_P (f
)
6926 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
6927 FRAME_EXTERNAL_MENU_BAR (f
)
6929 FRAME_MENU_BAR_LINES (f
) > 0
6931 : FRAME_MENU_BAR_LINES (f
) > 0)
6933 /* If the user has switched buffers or windows, we need to
6934 recompute to reflect the new bindings. But we'll
6935 recompute when update_mode_lines is set too; that means
6936 that people can use force-mode-line-update to request
6937 that the menu bar be recomputed. The adverse effect on
6938 the rest of the redisplay algorithm is about the same as
6939 windows_or_buffers_changed anyway. */
6940 if (windows_or_buffers_changed
6941 || !NILP (w
->update_mode_line
)
6942 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
6943 < BUF_MODIFF (XBUFFER (w
->buffer
)))
6944 != !NILP (w
->last_had_star
))
6945 || ((!NILP (Vtransient_mark_mode
)
6946 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
6947 != !NILP (w
->region_showing
)))
6949 struct buffer
*prev
= current_buffer
;
6950 int count
= BINDING_STACK_SIZE ();
6952 set_buffer_internal_1 (XBUFFER (w
->buffer
));
6953 if (save_match_data
)
6954 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
6955 if (NILP (Voverriding_local_map_menu_flag
))
6957 specbind (Qoverriding_terminal_local_map
, Qnil
);
6958 specbind (Qoverriding_local_map
, Qnil
);
6961 /* Run the Lucid hook. */
6962 call1 (Vrun_hooks
, Qactivate_menubar_hook
);
6964 /* If it has changed current-menubar from previous value,
6965 really recompute the menu-bar from the value. */
6966 if (! NILP (Vlucid_menu_bar_dirty_flag
))
6967 call0 (Qrecompute_lucid_menubar
);
6969 safe_run_hooks (Qmenu_bar_update_hook
);
6970 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
6972 /* Redisplay the menu bar in case we changed it. */
6973 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
6974 if (FRAME_WINDOW_P (f
)
6975 #if defined (macintosh)
6976 /* All frames on Mac OS share the same menubar. So only the
6977 selected frame should be allowed to set it. */
6978 && f
== SELECTED_FRAME ()
6981 set_frame_menubar (f
, 0, 0);
6983 /* On a terminal screen, the menu bar is an ordinary screen
6984 line, and this makes it get updated. */
6985 w
->update_mode_line
= Qt
;
6986 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6987 /* In the non-toolkit version, the menu bar is an ordinary screen
6988 line, and this makes it get updated. */
6989 w
->update_mode_line
= Qt
;
6990 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI) */
6992 unbind_to (count
, Qnil
);
6993 set_buffer_internal_1 (prev
);
7000 /***********************************************************************
7002 ***********************************************************************/
7004 #ifdef HAVE_WINDOW_SYSTEM
7006 /* Update the tool-bar item list for frame F. This has to be done
7007 before we start to fill in any display lines. Called from
7008 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
7009 and restore it here. */
7012 update_tool_bar (f
, save_match_data
)
7014 int save_match_data
;
7016 if (WINDOWP (f
->tool_bar_window
)
7017 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
) > 0)
7022 window
= FRAME_SELECTED_WINDOW (f
);
7023 w
= XWINDOW (window
);
7025 /* If the user has switched buffers or windows, we need to
7026 recompute to reflect the new bindings. But we'll
7027 recompute when update_mode_lines is set too; that means
7028 that people can use force-mode-line-update to request
7029 that the menu bar be recomputed. The adverse effect on
7030 the rest of the redisplay algorithm is about the same as
7031 windows_or_buffers_changed anyway. */
7032 if (windows_or_buffers_changed
7033 || !NILP (w
->update_mode_line
)
7034 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
7035 < BUF_MODIFF (XBUFFER (w
->buffer
)))
7036 != !NILP (w
->last_had_star
))
7037 || ((!NILP (Vtransient_mark_mode
)
7038 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
7039 != !NILP (w
->region_showing
)))
7041 struct buffer
*prev
= current_buffer
;
7042 int count
= BINDING_STACK_SIZE ();
7044 /* Set current_buffer to the buffer of the selected
7045 window of the frame, so that we get the right local
7047 set_buffer_internal_1 (XBUFFER (w
->buffer
));
7049 /* Save match data, if we must. */
7050 if (save_match_data
)
7051 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
7053 /* Make sure that we don't accidentally use bogus keymaps. */
7054 if (NILP (Voverriding_local_map_menu_flag
))
7056 specbind (Qoverriding_terminal_local_map
, Qnil
);
7057 specbind (Qoverriding_local_map
, Qnil
);
7060 /* Build desired tool-bar items from keymaps. */
7062 = tool_bar_items (f
->tool_bar_items
, &f
->n_tool_bar_items
);
7064 /* Redisplay the tool-bar in case we changed it. */
7065 w
->update_mode_line
= Qt
;
7067 unbind_to (count
, Qnil
);
7068 set_buffer_internal_1 (prev
);
7074 /* Set F->desired_tool_bar_string to a Lisp string representing frame
7075 F's desired tool-bar contents. F->tool_bar_items must have
7076 been set up previously by calling prepare_menu_bars. */
7079 build_desired_tool_bar_string (f
)
7082 int i
, size
, size_needed
, string_idx
;
7083 struct gcpro gcpro1
, gcpro2
, gcpro3
;
7084 Lisp_Object image
, plist
, props
;
7086 image
= plist
= props
= Qnil
;
7087 GCPRO3 (image
, plist
, props
);
7089 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
7090 Otherwise, make a new string. */
7092 /* The size of the string we might be able to reuse. */
7093 size
= (STRINGP (f
->desired_tool_bar_string
)
7094 ? XSTRING (f
->desired_tool_bar_string
)->size
7097 /* Each image in the string we build is preceded by a space,
7098 and there is a space at the end. */
7099 size_needed
= f
->n_tool_bar_items
+ 1;
7101 /* Reuse f->desired_tool_bar_string, if possible. */
7102 if (size
< size_needed
)
7103 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
7107 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
7108 Fremove_text_properties (make_number (0), make_number (size
),
7109 props
, f
->desired_tool_bar_string
);
7112 /* Put a `display' property on the string for the images to display,
7113 put a `menu_item' property on tool-bar items with a value that
7114 is the index of the item in F's tool-bar item vector. */
7115 for (i
= 0, string_idx
= 0;
7116 i
< f
->n_tool_bar_items
;
7117 ++i
, string_idx
+= 1)
7119 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
7121 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
7122 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
7123 int margin
, relief
, idx
;
7124 extern Lisp_Object QCrelief
, QCmargin
, QCalgorithm
, Qimage
;
7125 extern Lisp_Object Qlaplace
;
7127 /* If image is a vector, choose the image according to the
7129 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
7130 if (VECTORP (image
))
7134 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
7135 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
7138 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
7139 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
7141 xassert (ASIZE (image
) >= idx
);
7142 image
= AREF (image
, idx
);
7147 /* Ignore invalid image specifications. */
7148 if (!valid_image_p (image
))
7151 /* Display the tool-bar button pressed, or depressed. */
7152 plist
= Fcopy_sequence (XCDR (image
));
7154 /* Compute margin and relief to draw. */
7155 relief
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
7156 margin
= relief
+ max (0, tool_bar_button_margin
);
7158 if (auto_raise_tool_bar_buttons_p
)
7160 /* Add a `:relief' property to the image spec if the item is
7164 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
7170 /* If image is selected, display it pressed, i.e. with a
7171 negative relief. If it's not selected, display it with a
7173 plist
= Fplist_put (plist
, QCrelief
,
7175 ? make_number (-relief
)
7176 : make_number (relief
)));
7180 /* Put a margin around the image. */
7182 plist
= Fplist_put (plist
, QCmargin
, make_number (margin
));
7184 /* If button is not enabled, and we don't have special images
7185 for the disabled state, make the image appear disabled by
7186 applying an appropriate algorithm to it. */
7187 if (!enabled_p
&& idx
< 0)
7188 plist
= Fplist_put (plist
, QCalgorithm
, Qdisabled
);
7190 /* Put a `display' text property on the string for the image to
7191 display. Put a `menu-item' property on the string that gives
7192 the start of this item's properties in the tool-bar items
7194 image
= Fcons (Qimage
, plist
);
7195 props
= list4 (Qdisplay
, image
,
7196 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
)),
7197 Fadd_text_properties (make_number (string_idx
),
7198 make_number (string_idx
+ 1),
7199 props
, f
->desired_tool_bar_string
);
7207 /* Display one line of the tool-bar of frame IT->f. */
7210 display_tool_bar_line (it
)
7213 struct glyph_row
*row
= it
->glyph_row
;
7214 int max_x
= it
->last_visible_x
;
7217 prepare_desired_row (row
);
7218 row
->y
= it
->current_y
;
7220 while (it
->current_x
< max_x
)
7222 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
7224 /* Get the next display element. */
7225 if (!get_next_display_element (it
))
7228 /* Produce glyphs. */
7229 x_before
= it
->current_x
;
7230 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
7231 PRODUCE_GLYPHS (it
);
7233 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
7238 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
7240 if (x
+ glyph
->pixel_width
> max_x
)
7242 /* Glyph doesn't fit on line. */
7243 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
7249 x
+= glyph
->pixel_width
;
7253 /* Stop at line ends. */
7254 if (ITERATOR_AT_END_OF_LINE_P (it
))
7257 set_iterator_to_next (it
, 1);
7262 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
7263 extend_face_to_end_of_line (it
);
7264 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
7265 last
->right_box_line_p
= 1;
7266 compute_line_metrics (it
);
7268 /* If line is empty, make it occupy the rest of the tool-bar. */
7269 if (!row
->displays_text_p
)
7271 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
7272 row
->ascent
= row
->phys_ascent
= 0;
7275 row
->full_width_p
= 1;
7276 row
->continued_p
= 0;
7277 row
->truncated_on_left_p
= 0;
7278 row
->truncated_on_right_p
= 0;
7280 it
->current_x
= it
->hpos
= 0;
7281 it
->current_y
+= row
->height
;
7287 /* Value is the number of screen lines needed to make all tool-bar
7288 items of frame F visible. */
7291 tool_bar_lines_needed (f
)
7294 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7297 /* Initialize an iterator for iteration over
7298 F->desired_tool_bar_string in the tool-bar window of frame F. */
7299 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
7300 it
.first_visible_x
= 0;
7301 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
7302 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
7304 while (!ITERATOR_AT_END_P (&it
))
7306 it
.glyph_row
= w
->desired_matrix
->rows
;
7307 clear_glyph_row (it
.glyph_row
);
7308 display_tool_bar_line (&it
);
7311 return (it
.current_y
+ CANON_Y_UNIT (f
) - 1) / CANON_Y_UNIT (f
);
7315 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
7316 height should be changed. */
7319 redisplay_tool_bar (f
)
7324 struct glyph_row
*row
;
7325 int change_height_p
= 0;
7327 /* If frame hasn't a tool-bar window or if it is zero-height, don't
7328 do anything. This means you must start with tool-bar-lines
7329 non-zero to get the auto-sizing effect. Or in other words, you
7330 can turn off tool-bars by specifying tool-bar-lines zero. */
7331 if (!WINDOWP (f
->tool_bar_window
)
7332 || (w
= XWINDOW (f
->tool_bar_window
),
7333 XFASTINT (w
->height
) == 0))
7336 /* Set up an iterator for the tool-bar window. */
7337 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
7338 it
.first_visible_x
= 0;
7339 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
7342 /* Build a string that represents the contents of the tool-bar. */
7343 build_desired_tool_bar_string (f
);
7344 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
7346 /* Display as many lines as needed to display all tool-bar items. */
7347 while (it
.current_y
< it
.last_visible_y
)
7348 display_tool_bar_line (&it
);
7350 /* It doesn't make much sense to try scrolling in the tool-bar
7351 window, so don't do it. */
7352 w
->desired_matrix
->no_scrolling_p
= 1;
7353 w
->must_be_updated_p
= 1;
7355 if (auto_resize_tool_bars_p
)
7359 /* If there are blank lines at the end, except for a partially
7360 visible blank line at the end that is smaller than
7361 CANON_Y_UNIT, change the tool-bar's height. */
7362 row
= it
.glyph_row
- 1;
7363 if (!row
->displays_text_p
7364 && row
->height
>= CANON_Y_UNIT (f
))
7365 change_height_p
= 1;
7367 /* If row displays tool-bar items, but is partially visible,
7368 change the tool-bar's height. */
7369 if (row
->displays_text_p
7370 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
7371 change_height_p
= 1;
7373 /* Resize windows as needed by changing the `tool-bar-lines'
7376 && (nlines
= tool_bar_lines_needed (f
),
7377 nlines
!= XFASTINT (w
->height
)))
7379 extern Lisp_Object Qtool_bar_lines
;
7381 int old_height
= XFASTINT (w
->height
);
7383 XSETFRAME (frame
, f
);
7384 clear_glyph_matrix (w
->desired_matrix
);
7385 Fmodify_frame_parameters (frame
,
7386 Fcons (Fcons (Qtool_bar_lines
,
7387 make_number (nlines
)),
7389 if (XFASTINT (w
->height
) != old_height
)
7390 fonts_changed_p
= 1;
7394 return change_height_p
;
7398 /* Get information about the tool-bar item which is displayed in GLYPH
7399 on frame F. Return in *PROP_IDX the index where tool-bar item
7400 properties start in F->tool_bar_items. Value is zero if
7401 GLYPH doesn't display a tool-bar item. */
7404 tool_bar_item_info (f
, glyph
, prop_idx
)
7406 struct glyph
*glyph
;
7412 /* Get the text property `menu-item' at pos. The value of that
7413 property is the start index of this item's properties in
7414 F->tool_bar_items. */
7415 prop
= Fget_text_property (make_number (glyph
->charpos
),
7416 Qmenu_item
, f
->current_tool_bar_string
);
7417 if (INTEGERP (prop
))
7419 *prop_idx
= XINT (prop
);
7428 #endif /* HAVE_WINDOW_SYSTEM */
7432 /************************************************************************
7433 Horizontal scrolling
7434 ************************************************************************/
7436 static int hscroll_window_tree
P_ ((Lisp_Object
));
7437 static int hscroll_windows
P_ ((Lisp_Object
));
7439 /* For all leaf windows in the window tree rooted at WINDOW, set their
7440 hscroll value so that PT is (i) visible in the window, and (ii) so
7441 that it is not within a certain margin at the window's left and
7442 right border. Value is non-zero if any window's hscroll has been
7446 hscroll_window_tree (window
)
7449 int hscrolled_p
= 0;
7451 while (WINDOWP (window
))
7453 struct window
*w
= XWINDOW (window
);
7455 if (WINDOWP (w
->hchild
))
7456 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
7457 else if (WINDOWP (w
->vchild
))
7458 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
7459 else if (w
->cursor
.vpos
>= 0)
7461 int hscroll_margin
, text_area_x
, text_area_y
;
7462 int text_area_width
, text_area_height
;
7463 struct glyph_row
*current_cursor_row
7464 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
7465 struct glyph_row
*desired_cursor_row
7466 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
7467 struct glyph_row
*cursor_row
7468 = (desired_cursor_row
->enabled_p
7469 ? desired_cursor_row
7470 : current_cursor_row
);
7472 window_box (w
, TEXT_AREA
, &text_area_x
, &text_area_y
,
7473 &text_area_width
, &text_area_height
);
7475 /* Scroll when cursor is inside this scroll margin. */
7476 hscroll_margin
= 5 * CANON_X_UNIT (XFRAME (w
->frame
));
7478 if ((XFASTINT (w
->hscroll
)
7479 && w
->cursor
.x
< hscroll_margin
)
7480 || (cursor_row
->enabled_p
7481 && cursor_row
->truncated_on_right_p
7482 && (w
->cursor
.x
> text_area_width
- hscroll_margin
)))
7486 struct buffer
*saved_current_buffer
;
7489 /* Find point in a display of infinite width. */
7490 saved_current_buffer
= current_buffer
;
7491 current_buffer
= XBUFFER (w
->buffer
);
7493 if (w
== XWINDOW (selected_window
))
7494 pt
= BUF_PT (current_buffer
);
7497 pt
= marker_position (w
->pointm
);
7498 pt
= max (BEGV
, pt
);
7502 /* Move iterator to pt starting at cursor_row->start in
7503 a line with infinite width. */
7504 init_to_row_start (&it
, w
, cursor_row
);
7505 it
.last_visible_x
= INFINITY
;
7506 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
7507 current_buffer
= saved_current_buffer
;
7509 /* Center cursor in window. */
7510 hscroll
= (max (0, it
.current_x
- text_area_width
/ 2)
7511 / CANON_X_UNIT (it
.f
));
7513 /* Don't call Fset_window_hscroll if value hasn't
7514 changed because it will prevent redisplay
7516 if (XFASTINT (w
->hscroll
) != hscroll
)
7518 Fset_window_hscroll (window
, make_number (hscroll
));
7527 /* Value is non-zero if hscroll of any leaf window has been changed. */
7532 /* Set hscroll so that cursor is visible and not inside horizontal
7533 scroll margins for all windows in the tree rooted at WINDOW. See
7534 also hscroll_window_tree above. Value is non-zero if any window's
7535 hscroll has been changed. If it has, desired matrices on the frame
7536 of WINDOW are cleared. */
7539 hscroll_windows (window
)
7544 if (automatic_hscrolling_p
)
7546 hscrolled_p
= hscroll_window_tree (window
);
7548 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
7557 /************************************************************************
7559 ************************************************************************/
7561 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
7562 to a non-zero value. This is sometimes handy to have in a debugger
7567 /* First and last unchanged row for try_window_id. */
7569 int debug_first_unchanged_at_end_vpos
;
7570 int debug_last_unchanged_at_beg_vpos
;
7572 /* Delta vpos and y. */
7574 int debug_dvpos
, debug_dy
;
7576 /* Delta in characters and bytes for try_window_id. */
7578 int debug_delta
, debug_delta_bytes
;
7580 /* Values of window_end_pos and window_end_vpos at the end of
7583 int debug_end_pos
, debug_end_vpos
;
7585 /* Append a string to W->desired_matrix->method. FMT is a printf
7586 format string. A1...A9 are a supplement for a variable-length
7587 argument list. If trace_redisplay_p is non-zero also printf the
7588 resulting string to stderr. */
7591 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
7594 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
7597 char *method
= w
->desired_matrix
->method
;
7598 int len
= strlen (method
);
7599 int size
= sizeof w
->desired_matrix
->method
;
7600 int remaining
= size
- len
- 1;
7602 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
7603 if (len
&& remaining
)
7609 strncpy (method
+ len
, buffer
, remaining
);
7611 if (trace_redisplay_p
)
7612 fprintf (stderr
, "%p (%s): %s\n",
7614 ((BUFFERP (w
->buffer
)
7615 && STRINGP (XBUFFER (w
->buffer
)->name
))
7616 ? (char *) XSTRING (XBUFFER (w
->buffer
)->name
)->data
7621 #endif /* GLYPH_DEBUG */
7624 /* This counter is used to clear the face cache every once in a while
7625 in redisplay_internal. It is incremented for each redisplay.
7626 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
7629 #define CLEAR_FACE_CACHE_COUNT 10000
7630 static int clear_face_cache_count
;
7632 /* Record the previous terminal frame we displayed. */
7634 static struct frame
*previous_terminal_frame
;
7636 /* Non-zero while redisplay_internal is in progress. */
7641 /* Value is non-zero if all changes in window W, which displays
7642 current_buffer, are in the text between START and END. START is a
7643 buffer position, END is given as a distance from Z. Used in
7644 redisplay_internal for display optimization. */
7647 text_outside_line_unchanged_p (w
, start
, end
)
7651 int unchanged_p
= 1;
7653 /* If text or overlays have changed, see where. */
7654 if (XFASTINT (w
->last_modified
) < MODIFF
7655 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
7657 /* Gap in the line? */
7658 if (GPT
< start
|| Z
- GPT
< end
)
7661 /* Changes start in front of the line, or end after it? */
7663 && (BEG_UNCHANGED
< start
- 1
7664 || END_UNCHANGED
< end
))
7667 /* If selective display, can't optimize if changes start at the
7668 beginning of the line. */
7670 && INTEGERP (current_buffer
->selective_display
)
7671 && XINT (current_buffer
->selective_display
) > 0
7672 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
7680 /* Do a frame update, taking possible shortcuts into account. This is
7681 the main external entry point for redisplay.
7683 If the last redisplay displayed an echo area message and that message
7684 is no longer requested, we clear the echo area or bring back the
7685 mini-buffer if that is in use. */
7690 redisplay_internal (0);
7693 /* Return 1 if point moved out of or into a composition. Otherwise
7694 return 0. PREV_BUF and PREV_PT are the last point buffer and
7695 position. BUF and PT are the current point buffer and position. */
7698 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
7699 struct buffer
*prev_buf
, *buf
;
7706 XSETBUFFER (buffer
, buf
);
7707 /* Check a composition at the last point if point moved within the
7709 if (prev_buf
== buf
)
7712 /* Point didn't move. */
7715 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
7716 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
7717 && COMPOSITION_VALID_P (start
, end
, prop
)
7718 && start
< prev_pt
&& end
> prev_pt
)
7719 /* The last point was within the composition. Return 1 iff
7720 point moved out of the composition. */
7721 return (pt
<= start
|| pt
>= end
);
7724 /* Check a composition at the current point. */
7725 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
7726 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
7727 && COMPOSITION_VALID_P (start
, end
, prop
)
7728 && start
< pt
&& end
> pt
);
7731 /* Reconsider the setting of B->clip_changed which is displayed
7735 reconsider_clip_changes (w
, b
)
7739 if (b
->prevent_redisplay_optimizations_p
)
7740 b
->clip_changed
= 1;
7741 else if (b
->clip_changed
7742 && !NILP (w
->window_end_valid
)
7743 && w
->current_matrix
->buffer
== b
7744 && w
->current_matrix
->zv
== BUF_ZV (b
)
7745 && w
->current_matrix
->begv
== BUF_BEGV (b
))
7746 b
->clip_changed
= 0;
7748 /* If display wasn't paused, and W is not a tool bar window, see if
7749 point has been moved into or out of a composition. In that case,
7750 we set b->clip_changed to 1 to force updating the screen. If
7751 b->clip_changed has already been set to 1, we can skip this
7753 if (!b
->clip_changed
7754 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
7758 if (w
== XWINDOW (selected_window
))
7759 pt
= BUF_PT (current_buffer
);
7761 pt
= marker_position (w
->pointm
);
7763 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
7764 || pt
!= XINT (w
->last_point
))
7765 && check_point_in_composition (w
->current_matrix
->buffer
,
7766 XINT (w
->last_point
),
7767 XBUFFER (w
->buffer
), pt
))
7768 b
->clip_changed
= 1;
7773 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
7774 response to any user action; therefore, we should preserve the echo
7775 area. (Actually, our caller does that job.) Perhaps in the future
7776 avoid recentering windows if it is not necessary; currently that
7777 causes some problems. */
7780 redisplay_internal (preserve_echo_area
)
7781 int preserve_echo_area
;
7783 struct window
*w
= XWINDOW (selected_window
);
7784 struct frame
*f
= XFRAME (w
->frame
);
7786 int must_finish
= 0;
7787 struct text_pos tlbufpos
, tlendpos
;
7788 int number_of_visible_frames
;
7790 struct frame
*sf
= SELECTED_FRAME ();
7792 /* Non-zero means redisplay has to consider all windows on all
7793 frames. Zero means, only selected_window is considered. */
7794 int consider_all_windows_p
;
7796 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
7798 /* No redisplay if running in batch mode or frame is not yet fully
7799 initialized, or redisplay is explicitly turned off by setting
7800 Vinhibit_redisplay. */
7802 || !NILP (Vinhibit_redisplay
)
7803 || !f
->glyphs_initialized_p
)
7806 /* The flag redisplay_performed_directly_p is set by
7807 direct_output_for_insert when it already did the whole screen
7808 update necessary. */
7809 if (redisplay_performed_directly_p
)
7811 redisplay_performed_directly_p
= 0;
7812 if (!hscroll_windows (selected_window
))
7816 #ifdef USE_X_TOOLKIT
7817 if (popup_activated ())
7821 /* I don't think this happens but let's be paranoid. */
7825 /* Record a function that resets redisplaying_p to its old value
7826 when we leave this function. */
7827 count
= BINDING_STACK_SIZE ();
7828 record_unwind_protect (unwind_redisplay
, make_number (redisplaying_p
));
7833 reconsider_clip_changes (w
, current_buffer
);
7835 /* If new fonts have been loaded that make a glyph matrix adjustment
7836 necessary, do it. */
7837 if (fonts_changed_p
)
7839 adjust_glyphs (NULL
);
7840 ++windows_or_buffers_changed
;
7841 fonts_changed_p
= 0;
7844 if (! FRAME_WINDOW_P (sf
)
7845 && previous_terminal_frame
!= sf
)
7847 /* Since frames on an ASCII terminal share the same display
7848 area, displaying a different frame means redisplay the whole
7850 windows_or_buffers_changed
++;
7851 SET_FRAME_GARBAGED (sf
);
7852 XSETFRAME (Vterminal_frame
, sf
);
7854 previous_terminal_frame
= sf
;
7856 /* Set the visible flags for all frames. Do this before checking
7857 for resized or garbaged frames; they want to know if their frames
7858 are visible. See the comment in frame.h for
7859 FRAME_SAMPLE_VISIBILITY. */
7861 Lisp_Object tail
, frame
;
7863 number_of_visible_frames
= 0;
7865 FOR_EACH_FRAME (tail
, frame
)
7867 struct frame
*f
= XFRAME (frame
);
7869 FRAME_SAMPLE_VISIBILITY (f
);
7870 if (FRAME_VISIBLE_P (f
))
7871 ++number_of_visible_frames
;
7872 clear_desired_matrices (f
);
7876 /* Notice any pending interrupt request to change frame size. */
7877 do_pending_window_change (1);
7879 /* Clear frames marked as garbaged. */
7881 clear_garbaged_frames ();
7883 /* Build menubar and tool-bar items. */
7884 prepare_menu_bars ();
7886 if (windows_or_buffers_changed
)
7887 update_mode_lines
++;
7889 /* Detect case that we need to write or remove a star in the mode line. */
7890 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
7892 w
->update_mode_line
= Qt
;
7893 if (buffer_shared
> 1)
7894 update_mode_lines
++;
7897 /* If %c is in the mode line, update it if needed. */
7898 if (!NILP (w
->column_number_displayed
)
7899 /* This alternative quickly identifies a common case
7900 where no change is needed. */
7901 && !(PT
== XFASTINT (w
->last_point
)
7902 && XFASTINT (w
->last_modified
) >= MODIFF
7903 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
7904 && XFASTINT (w
->column_number_displayed
) != current_column ())
7905 w
->update_mode_line
= Qt
;
7907 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
7909 /* The variable buffer_shared is set in redisplay_window and
7910 indicates that we redisplay a buffer in different windows. See
7912 consider_all_windows_p
= update_mode_lines
|| buffer_shared
> 1;
7914 /* If specs for an arrow have changed, do thorough redisplay
7915 to ensure we remove any arrow that should no longer exist. */
7916 if (! EQ (COERCE_MARKER (Voverlay_arrow_position
), last_arrow_position
)
7917 || ! EQ (Voverlay_arrow_string
, last_arrow_string
))
7918 consider_all_windows_p
= windows_or_buffers_changed
= 1;
7920 /* Normally the message* functions will have already displayed and
7921 updated the echo area, but the frame may have been trashed, or
7922 the update may have been preempted, so display the echo area
7923 again here. Checking both message buffers captures the case that
7924 the echo area should be cleared. */
7925 if (!NILP (echo_area_buffer
[0]) || !NILP (echo_area_buffer
[1]))
7927 int window_height_changed_p
= echo_area_display (0);
7930 if (fonts_changed_p
)
7932 else if (window_height_changed_p
)
7934 consider_all_windows_p
= 1;
7935 ++update_mode_lines
;
7936 ++windows_or_buffers_changed
;
7938 /* If window configuration was changed, frames may have been
7939 marked garbaged. Clear them or we will experience
7940 surprises wrt scrolling. */
7942 clear_garbaged_frames ();
7945 else if (EQ (selected_window
, minibuf_window
)
7946 && (current_buffer
->clip_changed
7947 || XFASTINT (w
->last_modified
) < MODIFF
7948 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
7949 && resize_mini_window (w
, 0))
7951 /* Resized active mini-window to fit the size of what it is
7952 showing if its contents might have changed. */
7954 consider_all_windows_p
= 1;
7955 ++windows_or_buffers_changed
;
7956 ++update_mode_lines
;
7958 /* If window configuration was changed, frames may have been
7959 marked garbaged. Clear them or we will experience
7960 surprises wrt scrolling. */
7962 clear_garbaged_frames ();
7966 /* If showing the region, and mark has changed, we must redisplay
7967 the whole window. The assignment to this_line_start_pos prevents
7968 the optimization directly below this if-statement. */
7969 if (((!NILP (Vtransient_mark_mode
)
7970 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
7971 != !NILP (w
->region_showing
))
7972 || (!NILP (w
->region_showing
)
7973 && !EQ (w
->region_showing
,
7974 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
7975 CHARPOS (this_line_start_pos
) = 0;
7977 /* Optimize the case that only the line containing the cursor in the
7978 selected window has changed. Variables starting with this_ are
7979 set in display_line and record information about the line
7980 containing the cursor. */
7981 tlbufpos
= this_line_start_pos
;
7982 tlendpos
= this_line_end_pos
;
7983 if (!consider_all_windows_p
7984 && CHARPOS (tlbufpos
) > 0
7985 && NILP (w
->update_mode_line
)
7986 && !current_buffer
->clip_changed
7987 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
7988 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
7989 /* Make sure recorded data applies to current buffer, etc. */
7990 && this_line_buffer
== current_buffer
7991 && current_buffer
== XBUFFER (w
->buffer
)
7992 && NILP (w
->force_start
)
7993 /* Point must be on the line that we have info recorded about. */
7994 && PT
>= CHARPOS (tlbufpos
)
7995 && PT
<= Z
- CHARPOS (tlendpos
)
7996 /* All text outside that line, including its final newline,
7997 must be unchanged */
7998 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
7999 CHARPOS (tlendpos
)))
8001 if (CHARPOS (tlbufpos
) > BEGV
8002 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
8003 && (CHARPOS (tlbufpos
) == ZV
8004 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
8005 /* Former continuation line has disappeared by becoming empty */
8007 else if (XFASTINT (w
->last_modified
) < MODIFF
8008 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
8009 || MINI_WINDOW_P (w
))
8011 /* We have to handle the case of continuation around a
8012 wide-column character (See the comment in indent.c around
8015 For instance, in the following case:
8017 -------- Insert --------
8018 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
8019 J_I_ ==> J_I_ `^^' are cursors.
8023 As we have to redraw the line above, we should goto cancel. */
8026 int line_height_before
= this_line_pixel_height
;
8028 /* Note that start_display will handle the case that the
8029 line starting at tlbufpos is a continuation lines. */
8030 start_display (&it
, w
, tlbufpos
);
8032 /* Implementation note: It this still necessary? */
8033 if (it
.current_x
!= this_line_start_x
)
8036 TRACE ((stderr
, "trying display optimization 1\n"));
8037 w
->cursor
.vpos
= -1;
8038 overlay_arrow_seen
= 0;
8039 it
.vpos
= this_line_vpos
;
8040 it
.current_y
= this_line_y
;
8041 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
8044 /* If line contains point, is not continued,
8045 and ends at same distance from eob as before, we win */
8046 if (w
->cursor
.vpos
>= 0
8047 /* Line is not continued, otherwise this_line_start_pos
8048 would have been set to 0 in display_line. */
8049 && CHARPOS (this_line_start_pos
)
8050 /* Line ends as before. */
8051 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
8052 /* Line has same height as before. Otherwise other lines
8053 would have to be shifted up or down. */
8054 && this_line_pixel_height
== line_height_before
)
8056 /* If this is not the window's last line, we must adjust
8057 the charstarts of the lines below. */
8058 if (it
.current_y
< it
.last_visible_y
)
8060 struct glyph_row
*row
8061 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
8062 int delta
, delta_bytes
;
8064 if (Z
- CHARPOS (tlendpos
) == ZV
)
8066 /* This line ends at end of (accessible part of)
8067 buffer. There is no newline to count. */
8069 - CHARPOS (tlendpos
)
8070 - MATRIX_ROW_START_CHARPOS (row
));
8071 delta_bytes
= (Z_BYTE
8072 - BYTEPOS (tlendpos
)
8073 - MATRIX_ROW_START_BYTEPOS (row
));
8077 /* This line ends in a newline. Must take
8078 account of the newline and the rest of the
8079 text that follows. */
8081 - CHARPOS (tlendpos
)
8082 - MATRIX_ROW_START_CHARPOS (row
));
8083 delta_bytes
= (Z_BYTE
8084 - BYTEPOS (tlendpos
)
8085 - MATRIX_ROW_START_BYTEPOS (row
));
8088 increment_matrix_positions (w
->current_matrix
,
8090 w
->current_matrix
->nrows
,
8091 delta
, delta_bytes
);
8094 /* If this row displays text now but previously didn't,
8095 or vice versa, w->window_end_vpos may have to be
8097 if ((it
.glyph_row
- 1)->displays_text_p
)
8099 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
8100 XSETINT (w
->window_end_vpos
, this_line_vpos
);
8102 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
8103 && this_line_vpos
> 0)
8104 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
8105 w
->window_end_valid
= Qnil
;
8107 /* Update hint: No need to try to scroll in update_window. */
8108 w
->desired_matrix
->no_scrolling_p
= 1;
8111 *w
->desired_matrix
->method
= 0;
8112 debug_method_add (w
, "optimization 1");
8119 else if (/* Cursor position hasn't changed. */
8120 PT
== XFASTINT (w
->last_point
)
8121 /* Make sure the cursor was last displayed
8122 in this window. Otherwise we have to reposition it. */
8123 && 0 <= w
->cursor
.vpos
8124 && XINT (w
->height
) > w
->cursor
.vpos
)
8128 do_pending_window_change (1);
8130 /* We used to always goto end_of_redisplay here, but this
8131 isn't enough if we have a blinking cursor. */
8132 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
8133 goto end_of_redisplay
;
8137 /* If highlighting the region, or if the cursor is in the echo area,
8138 then we can't just move the cursor. */
8139 else if (! (!NILP (Vtransient_mark_mode
)
8140 && !NILP (current_buffer
->mark_active
))
8141 && (EQ (selected_window
, current_buffer
->last_selected_window
)
8142 || highlight_nonselected_windows
)
8143 && NILP (w
->region_showing
)
8144 && NILP (Vshow_trailing_whitespace
)
8145 && !cursor_in_echo_area
)
8148 struct glyph_row
*row
;
8150 /* Skip from tlbufpos to PT and see where it is. Note that
8151 PT may be in invisible text. If so, we will end at the
8152 next visible position. */
8153 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
8154 NULL
, DEFAULT_FACE_ID
);
8155 it
.current_x
= this_line_start_x
;
8156 it
.current_y
= this_line_y
;
8157 it
.vpos
= this_line_vpos
;
8159 /* The call to move_it_to stops in front of PT, but
8160 moves over before-strings. */
8161 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
8163 if (it
.vpos
== this_line_vpos
8164 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
8167 xassert (this_line_vpos
== it
.vpos
);
8168 xassert (this_line_y
== it
.current_y
);
8169 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
8177 /* Text changed drastically or point moved off of line. */
8178 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
8181 CHARPOS (this_line_start_pos
) = 0;
8182 consider_all_windows_p
|= buffer_shared
> 1;
8183 ++clear_face_cache_count
;
8186 /* Build desired matrices, and update the display. If
8187 consider_all_windows_p is non-zero, do it for all windows on all
8188 frames. Otherwise do it for selected_window, only. */
8190 if (consider_all_windows_p
)
8192 Lisp_Object tail
, frame
;
8194 /* Clear the face cache eventually. */
8195 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
8197 clear_face_cache (0);
8198 clear_face_cache_count
= 0;
8201 /* Recompute # windows showing selected buffer. This will be
8202 incremented each time such a window is displayed. */
8205 FOR_EACH_FRAME (tail
, frame
)
8207 struct frame
*f
= XFRAME (frame
);
8209 if (FRAME_WINDOW_P (f
) || f
== sf
)
8211 /* Mark all the scroll bars to be removed; we'll redeem
8212 the ones we want when we redisplay their windows. */
8213 if (condemn_scroll_bars_hook
)
8214 (*condemn_scroll_bars_hook
) (f
);
8216 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
8217 redisplay_windows (FRAME_ROOT_WINDOW (f
));
8219 /* Any scroll bars which redisplay_windows should have
8220 nuked should now go away. */
8221 if (judge_scroll_bars_hook
)
8222 (*judge_scroll_bars_hook
) (f
);
8224 /* If fonts changed, display again. */
8225 if (fonts_changed_p
)
8228 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
8230 /* See if we have to hscroll. */
8231 if (hscroll_windows (f
->root_window
))
8234 /* Prevent various kinds of signals during display
8235 update. stdio is not robust about handling
8236 signals, which can cause an apparent I/O
8238 if (interrupt_input
)
8242 /* Update the display. */
8243 set_window_update_flags (XWINDOW (f
->root_window
), 1);
8244 pause
|= update_frame (f
, 0, 0);
8248 mark_window_display_accurate (f
->root_window
, 1);
8249 if (frame_up_to_date_hook
)
8250 frame_up_to_date_hook (f
);
8255 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
8257 Lisp_Object mini_window
;
8258 struct frame
*mini_frame
;
8260 redisplay_window (selected_window
, 1);
8262 /* Compare desired and current matrices, perform output. */
8265 /* If fonts changed, display again. */
8266 if (fonts_changed_p
)
8269 /* Prevent various kinds of signals during display update.
8270 stdio is not robust about handling signals,
8271 which can cause an apparent I/O error. */
8272 if (interrupt_input
)
8276 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
8278 if (hscroll_windows (selected_window
))
8281 XWINDOW (selected_window
)->must_be_updated_p
= 1;
8282 pause
= update_frame (sf
, 0, 0);
8285 /* We may have called echo_area_display at the top of this
8286 function. If the echo area is on another frame, that may
8287 have put text on a frame other than the selected one, so the
8288 above call to update_frame would not have caught it. Catch
8290 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8291 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
8293 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
8295 XWINDOW (mini_window
)->must_be_updated_p
= 1;
8296 pause
|= update_frame (mini_frame
, 0, 0);
8297 if (!pause
&& hscroll_windows (mini_window
))
8302 /* If display was paused because of pending input, make sure we do a
8303 thorough update the next time. */
8306 /* Prevent the optimization at the beginning of
8307 redisplay_internal that tries a single-line update of the
8308 line containing the cursor in the selected window. */
8309 CHARPOS (this_line_start_pos
) = 0;
8311 /* Let the overlay arrow be updated the next time. */
8312 if (!NILP (last_arrow_position
))
8314 last_arrow_position
= Qt
;
8315 last_arrow_string
= Qt
;
8318 /* If we pause after scrolling, some rows in the current
8319 matrices of some windows are not valid. */
8320 if (!WINDOW_FULL_WIDTH_P (w
)
8321 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
8322 update_mode_lines
= 1;
8325 /* Now text on frame agrees with windows, so put info into the
8326 windows for partial redisplay to follow. */
8329 register struct buffer
*b
= XBUFFER (w
->buffer
);
8331 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
8332 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
8333 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
8334 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
8336 if (consider_all_windows_p
)
8337 mark_window_display_accurate (FRAME_ROOT_WINDOW (sf
), 1);
8340 XSETFASTINT (w
->last_point
, BUF_PT (b
));
8341 w
->last_cursor
= w
->cursor
;
8342 w
->last_cursor_off_p
= w
->cursor_off_p
;
8344 b
->clip_changed
= 0;
8345 b
->prevent_redisplay_optimizations_p
= 0;
8346 w
->update_mode_line
= Qnil
;
8347 XSETFASTINT (w
->last_modified
, BUF_MODIFF (b
));
8348 XSETFASTINT (w
->last_overlay_modified
, BUF_OVERLAY_MODIFF (b
));
8350 = (BUF_MODIFF (XBUFFER (w
->buffer
)) > BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8353 /* Record if we are showing a region, so can make sure to
8354 update it fully at next redisplay. */
8355 w
->region_showing
= (!NILP (Vtransient_mark_mode
)
8356 && (EQ (selected_window
,
8357 current_buffer
->last_selected_window
)
8358 || highlight_nonselected_windows
)
8359 && !NILP (XBUFFER (w
->buffer
)->mark_active
)
8360 ? Fmarker_position (XBUFFER (w
->buffer
)->mark
)
8363 w
->window_end_valid
= w
->buffer
;
8364 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
8365 last_arrow_string
= Voverlay_arrow_string
;
8366 if (frame_up_to_date_hook
!= 0)
8367 (*frame_up_to_date_hook
) (sf
);
8369 w
->current_matrix
->buffer
= b
;
8370 w
->current_matrix
->begv
= BUF_BEGV (b
);
8371 w
->current_matrix
->zv
= BUF_ZV (b
);
8374 update_mode_lines
= 0;
8375 windows_or_buffers_changed
= 0;
8378 /* Start SIGIO interrupts coming again. Having them off during the
8379 code above makes it less likely one will discard output, but not
8380 impossible, since there might be stuff in the system buffer here.
8381 But it is much hairier to try to do anything about that. */
8382 if (interrupt_input
)
8386 /* If a frame has become visible which was not before, redisplay
8387 again, so that we display it. Expose events for such a frame
8388 (which it gets when becoming visible) don't call the parts of
8389 redisplay constructing glyphs, so simply exposing a frame won't
8390 display anything in this case. So, we have to display these
8391 frames here explicitly. */
8394 Lisp_Object tail
, frame
;
8397 FOR_EACH_FRAME (tail
, frame
)
8399 int this_is_visible
= 0;
8401 if (XFRAME (frame
)->visible
)
8402 this_is_visible
= 1;
8403 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
8404 if (XFRAME (frame
)->visible
)
8405 this_is_visible
= 1;
8407 if (this_is_visible
)
8411 if (new_count
!= number_of_visible_frames
)
8412 windows_or_buffers_changed
++;
8415 /* Change frame size now if a change is pending. */
8416 do_pending_window_change (1);
8418 /* If we just did a pending size change, or have additional
8419 visible frames, redisplay again. */
8420 if (windows_or_buffers_changed
&& !pause
)
8425 unbind_to (count
, Qnil
);
8429 /* Redisplay, but leave alone any recent echo area message unless
8430 another message has been requested in its place.
8432 This is useful in situations where you need to redisplay but no
8433 user action has occurred, making it inappropriate for the message
8434 area to be cleared. See tracking_off and
8435 wait_reading_process_input for examples of these situations. */
8438 redisplay_preserve_echo_area ()
8440 if (!NILP (echo_area_buffer
[1]))
8442 /* We have a previously displayed message, but no current
8443 message. Redisplay the previous message. */
8444 display_last_displayed_message_p
= 1;
8445 redisplay_internal (1);
8446 display_last_displayed_message_p
= 0;
8449 redisplay_internal (1);
8453 /* Function registered with record_unwind_protect in
8454 redisplay_internal. Clears the flag indicating that a redisplay is
8458 unwind_redisplay (old_redisplaying_p
)
8459 Lisp_Object old_redisplaying_p
;
8461 redisplaying_p
= XFASTINT (old_redisplaying_p
);
8466 /* Mark the display of windows in the window tree rooted at WINDOW as
8467 accurate or inaccurate. If FLAG is non-zero mark display of WINDOW
8468 as accurate. If FLAG is zero arrange for WINDOW to be redisplayed
8469 the next time redisplay_internal is called. */
8472 mark_window_display_accurate (window
, accurate_p
)
8478 for (; !NILP (window
); window
= w
->next
)
8480 w
= XWINDOW (window
);
8482 if (BUFFERP (w
->buffer
))
8484 struct buffer
*b
= XBUFFER (w
->buffer
);
8486 XSETFASTINT (w
->last_modified
,
8487 accurate_p
? BUF_MODIFF (b
) : 0);
8488 XSETFASTINT (w
->last_overlay_modified
,
8489 accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
8490 w
->last_had_star
= (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
)
8493 #if 0 /* I don't think this is necessary because display_line does it.
8495 /* Record if we are showing a region, so can make sure to
8496 update it fully at next redisplay. */
8498 = (!NILP (Vtransient_mark_mode
)
8499 && (w
== XWINDOW (current_buffer
->last_selected_window
)
8500 || highlight_nonselected_windows
)
8501 && (!NILP (b
->mark_active
)
8502 ? Fmarker_position (b
->mark
)
8508 b
->clip_changed
= 0;
8509 b
->prevent_redisplay_optimizations_p
= 0;
8510 w
->current_matrix
->buffer
= b
;
8511 w
->current_matrix
->begv
= BUF_BEGV (b
);
8512 w
->current_matrix
->zv
= BUF_ZV (b
);
8513 w
->last_cursor
= w
->cursor
;
8514 w
->last_cursor_off_p
= w
->cursor_off_p
;
8515 if (w
== XWINDOW (selected_window
))
8516 w
->last_point
= make_number (BUF_PT (b
));
8518 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
8522 w
->window_end_valid
= w
->buffer
;
8523 w
->update_mode_line
= Qnil
;
8525 if (!NILP (w
->vchild
))
8526 mark_window_display_accurate (w
->vchild
, accurate_p
);
8527 if (!NILP (w
->hchild
))
8528 mark_window_display_accurate (w
->hchild
, accurate_p
);
8533 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
8534 last_arrow_string
= Voverlay_arrow_string
;
8538 /* Force a thorough redisplay the next time by setting
8539 last_arrow_position and last_arrow_string to t, which is
8540 unequal to any useful value of Voverlay_arrow_... */
8541 last_arrow_position
= Qt
;
8542 last_arrow_string
= Qt
;
8547 /* Return value in display table DP (Lisp_Char_Table *) for character
8548 C. Since a display table doesn't have any parent, we don't have to
8549 follow parent. Do not call this function directly but use the
8550 macro DISP_CHAR_VECTOR. */
8553 disp_char_vector (dp
, c
)
8554 struct Lisp_Char_Table
*dp
;
8560 if (SINGLE_BYTE_CHAR_P (c
))
8561 return (dp
->contents
[c
]);
8563 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
8566 else if (code
[2] < 32)
8569 /* Here, the possible range of code[0] (== charset ID) is
8570 128..max_charset. Since the top level char table contains data
8571 for multibyte characters after 256th element, we must increment
8572 code[0] by 128 to get a correct index. */
8574 code
[3] = -1; /* anchor */
8576 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
8578 val
= dp
->contents
[code
[i
]];
8579 if (!SUB_CHAR_TABLE_P (val
))
8580 return (NILP (val
) ? dp
->defalt
: val
);
8583 /* Here, val is a sub char table. We return the default value of
8585 return (dp
->defalt
);
8590 /***********************************************************************
8592 ***********************************************************************/
8594 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
8597 redisplay_windows (window
)
8600 while (!NILP (window
))
8602 struct window
*w
= XWINDOW (window
);
8604 if (!NILP (w
->hchild
))
8605 redisplay_windows (w
->hchild
);
8606 else if (!NILP (w
->vchild
))
8607 redisplay_windows (w
->vchild
);
8609 redisplay_window (window
, 0);
8616 /* Set cursor position of W. PT is assumed to be displayed in ROW.
8617 DELTA is the number of bytes by which positions recorded in ROW
8618 differ from current buffer positions. */
8621 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
8623 struct glyph_row
*row
;
8624 struct glyph_matrix
*matrix
;
8625 int delta
, delta_bytes
, dy
, dvpos
;
8627 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
8628 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
8630 int pt_old
= PT
- delta
;
8632 /* Skip over glyphs not having an object at the start of the row.
8633 These are special glyphs like truncation marks on terminal
8635 if (row
->displays_text_p
)
8637 && INTEGERP (glyph
->object
)
8638 && glyph
->charpos
< 0)
8640 x
+= glyph
->pixel_width
;
8645 && !INTEGERP (glyph
->object
)
8646 && (!BUFFERP (glyph
->object
)
8647 || glyph
->charpos
< pt_old
))
8649 x
+= glyph
->pixel_width
;
8653 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
8655 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
8656 w
->cursor
.y
= row
->y
+ dy
;
8658 if (w
== XWINDOW (selected_window
))
8660 if (!row
->continued_p
8661 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
8664 this_line_buffer
= XBUFFER (w
->buffer
);
8666 CHARPOS (this_line_start_pos
)
8667 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
8668 BYTEPOS (this_line_start_pos
)
8669 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
8671 CHARPOS (this_line_end_pos
)
8672 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
8673 BYTEPOS (this_line_end_pos
)
8674 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
8676 this_line_y
= w
->cursor
.y
;
8677 this_line_pixel_height
= row
->height
;
8678 this_line_vpos
= w
->cursor
.vpos
;
8679 this_line_start_x
= row
->x
;
8682 CHARPOS (this_line_start_pos
) = 0;
8687 /* Run window scroll functions, if any, for WINDOW with new window
8688 start STARTP. Sets the window start of WINDOW to that position.
8690 We assume that the window's buffer is really current. */
8692 static INLINE
struct text_pos
8693 run_window_scroll_functions (window
, startp
)
8695 struct text_pos startp
;
8697 struct window
*w
= XWINDOW (window
);
8698 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
8700 if (current_buffer
!= XBUFFER (w
->buffer
))
8703 if (!NILP (Vwindow_scroll_functions
))
8705 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
8706 make_number (CHARPOS (startp
)));
8707 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
8708 /* In case the hook functions switch buffers. */
8709 if (current_buffer
!= XBUFFER (w
->buffer
))
8710 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8717 /* Modify the desired matrix of window W and W->vscroll so that the
8718 line containing the cursor is fully visible. */
8721 make_cursor_line_fully_visible (w
)
8724 struct glyph_matrix
*matrix
;
8725 struct glyph_row
*row
;
8726 int window_height
, header_line_height
;
8728 /* It's not always possible to find the cursor, e.g, when a window
8729 is full of overlay strings. Don't do anything in that case. */
8730 if (w
->cursor
.vpos
< 0)
8733 matrix
= w
->desired_matrix
;
8734 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
8736 /* If the cursor row is not partially visible, there's nothing
8738 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
8741 /* If the row the cursor is in is taller than the window's height,
8742 it's not clear what to do, so do nothing. */
8743 window_height
= window_box_height (w
);
8744 if (row
->height
>= window_height
)
8747 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
8749 int dy
= row
->height
- row
->visible_height
;
8752 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
8754 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
8756 int dy
= - (row
->height
- row
->visible_height
);
8759 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
8762 /* When we change the cursor y-position of the selected window,
8763 change this_line_y as well so that the display optimization for
8764 the cursor line of the selected window in redisplay_internal uses
8765 the correct y-position. */
8766 if (w
== XWINDOW (selected_window
))
8767 this_line_y
= w
->cursor
.y
;
8771 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
8772 non-zero means only WINDOW is redisplayed in redisplay_internal.
8773 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
8774 in redisplay_window to bring a partially visible line into view in
8775 the case that only the cursor has moved.
8779 1 if scrolling succeeded
8781 0 if scrolling didn't find point.
8783 -1 if new fonts have been loaded so that we must interrupt
8784 redisplay, adjust glyph matrices, and try again. */
8787 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
8788 scroll_step
, temp_scroll_step
)
8790 int just_this_one_p
;
8791 int scroll_conservatively
, scroll_step
;
8792 int temp_scroll_step
;
8794 struct window
*w
= XWINDOW (window
);
8795 struct frame
*f
= XFRAME (w
->frame
);
8796 struct text_pos scroll_margin_pos
;
8797 struct text_pos pos
;
8798 struct text_pos startp
;
8800 Lisp_Object window_end
;
8801 int this_scroll_margin
;
8805 int amount_to_scroll
= 0;
8806 Lisp_Object aggressive
;
8810 debug_method_add (w
, "try_scrolling");
8813 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
8815 /* Compute scroll margin height in pixels. We scroll when point is
8816 within this distance from the top or bottom of the window. */
8817 if (scroll_margin
> 0)
8819 this_scroll_margin
= min (scroll_margin
, XINT (w
->height
) / 4);
8820 this_scroll_margin
*= CANON_Y_UNIT (f
);
8823 this_scroll_margin
= 0;
8825 /* Compute how much we should try to scroll maximally to bring point
8827 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
8828 scroll_max
= max (scroll_step
,
8829 max (scroll_conservatively
, temp_scroll_step
));
8830 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
8831 || NUMBERP (current_buffer
->scroll_up_aggressively
))
8832 /* We're trying to scroll because of aggressive scrolling
8833 but no scroll_step is set. Choose an arbitrary one. Maybe
8834 there should be a variable for this. */
8838 scroll_max
*= CANON_Y_UNIT (f
);
8840 /* Decide whether we have to scroll down. Start at the window end
8841 and move this_scroll_margin up to find the position of the scroll
8843 window_end
= Fwindow_end (window
, Qt
);
8844 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
8845 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
8846 if (this_scroll_margin
)
8848 start_display (&it
, w
, scroll_margin_pos
);
8849 move_it_vertically (&it
, - this_scroll_margin
);
8850 scroll_margin_pos
= it
.current
.pos
;
8853 if (PT
>= CHARPOS (scroll_margin_pos
))
8860 /* Point is in the scroll margin at the bottom of the window, or
8861 below. Compute a new window start that makes point visible. */
8863 /* Compute the distance from the scroll margin to PT.
8864 Give up if the distance is greater than scroll_max. */
8865 start_display (&it
, w
, scroll_margin_pos
);
8867 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
8868 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
8869 #if 0 /* Taking the line's height into account here looks wrong. */
8870 line_height
= (it
.max_ascent
+ it
.max_descent
8871 ? it
.max_ascent
+ it
.max_descent
8873 dy
= it
.current_y
+ line_height
- y0
;
8875 /* With a scroll_margin of 0, scroll_margin_pos is at the window
8876 end, which is one line below the window. The iterator's
8877 current_y will be same as y0 in that case, but we have to
8878 scroll a line to make PT visible. That's the reason why 1 is
8880 dy
= 1 + it
.current_y
- y0
;
8883 if (dy
> scroll_max
)
8886 /* Move the window start down. If scrolling conservatively,
8887 move it just enough down to make point visible. If
8888 scroll_step is set, move it down by scroll_step. */
8889 start_display (&it
, w
, startp
);
8891 if (scroll_conservatively
)
8893 max (dy
, CANON_Y_UNIT (f
) * max (scroll_step
, temp_scroll_step
));
8894 else if (scroll_step
|| temp_scroll_step
)
8895 amount_to_scroll
= scroll_max
;
8898 aggressive
= current_buffer
->scroll_down_aggressively
;
8899 height
= (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w
)
8900 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
));
8901 if (NUMBERP (aggressive
))
8902 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
8905 if (amount_to_scroll
<= 0)
8908 move_it_vertically (&it
, amount_to_scroll
);
8909 startp
= it
.current
.pos
;
8913 /* See if point is inside the scroll margin at the top of the
8915 scroll_margin_pos
= startp
;
8916 if (this_scroll_margin
)
8918 start_display (&it
, w
, startp
);
8919 move_it_vertically (&it
, this_scroll_margin
);
8920 scroll_margin_pos
= it
.current
.pos
;
8923 if (PT
< CHARPOS (scroll_margin_pos
))
8925 /* Point is in the scroll margin at the top of the window or
8926 above what is displayed in the window. */
8929 /* Compute the vertical distance from PT to the scroll
8930 margin position. Give up if distance is greater than
8932 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
8933 start_display (&it
, w
, pos
);
8935 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
8936 it
.last_visible_y
, -1,
8937 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
8938 dy
= it
.current_y
- y0
;
8939 if (dy
> scroll_max
)
8942 /* Compute new window start. */
8943 start_display (&it
, w
, startp
);
8945 if (scroll_conservatively
)
8947 max (dy
, CANON_Y_UNIT (f
) * max (scroll_step
, temp_scroll_step
));
8948 else if (scroll_step
|| temp_scroll_step
)
8949 amount_to_scroll
= scroll_max
;
8952 aggressive
= current_buffer
->scroll_up_aggressively
;
8953 height
= (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w
)
8954 - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
));
8955 if (NUMBERP (aggressive
))
8956 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
8959 if (amount_to_scroll
<= 0)
8962 move_it_vertically (&it
, - amount_to_scroll
);
8963 startp
= it
.current
.pos
;
8967 /* Run window scroll functions. */
8968 startp
= run_window_scroll_functions (window
, startp
);
8970 /* Display the window. Give up if new fonts are loaded, or if point
8972 if (!try_window (window
, startp
))
8974 else if (w
->cursor
.vpos
< 0)
8976 clear_glyph_matrix (w
->desired_matrix
);
8981 /* Maybe forget recorded base line for line number display. */
8982 if (!just_this_one_p
8983 || current_buffer
->clip_changed
8984 || BEG_UNCHANGED
< CHARPOS (startp
))
8985 w
->base_line_number
= Qnil
;
8987 /* If cursor ends up on a partially visible line, shift display
8988 lines up or down. */
8989 make_cursor_line_fully_visible (w
);
8997 /* Compute a suitable window start for window W if display of W starts
8998 on a continuation line. Value is non-zero if a new window start
9001 The new window start will be computed, based on W's width, starting
9002 from the start of the continued line. It is the start of the
9003 screen line with the minimum distance from the old start W->start. */
9006 compute_window_start_on_continuation_line (w
)
9009 struct text_pos pos
, start_pos
;
9010 int window_start_changed_p
= 0;
9012 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
9014 /* If window start is on a continuation line... Window start may be
9015 < BEGV in case there's invisible text at the start of the
9016 buffer (M-x rmail, for example). */
9017 if (CHARPOS (start_pos
) > BEGV
9018 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
9021 struct glyph_row
*row
;
9023 /* Handle the case that the window start is out of range. */
9024 if (CHARPOS (start_pos
) < BEGV
)
9025 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
9026 else if (CHARPOS (start_pos
) > ZV
)
9027 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
9029 /* Find the start of the continued line. This should be fast
9030 because scan_buffer is fast (newline cache). */
9031 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
9032 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
9033 row
, DEFAULT_FACE_ID
);
9034 reseat_at_previous_visible_line_start (&it
);
9036 /* If the line start is "too far" away from the window start,
9037 say it takes too much time to compute a new window start. */
9038 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
9039 < XFASTINT (w
->height
) * XFASTINT (w
->width
))
9041 int min_distance
, distance
;
9043 /* Move forward by display lines to find the new window
9044 start. If window width was enlarged, the new start can
9045 be expected to be > the old start. If window width was
9046 decreased, the new window start will be < the old start.
9047 So, we're looking for the display line start with the
9048 minimum distance from the old window start. */
9049 pos
= it
.current
.pos
;
9050 min_distance
= INFINITY
;
9051 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
9052 distance
< min_distance
)
9054 min_distance
= distance
;
9055 pos
= it
.current
.pos
;
9056 move_it_by_lines (&it
, 1, 0);
9059 /* Set the window start there. */
9060 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
9061 window_start_changed_p
= 1;
9065 return window_start_changed_p
;
9069 /* Try cursor movement in case text has not changes in window WINDOW,
9070 with window start STARTP. Value is
9074 0 if this method cannot be used
9076 -1 if we know we have to scroll the display. *SCROLL_STEP is
9077 set to 1, under certain circumstances, if we want to scroll as
9078 if scroll-step were set to 1. See the code. */
9081 try_cursor_movement (window
, startp
, scroll_step
)
9083 struct text_pos startp
;
9086 struct window
*w
= XWINDOW (window
);
9087 struct frame
*f
= XFRAME (w
->frame
);
9090 /* Handle case where text has not changed, only point, and it has
9091 not moved off the frame. */
9092 if (/* Point may be in this window. */
9093 PT
>= CHARPOS (startp
)
9094 /* If we don't check this, we are called to move the cursor in a
9095 horizontally split window with a current matrix that doesn't
9097 && !windows_or_buffers_changed
9098 /* Selective display hasn't changed. */
9099 && !current_buffer
->clip_changed
9100 /* If force-mode-line-update was called, really redisplay;
9101 that's how redisplay is forced after e.g. changing
9102 buffer-invisibility-spec. */
9103 && NILP (w
->update_mode_line
)
9104 /* Can't use this case if highlighting a region. When a
9105 region exists, cursor movement has to do more than just
9107 && !(!NILP (Vtransient_mark_mode
)
9108 && !NILP (current_buffer
->mark_active
))
9109 && NILP (w
->region_showing
)
9110 && NILP (Vshow_trailing_whitespace
)
9111 /* Right after splitting windows, last_point may be nil. */
9112 && INTEGERP (w
->last_point
)
9113 /* This code is not used for mini-buffer for the sake of the case
9114 of redisplaying to replace an echo area message; since in
9115 that case the mini-buffer contents per se are usually
9116 unchanged. This code is of no real use in the mini-buffer
9117 since the handling of this_line_start_pos, etc., in redisplay
9118 handles the same cases. */
9119 && !EQ (window
, minibuf_window
)
9120 /* When splitting windows or for new windows, it happens that
9121 redisplay is called with a nil window_end_vpos or one being
9122 larger than the window. This should really be fixed in
9123 window.c. I don't have this on my list, now, so we do
9124 approximately the same as the old redisplay code. --gerd. */
9125 && INTEGERP (w
->window_end_vpos
)
9126 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
9127 && (FRAME_WINDOW_P (f
)
9128 || !MARKERP (Voverlay_arrow_position
)
9129 || current_buffer
!= XMARKER (Voverlay_arrow_position
)->buffer
))
9131 int this_scroll_margin
;
9132 struct glyph_row
*row
;
9135 debug_method_add (w
, "cursor movement");
9138 /* Scroll if point within this distance from the top or bottom
9139 of the window. This is a pixel value. */
9140 this_scroll_margin
= max (0, scroll_margin
);
9141 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
9142 this_scroll_margin
*= CANON_Y_UNIT (f
);
9144 /* Start with the row the cursor was displayed during the last
9145 not paused redisplay. Give up if that row is not valid. */
9146 if (w
->last_cursor
.vpos
< 0
9147 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
9151 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
9152 if (row
->mode_line_p
)
9154 if (!row
->enabled_p
)
9161 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
9164 if (PT
> XFASTINT (w
->last_point
))
9166 /* Point has moved forward. */
9167 while (MATRIX_ROW_END_CHARPOS (row
) < PT
9168 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
9170 xassert (row
->enabled_p
);
9174 /* The end position of a row equals the start position
9175 of the next row. If PT is there, we would rather
9176 display it in the next line. */
9177 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
9178 && MATRIX_ROW_END_CHARPOS (row
) == PT
9179 && !cursor_row_p (w
, row
))
9182 /* If within the scroll margin, scroll. Note that
9183 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
9184 the next line would be drawn, and that
9185 this_scroll_margin can be zero. */
9186 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
9187 || PT
> MATRIX_ROW_END_CHARPOS (row
)
9188 /* Line is completely visible last line in window
9189 and PT is to be set in the next line. */
9190 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
9191 && PT
== MATRIX_ROW_END_CHARPOS (row
)
9192 && !row
->ends_at_zv_p
9193 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
9196 else if (PT
< XFASTINT (w
->last_point
))
9198 /* Cursor has to be moved backward. Note that PT >=
9199 CHARPOS (startp) because of the outer
9201 while (!row
->mode_line_p
9202 && (MATRIX_ROW_START_CHARPOS (row
) > PT
9203 || (MATRIX_ROW_START_CHARPOS (row
) == PT
9204 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
9205 && (row
->y
> this_scroll_margin
9206 || CHARPOS (startp
) == BEGV
))
9208 xassert (row
->enabled_p
);
9212 /* Consider the following case: Window starts at BEGV,
9213 there is invisible, intangible text at BEGV, so that
9214 display starts at some point START > BEGV. It can
9215 happen that we are called with PT somewhere between
9216 BEGV and START. Try to handle that case. */
9217 if (row
< w
->current_matrix
->rows
9218 || row
->mode_line_p
)
9220 row
= w
->current_matrix
->rows
;
9221 if (row
->mode_line_p
)
9225 /* Due to newlines in overlay strings, we may have to
9226 skip forward over overlay strings. */
9227 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
9228 && MATRIX_ROW_END_CHARPOS (row
) == PT
9229 && !cursor_row_p (w
, row
))
9232 /* If within the scroll margin, scroll. */
9233 if (row
->y
< this_scroll_margin
9234 && CHARPOS (startp
) != BEGV
)
9238 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
9239 || PT
> MATRIX_ROW_END_CHARPOS (row
))
9241 /* if PT is not in the glyph row, give up. */
9244 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
9246 /* If we end up in a partially visible line, let's make it
9247 fully visible, except when it's taller than the window,
9248 in which case we can't do much about it. */
9249 if (row
->height
> window_box_height (w
))
9256 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
9257 try_window (window
, startp
);
9258 make_cursor_line_fully_visible (w
);
9266 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
9276 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
9277 selected_window is redisplayed. */
9280 redisplay_window (window
, just_this_one_p
)
9282 int just_this_one_p
;
9284 struct window
*w
= XWINDOW (window
);
9285 struct frame
*f
= XFRAME (w
->frame
);
9286 struct buffer
*buffer
= XBUFFER (w
->buffer
);
9287 struct buffer
*old
= current_buffer
;
9288 struct text_pos lpoint
, opoint
, startp
;
9289 int update_mode_line
;
9292 /* Record it now because it's overwritten. */
9293 int current_matrix_up_to_date_p
= 0;
9294 int temp_scroll_step
= 0;
9295 int count
= BINDING_STACK_SIZE ();
9298 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
9301 /* W must be a leaf window here. */
9302 xassert (!NILP (w
->buffer
));
9304 *w
->desired_matrix
->method
= 0;
9307 specbind (Qinhibit_point_motion_hooks
, Qt
);
9309 reconsider_clip_changes (w
, buffer
);
9311 /* Has the mode line to be updated? */
9312 update_mode_line
= (!NILP (w
->update_mode_line
)
9313 || update_mode_lines
9314 || buffer
->clip_changed
);
9316 if (MINI_WINDOW_P (w
))
9318 if (w
== XWINDOW (echo_area_window
)
9319 && !NILP (echo_area_buffer
[0]))
9321 if (update_mode_line
)
9322 /* We may have to update a tty frame's menu bar or a
9323 tool-bar. Example `M-x C-h C-h C-g'. */
9324 goto finish_menu_bars
;
9326 /* We've already displayed the echo area glyphs in this window. */
9327 goto finish_scroll_bars
;
9329 else if (w
!= XWINDOW (minibuf_window
))
9331 /* W is a mini-buffer window, but it's not the currently
9332 active one, so clear it. */
9333 int yb
= window_text_bottom_y (w
);
9334 struct glyph_row
*row
;
9337 for (y
= 0, row
= w
->desired_matrix
->rows
;
9339 y
+= row
->height
, ++row
)
9340 blank_row (w
, row
, y
);
9341 goto finish_scroll_bars
;
9345 /* Otherwise set up data on this window; select its buffer and point
9347 /* Really select the buffer, for the sake of buffer-local
9349 set_buffer_internal_1 (XBUFFER (w
->buffer
));
9350 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
9352 current_matrix_up_to_date_p
9353 = (!NILP (w
->window_end_valid
)
9354 && !current_buffer
->clip_changed
9355 && XFASTINT (w
->last_modified
) >= MODIFF
9356 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
9358 /* When windows_or_buffers_changed is non-zero, we can't rely on
9359 the window end being valid, so set it to nil there. */
9360 if (windows_or_buffers_changed
)
9362 /* If window starts on a continuation line, maybe adjust the
9363 window start in case the window's width changed. */
9364 if (XMARKER (w
->start
)->buffer
== current_buffer
)
9365 compute_window_start_on_continuation_line (w
);
9367 w
->window_end_valid
= Qnil
;
9370 /* Some sanity checks. */
9371 CHECK_WINDOW_END (w
);
9372 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
9374 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
9377 /* If %c is in mode line, update it if needed. */
9378 if (!NILP (w
->column_number_displayed
)
9379 /* This alternative quickly identifies a common case
9380 where no change is needed. */
9381 && !(PT
== XFASTINT (w
->last_point
)
9382 && XFASTINT (w
->last_modified
) >= MODIFF
9383 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
9384 && XFASTINT (w
->column_number_displayed
) != current_column ())
9385 update_mode_line
= 1;
9387 /* Count number of windows showing the selected buffer. An indirect
9388 buffer counts as its base buffer. */
9389 if (!just_this_one_p
)
9391 struct buffer
*current_base
, *window_base
;
9392 current_base
= current_buffer
;
9393 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
9394 if (current_base
->base_buffer
)
9395 current_base
= current_base
->base_buffer
;
9396 if (window_base
->base_buffer
)
9397 window_base
= window_base
->base_buffer
;
9398 if (current_base
== window_base
)
9402 /* Point refers normally to the selected window. For any other
9403 window, set up appropriate value. */
9404 if (!EQ (window
, selected_window
))
9406 int new_pt
= XMARKER (w
->pointm
)->charpos
;
9407 int new_pt_byte
= marker_byte_position (w
->pointm
);
9411 new_pt_byte
= BEGV_BYTE
;
9412 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
9414 else if (new_pt
> (ZV
- 1))
9417 new_pt_byte
= ZV_BYTE
;
9418 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
9421 /* We don't use SET_PT so that the point-motion hooks don't run. */
9422 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
9425 /* If any of the character widths specified in the display table
9426 have changed, invalidate the width run cache. It's true that
9427 this may be a bit late to catch such changes, but the rest of
9428 redisplay goes (non-fatally) haywire when the display table is
9429 changed, so why should we worry about doing any better? */
9430 if (current_buffer
->width_run_cache
)
9432 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
9434 if (! disptab_matches_widthtab (disptab
,
9435 XVECTOR (current_buffer
->width_table
)))
9437 invalidate_region_cache (current_buffer
,
9438 current_buffer
->width_run_cache
,
9440 recompute_width_table (current_buffer
, disptab
);
9444 /* If window-start is screwed up, choose a new one. */
9445 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
9448 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
9450 /* If someone specified a new starting point but did not insist,
9451 check whether it can be used. */
9452 if (!NILP (w
->optional_new_start
)
9453 && CHARPOS (startp
) >= BEGV
9454 && CHARPOS (startp
) <= ZV
)
9456 w
->optional_new_start
= Qnil
;
9457 start_display (&it
, w
, startp
);
9458 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
9459 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
9460 if (IT_CHARPOS (it
) == PT
)
9461 w
->force_start
= Qt
;
9464 /* Handle case where place to start displaying has been specified,
9465 unless the specified location is outside the accessible range. */
9466 if (!NILP (w
->force_start
)
9467 || w
->frozen_window_start_p
)
9469 w
->force_start
= Qnil
;
9471 w
->window_end_valid
= Qnil
;
9473 /* Forget any recorded base line for line number display. */
9474 if (!current_matrix_up_to_date_p
9475 || current_buffer
->clip_changed
)
9476 w
->base_line_number
= Qnil
;
9478 /* Redisplay the mode line. Select the buffer properly for that.
9479 Also, run the hook window-scroll-functions
9480 because we have scrolled. */
9481 /* Note, we do this after clearing force_start because
9482 if there's an error, it is better to forget about force_start
9483 than to get into an infinite loop calling the hook functions
9484 and having them get more errors. */
9485 if (!update_mode_line
9486 || ! NILP (Vwindow_scroll_functions
))
9488 update_mode_line
= 1;
9489 w
->update_mode_line
= Qt
;
9490 startp
= run_window_scroll_functions (window
, startp
);
9493 XSETFASTINT (w
->last_modified
, 0);
9494 XSETFASTINT (w
->last_overlay_modified
, 0);
9495 if (CHARPOS (startp
) < BEGV
)
9496 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
9497 else if (CHARPOS (startp
) > ZV
)
9498 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
9500 /* Redisplay, then check if cursor has been set during the
9501 redisplay. Give up if new fonts were loaded. */
9502 if (!try_window (window
, startp
))
9504 w
->force_start
= Qt
;
9505 clear_glyph_matrix (w
->desired_matrix
);
9506 goto restore_buffers
;
9509 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
9511 /* If point does not appear, try to move point so it does
9512 appear. The desired matrix has been built above, so we
9515 struct glyph_row
*row
;
9517 window_height
= window_box_height (w
) / 2;
9518 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
9519 while (MATRIX_ROW_BOTTOM_Y (row
) < window_height
)
9522 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
9523 MATRIX_ROW_START_BYTEPOS (row
));
9525 if (w
!= XWINDOW (selected_window
))
9526 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
9527 else if (current_buffer
== old
)
9528 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
9530 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
9532 /* If we are highlighting the region, then we just changed
9533 the region, so redisplay to show it. */
9534 if (!NILP (Vtransient_mark_mode
)
9535 && !NILP (current_buffer
->mark_active
))
9537 clear_glyph_matrix (w
->desired_matrix
);
9538 if (!try_window (window
, startp
))
9539 goto restore_buffers
;
9543 make_cursor_line_fully_visible (w
);
9545 debug_method_add (w
, "forced window start");
9550 /* Handle case where text has not changed, only point, and it has
9551 not moved off the frame. */
9552 if (current_matrix_up_to_date_p
9553 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
9561 /* If current starting point was originally the beginning of a line
9562 but no longer is, find a new starting point. */
9563 else if (!NILP (w
->start_at_line_beg
)
9564 && !(CHARPOS (startp
) <= BEGV
9565 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
9568 debug_method_add (w
, "recenter 1");
9573 /* Try scrolling with try_window_id. */
9574 else if (/* Windows and buffers haven't changed. */
9575 !windows_or_buffers_changed
9576 /* Window must be either use window-based redisplay or
9578 && (FRAME_WINDOW_P (f
)
9579 || (line_ins_del_ok
&& WINDOW_FULL_WIDTH_P (w
)))
9580 && !MINI_WINDOW_P (w
)
9581 /* Point is not known NOT to appear in window. */
9582 && PT
>= CHARPOS (startp
)
9583 && XFASTINT (w
->last_modified
)
9584 /* Window is not hscrolled. */
9585 && XFASTINT (w
->hscroll
) == 0
9586 /* Selective display has not changed. */
9587 && !current_buffer
->clip_changed
9588 /* Current matrix is up to date. */
9589 && !NILP (w
->window_end_valid
)
9590 /* Can't use this case if highlighting a region because
9591 a cursor movement will do more than just set the cursor. */
9592 && !(!NILP (Vtransient_mark_mode
)
9593 && !NILP (current_buffer
->mark_active
))
9594 && NILP (w
->region_showing
)
9595 && NILP (Vshow_trailing_whitespace
)
9596 /* Overlay arrow position and string not changed. */
9597 && EQ (last_arrow_position
, COERCE_MARKER (Voverlay_arrow_position
))
9598 && EQ (last_arrow_string
, Voverlay_arrow_string
)
9599 /* Value is > 0 if update has been done, it is -1 if we
9600 know that the same window start will not work. It is 0
9601 if unsuccessful for some other reason. */
9602 && (tem
= try_window_id (w
)) != 0)
9605 debug_method_add (w
, "try_window_id %d", tem
);
9608 if (fonts_changed_p
)
9609 goto restore_buffers
;
9613 /* Otherwise try_window_id has returned -1 which means that we
9614 don't want the alternative below this comment to execute. */
9616 else if (CHARPOS (startp
) >= BEGV
9617 && CHARPOS (startp
) <= ZV
9618 && PT
>= CHARPOS (startp
)
9619 && (CHARPOS (startp
) < ZV
9620 /* Avoid starting at end of buffer. */
9621 || CHARPOS (startp
) == BEGV
9622 || (XFASTINT (w
->last_modified
) >= MODIFF
9623 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
9626 debug_method_add (w
, "same window start");
9629 /* Try to redisplay starting at same place as before.
9630 If point has not moved off frame, accept the results. */
9631 if (!current_matrix_up_to_date_p
9632 /* Don't use try_window_reusing_current_matrix in this case
9633 because a window scroll function can have changed the
9635 || !NILP (Vwindow_scroll_functions
)
9636 || MINI_WINDOW_P (w
)
9637 || !try_window_reusing_current_matrix (w
))
9639 IF_DEBUG (debug_method_add (w
, "1"));
9640 try_window (window
, startp
);
9643 if (fonts_changed_p
)
9644 goto restore_buffers
;
9646 if (w
->cursor
.vpos
>= 0)
9648 if (!just_this_one_p
9649 || current_buffer
->clip_changed
9650 || BEG_UNCHANGED
< CHARPOS (startp
))
9651 /* Forget any recorded base line for line number display. */
9652 w
->base_line_number
= Qnil
;
9654 make_cursor_line_fully_visible (w
);
9658 clear_glyph_matrix (w
->desired_matrix
);
9663 XSETFASTINT (w
->last_modified
, 0);
9664 XSETFASTINT (w
->last_overlay_modified
, 0);
9666 /* Redisplay the mode line. Select the buffer properly for that. */
9667 if (!update_mode_line
)
9669 update_mode_line
= 1;
9670 w
->update_mode_line
= Qt
;
9673 /* Try to scroll by specified few lines. */
9674 if ((scroll_conservatively
9677 || NUMBERP (current_buffer
->scroll_up_aggressively
)
9678 || NUMBERP (current_buffer
->scroll_down_aggressively
))
9679 && !current_buffer
->clip_changed
9680 && CHARPOS (startp
) >= BEGV
9681 && CHARPOS (startp
) <= ZV
)
9683 /* The function returns -1 if new fonts were loaded, 1 if
9684 successful, 0 if not successful. */
9685 int rc
= try_scrolling (window
, just_this_one_p
,
9686 scroll_conservatively
,
9692 goto restore_buffers
;
9695 /* Finally, just choose place to start which centers point */
9700 debug_method_add (w
, "recenter");
9703 /* w->vscroll = 0; */
9705 /* Forget any previously recorded base line for line number display. */
9706 if (!current_matrix_up_to_date_p
9707 || current_buffer
->clip_changed
)
9708 w
->base_line_number
= Qnil
;
9710 /* Move backward half the height of the window. */
9711 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
9712 it
.current_y
= it
.last_visible_y
;
9713 move_it_vertically_backward (&it
, it
.last_visible_y
/ 2);
9714 xassert (IT_CHARPOS (it
) >= BEGV
);
9716 /* The function move_it_vertically_backward may move over more
9717 than the specified y-distance. If it->w is small, e.g. a
9718 mini-buffer window, we may end up in front of the window's
9719 display area. Start displaying at the start of the line
9720 containing PT in this case. */
9721 if (it
.current_y
<= 0)
9723 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
9724 move_it_vertically (&it
, 0);
9725 xassert (IT_CHARPOS (it
) <= PT
);
9729 it
.current_x
= it
.hpos
= 0;
9731 /* Set startp here explicitly in case that helps avoid an infinite loop
9732 in case the window-scroll-functions functions get errors. */
9733 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
9735 /* Run scroll hooks. */
9736 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
9738 /* Redisplay the window. */
9739 if (!current_matrix_up_to_date_p
9740 || windows_or_buffers_changed
9741 /* Don't use try_window_reusing_current_matrix in this case
9742 because it can have changed the buffer. */
9743 || !NILP (Vwindow_scroll_functions
)
9745 || MINI_WINDOW_P (w
)
9746 || !try_window_reusing_current_matrix (w
))
9747 try_window (window
, startp
);
9749 /* If new fonts have been loaded (due to fontsets), give up. We
9750 have to start a new redisplay since we need to re-adjust glyph
9752 if (fonts_changed_p
)
9753 goto restore_buffers
;
9755 /* If cursor did not appear assume that the middle of the window is
9756 in the first line of the window. Do it again with the next line.
9757 (Imagine a window of height 100, displaying two lines of height
9758 60. Moving back 50 from it->last_visible_y will end in the first
9760 if (w
->cursor
.vpos
< 0)
9762 if (!NILP (w
->window_end_valid
)
9763 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
9765 clear_glyph_matrix (w
->desired_matrix
);
9766 move_it_by_lines (&it
, 1, 0);
9767 try_window (window
, it
.current
.pos
);
9769 else if (PT
< IT_CHARPOS (it
))
9771 clear_glyph_matrix (w
->desired_matrix
);
9772 move_it_by_lines (&it
, -1, 0);
9773 try_window (window
, it
.current
.pos
);
9777 /* Not much we can do about it. */
9781 /* Consider the following case: Window starts at BEGV, there is
9782 invisible, intangible text at BEGV, so that display starts at
9783 some point START > BEGV. It can happen that we are called with
9784 PT somewhere between BEGV and START. Try to handle that case. */
9785 if (w
->cursor
.vpos
< 0)
9787 struct glyph_row
*row
= w
->current_matrix
->rows
;
9788 if (row
->mode_line_p
)
9790 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
9793 make_cursor_line_fully_visible (w
);
9797 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
9798 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
9799 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
9802 /* Display the mode line, if we must. */
9803 if ((update_mode_line
9804 /* If window not full width, must redo its mode line
9805 if (a) the window to its side is being redone and
9806 (b) we do a frame-based redisplay. This is a consequence
9807 of how inverted lines are drawn in frame-based redisplay. */
9808 || (!just_this_one_p
9809 && !FRAME_WINDOW_P (f
)
9810 && !WINDOW_FULL_WIDTH_P (w
))
9811 /* Line number to display. */
9812 || INTEGERP (w
->base_line_pos
)
9813 /* Column number is displayed and different from the one displayed. */
9814 || (!NILP (w
->column_number_displayed
)
9815 && XFASTINT (w
->column_number_displayed
) != current_column ()))
9816 /* This means that the window has a mode line. */
9817 && (WINDOW_WANTS_MODELINE_P (w
)
9818 || WINDOW_WANTS_HEADER_LINE_P (w
)))
9820 Lisp_Object old_selected_frame
;
9822 old_selected_frame
= selected_frame
;
9824 XSETFRAME (selected_frame
, f
);
9825 display_mode_lines (w
);
9826 selected_frame
= old_selected_frame
;
9828 /* If mode line height has changed, arrange for a thorough
9829 immediate redisplay using the correct mode line height. */
9830 if (WINDOW_WANTS_MODELINE_P (w
)
9831 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
9833 fonts_changed_p
= 1;
9834 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
9835 = DESIRED_MODE_LINE_HEIGHT (w
);
9838 /* If top line height has changed, arrange for a thorough
9839 immediate redisplay using the correct mode line height. */
9840 if (WINDOW_WANTS_HEADER_LINE_P (w
)
9841 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
9843 fonts_changed_p
= 1;
9844 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
9845 = DESIRED_HEADER_LINE_HEIGHT (w
);
9848 if (fonts_changed_p
)
9849 goto restore_buffers
;
9852 if (!line_number_displayed
9853 && !BUFFERP (w
->base_line_pos
))
9855 w
->base_line_pos
= Qnil
;
9856 w
->base_line_number
= Qnil
;
9861 /* When we reach a frame's selected window, redo the frame's menu bar. */
9862 if (update_mode_line
9863 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
9865 int redisplay_menu_p
= 0;
9867 if (FRAME_WINDOW_P (f
))
9869 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (macintosh)
9870 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
9872 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
9876 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
9878 if (redisplay_menu_p
)
9879 display_menu_bar (w
);
9881 #ifdef HAVE_WINDOW_SYSTEM
9882 if (WINDOWP (f
->tool_bar_window
)
9883 && (FRAME_TOOL_BAR_LINES (f
) > 0
9884 || auto_resize_tool_bars_p
))
9885 redisplay_tool_bar (f
);
9891 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9893 int start
, end
, whole
;
9895 /* Calculate the start and end positions for the current window.
9896 At some point, it would be nice to choose between scrollbars
9897 which reflect the whole buffer size, with special markers
9898 indicating narrowing, and scrollbars which reflect only the
9901 Note that mini-buffers sometimes aren't displaying any text. */
9902 if (!MINI_WINDOW_P (w
)
9903 || (w
== XWINDOW (minibuf_window
)
9904 && NILP (echo_area_buffer
[0])))
9907 start
= marker_position (w
->start
) - BEGV
;
9908 /* I don't think this is guaranteed to be right. For the
9909 moment, we'll pretend it is. */
9910 end
= (Z
- XFASTINT (w
->window_end_pos
)) - BEGV
;
9914 if (whole
< (end
- start
))
9915 whole
= end
- start
;
9918 start
= end
= whole
= 0;
9920 /* Indicate what this scroll bar ought to be displaying now. */
9921 (*set_vertical_scroll_bar_hook
) (w
, end
- start
, whole
, start
);
9923 /* Note that we actually used the scroll bar attached to this
9924 window, so it shouldn't be deleted at the end of redisplay. */
9925 (*redeem_scroll_bar_hook
) (w
);
9930 /* Restore current_buffer and value of point in it. */
9931 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
9932 set_buffer_internal_1 (old
);
9933 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
9935 unbind_to (count
, Qnil
);
9939 /* Build the complete desired matrix of WINDOW with a window start
9940 buffer position POS. Value is non-zero if successful. It is zero
9941 if fonts were loaded during redisplay which makes re-adjusting
9942 glyph matrices necessary. */
9945 try_window (window
, pos
)
9947 struct text_pos pos
;
9949 struct window
*w
= XWINDOW (window
);
9951 struct glyph_row
*last_text_row
= NULL
;
9953 /* Make POS the new window start. */
9954 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
9956 /* Mark cursor position as unknown. No overlay arrow seen. */
9957 w
->cursor
.vpos
= -1;
9958 overlay_arrow_seen
= 0;
9960 /* Initialize iterator and info to start at POS. */
9961 start_display (&it
, w
, pos
);
9963 /* Display all lines of W. */
9964 while (it
.current_y
< it
.last_visible_y
)
9966 if (display_line (&it
))
9967 last_text_row
= it
.glyph_row
- 1;
9968 if (fonts_changed_p
)
9972 /* If bottom moved off end of frame, change mode line percentage. */
9973 if (XFASTINT (w
->window_end_pos
) <= 0
9974 && Z
!= IT_CHARPOS (it
))
9975 w
->update_mode_line
= Qt
;
9977 /* Set window_end_pos to the offset of the last character displayed
9978 on the window from the end of current_buffer. Set
9979 window_end_vpos to its row number. */
9982 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
9983 w
->window_end_bytepos
9984 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
9985 XSETFASTINT (w
->window_end_pos
,
9986 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
9987 XSETFASTINT (w
->window_end_vpos
,
9988 MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
9989 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
9994 w
->window_end_bytepos
= 0;
9995 XSETFASTINT (w
->window_end_pos
, 0);
9996 XSETFASTINT (w
->window_end_vpos
, 0);
9999 /* But that is not valid info until redisplay finishes. */
10000 w
->window_end_valid
= Qnil
;
10006 /************************************************************************
10007 Window redisplay reusing current matrix when buffer has not changed
10008 ************************************************************************/
10010 /* Try redisplay of window W showing an unchanged buffer with a
10011 different window start than the last time it was displayed by
10012 reusing its current matrix. Value is non-zero if successful.
10013 W->start is the new window start. */
10016 try_window_reusing_current_matrix (w
)
10019 struct frame
*f
= XFRAME (w
->frame
);
10020 struct glyph_row
*row
, *bottom_row
;
10023 struct text_pos start
, new_start
;
10024 int nrows_scrolled
, i
;
10025 struct glyph_row
*last_text_row
;
10026 struct glyph_row
*last_reused_text_row
;
10027 struct glyph_row
*start_row
;
10028 int start_vpos
, min_y
, max_y
;
10030 if (/* This function doesn't handle terminal frames. */
10031 !FRAME_WINDOW_P (f
)
10032 /* Don't try to reuse the display if windows have been split
10034 || windows_or_buffers_changed
)
10037 /* Can't do this if region may have changed. */
10038 if ((!NILP (Vtransient_mark_mode
)
10039 && !NILP (current_buffer
->mark_active
))
10040 || !NILP (w
->region_showing
)
10041 || !NILP (Vshow_trailing_whitespace
))
10044 /* If top-line visibility has changed, give up. */
10045 if (WINDOW_WANTS_HEADER_LINE_P (w
)
10046 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
10049 /* Give up if old or new display is scrolled vertically. We could
10050 make this function handle this, but right now it doesn't. */
10051 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
10052 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
10055 /* The variable new_start now holds the new window start. The old
10056 start `start' can be determined from the current matrix. */
10057 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
10058 start
= start_row
->start
.pos
;
10059 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
10061 /* Clear the desired matrix for the display below. */
10062 clear_glyph_matrix (w
->desired_matrix
);
10064 if (CHARPOS (new_start
) <= CHARPOS (start
))
10068 IF_DEBUG (debug_method_add (w
, "twu1"));
10070 /* Display up to a row that can be reused. The variable
10071 last_text_row is set to the last row displayed that displays
10072 text. Note that it.vpos == 0 if or if not there is a
10073 header-line; it's not the same as the MATRIX_ROW_VPOS! */
10074 start_display (&it
, w
, new_start
);
10075 first_row_y
= it
.current_y
;
10076 w
->cursor
.vpos
= -1;
10077 last_text_row
= last_reused_text_row
= NULL
;
10079 while (it
.current_y
< it
.last_visible_y
10080 && IT_CHARPOS (it
) < CHARPOS (start
)
10081 && !fonts_changed_p
)
10082 if (display_line (&it
))
10083 last_text_row
= it
.glyph_row
- 1;
10085 /* A value of current_y < last_visible_y means that we stopped
10086 at the previous window start, which in turn means that we
10087 have at least one reusable row. */
10088 if (it
.current_y
< it
.last_visible_y
)
10090 /* IT.vpos always starts from 0; it counts text lines. */
10091 nrows_scrolled
= it
.vpos
;
10093 /* Find PT if not already found in the lines displayed. */
10094 if (w
->cursor
.vpos
< 0)
10096 int dy
= it
.current_y
- first_row_y
;
10098 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
10099 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
10101 if (PT
>= MATRIX_ROW_START_CHARPOS (row
)
10102 && PT
< MATRIX_ROW_END_CHARPOS (row
))
10104 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
10105 dy
, nrows_scrolled
);
10109 if (MATRIX_ROW_BOTTOM_Y (row
) + dy
>= it
.last_visible_y
)
10115 /* Give up if point was not found. This shouldn't
10116 happen often; not more often than with try_window
10118 if (w
->cursor
.vpos
< 0)
10120 clear_glyph_matrix (w
->desired_matrix
);
10125 /* Scroll the display. Do it before the current matrix is
10126 changed. The problem here is that update has not yet
10127 run, i.e. part of the current matrix is not up to date.
10128 scroll_run_hook will clear the cursor, and use the
10129 current matrix to get the height of the row the cursor is
10131 run
.current_y
= first_row_y
;
10132 run
.desired_y
= it
.current_y
;
10133 run
.height
= it
.last_visible_y
- it
.current_y
;
10135 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
10138 rif
->update_window_begin_hook (w
);
10139 rif
->clear_mouse_face (w
);
10140 rif
->scroll_run_hook (w
, &run
);
10141 rif
->update_window_end_hook (w
, 0, 0);
10145 /* Shift current matrix down by nrows_scrolled lines. */
10146 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
10147 rotate_matrix (w
->current_matrix
,
10149 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
10152 /* Disable lines not reused. */
10153 for (i
= 0; i
< it
.vpos
; ++i
)
10154 (start_row
+ i
)->enabled_p
= 0;
10156 /* Re-compute Y positions. */
10157 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
10158 max_y
= it
.last_visible_y
;
10159 for (row
= start_row
+ nrows_scrolled
;
10163 row
->y
= it
.current_y
;
10165 if (row
->y
< min_y
)
10166 row
->visible_height
= row
->height
- (min_y
- row
->y
);
10167 else if (row
->y
+ row
->height
> max_y
)
10168 row
->visible_height
10169 = row
->height
- (row
->y
+ row
->height
- max_y
);
10171 row
->visible_height
= row
->height
;
10173 it
.current_y
+= row
->height
;
10175 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
10176 last_reused_text_row
= row
;
10177 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
10182 /* Update window_end_pos etc.; last_reused_text_row is the last
10183 reused row from the current matrix containing text, if any.
10184 The value of last_text_row is the last displayed line
10185 containing text. */
10186 if (last_reused_text_row
)
10188 w
->window_end_bytepos
10189 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
10190 XSETFASTINT (w
->window_end_pos
,
10191 Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
10192 XSETFASTINT (w
->window_end_vpos
,
10193 MATRIX_ROW_VPOS (last_reused_text_row
,
10194 w
->current_matrix
));
10196 else if (last_text_row
)
10198 w
->window_end_bytepos
10199 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
10200 XSETFASTINT (w
->window_end_pos
,
10201 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
10202 XSETFASTINT (w
->window_end_vpos
,
10203 MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
10207 /* This window must be completely empty. */
10208 w
->window_end_bytepos
= 0;
10209 XSETFASTINT (w
->window_end_pos
, 0);
10210 XSETFASTINT (w
->window_end_vpos
, 0);
10212 w
->window_end_valid
= Qnil
;
10214 /* Update hint: don't try scrolling again in update_window. */
10215 w
->desired_matrix
->no_scrolling_p
= 1;
10218 debug_method_add (w
, "try_window_reusing_current_matrix 1");
10222 else if (CHARPOS (new_start
) > CHARPOS (start
))
10224 struct glyph_row
*pt_row
, *row
;
10225 struct glyph_row
*first_reusable_row
;
10226 struct glyph_row
*first_row_to_display
;
10228 int yb
= window_text_bottom_y (w
);
10230 IF_DEBUG (debug_method_add (w
, "twu2"));
10232 /* Find the row starting at new_start, if there is one. Don't
10233 reuse a partially visible line at the end. */
10234 first_reusable_row
= start_row
;
10235 while (first_reusable_row
->enabled_p
10236 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
10237 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
10238 < CHARPOS (new_start
)))
10239 ++first_reusable_row
;
10241 /* Give up if there is no row to reuse. */
10242 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
10243 || !first_reusable_row
->enabled_p
10244 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
10245 != CHARPOS (new_start
)))
10248 /* We can reuse fully visible rows beginning with
10249 first_reusable_row to the end of the window. Set
10250 first_row_to_display to the first row that cannot be reused.
10251 Set pt_row to the row containing point, if there is any. */
10252 first_row_to_display
= first_reusable_row
;
10254 while (MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
)
10256 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
10257 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
10258 pt_row
= first_row_to_display
;
10260 ++first_row_to_display
;
10263 /* Start displaying at the start of first_row_to_display. */
10264 xassert (first_row_to_display
->y
< yb
);
10265 init_to_row_start (&it
, w
, first_row_to_display
);
10266 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
10268 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
10270 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
10271 + WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
));
10273 /* Display lines beginning with first_row_to_display in the
10274 desired matrix. Set last_text_row to the last row displayed
10275 that displays text. */
10276 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
10277 if (pt_row
== NULL
)
10278 w
->cursor
.vpos
= -1;
10279 last_text_row
= NULL
;
10280 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
10281 if (display_line (&it
))
10282 last_text_row
= it
.glyph_row
- 1;
10284 /* Give up If point isn't in a row displayed or reused. */
10285 if (w
->cursor
.vpos
< 0)
10287 clear_glyph_matrix (w
->desired_matrix
);
10291 /* If point is in a reused row, adjust y and vpos of the cursor
10295 w
->cursor
.vpos
-= MATRIX_ROW_VPOS (first_reusable_row
,
10296 w
->current_matrix
);
10297 w
->cursor
.y
-= first_reusable_row
->y
;
10300 /* Scroll the display. */
10301 run
.current_y
= first_reusable_row
->y
;
10302 run
.desired_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
10303 run
.height
= it
.last_visible_y
- run
.current_y
;
10304 dy
= run
.current_y
- run
.desired_y
;
10308 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10310 rif
->update_window_begin_hook (w
);
10311 rif
->clear_mouse_face (w
);
10312 rif
->scroll_run_hook (w
, &run
);
10313 rif
->update_window_end_hook (w
, 0, 0);
10317 /* Adjust Y positions of reused rows. */
10318 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
10319 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
10320 max_y
= it
.last_visible_y
;
10321 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
10324 if (row
->y
< min_y
)
10325 row
->visible_height
= row
->height
- (min_y
- row
->y
);
10326 else if (row
->y
+ row
->height
> max_y
)
10327 row
->visible_height
10328 = row
->height
- (row
->y
+ row
->height
- max_y
);
10330 row
->visible_height
= row
->height
;
10333 /* Disable rows not reused. */
10334 while (row
< bottom_row
)
10336 row
->enabled_p
= 0;
10340 /* Scroll the current matrix. */
10341 xassert (nrows_scrolled
> 0);
10342 rotate_matrix (w
->current_matrix
,
10344 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
10347 /* Adjust window end. A null value of last_text_row means that
10348 the window end is in reused rows which in turn means that
10349 only its vpos can have changed. */
10352 w
->window_end_bytepos
10353 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
10354 XSETFASTINT (w
->window_end_pos
,
10355 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
10356 XSETFASTINT (w
->window_end_vpos
,
10357 MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
10361 XSETFASTINT (w
->window_end_vpos
,
10362 XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
10365 w
->window_end_valid
= Qnil
;
10366 w
->desired_matrix
->no_scrolling_p
= 1;
10369 debug_method_add (w
, "try_window_reusing_current_matrix 2");
10379 /************************************************************************
10380 Window redisplay reusing current matrix when buffer has changed
10381 ************************************************************************/
10383 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
10384 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
10386 static struct glyph_row
*
10387 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
10388 struct glyph_row
*));
10391 /* Return the last row in MATRIX displaying text. If row START is
10392 non-null, start searching with that row. IT gives the dimensions
10393 of the display. Value is null if matrix is empty; otherwise it is
10394 a pointer to the row found. */
10396 static struct glyph_row
*
10397 find_last_row_displaying_text (matrix
, it
, start
)
10398 struct glyph_matrix
*matrix
;
10400 struct glyph_row
*start
;
10402 struct glyph_row
*row
, *row_found
;
10404 /* Set row_found to the last row in IT->w's current matrix
10405 displaying text. The loop looks funny but think of partially
10408 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
10409 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
10411 xassert (row
->enabled_p
);
10413 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
10422 /* Return the last row in the current matrix of W that is not affected
10423 by changes at the start of current_buffer that occurred since the
10424 last time W was redisplayed. Value is null if no such row exists.
10426 The global variable beg_unchanged has to contain the number of
10427 bytes unchanged at the start of current_buffer. BEG +
10428 beg_unchanged is the buffer position of the first changed byte in
10429 current_buffer. Characters at positions < BEG + beg_unchanged are
10430 at the same buffer positions as they were when the current matrix
10433 static struct glyph_row
*
10434 find_last_unchanged_at_beg_row (w
)
10437 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
10438 struct glyph_row
*row
;
10439 struct glyph_row
*row_found
= NULL
;
10440 int yb
= window_text_bottom_y (w
);
10442 /* Find the last row displaying unchanged text. */
10443 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
10444 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
10445 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
10447 if (/* If row ends before first_changed_pos, it is unchanged,
10448 except in some case. */
10449 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
10450 /* When row ends in ZV and we write at ZV it is not
10452 && !row
->ends_at_zv_p
10453 /* When first_changed_pos is the end of a continued line,
10454 row is not unchanged because it may be no longer
10456 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
10457 && row
->continued_p
))
10460 /* Stop if last visible row. */
10461 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
10471 /* Find the first glyph row in the current matrix of W that is not
10472 affected by changes at the end of current_buffer since the last
10473 time the window was redisplayed. Return in *DELTA the number of
10474 chars by which buffer positions in unchanged text at the end of
10475 current_buffer must be adjusted. Return in *DELTA_BYTES the
10476 corresponding number of bytes. Value is null if no such row
10477 exists, i.e. all rows are affected by changes. */
10479 static struct glyph_row
*
10480 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
10482 int *delta
, *delta_bytes
;
10484 struct glyph_row
*row
;
10485 struct glyph_row
*row_found
= NULL
;
10487 *delta
= *delta_bytes
= 0;
10489 /* Display must not have been paused, otherwise the current matrix
10490 is not up to date. */
10491 if (NILP (w
->window_end_valid
))
10494 /* A value of window_end_pos >= END_UNCHANGED means that the window
10495 end is in the range of changed text. If so, there is no
10496 unchanged row at the end of W's current matrix. */
10497 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
10500 /* Set row to the last row in W's current matrix displaying text. */
10501 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
10503 /* If matrix is entirely empty, no unchanged row exists. */
10504 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
10506 /* The value of row is the last glyph row in the matrix having a
10507 meaningful buffer position in it. The end position of row
10508 corresponds to window_end_pos. This allows us to translate
10509 buffer positions in the current matrix to current buffer
10510 positions for characters not in changed text. */
10511 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
10512 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
10513 int last_unchanged_pos
, last_unchanged_pos_old
;
10514 struct glyph_row
*first_text_row
10515 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
10517 *delta
= Z
- Z_old
;
10518 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
10520 /* Set last_unchanged_pos to the buffer position of the last
10521 character in the buffer that has not been changed. Z is the
10522 index + 1 of the last byte in current_buffer, i.e. by
10523 subtracting end_unchanged we get the index of the last
10524 unchanged character, and we have to add BEG to get its buffer
10526 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
10527 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
10529 /* Search backward from ROW for a row displaying a line that
10530 starts at a minimum position >= last_unchanged_pos_old. */
10531 for (; row
> first_text_row
; --row
)
10533 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
10536 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
10541 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
10548 /* Make sure that glyph rows in the current matrix of window W
10549 reference the same glyph memory as corresponding rows in the
10550 frame's frame matrix. This function is called after scrolling W's
10551 current matrix on a terminal frame in try_window_id and
10552 try_window_reusing_current_matrix. */
10555 sync_frame_with_window_matrix_rows (w
)
10558 struct frame
*f
= XFRAME (w
->frame
);
10559 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
10561 /* Preconditions: W must be a leaf window and full-width. Its frame
10562 must have a frame matrix. */
10563 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
10564 xassert (WINDOW_FULL_WIDTH_P (w
));
10565 xassert (!FRAME_WINDOW_P (f
));
10567 /* If W is a full-width window, glyph pointers in W's current matrix
10568 have, by definition, to be the same as glyph pointers in the
10569 corresponding frame matrix. */
10570 window_row
= w
->current_matrix
->rows
;
10571 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
10572 frame_row
= f
->current_matrix
->rows
+ XFASTINT (w
->top
);
10573 while (window_row
< window_row_end
)
10577 for (area
= LEFT_MARGIN_AREA
; area
<= LAST_AREA
; ++area
)
10578 frame_row
->glyphs
[area
] = window_row
->glyphs
[area
];
10580 /* Disable frame rows whose corresponding window rows have
10581 been disabled in try_window_id. */
10582 if (!window_row
->enabled_p
)
10583 frame_row
->enabled_p
= 0;
10585 ++window_row
, ++frame_row
;
10590 /* Find the glyph row in window W containing CHARPOS. Consider all
10591 rows between START and END (not inclusive). END null means search
10592 all rows to the end of the display area of W. Value is the row
10593 containing CHARPOS or null. */
10595 static struct glyph_row
*
10596 row_containing_pos (w
, charpos
, start
, end
)
10599 struct glyph_row
*start
, *end
;
10601 struct glyph_row
*row
= start
;
10604 /* If we happen to start on a header-line, skip that. */
10605 if (row
->mode_line_p
)
10608 if ((end
&& row
>= end
) || !row
->enabled_p
)
10611 last_y
= window_text_bottom_y (w
);
10613 while ((end
== NULL
|| row
< end
)
10614 && (MATRIX_ROW_END_CHARPOS (row
) < charpos
10615 /* The end position of a row equals the start
10616 position of the next row. If CHARPOS is there, we
10617 would rather display it in the next line, except
10618 when this line ends in ZV. */
10619 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
10620 && (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)
10621 || !row
->ends_at_zv_p
)))
10622 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
10625 /* Give up if CHARPOS not found. */
10626 if ((end
&& row
>= end
)
10627 || charpos
< MATRIX_ROW_START_CHARPOS (row
)
10628 || charpos
> MATRIX_ROW_END_CHARPOS (row
))
10635 /* Try to redisplay window W by reusing its existing display. W's
10636 current matrix must be up to date when this function is called,
10637 i.e. window_end_valid must not be nil.
10641 1 if display has been updated
10642 0 if otherwise unsuccessful
10643 -1 if redisplay with same window start is known not to succeed
10645 The following steps are performed:
10647 1. Find the last row in the current matrix of W that is not
10648 affected by changes at the start of current_buffer. If no such row
10651 2. Find the first row in W's current matrix that is not affected by
10652 changes at the end of current_buffer. Maybe there is no such row.
10654 3. Display lines beginning with the row + 1 found in step 1 to the
10655 row found in step 2 or, if step 2 didn't find a row, to the end of
10658 4. If cursor is not known to appear on the window, give up.
10660 5. If display stopped at the row found in step 2, scroll the
10661 display and current matrix as needed.
10663 6. Maybe display some lines at the end of W, if we must. This can
10664 happen under various circumstances, like a partially visible line
10665 becoming fully visible, or because newly displayed lines are displayed
10666 in smaller font sizes.
10668 7. Update W's window end information. */
10670 /* Check that window end is what we expect it to be. */
10676 struct frame
*f
= XFRAME (w
->frame
);
10677 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
10678 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
10679 struct glyph_row
*last_unchanged_at_beg_row
;
10680 struct glyph_row
*first_unchanged_at_end_row
;
10681 struct glyph_row
*row
;
10682 struct glyph_row
*bottom_row
;
10685 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
10686 struct text_pos start_pos
;
10688 int first_unchanged_at_end_vpos
= 0;
10689 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
10690 struct text_pos start
;
10692 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
10694 /* Check pre-conditions. Window end must be valid, otherwise
10695 the current matrix would not be up to date. */
10696 xassert (!NILP (w
->window_end_valid
));
10697 xassert (FRAME_WINDOW_P (XFRAME (w
->frame
))
10698 || (line_ins_del_ok
&& WINDOW_FULL_WIDTH_P (w
)));
10700 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
10701 only if buffer has really changed. The reason is that the gap is
10702 initially at Z for freshly visited files. The code below would
10703 set end_unchanged to 0 in that case. */
10704 if (MODIFF
> SAVE_MODIFF
10705 /* This seems to happen sometimes after saving a buffer. */
10706 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
10708 if (GPT
- BEG
< BEG_UNCHANGED
)
10709 BEG_UNCHANGED
= GPT
- BEG
;
10710 if (Z
- GPT
< END_UNCHANGED
)
10711 END_UNCHANGED
= Z
- GPT
;
10714 /* If window starts after a line end, and the last change is in
10715 front of that newline, then changes don't affect the display.
10716 This case happens with stealth-fontification. Note that although
10717 the display is unchanged, glyph positions in the matrix have to
10718 be adjusted, of course. */
10719 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
10720 if (CHARPOS (start
) > BEGV
10721 && Z
- END_UNCHANGED
< CHARPOS (start
) - 1
10722 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n'
10723 && PT
< MATRIX_ROW_END_CHARPOS (row
))
10725 struct glyph_row
*r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
10726 int delta
= CHARPOS (start
) - MATRIX_ROW_START_CHARPOS (r0
);
10730 struct glyph_row
*r1
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
10731 int delta_bytes
= BYTEPOS (start
) - MATRIX_ROW_START_BYTEPOS (r0
);
10733 increment_matrix_positions (w
->current_matrix
,
10734 MATRIX_ROW_VPOS (r0
, current_matrix
),
10735 MATRIX_ROW_VPOS (r1
, current_matrix
),
10736 delta
, delta_bytes
);
10739 #if 0 /* If changes are all in front of the window start, the
10740 distance of the last displayed glyph from Z hasn't
10743 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
10744 w
->window_end_bytepos
10745 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
10751 /* Return quickly if changes are all below what is displayed in the
10752 window, and if PT is in the window. */
10753 if (BEG_UNCHANGED
> MATRIX_ROW_END_CHARPOS (row
)
10754 && PT
< MATRIX_ROW_END_CHARPOS (row
))
10756 /* We have to update window end positions because the buffer's
10757 size has changed. */
10759 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
10760 w
->window_end_bytepos
10761 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
10763 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
10764 row
= row_containing_pos (w
, PT
, row
, NULL
);
10765 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
10769 /* Check that window start agrees with the start of the first glyph
10770 row in its current matrix. Check this after we know the window
10771 start is not in changed text, otherwise positions would not be
10773 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
10774 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
10777 /* Compute the position at which we have to start displaying new
10778 lines. Some of the lines at the top of the window might be
10779 reusable because they are not displaying changed text. Find the
10780 last row in W's current matrix not affected by changes at the
10781 start of current_buffer. Value is null if changes start in the
10782 first line of window. */
10783 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
10784 if (last_unchanged_at_beg_row
)
10786 /* Avoid starting to display in the moddle of a character, a TAB
10787 for instance. This is easier than to set up the iterator
10788 exactly, and it's not a frequent case, so the additional
10789 effort wouldn't really pay off. */
10790 while (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
10791 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
10792 --last_unchanged_at_beg_row
;
10794 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
10797 init_to_row_end (&it
, w
, last_unchanged_at_beg_row
);
10798 start_pos
= it
.current
.pos
;
10800 /* Start displaying new lines in the desired matrix at the same
10801 vpos we would use in the current matrix, i.e. below
10802 last_unchanged_at_beg_row. */
10803 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
10805 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
10806 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
10808 xassert (it
.hpos
== 0 && it
.current_x
== 0);
10812 /* There are no reusable lines at the start of the window.
10813 Start displaying in the first line. */
10814 start_display (&it
, w
, start
);
10815 start_pos
= it
.current
.pos
;
10818 /* Find the first row that is not affected by changes at the end of
10819 the buffer. Value will be null if there is no unchanged row, in
10820 which case we must redisplay to the end of the window. delta
10821 will be set to the value by which buffer positions beginning with
10822 first_unchanged_at_end_row have to be adjusted due to text
10824 first_unchanged_at_end_row
10825 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
10826 IF_DEBUG (debug_delta
= delta
);
10827 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
10829 /* Set stop_pos to the buffer position up to which we will have to
10830 display new lines. If first_unchanged_at_end_row != NULL, this
10831 is the buffer position of the start of the line displayed in that
10832 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
10833 that we don't stop at a buffer position. */
10835 if (first_unchanged_at_end_row
)
10837 xassert (last_unchanged_at_beg_row
== NULL
10838 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
10840 /* If this is a continuation line, move forward to the next one
10841 that isn't. Changes in lines above affect this line.
10842 Caution: this may move first_unchanged_at_end_row to a row
10843 not displaying text. */
10844 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
10845 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
10846 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
10847 < it
.last_visible_y
))
10848 ++first_unchanged_at_end_row
;
10850 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
10851 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
10852 >= it
.last_visible_y
))
10853 first_unchanged_at_end_row
= NULL
;
10856 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
10858 first_unchanged_at_end_vpos
10859 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
10860 xassert (stop_pos
>= Z
- END_UNCHANGED
);
10863 else if (last_unchanged_at_beg_row
== NULL
)
10869 /* Either there is no unchanged row at the end, or the one we have
10870 now displays text. This is a necessary condition for the window
10871 end pos calculation at the end of this function. */
10872 xassert (first_unchanged_at_end_row
== NULL
10873 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
10875 debug_last_unchanged_at_beg_vpos
10876 = (last_unchanged_at_beg_row
10877 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
10879 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
10881 #endif /* GLYPH_DEBUG != 0 */
10884 /* Display new lines. Set last_text_row to the last new line
10885 displayed which has text on it, i.e. might end up as being the
10886 line where the window_end_vpos is. */
10887 w
->cursor
.vpos
= -1;
10888 last_text_row
= NULL
;
10889 overlay_arrow_seen
= 0;
10890 while (it
.current_y
< it
.last_visible_y
10891 && !fonts_changed_p
10892 && (first_unchanged_at_end_row
== NULL
10893 || IT_CHARPOS (it
) < stop_pos
))
10895 if (display_line (&it
))
10896 last_text_row
= it
.glyph_row
- 1;
10899 if (fonts_changed_p
)
10903 /* Compute differences in buffer positions, y-positions etc. for
10904 lines reused at the bottom of the window. Compute what we can
10906 if (first_unchanged_at_end_row
10907 /* No lines reused because we displayed everything up to the
10908 bottom of the window. */
10909 && it
.current_y
< it
.last_visible_y
)
10912 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
10914 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
10915 run
.current_y
= first_unchanged_at_end_row
->y
;
10916 run
.desired_y
= run
.current_y
+ dy
;
10917 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
10921 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
10922 first_unchanged_at_end_row
= NULL
;
10924 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
10927 /* Find the cursor if not already found. We have to decide whether
10928 PT will appear on this window (it sometimes doesn't, but this is
10929 not a very frequent case.) This decision has to be made before
10930 the current matrix is altered. A value of cursor.vpos < 0 means
10931 that PT is either in one of the lines beginning at
10932 first_unchanged_at_end_row or below the window. Don't care for
10933 lines that might be displayed later at the window end; as
10934 mentioned, this is not a frequent case. */
10935 if (w
->cursor
.vpos
< 0)
10937 /* Cursor in unchanged rows at the top? */
10938 if (PT
< CHARPOS (start_pos
)
10939 && last_unchanged_at_beg_row
)
10941 row
= row_containing_pos (w
, PT
,
10942 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
10943 last_unchanged_at_beg_row
+ 1);
10945 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
10948 /* Start from first_unchanged_at_end_row looking for PT. */
10949 else if (first_unchanged_at_end_row
)
10951 row
= row_containing_pos (w
, PT
- delta
,
10952 first_unchanged_at_end_row
, NULL
);
10954 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
10955 delta_bytes
, dy
, dvpos
);
10958 /* Give up if cursor was not found. */
10959 if (w
->cursor
.vpos
< 0)
10961 clear_glyph_matrix (w
->desired_matrix
);
10966 /* Don't let the cursor end in the scroll margins. */
10968 int this_scroll_margin
, cursor_height
;
10970 this_scroll_margin
= max (0, scroll_margin
);
10971 this_scroll_margin
= min (this_scroll_margin
,
10972 XFASTINT (w
->height
) / 4);
10973 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
10974 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
10976 if ((w
->cursor
.y
< this_scroll_margin
10977 && CHARPOS (start
) > BEGV
)
10978 /* Don't take scroll margin into account at the bottom because
10979 old redisplay didn't do it either. */
10980 || w
->cursor
.y
+ cursor_height
> it
.last_visible_y
)
10982 w
->cursor
.vpos
= -1;
10983 clear_glyph_matrix (w
->desired_matrix
);
10988 /* Scroll the display. Do it before changing the current matrix so
10989 that xterm.c doesn't get confused about where the cursor glyph is
10991 if (dy
&& run
.height
)
10995 if (FRAME_WINDOW_P (f
))
10997 rif
->update_window_begin_hook (w
);
10998 rif
->clear_mouse_face (w
);
10999 rif
->scroll_run_hook (w
, &run
);
11000 rif
->update_window_end_hook (w
, 0, 0);
11004 /* Terminal frame. In this case, dvpos gives the number of
11005 lines to scroll by; dvpos < 0 means scroll up. */
11006 int first_unchanged_at_end_vpos
11007 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
11008 int from
= XFASTINT (w
->top
) + first_unchanged_at_end_vpos
;
11009 int end
= XFASTINT (w
->top
) + window_internal_height (w
);
11011 /* Perform the operation on the screen. */
11014 /* Scroll last_unchanged_at_beg_row to the end of the
11015 window down dvpos lines. */
11016 set_terminal_window (end
);
11018 /* On dumb terminals delete dvpos lines at the end
11019 before inserting dvpos empty lines. */
11020 if (!scroll_region_ok
)
11021 ins_del_lines (end
- dvpos
, -dvpos
);
11023 /* Insert dvpos empty lines in front of
11024 last_unchanged_at_beg_row. */
11025 ins_del_lines (from
, dvpos
);
11027 else if (dvpos
< 0)
11029 /* Scroll up last_unchanged_at_beg_vpos to the end of
11030 the window to last_unchanged_at_beg_vpos - |dvpos|. */
11031 set_terminal_window (end
);
11033 /* Delete dvpos lines in front of
11034 last_unchanged_at_beg_vpos. ins_del_lines will set
11035 the cursor to the given vpos and emit |dvpos| delete
11037 ins_del_lines (from
+ dvpos
, dvpos
);
11039 /* On a dumb terminal insert dvpos empty lines at the
11041 if (!scroll_region_ok
)
11042 ins_del_lines (end
+ dvpos
, -dvpos
);
11045 set_terminal_window (0);
11051 /* Shift reused rows of the current matrix to the right position.
11052 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
11054 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
11055 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
11058 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
11059 bottom_vpos
, dvpos
);
11060 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
11063 else if (dvpos
> 0)
11065 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
11066 bottom_vpos
, dvpos
);
11067 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
11068 first_unchanged_at_end_vpos
+ dvpos
, 0);
11071 /* For frame-based redisplay, make sure that current frame and window
11072 matrix are in sync with respect to glyph memory. */
11073 if (!FRAME_WINDOW_P (f
))
11074 sync_frame_with_window_matrix_rows (w
);
11076 /* Adjust buffer positions in reused rows. */
11078 increment_matrix_positions (current_matrix
,
11079 first_unchanged_at_end_vpos
+ dvpos
,
11080 bottom_vpos
, delta
, delta_bytes
);
11082 /* Adjust Y positions. */
11084 shift_glyph_matrix (w
, current_matrix
,
11085 first_unchanged_at_end_vpos
+ dvpos
,
11088 if (first_unchanged_at_end_row
)
11089 first_unchanged_at_end_row
+= dvpos
;
11091 /* If scrolling up, there may be some lines to display at the end of
11093 last_text_row_at_end
= NULL
;
11096 /* Set last_row to the glyph row in the current matrix where the
11097 window end line is found. It has been moved up or down in
11098 the matrix by dvpos. */
11099 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
11100 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
11102 /* If last_row is the window end line, it should display text. */
11103 xassert (last_row
->displays_text_p
);
11105 /* If window end line was partially visible before, begin
11106 displaying at that line. Otherwise begin displaying with the
11107 line following it. */
11108 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
11110 init_to_row_start (&it
, w
, last_row
);
11111 it
.vpos
= last_vpos
;
11112 it
.current_y
= last_row
->y
;
11116 init_to_row_end (&it
, w
, last_row
);
11117 it
.vpos
= 1 + last_vpos
;
11118 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
11122 /* We may start in a continuation line. If so, we have to get
11123 the right continuation_lines_width and current_x. */
11124 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
11125 it
.hpos
= it
.current_x
= 0;
11127 /* Display the rest of the lines at the window end. */
11128 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
11129 while (it
.current_y
< it
.last_visible_y
11130 && !fonts_changed_p
)
11132 /* Is it always sure that the display agrees with lines in
11133 the current matrix? I don't think so, so we mark rows
11134 displayed invalid in the current matrix by setting their
11135 enabled_p flag to zero. */
11136 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
11137 if (display_line (&it
))
11138 last_text_row_at_end
= it
.glyph_row
- 1;
11142 /* Update window_end_pos and window_end_vpos. */
11143 if (first_unchanged_at_end_row
11144 && first_unchanged_at_end_row
->y
< it
.last_visible_y
11145 && !last_text_row_at_end
)
11147 /* Window end line if one of the preserved rows from the current
11148 matrix. Set row to the last row displaying text in current
11149 matrix starting at first_unchanged_at_end_row, after
11151 xassert (first_unchanged_at_end_row
->displays_text_p
);
11152 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
11153 first_unchanged_at_end_row
);
11154 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
11156 XSETFASTINT (w
->window_end_pos
, Z
- MATRIX_ROW_END_CHARPOS (row
));
11157 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
11158 XSETFASTINT (w
->window_end_vpos
,
11159 MATRIX_ROW_VPOS (row
, w
->current_matrix
));
11161 else if (last_text_row_at_end
)
11163 XSETFASTINT (w
->window_end_pos
,
11164 Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
11165 w
->window_end_bytepos
11166 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
11167 XSETFASTINT (w
->window_end_vpos
,
11168 MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
11170 else if (last_text_row
)
11172 /* We have displayed either to the end of the window or at the
11173 end of the window, i.e. the last row with text is to be found
11174 in the desired matrix. */
11175 XSETFASTINT (w
->window_end_pos
,
11176 Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
11177 w
->window_end_bytepos
11178 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
11179 XSETFASTINT (w
->window_end_vpos
,
11180 MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
11182 else if (first_unchanged_at_end_row
== NULL
11183 && last_text_row
== NULL
11184 && last_text_row_at_end
== NULL
)
11186 /* Displayed to end of window, but no line containing text was
11187 displayed. Lines were deleted at the end of the window. */
11189 int header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
11191 for (vpos
= XFASTINT (w
->window_end_vpos
); vpos
> 0; --vpos
)
11192 if ((w
->desired_matrix
->rows
[vpos
+ header_line_p
].enabled_p
11193 && w
->desired_matrix
->rows
[vpos
+ header_line_p
].displays_text_p
)
11194 || (!w
->desired_matrix
->rows
[vpos
+ header_line_p
].enabled_p
11195 && w
->current_matrix
->rows
[vpos
+ header_line_p
].displays_text_p
))
11198 w
->window_end_vpos
= make_number (vpos
);
11203 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
11204 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
11206 /* Record that display has not been completed. */
11207 w
->window_end_valid
= Qnil
;
11208 w
->desired_matrix
->no_scrolling_p
= 1;
11214 /***********************************************************************
11215 More debugging support
11216 ***********************************************************************/
11220 void dump_glyph_row
P_ ((struct glyph_matrix
*, int, int));
11221 static void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
11224 /* Dump the contents of glyph matrix MATRIX on stderr. If
11225 WITH_GLYPHS_P is non-zero, dump glyph contents as well. */
11228 dump_glyph_matrix (matrix
, with_glyphs_p
)
11229 struct glyph_matrix
*matrix
;
11233 for (i
= 0; i
< matrix
->nrows
; ++i
)
11234 dump_glyph_row (matrix
, i
, with_glyphs_p
);
11238 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
11239 WITH_GLYPH_SP non-zero means dump glyph contents, too. */
11242 dump_glyph_row (matrix
, vpos
, with_glyphs_p
)
11243 struct glyph_matrix
*matrix
;
11244 int vpos
, with_glyphs_p
;
11246 struct glyph_row
*row
;
11248 if (vpos
< 0 || vpos
>= matrix
->nrows
)
11251 row
= MATRIX_ROW (matrix
, vpos
);
11253 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFes X Y W H V A P\n");
11254 fprintf (stderr
, "=======================================================================\n");
11256 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d\
11257 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
11258 row
- matrix
->rows
,
11259 MATRIX_ROW_START_CHARPOS (row
),
11260 MATRIX_ROW_END_CHARPOS (row
),
11261 row
->used
[TEXT_AREA
],
11262 row
->contains_overlapping_glyphs_p
,
11265 row
->truncated_on_left_p
,
11266 row
->truncated_on_right_p
,
11267 row
->overlay_arrow_p
,
11269 MATRIX_ROW_CONTINUATION_LINE_P (row
),
11270 row
->displays_text_p
,
11273 row
->ends_in_middle_of_char_p
,
11274 row
->starts_in_middle_of_char_p
,
11279 row
->visible_height
,
11282 fprintf (stderr
, "%9d %5d\n", row
->start
.overlay_string_index
,
11283 row
->end
.overlay_string_index
);
11284 fprintf (stderr
, "%9d %5d\n",
11285 CHARPOS (row
->start
.string_pos
),
11286 CHARPOS (row
->end
.string_pos
));
11287 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
11288 row
->end
.dpvec_index
);
11292 struct glyph
*glyph
, *glyph_end
;
11293 int prev_had_glyphs_p
;
11295 glyph
= row
->glyphs
[TEXT_AREA
];
11296 glyph_end
= glyph
+ row
->used
[TEXT_AREA
];
11298 /* Glyph for a line end in text. */
11299 if (glyph
== glyph_end
&& glyph
->charpos
> 0)
11302 if (glyph
< glyph_end
)
11304 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
11305 prev_had_glyphs_p
= 1;
11308 prev_had_glyphs_p
= 0;
11310 while (glyph
< glyph_end
)
11312 if (glyph
->type
== CHAR_GLYPH
)
11315 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11316 glyph
- row
->glyphs
[TEXT_AREA
],
11319 (BUFFERP (glyph
->object
)
11321 : (STRINGP (glyph
->object
)
11324 glyph
->pixel_width
,
11326 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
11330 glyph
->left_box_line_p
,
11331 glyph
->right_box_line_p
);
11333 else if (glyph
->type
== STRETCH_GLYPH
)
11336 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11337 glyph
- row
->glyphs
[TEXT_AREA
],
11340 (BUFFERP (glyph
->object
)
11342 : (STRINGP (glyph
->object
)
11345 glyph
->pixel_width
,
11349 glyph
->left_box_line_p
,
11350 glyph
->right_box_line_p
);
11352 else if (glyph
->type
== IMAGE_GLYPH
)
11355 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
11356 glyph
- row
->glyphs
[TEXT_AREA
],
11359 (BUFFERP (glyph
->object
)
11361 : (STRINGP (glyph
->object
)
11364 glyph
->pixel_width
,
11368 glyph
->left_box_line_p
,
11369 glyph
->right_box_line_p
);
11377 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
11378 Sdump_glyph_matrix
, 0, 1, "p",
11379 "Dump the current matrix of the selected window to stderr.\n\
11380 Shows contents of glyph row structures. With non-nil optional\n\
11381 parameter WITH-GLYPHS-P, dump glyphs as well.")
11383 Lisp_Object with_glyphs_p
;
11385 struct window
*w
= XWINDOW (selected_window
);
11386 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11388 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
11389 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
11390 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
11391 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
11392 fprintf (stderr
, "=============================================\n");
11393 dump_glyph_matrix (w
->current_matrix
, !NILP (with_glyphs_p
));
11398 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 1, "",
11399 "Dump glyph row ROW to stderr.")
11403 CHECK_NUMBER (row
, 0);
11404 dump_glyph_row (XWINDOW (selected_window
)->current_matrix
, XINT (row
), 1);
11409 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
,
11413 struct frame
*sf
= SELECTED_FRAME ();
11414 struct glyph_matrix
*m
= (XWINDOW (sf
->tool_bar_window
)
11416 dump_glyph_row (m
, 0, 1);
11421 DEFUN ("trace-redisplay-toggle", Ftrace_redisplay_toggle
,
11422 Strace_redisplay_toggle
, 0, 0, "",
11423 "Toggle tracing of redisplay.")
11426 trace_redisplay_p
= !trace_redisplay_p
;
11431 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, 1, "",
11432 "Print STRING to stderr.")
11434 Lisp_Object string
;
11436 CHECK_STRING (string
, 0);
11437 fprintf (stderr
, "%s", XSTRING (string
)->data
);
11441 #endif /* GLYPH_DEBUG */
11445 /***********************************************************************
11446 Building Desired Matrix Rows
11447 ***********************************************************************/
11449 /* Return a temporary glyph row holding the glyphs of an overlay
11450 arrow. Only used for non-window-redisplay windows. */
11452 static struct glyph_row
*
11453 get_overlay_arrow_glyph_row (w
)
11456 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11457 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11458 struct buffer
*old
= current_buffer
;
11459 unsigned char *arrow_string
= XSTRING (Voverlay_arrow_string
)->data
;
11460 int arrow_len
= XSTRING (Voverlay_arrow_string
)->size
;
11461 unsigned char *arrow_end
= arrow_string
+ arrow_len
;
11465 int n_glyphs_before
;
11467 set_buffer_temp (buffer
);
11468 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
11469 it
.glyph_row
->used
[TEXT_AREA
] = 0;
11470 SET_TEXT_POS (it
.position
, 0, 0);
11472 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
11474 while (p
< arrow_end
)
11476 Lisp_Object face
, ilisp
;
11478 /* Get the next character. */
11480 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
11482 it
.c
= *p
, it
.len
= 1;
11485 /* Get its face. */
11486 XSETFASTINT (ilisp
, p
- arrow_string
);
11487 face
= Fget_text_property (ilisp
, Qface
, Voverlay_arrow_string
);
11488 it
.face_id
= compute_char_face (f
, it
.c
, face
);
11490 /* Compute its width, get its glyphs. */
11491 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
11492 SET_TEXT_POS (it
.position
, -1, -1);
11493 PRODUCE_GLYPHS (&it
);
11495 /* If this character doesn't fit any more in the line, we have
11496 to remove some glyphs. */
11497 if (it
.current_x
> it
.last_visible_x
)
11499 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
11504 set_buffer_temp (old
);
11505 return it
.glyph_row
;
11509 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
11510 glyphs are only inserted for terminal frames since we can't really
11511 win with truncation glyphs when partially visible glyphs are
11512 involved. Which glyphs to insert is determined by
11513 produce_special_glyphs. */
11516 insert_left_trunc_glyphs (it
)
11519 struct it truncate_it
;
11520 struct glyph
*from
, *end
, *to
, *toend
;
11522 xassert (!FRAME_WINDOW_P (it
->f
));
11524 /* Get the truncation glyphs. */
11526 truncate_it
.current_x
= 0;
11527 truncate_it
.face_id
= DEFAULT_FACE_ID
;
11528 truncate_it
.glyph_row
= &scratch_glyph_row
;
11529 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
11530 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
11531 truncate_it
.object
= make_number (0);
11532 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
11534 /* Overwrite glyphs from IT with truncation glyphs. */
11535 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
11536 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
11537 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
11538 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
11543 /* There may be padding glyphs left over. Remove them. */
11545 while (from
< toend
&& CHAR_GLYPH_PADDING_P (*from
))
11547 while (from
< toend
)
11550 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
11554 /* Compute the pixel height and width of IT->glyph_row.
11556 Most of the time, ascent and height of a display line will be equal
11557 to the max_ascent and max_height values of the display iterator
11558 structure. This is not the case if
11560 1. We hit ZV without displaying anything. In this case, max_ascent
11561 and max_height will be zero.
11563 2. We have some glyphs that don't contribute to the line height.
11564 (The glyph row flag contributes_to_line_height_p is for future
11565 pixmap extensions).
11567 The first case is easily covered by using default values because in
11568 these cases, the line height does not really matter, except that it
11569 must not be zero. */
11572 compute_line_metrics (it
)
11575 struct glyph_row
*row
= it
->glyph_row
;
11578 if (FRAME_WINDOW_P (it
->f
))
11580 int i
, header_line_height
;
11582 /* The line may consist of one space only, that was added to
11583 place the cursor on it. If so, the row's height hasn't been
11585 if (row
->height
== 0)
11587 if (it
->max_ascent
+ it
->max_descent
== 0)
11588 it
->max_descent
= it
->max_phys_descent
= CANON_Y_UNIT (it
->f
);
11589 row
->ascent
= it
->max_ascent
;
11590 row
->height
= it
->max_ascent
+ it
->max_descent
;
11591 row
->phys_ascent
= it
->max_phys_ascent
;
11592 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
11595 /* Compute the width of this line. */
11596 row
->pixel_width
= row
->x
;
11597 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
11598 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
11600 xassert (row
->pixel_width
>= 0);
11601 xassert (row
->ascent
>= 0 && row
->height
> 0);
11603 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
11604 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
11606 /* If first line's physical ascent is larger than its logical
11607 ascent, use the physical ascent, and make the row taller.
11608 This makes accented characters fully visible. */
11609 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
11610 && row
->phys_ascent
> row
->ascent
)
11612 row
->height
+= row
->phys_ascent
- row
->ascent
;
11613 row
->ascent
= row
->phys_ascent
;
11616 /* Compute how much of the line is visible. */
11617 row
->visible_height
= row
->height
;
11619 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it
->w
);
11620 if (row
->y
< header_line_height
)
11621 row
->visible_height
-= header_line_height
- row
->y
;
11624 int max_y
= WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it
->w
);
11625 if (row
->y
+ row
->height
> max_y
)
11626 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
11631 row
->pixel_width
= row
->used
[TEXT_AREA
];
11632 row
->ascent
= row
->phys_ascent
= 0;
11633 row
->height
= row
->phys_height
= row
->visible_height
= 1;
11636 /* Compute a hash code for this row. */
11638 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
11639 for (i
= 0; i
< row
->used
[area
]; ++i
)
11640 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
11641 + row
->glyphs
[area
][i
].u
.val
11642 + row
->glyphs
[area
][i
].face_id
11643 + row
->glyphs
[area
][i
].padding_p
11644 + (row
->glyphs
[area
][i
].type
<< 2));
11646 it
->max_ascent
= it
->max_descent
= 0;
11647 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
11651 /* Append one space to the glyph row of iterator IT if doing a
11652 window-based redisplay. DEFAULT_FACE_P non-zero means let the
11653 space have the default face, otherwise let it have the same face as
11654 IT->face_id. Value is non-zero if a space was added.
11656 This function is called to make sure that there is always one glyph
11657 at the end of a glyph row that the cursor can be set on under
11658 window-systems. (If there weren't such a glyph we would not know
11659 how wide and tall a box cursor should be displayed).
11661 At the same time this space let's a nicely handle clearing to the
11662 end of the line if the row ends in italic text. */
11665 append_space (it
, default_face_p
)
11667 int default_face_p
;
11669 if (FRAME_WINDOW_P (it
->f
))
11671 int n
= it
->glyph_row
->used
[TEXT_AREA
];
11673 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
11674 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
11676 /* Save some values that must not be changed.
11677 Must save IT->c and IT->len because otherwise
11678 ITERATOR_AT_END_P wouldn't work anymore after
11679 append_space has been called. */
11680 int saved_what
= it
->what
;
11681 int saved_c
= it
->c
, saved_len
= it
->len
;
11682 int saved_x
= it
->current_x
;
11683 int saved_face_id
= it
->face_id
;
11684 struct text_pos saved_pos
;
11685 Lisp_Object saved_object
;
11688 saved_object
= it
->object
;
11689 saved_pos
= it
->position
;
11691 it
->what
= IT_CHARACTER
;
11692 bzero (&it
->position
, sizeof it
->position
);
11693 it
->object
= make_number (0);
11697 if (default_face_p
)
11698 it
->face_id
= DEFAULT_FACE_ID
;
11699 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
11700 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
11702 PRODUCE_GLYPHS (it
);
11704 it
->current_x
= saved_x
;
11705 it
->object
= saved_object
;
11706 it
->position
= saved_pos
;
11707 it
->what
= saved_what
;
11708 it
->face_id
= saved_face_id
;
11709 it
->len
= saved_len
;
11719 /* Extend the face of the last glyph in the text area of IT->glyph_row
11720 to the end of the display line. Called from display_line.
11721 If the glyph row is empty, add a space glyph to it so that we
11722 know the face to draw. Set the glyph row flag fill_line_p. */
11725 extend_face_to_end_of_line (it
)
11729 struct frame
*f
= it
->f
;
11731 /* If line is already filled, do nothing. */
11732 if (it
->current_x
>= it
->last_visible_x
)
11735 /* Face extension extends the background and box of IT->face_id
11736 to the end of the line. If the background equals the background
11737 of the frame, we haven't to do anything. */
11738 face
= FACE_FROM_ID (f
, it
->face_id
);
11739 if (FRAME_WINDOW_P (f
)
11740 && face
->box
== FACE_NO_BOX
11741 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
11745 /* Set the glyph row flag indicating that the face of the last glyph
11746 in the text area has to be drawn to the end of the text area. */
11747 it
->glyph_row
->fill_line_p
= 1;
11749 /* If current character of IT is not ASCII, make sure we have the
11750 ASCII face. This will be automatically undone the next time
11751 get_next_display_element returns a multibyte character. Note
11752 that the character will always be single byte in unibyte text. */
11753 if (!SINGLE_BYTE_CHAR_P (it
->c
))
11755 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
11758 if (FRAME_WINDOW_P (f
))
11760 /* If the row is empty, add a space with the current face of IT,
11761 so that we know which face to draw. */
11762 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
11764 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
11765 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
11766 it
->glyph_row
->used
[TEXT_AREA
] = 1;
11771 /* Save some values that must not be changed. */
11772 int saved_x
= it
->current_x
;
11773 struct text_pos saved_pos
;
11774 Lisp_Object saved_object
;
11775 int saved_what
= it
->what
;
11777 saved_object
= it
->object
;
11778 saved_pos
= it
->position
;
11780 it
->what
= IT_CHARACTER
;
11781 bzero (&it
->position
, sizeof it
->position
);
11782 it
->object
= make_number (0);
11786 PRODUCE_GLYPHS (it
);
11788 while (it
->current_x
<= it
->last_visible_x
)
11789 PRODUCE_GLYPHS (it
);
11791 /* Don't count these blanks really. It would let us insert a left
11792 truncation glyph below and make us set the cursor on them, maybe. */
11793 it
->current_x
= saved_x
;
11794 it
->object
= saved_object
;
11795 it
->position
= saved_pos
;
11796 it
->what
= saved_what
;
11801 /* Value is non-zero if text starting at CHARPOS in current_buffer is
11802 trailing whitespace. */
11805 trailing_whitespace_p (charpos
)
11808 int bytepos
= CHAR_TO_BYTE (charpos
);
11811 while (bytepos
< ZV_BYTE
11812 && (c
= FETCH_CHAR (bytepos
),
11813 c
== ' ' || c
== '\t'))
11816 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
11818 if (bytepos
!= PT_BYTE
)
11825 /* Highlight trailing whitespace, if any, in ROW. */
11828 highlight_trailing_whitespace (f
, row
)
11830 struct glyph_row
*row
;
11832 int used
= row
->used
[TEXT_AREA
];
11836 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
11837 struct glyph
*glyph
= start
+ used
- 1;
11839 /* Skip over the space glyph inserted to display the
11840 cursor at the end of a line. */
11841 if (glyph
->type
== CHAR_GLYPH
11842 && glyph
->u
.ch
== ' '
11843 && INTEGERP (glyph
->object
))
11846 /* If last glyph is a space or stretch, and it's trailing
11847 whitespace, set the face of all trailing whitespace glyphs in
11848 IT->glyph_row to `trailing-whitespace'. */
11850 && BUFFERP (glyph
->object
)
11851 && (glyph
->type
== STRETCH_GLYPH
11852 || (glyph
->type
== CHAR_GLYPH
11853 && glyph
->u
.ch
== ' '))
11854 && trailing_whitespace_p (glyph
->charpos
))
11856 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
11858 while (glyph
>= start
11859 && BUFFERP (glyph
->object
)
11860 && (glyph
->type
== STRETCH_GLYPH
11861 || (glyph
->type
== CHAR_GLYPH
11862 && glyph
->u
.ch
== ' ')))
11863 (glyph
--)->face_id
= face_id
;
11869 /* Value is non-zero if glyph row ROW in window W should be
11870 used to hold the cursor. */
11873 cursor_row_p (w
, row
)
11875 struct glyph_row
*row
;
11877 int cursor_row_p
= 1;
11879 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
11881 /* If the row ends with a newline from a string, we don't want
11882 the cursor there (if the row is continued it doesn't end in a
11884 if (CHARPOS (row
->end
.string_pos
) >= 0
11885 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11886 cursor_row_p
= row
->continued_p
;
11888 /* If the row ends at ZV, display the cursor at the end of that
11889 row instead of at the start of the row below. */
11890 else if (row
->ends_at_zv_p
)
11896 return cursor_row_p
;
11900 /* Construct the glyph row IT->glyph_row in the desired matrix of
11901 IT->w from text at the current position of IT. See dispextern.h
11902 for an overview of struct it. Value is non-zero if
11903 IT->glyph_row displays text, as opposed to a line displaying ZV
11910 struct glyph_row
*row
= it
->glyph_row
;
11912 /* We always start displaying at hpos zero even if hscrolled. */
11913 xassert (it
->hpos
== 0 && it
->current_x
== 0);
11915 /* We must not display in a row that's not a text row. */
11916 xassert (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
11917 < it
->w
->desired_matrix
->nrows
);
11919 /* Is IT->w showing the region? */
11920 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
11922 /* Clear the result glyph row and enable it. */
11923 prepare_desired_row (row
);
11925 row
->y
= it
->current_y
;
11926 row
->start
= it
->current
;
11927 row
->continuation_lines_width
= it
->continuation_lines_width
;
11928 row
->displays_text_p
= 1;
11929 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
11930 it
->starts_in_middle_of_char_p
= 0;
11932 /* Arrange the overlays nicely for our purposes. Usually, we call
11933 display_line on only one line at a time, in which case this
11934 can't really hurt too much, or we call it on lines which appear
11935 one after another in the buffer, in which case all calls to
11936 recenter_overlay_lists but the first will be pretty cheap. */
11937 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
11939 /* Move over display elements that are not visible because we are
11940 hscrolled. This may stop at an x-position < IT->first_visible_x
11941 if the first glyph is partially visible or if we hit a line end. */
11942 if (it
->current_x
< it
->first_visible_x
)
11943 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
11944 MOVE_TO_POS
| MOVE_TO_X
);
11946 /* Get the initial row height. This is either the height of the
11947 text hscrolled, if there is any, or zero. */
11948 row
->ascent
= it
->max_ascent
;
11949 row
->height
= it
->max_ascent
+ it
->max_descent
;
11950 row
->phys_ascent
= it
->max_phys_ascent
;
11951 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
11953 /* Loop generating characters. The loop is left with IT on the next
11954 character to display. */
11957 int n_glyphs_before
, hpos_before
, x_before
;
11959 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
11961 /* Retrieve the next thing to display. Value is zero if end of
11963 if (!get_next_display_element (it
))
11965 /* Maybe add a space at the end of this line that is used to
11966 display the cursor there under X. Set the charpos of the
11967 first glyph of blank lines not corresponding to any text
11969 if ((append_space (it
, 1) && row
->used
[TEXT_AREA
] == 1)
11970 || row
->used
[TEXT_AREA
] == 0)
11972 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
11973 row
->displays_text_p
= 0;
11975 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
))
11976 row
->indicate_empty_line_p
= 1;
11979 it
->continuation_lines_width
= 0;
11980 row
->ends_at_zv_p
= 1;
11984 /* Now, get the metrics of what we want to display. This also
11985 generates glyphs in `row' (which is IT->glyph_row). */
11986 n_glyphs_before
= row
->used
[TEXT_AREA
];
11989 /* Remember the line height so far in case the next element doesn't
11990 fit on the line. */
11991 if (!it
->truncate_lines_p
)
11993 ascent
= it
->max_ascent
;
11994 descent
= it
->max_descent
;
11995 phys_ascent
= it
->max_phys_ascent
;
11996 phys_descent
= it
->max_phys_descent
;
11999 PRODUCE_GLYPHS (it
);
12001 /* If this display element was in marginal areas, continue with
12003 if (it
->area
!= TEXT_AREA
)
12005 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
12006 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
12007 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
12008 row
->phys_height
= max (row
->phys_height
,
12009 it
->max_phys_ascent
+ it
->max_phys_descent
);
12010 set_iterator_to_next (it
, 1);
12014 /* Does the display element fit on the line? If we truncate
12015 lines, we should draw past the right edge of the window. If
12016 we don't truncate, we want to stop so that we can display the
12017 continuation glyph before the right margin. If lines are
12018 continued, there are two possible strategies for characters
12019 resulting in more than 1 glyph (e.g. tabs): Display as many
12020 glyphs as possible in this line and leave the rest for the
12021 continuation line, or display the whole element in the next
12022 line. Original redisplay did the former, so we do it also. */
12023 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
12024 hpos_before
= it
->hpos
;
12028 && it
->current_x
< it
->last_visible_x
)
12031 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
12032 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
12033 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
12034 row
->phys_height
= max (row
->phys_height
,
12035 it
->max_phys_ascent
+ it
->max_phys_descent
);
12036 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
12037 row
->x
= x
- it
->first_visible_x
;
12042 struct glyph
*glyph
;
12044 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
12046 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
12047 new_x
= x
+ glyph
->pixel_width
;
12049 if (/* Lines are continued. */
12050 !it
->truncate_lines_p
12051 && (/* Glyph doesn't fit on the line. */
12052 new_x
> it
->last_visible_x
12053 /* Or it fits exactly on a window system frame. */
12054 || (new_x
== it
->last_visible_x
12055 && FRAME_WINDOW_P (it
->f
))))
12057 /* End of a continued line. */
12060 || (new_x
== it
->last_visible_x
12061 && FRAME_WINDOW_P (it
->f
)))
12063 /* Current glyph is the only one on the line or
12064 fits exactly on the line. We must continue
12065 the line because we can't draw the cursor
12066 after the glyph. */
12067 row
->continued_p
= 1;
12068 it
->current_x
= new_x
;
12069 it
->continuation_lines_width
+= new_x
;
12071 if (i
== nglyphs
- 1)
12072 set_iterator_to_next (it
, 1);
12074 else if (CHAR_GLYPH_PADDING_P (*glyph
)
12075 && !FRAME_WINDOW_P (it
->f
))
12077 /* A padding glyph that doesn't fit on this line.
12078 This means the whole character doesn't fit
12080 row
->used
[TEXT_AREA
] = n_glyphs_before
;
12082 /* Fill the rest of the row with continuation
12083 glyphs like in 20.x. */
12084 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
12085 < row
->glyphs
[1 + TEXT_AREA
])
12086 produce_special_glyphs (it
, IT_CONTINUATION
);
12088 row
->continued_p
= 1;
12089 it
->current_x
= x_before
;
12090 it
->continuation_lines_width
+= x_before
;
12092 /* Restore the height to what it was before the
12093 element not fitting on the line. */
12094 it
->max_ascent
= ascent
;
12095 it
->max_descent
= descent
;
12096 it
->max_phys_ascent
= phys_ascent
;
12097 it
->max_phys_descent
= phys_descent
;
12101 /* Display element draws past the right edge of
12102 the window. Restore positions to values
12103 before the element. The next line starts
12104 with current_x before the glyph that could
12105 not be displayed, so that TAB works right. */
12106 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
12108 /* Display continuation glyphs. */
12109 if (!FRAME_WINDOW_P (it
->f
))
12110 produce_special_glyphs (it
, IT_CONTINUATION
);
12111 row
->continued_p
= 1;
12114 it
->continuation_lines_width
+= x
;
12115 if (nglyphs
> 1 && i
> 0)
12117 row
->ends_in_middle_of_char_p
= 1;
12118 it
->starts_in_middle_of_char_p
= 1;
12121 /* Restore the height to what it was before the
12122 element not fitting on the line. */
12123 it
->max_ascent
= ascent
;
12124 it
->max_descent
= descent
;
12125 it
->max_phys_ascent
= phys_ascent
;
12126 it
->max_phys_descent
= phys_descent
;
12131 else if (new_x
> it
->first_visible_x
)
12133 /* Increment number of glyphs actually displayed. */
12136 if (x
< it
->first_visible_x
)
12137 /* Glyph is partially visible, i.e. row starts at
12138 negative X position. */
12139 row
->x
= x
- it
->first_visible_x
;
12143 /* Glyph is completely off the left margin of the
12144 window. This should not happen because of the
12145 move_it_in_display_line at the start of
12151 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
12152 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
12153 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
12154 row
->phys_height
= max (row
->phys_height
,
12155 it
->max_phys_ascent
+ it
->max_phys_descent
);
12157 /* End of this display line if row is continued. */
12158 if (row
->continued_p
)
12162 /* Is this a line end? If yes, we're also done, after making
12163 sure that a non-default face is extended up to the right
12164 margin of the window. */
12165 if (ITERATOR_AT_END_OF_LINE_P (it
))
12167 int used_before
= row
->used
[TEXT_AREA
];
12169 /* Add a space at the end of the line that is used to
12170 display the cursor there. */
12171 append_space (it
, 0);
12173 /* Extend the face to the end of the line. */
12174 extend_face_to_end_of_line (it
);
12176 /* Make sure we have the position. */
12177 if (used_before
== 0)
12178 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
12180 /* Consume the line end. This skips over invisible lines. */
12181 set_iterator_to_next (it
, 1);
12182 it
->continuation_lines_width
= 0;
12186 /* Proceed with next display element. Note that this skips
12187 over lines invisible because of selective display. */
12188 set_iterator_to_next (it
, 1);
12190 /* If we truncate lines, we are done when the last displayed
12191 glyphs reach past the right margin of the window. */
12192 if (it
->truncate_lines_p
12193 && (FRAME_WINDOW_P (it
->f
)
12194 ? (it
->current_x
>= it
->last_visible_x
)
12195 : (it
->current_x
> it
->last_visible_x
)))
12197 /* Maybe add truncation glyphs. */
12198 if (!FRAME_WINDOW_P (it
->f
))
12200 --it
->glyph_row
->used
[TEXT_AREA
];
12201 produce_special_glyphs (it
, IT_TRUNCATION
);
12204 row
->truncated_on_right_p
= 1;
12205 it
->continuation_lines_width
= 0;
12206 reseat_at_next_visible_line_start (it
, 0);
12207 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
12208 it
->hpos
= hpos_before
;
12209 it
->current_x
= x_before
;
12214 /* If line is not empty and hscrolled, maybe insert truncation glyphs
12215 at the left window margin. */
12216 if (it
->first_visible_x
12217 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
12219 if (!FRAME_WINDOW_P (it
->f
))
12220 insert_left_trunc_glyphs (it
);
12221 row
->truncated_on_left_p
= 1;
12224 /* If the start of this line is the overlay arrow-position, then
12225 mark this glyph row as the one containing the overlay arrow.
12226 This is clearly a mess with variable size fonts. It would be
12227 better to let it be displayed like cursors under X. */
12228 if (MARKERP (Voverlay_arrow_position
)
12229 && current_buffer
== XMARKER (Voverlay_arrow_position
)->buffer
12230 && (MATRIX_ROW_START_CHARPOS (row
)
12231 == marker_position (Voverlay_arrow_position
))
12232 && STRINGP (Voverlay_arrow_string
)
12233 && ! overlay_arrow_seen
)
12235 /* Overlay arrow in window redisplay is a bitmap. */
12236 if (!FRAME_WINDOW_P (it
->f
))
12238 struct glyph_row
*arrow_row
= get_overlay_arrow_glyph_row (it
->w
);
12239 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
12240 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
12241 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
12242 struct glyph
*p2
, *end
;
12244 /* Copy the arrow glyphs. */
12245 while (glyph
< arrow_end
)
12248 /* Throw away padding glyphs. */
12250 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
12251 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
12257 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
12261 overlay_arrow_seen
= 1;
12262 row
->overlay_arrow_p
= 1;
12265 /* Compute pixel dimensions of this line. */
12266 compute_line_metrics (it
);
12268 /* Remember the position at which this line ends. */
12269 row
->end
= it
->current
;
12271 /* Maybe set the cursor. */
12272 if (it
->w
->cursor
.vpos
< 0
12273 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
12274 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
12275 && cursor_row_p (it
->w
, row
))
12276 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
12278 /* Highlight trailing whitespace. */
12279 if (!NILP (Vshow_trailing_whitespace
))
12280 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
12282 /* Prepare for the next line. This line starts horizontally at (X
12283 HPOS) = (0 0). Vertical positions are incremented. As a
12284 convenience for the caller, IT->glyph_row is set to the next
12286 it
->current_x
= it
->hpos
= 0;
12287 it
->current_y
+= row
->height
;
12290 return row
->displays_text_p
;
12295 /***********************************************************************
12297 ***********************************************************************/
12299 /* Redisplay the menu bar in the frame for window W.
12301 The menu bar of X frames that don't have X toolkit support is
12302 displayed in a special window W->frame->menu_bar_window.
12304 The menu bar of terminal frames is treated specially as far as
12305 glyph matrices are concerned. Menu bar lines are not part of
12306 windows, so the update is done directly on the frame matrix rows
12307 for the menu bar. */
12310 display_menu_bar (w
)
12313 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
12318 /* Don't do all this for graphical frames. */
12320 if (!NILP (Vwindow_system
))
12323 #ifdef USE_X_TOOLKIT
12328 if (FRAME_MAC_P (f
))
12332 #ifdef USE_X_TOOLKIT
12333 xassert (!FRAME_WINDOW_P (f
));
12334 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
12335 it
.first_visible_x
= 0;
12336 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
12337 #else /* not USE_X_TOOLKIT */
12338 if (FRAME_WINDOW_P (f
))
12340 /* Menu bar lines are displayed in the desired matrix of the
12341 dummy window menu_bar_window. */
12342 struct window
*menu_w
;
12343 xassert (WINDOWP (f
->menu_bar_window
));
12344 menu_w
= XWINDOW (f
->menu_bar_window
);
12345 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
12347 it
.first_visible_x
= 0;
12348 it
.last_visible_x
= FRAME_WINDOW_WIDTH (f
) * CANON_X_UNIT (f
);
12352 /* This is a TTY frame, i.e. character hpos/vpos are used as
12354 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
12356 it
.first_visible_x
= 0;
12357 it
.last_visible_x
= FRAME_WIDTH (f
);
12359 #endif /* not USE_X_TOOLKIT */
12361 if (! mode_line_inverse_video
)
12362 /* Force the menu-bar to be displayed in the default face. */
12363 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
12365 /* Clear all rows of the menu bar. */
12366 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
12368 struct glyph_row
*row
= it
.glyph_row
+ i
;
12369 clear_glyph_row (row
);
12370 row
->enabled_p
= 1;
12371 row
->full_width_p
= 1;
12374 /* Display all items of the menu bar. */
12375 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
12376 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
12378 Lisp_Object string
;
12380 /* Stop at nil string. */
12381 string
= XVECTOR (items
)->contents
[i
+ 1];
12385 /* Remember where item was displayed. */
12386 XSETFASTINT (XVECTOR (items
)->contents
[i
+ 3], it
.hpos
);
12388 /* Display the item, pad with one space. */
12389 if (it
.current_x
< it
.last_visible_x
)
12390 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
12391 XSTRING (string
)->size
+ 1, 0, 0, -1);
12394 /* Fill out the line with spaces. */
12395 if (it
.current_x
< it
.last_visible_x
)
12396 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
12398 /* Compute the total height of the lines. */
12399 compute_line_metrics (&it
);
12404 /***********************************************************************
12406 ***********************************************************************/
12408 /* Redisplay mode lines in the window tree whose root is WINDOW. If
12409 FORCE is non-zero, redisplay mode lines unconditionally.
12410 Otherwise, redisplay only mode lines that are garbaged. Value is
12411 the number of windows whose mode lines were redisplayed. */
12414 redisplay_mode_lines (window
, force
)
12415 Lisp_Object window
;
12420 while (!NILP (window
))
12422 struct window
*w
= XWINDOW (window
);
12424 if (WINDOWP (w
->hchild
))
12425 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
12426 else if (WINDOWP (w
->vchild
))
12427 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
12429 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
12430 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
12432 Lisp_Object old_selected_frame
;
12433 struct text_pos lpoint
;
12434 struct buffer
*old
= current_buffer
;
12436 /* Set the window's buffer for the mode line display. */
12437 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
12438 set_buffer_internal_1 (XBUFFER (w
->buffer
));
12440 /* Point refers normally to the selected window. For any
12441 other window, set up appropriate value. */
12442 if (!EQ (window
, selected_window
))
12444 struct text_pos pt
;
12446 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
12447 if (CHARPOS (pt
) < BEGV
)
12448 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
12449 else if (CHARPOS (pt
) > (ZV
- 1))
12450 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
12452 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
12455 /* Temporarily set up the selected frame. */
12456 old_selected_frame
= selected_frame
;
12457 selected_frame
= w
->frame
;
12459 /* Display mode lines. */
12460 clear_glyph_matrix (w
->desired_matrix
);
12461 if (display_mode_lines (w
))
12464 w
->must_be_updated_p
= 1;
12467 /* Restore old settings. */
12468 selected_frame
= old_selected_frame
;
12469 set_buffer_internal_1 (old
);
12470 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
12480 /* Display the mode and/or top line of window W. Value is the number
12481 of mode lines displayed. */
12484 display_mode_lines (w
)
12489 /* These will be set while the mode line specs are processed. */
12490 line_number_displayed
= 0;
12491 w
->column_number_displayed
= Qnil
;
12493 if (WINDOW_WANTS_MODELINE_P (w
))
12495 display_mode_line (w
, MODE_LINE_FACE_ID
,
12496 current_buffer
->mode_line_format
);
12500 if (WINDOW_WANTS_HEADER_LINE_P (w
))
12502 display_mode_line (w
, HEADER_LINE_FACE_ID
,
12503 current_buffer
->header_line_format
);
12511 /* Display mode or top line of window W. FACE_ID specifies which line
12512 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
12513 FORMAT is the mode line format to display. Value is the pixel
12514 height of the mode line displayed. */
12517 display_mode_line (w
, face_id
, format
)
12519 enum face_id face_id
;
12520 Lisp_Object format
;
12525 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
12526 prepare_desired_row (it
.glyph_row
);
12528 if (! mode_line_inverse_video
)
12529 /* Force the mode-line to be displayed in the default face. */
12530 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
12532 /* Temporarily make frame's keyboard the current kboard so that
12533 kboard-local variables in the mode_line_format will get the right
12535 push_frame_kboard (it
.f
);
12536 display_mode_element (&it
, 0, 0, 0, format
);
12537 pop_frame_kboard ();
12539 /* Fill up with spaces. */
12540 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
12542 compute_line_metrics (&it
);
12543 it
.glyph_row
->full_width_p
= 1;
12544 it
.glyph_row
->mode_line_p
= 1;
12545 it
.glyph_row
->inverse_p
= 0;
12546 it
.glyph_row
->continued_p
= 0;
12547 it
.glyph_row
->truncated_on_left_p
= 0;
12548 it
.glyph_row
->truncated_on_right_p
= 0;
12550 /* Make a 3D mode-line have a shadow at its right end. */
12551 face
= FACE_FROM_ID (it
.f
, face_id
);
12552 extend_face_to_end_of_line (&it
);
12553 if (face
->box
!= FACE_NO_BOX
)
12555 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
12556 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
12557 last
->right_box_line_p
= 1;
12560 return it
.glyph_row
->height
;
12564 /* Contribute ELT to the mode line for window IT->w. How it
12565 translates into text depends on its data type.
12567 IT describes the display environment in which we display, as usual.
12569 DEPTH is the depth in recursion. It is used to prevent
12570 infinite recursion here.
12572 FIELD_WIDTH is the number of characters the display of ELT should
12573 occupy in the mode line, and PRECISION is the maximum number of
12574 characters to display from ELT's representation. See
12575 display_string for details. *
12577 Returns the hpos of the end of the text generated by ELT. */
12580 display_mode_element (it
, depth
, field_width
, precision
, elt
)
12583 int field_width
, precision
;
12586 int n
= 0, field
, prec
;
12594 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
12598 /* A string: output it and check for %-constructs within it. */
12600 unsigned char *this = XSTRING (elt
)->data
;
12601 unsigned char *lisp_string
= this;
12603 while ((precision
<= 0 || n
< precision
)
12605 && (frame_title_ptr
12606 || it
->current_x
< it
->last_visible_x
))
12608 unsigned char *last
= this;
12610 /* Advance to end of string or next format specifier. */
12611 while ((c
= *this++) != '\0' && c
!= '%')
12614 if (this - 1 != last
)
12616 /* Output to end of string or up to '%'. Field width
12617 is length of string. Don't output more than
12618 PRECISION allows us. */
12619 prec
= --this - last
;
12620 if (precision
> 0 && prec
> precision
- n
)
12621 prec
= precision
- n
;
12623 if (frame_title_ptr
)
12624 n
+= store_frame_title (last
, prec
, prec
);
12626 n
+= display_string (NULL
, elt
, Qnil
, 0, last
- lisp_string
,
12627 it
, 0, prec
, 0, -1);
12629 else /* c == '%' */
12631 unsigned char *percent_position
= this;
12633 /* Get the specified minimum width. Zero means
12636 while ((c
= *this++) >= '0' && c
<= '9')
12637 field
= field
* 10 + c
- '0';
12639 /* Don't pad beyond the total padding allowed. */
12640 if (field_width
- n
> 0 && field
> field_width
- n
)
12641 field
= field_width
- n
;
12643 /* Note that either PRECISION <= 0 or N < PRECISION. */
12644 prec
= precision
- n
;
12647 n
+= display_mode_element (it
, depth
, field
, prec
,
12648 Vglobal_mode_string
);
12651 unsigned char *spec
12652 = decode_mode_spec (it
->w
, c
, field
, prec
);
12654 if (frame_title_ptr
)
12655 n
+= store_frame_title (spec
, field
, prec
);
12659 = it
->glyph_row
->used
[TEXT_AREA
];
12661 = percent_position
- XSTRING (elt
)->data
;
12663 = display_string (spec
, Qnil
, elt
, charpos
, 0, it
,
12664 field
, prec
, 0, -1);
12666 /* Assign to the glyphs written above the
12667 string where the `%x' came from, position
12671 struct glyph
*glyph
12672 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
12676 for (i
= 0; i
< nwritten
; ++i
)
12678 glyph
[i
].object
= elt
;
12679 glyph
[i
].charpos
= charpos
;
12692 /* A symbol: process the value of the symbol recursively
12693 as if it appeared here directly. Avoid error if symbol void.
12694 Special case: if value of symbol is a string, output the string
12697 register Lisp_Object tem
;
12698 tem
= Fboundp (elt
);
12701 tem
= Fsymbol_value (elt
);
12702 /* If value is a string, output that string literally:
12703 don't check for % within it. */
12706 prec
= XSTRING (tem
)->size
;
12707 if (precision
> 0 && prec
> precision
- n
)
12708 prec
= precision
- n
;
12709 if (frame_title_ptr
)
12710 n
+= store_frame_title (XSTRING (tem
)->data
, -1, prec
);
12712 n
+= display_string (NULL
, tem
, Qnil
, 0, 0, it
,
12715 else if (!EQ (tem
, elt
))
12717 /* Give up right away for nil or t. */
12727 register Lisp_Object car
, tem
;
12729 /* A cons cell: three distinct cases.
12730 If first element is a string or a cons, process all the elements
12731 and effectively concatenate them.
12732 If first element is a negative number, truncate displaying cdr to
12733 at most that many characters. If positive, pad (with spaces)
12734 to at least that many characters.
12735 If first element is a symbol, process the cadr or caddr recursively
12736 according to whether the symbol's value is non-nil or nil. */
12738 if (EQ (car
, QCeval
) && CONSP (XCDR (elt
)))
12740 /* An element of the form (:eval FORM) means evaluate FORM
12741 and use the result as mode line elements. */
12742 struct gcpro gcpro1
;
12745 spec
= safe_eval (XCAR (XCDR (elt
)));
12747 n
+= display_mode_element (it
, depth
, field_width
- n
,
12748 precision
- n
, spec
);
12751 else if (SYMBOLP (car
))
12753 tem
= Fboundp (car
);
12757 /* elt is now the cdr, and we know it is a cons cell.
12758 Use its car if CAR has a non-nil value. */
12761 tem
= Fsymbol_value (car
);
12768 /* Symbol's value is nil (or symbol is unbound)
12769 Get the cddr of the original list
12770 and if possible find the caddr and use that. */
12774 else if (!CONSP (elt
))
12779 else if (INTEGERP (car
))
12781 register int lim
= XINT (car
);
12785 /* Negative int means reduce maximum width. */
12786 if (precision
<= 0)
12789 precision
= min (precision
, -lim
);
12793 /* Padding specified. Don't let it be more than
12794 current maximum. */
12796 lim
= min (precision
, lim
);
12798 /* If that's more padding than already wanted, queue it.
12799 But don't reduce padding already specified even if
12800 that is beyond the current truncation point. */
12801 field_width
= max (lim
, field_width
);
12805 else if (STRINGP (car
) || CONSP (car
))
12807 register int limit
= 50;
12808 /* Limit is to protect against circular lists. */
12811 && (precision
<= 0 || n
< precision
))
12813 n
+= display_mode_element (it
, depth
, field_width
- n
,
12814 precision
- n
, XCAR (elt
));
12823 if (frame_title_ptr
)
12824 n
+= store_frame_title ("*invalid*", 0, precision
- n
);
12826 n
+= display_string ("*invalid*", Qnil
, Qnil
, 0, 0, it
, 0,
12827 precision
- n
, 0, 0);
12831 /* Pad to FIELD_WIDTH. */
12832 if (field_width
> 0 && n
< field_width
)
12834 if (frame_title_ptr
)
12835 n
+= store_frame_title ("", field_width
- n
, 0);
12837 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
12845 /* Write a null-terminated, right justified decimal representation of
12846 the positive integer D to BUF using a minimal field width WIDTH. */
12849 pint2str (buf
, width
, d
)
12850 register char *buf
;
12851 register int width
;
12854 register char *p
= buf
;
12862 *p
++ = d
% 10 + '0';
12867 for (width
-= (int) (p
- buf
); width
> 0; --width
)
12878 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
12879 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
12880 type of CODING_SYSTEM. Return updated pointer into BUF. */
12882 static unsigned char invalid_eol_type
[] = "(*invalid*)";
12885 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
12886 Lisp_Object coding_system
;
12887 register char *buf
;
12891 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
12892 unsigned char *eol_str
;
12894 /* The EOL conversion we are using. */
12895 Lisp_Object eoltype
;
12897 val
= Fget (coding_system
, Qcoding_system
);
12900 if (!VECTORP (val
)) /* Not yet decided. */
12905 eoltype
= eol_mnemonic_undecided
;
12906 /* Don't mention EOL conversion if it isn't decided. */
12910 Lisp_Object eolvalue
;
12912 eolvalue
= Fget (coding_system
, Qeol_type
);
12915 *buf
++ = XFASTINT (XVECTOR (val
)->contents
[1]);
12919 /* The EOL conversion that is normal on this system. */
12921 if (NILP (eolvalue
)) /* Not yet decided. */
12922 eoltype
= eol_mnemonic_undecided
;
12923 else if (VECTORP (eolvalue
)) /* Not yet decided. */
12924 eoltype
= eol_mnemonic_undecided
;
12925 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
12926 eoltype
= (XFASTINT (eolvalue
) == 0
12927 ? eol_mnemonic_unix
12928 : (XFASTINT (eolvalue
) == 1
12929 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
12935 /* Mention the EOL conversion if it is not the usual one. */
12936 if (STRINGP (eoltype
))
12938 eol_str
= XSTRING (eoltype
)->data
;
12939 eol_str_len
= XSTRING (eoltype
)->size
;
12941 else if (INTEGERP (eoltype
)
12942 && CHAR_VALID_P (XINT (eoltype
), 0))
12944 eol_str
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
12945 eol_str_len
= CHAR_STRING (XINT (eoltype
), eol_str
);
12949 eol_str
= invalid_eol_type
;
12950 eol_str_len
= sizeof (invalid_eol_type
) - 1;
12952 bcopy (eol_str
, buf
, eol_str_len
);
12953 buf
+= eol_str_len
;
12959 /* Return a string for the output of a mode line %-spec for window W,
12960 generated by character C. PRECISION >= 0 means don't return a
12961 string longer than that value. FIELD_WIDTH > 0 means pad the
12962 string returned with spaces to that value. */
12964 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
12967 decode_mode_spec (w
, c
, field_width
, precision
)
12970 int field_width
, precision
;
12973 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
12974 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
12975 struct buffer
*b
= XBUFFER (w
->buffer
);
12982 if (!NILP (b
->read_only
))
12984 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
12989 /* This differs from %* only for a modified read-only buffer. */
12990 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
12992 if (!NILP (b
->read_only
))
12997 /* This differs from %* in ignoring read-only-ness. */
12998 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
13010 if (command_loop_level
> 5)
13012 p
= decode_mode_spec_buf
;
13013 for (i
= 0; i
< command_loop_level
; i
++)
13016 return decode_mode_spec_buf
;
13024 if (command_loop_level
> 5)
13026 p
= decode_mode_spec_buf
;
13027 for (i
= 0; i
< command_loop_level
; i
++)
13030 return decode_mode_spec_buf
;
13037 /* Let lots_of_dashes be a string of infinite length. */
13038 if (field_width
<= 0
13039 || field_width
> sizeof (lots_of_dashes
))
13041 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
13042 decode_mode_spec_buf
[i
] = '-';
13043 decode_mode_spec_buf
[i
] = '\0';
13044 return decode_mode_spec_buf
;
13047 return lots_of_dashes
;
13056 int col
= current_column ();
13057 XSETFASTINT (w
->column_number_displayed
, col
);
13058 pint2str (decode_mode_spec_buf
, field_width
, col
);
13059 return decode_mode_spec_buf
;
13063 /* %F displays the frame name. */
13064 if (!NILP (f
->title
))
13065 return (char *) XSTRING (f
->title
)->data
;
13066 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
13067 return (char *) XSTRING (f
->name
)->data
;
13076 int startpos
= XMARKER (w
->start
)->charpos
;
13077 int startpos_byte
= marker_byte_position (w
->start
);
13078 int line
, linepos
, linepos_byte
, topline
;
13080 int height
= XFASTINT (w
->height
);
13082 /* If we decided that this buffer isn't suitable for line numbers,
13083 don't forget that too fast. */
13084 if (EQ (w
->base_line_pos
, w
->buffer
))
13086 /* But do forget it, if the window shows a different buffer now. */
13087 else if (BUFFERP (w
->base_line_pos
))
13088 w
->base_line_pos
= Qnil
;
13090 /* If the buffer is very big, don't waste time. */
13091 if (INTEGERP (Vline_number_display_limit
)
13092 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
13094 w
->base_line_pos
= Qnil
;
13095 w
->base_line_number
= Qnil
;
13099 if (!NILP (w
->base_line_number
)
13100 && !NILP (w
->base_line_pos
)
13101 && XFASTINT (w
->base_line_pos
) <= startpos
)
13103 line
= XFASTINT (w
->base_line_number
);
13104 linepos
= XFASTINT (w
->base_line_pos
);
13105 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
13110 linepos
= BUF_BEGV (b
);
13111 linepos_byte
= BUF_BEGV_BYTE (b
);
13114 /* Count lines from base line to window start position. */
13115 nlines
= display_count_lines (linepos
, linepos_byte
,
13119 topline
= nlines
+ line
;
13121 /* Determine a new base line, if the old one is too close
13122 or too far away, or if we did not have one.
13123 "Too close" means it's plausible a scroll-down would
13124 go back past it. */
13125 if (startpos
== BUF_BEGV (b
))
13127 XSETFASTINT (w
->base_line_number
, topline
);
13128 XSETFASTINT (w
->base_line_pos
, BUF_BEGV (b
));
13130 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
13131 || linepos
== BUF_BEGV (b
))
13133 int limit
= BUF_BEGV (b
);
13134 int limit_byte
= BUF_BEGV_BYTE (b
);
13136 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
13138 if (startpos
- distance
> limit
)
13140 limit
= startpos
- distance
;
13141 limit_byte
= CHAR_TO_BYTE (limit
);
13144 nlines
= display_count_lines (startpos
, startpos_byte
,
13146 - (height
* 2 + 30),
13148 /* If we couldn't find the lines we wanted within
13149 line_number_display_limit_width chars per line,
13150 give up on line numbers for this window. */
13151 if (position
== limit_byte
&& limit
== startpos
- distance
)
13153 w
->base_line_pos
= w
->buffer
;
13154 w
->base_line_number
= Qnil
;
13158 XSETFASTINT (w
->base_line_number
, topline
- nlines
);
13159 XSETFASTINT (w
->base_line_pos
, BYTE_TO_CHAR (position
));
13162 /* Now count lines from the start pos to point. */
13163 nlines
= display_count_lines (startpos
, startpos_byte
,
13164 PT_BYTE
, PT
, &junk
);
13166 /* Record that we did display the line number. */
13167 line_number_displayed
= 1;
13169 /* Make the string to show. */
13170 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
13171 return decode_mode_spec_buf
;
13174 char* p
= decode_mode_spec_buf
;
13175 int pad
= field_width
- 2;
13181 return decode_mode_spec_buf
;
13187 obj
= b
->mode_name
;
13191 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
13197 int pos
= marker_position (w
->start
);
13198 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
13200 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
13202 if (pos
<= BUF_BEGV (b
))
13207 else if (pos
<= BUF_BEGV (b
))
13211 if (total
> 1000000)
13212 /* Do it differently for a large value, to avoid overflow. */
13213 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
13215 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
13216 /* We can't normally display a 3-digit number,
13217 so get us a 2-digit number that is close. */
13220 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
13221 return decode_mode_spec_buf
;
13225 /* Display percentage of size above the bottom of the screen. */
13228 int toppos
= marker_position (w
->start
);
13229 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
13230 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
13232 if (botpos
>= BUF_ZV (b
))
13234 if (toppos
<= BUF_BEGV (b
))
13241 if (total
> 1000000)
13242 /* Do it differently for a large value, to avoid overflow. */
13243 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
13245 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
13246 /* We can't normally display a 3-digit number,
13247 so get us a 2-digit number that is close. */
13250 if (toppos
<= BUF_BEGV (b
))
13251 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
13253 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
13254 return decode_mode_spec_buf
;
13259 /* status of process */
13260 obj
= Fget_buffer_process (w
->buffer
);
13262 return "no process";
13263 #ifdef subprocesses
13264 obj
= Fsymbol_name (Fprocess_status (obj
));
13268 case 't': /* indicate TEXT or BINARY */
13269 #ifdef MODE_LINE_BINARY_TEXT
13270 return MODE_LINE_BINARY_TEXT (b
);
13276 /* coding-system (not including end-of-line format) */
13278 /* coding-system (including end-of-line type) */
13280 int eol_flag
= (c
== 'Z');
13281 char *p
= decode_mode_spec_buf
;
13283 if (! FRAME_WINDOW_P (f
))
13285 /* No need to mention EOL here--the terminal never needs
13286 to do EOL conversion. */
13287 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
13288 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
13290 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
13293 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
13294 #ifdef subprocesses
13295 obj
= Fget_buffer_process (Fcurrent_buffer ());
13296 if (PROCESSP (obj
))
13298 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
13300 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
13303 #endif /* subprocesses */
13306 return decode_mode_spec_buf
;
13311 return (char *) XSTRING (obj
)->data
;
13317 /* Count up to COUNT lines starting from START / START_BYTE.
13318 But don't go beyond LIMIT_BYTE.
13319 Return the number of lines thus found (always nonnegative).
13321 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
13324 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
13325 int start
, start_byte
, limit_byte
, count
;
13328 register unsigned char *cursor
;
13329 unsigned char *base
;
13331 register int ceiling
;
13332 register unsigned char *ceiling_addr
;
13333 int orig_count
= count
;
13335 /* If we are not in selective display mode,
13336 check only for newlines. */
13337 int selective_display
= (!NILP (current_buffer
->selective_display
)
13338 && !INTEGERP (current_buffer
->selective_display
));
13342 while (start_byte
< limit_byte
)
13344 ceiling
= BUFFER_CEILING_OF (start_byte
);
13345 ceiling
= min (limit_byte
- 1, ceiling
);
13346 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
13347 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
13350 if (selective_display
)
13351 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
13354 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
13357 if (cursor
!= ceiling_addr
)
13361 start_byte
+= cursor
- base
+ 1;
13362 *byte_pos_ptr
= start_byte
;
13366 if (++cursor
== ceiling_addr
)
13372 start_byte
+= cursor
- base
;
13377 while (start_byte
> limit_byte
)
13379 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
13380 ceiling
= max (limit_byte
, ceiling
);
13381 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
13382 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
13385 if (selective_display
)
13386 while (--cursor
!= ceiling_addr
13387 && *cursor
!= '\n' && *cursor
!= 015)
13390 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
13393 if (cursor
!= ceiling_addr
)
13397 start_byte
+= cursor
- base
+ 1;
13398 *byte_pos_ptr
= start_byte
;
13399 /* When scanning backwards, we should
13400 not count the newline posterior to which we stop. */
13401 return - orig_count
- 1;
13407 /* Here we add 1 to compensate for the last decrement
13408 of CURSOR, which took it past the valid range. */
13409 start_byte
+= cursor
- base
+ 1;
13413 *byte_pos_ptr
= limit_byte
;
13416 return - orig_count
+ count
;
13417 return orig_count
- count
;
13423 /***********************************************************************
13425 ***********************************************************************/
13427 /* Display a NUL-terminated string, starting with index START.
13429 If STRING is non-null, display that C string. Otherwise, the Lisp
13430 string LISP_STRING is displayed.
13432 If FACE_STRING is not nil, FACE_STRING_POS is a position in
13433 FACE_STRING. Display STRING or LISP_STRING with the face at
13434 FACE_STRING_POS in FACE_STRING:
13436 Display the string in the environment given by IT, but use the
13437 standard display table, temporarily.
13439 FIELD_WIDTH is the minimum number of output glyphs to produce.
13440 If STRING has fewer characters than FIELD_WIDTH, pad to the right
13441 with spaces. If STRING has more characters, more than FIELD_WIDTH
13442 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
13444 PRECISION is the maximum number of characters to output from
13445 STRING. PRECISION < 0 means don't truncate the string.
13447 This is roughly equivalent to printf format specifiers:
13449 FIELD_WIDTH PRECISION PRINTF
13450 ----------------------------------------
13456 MULTIBYTE zero means do not display multibyte chars, > 0 means do
13457 display them, and < 0 means obey the current buffer's value of
13458 enable_multibyte_characters.
13460 Value is the number of glyphs produced. */
13463 display_string (string
, lisp_string
, face_string
, face_string_pos
,
13464 start
, it
, field_width
, precision
, max_x
, multibyte
)
13465 unsigned char *string
;
13466 Lisp_Object lisp_string
;
13467 Lisp_Object face_string
;
13468 int face_string_pos
;
13471 int field_width
, precision
, max_x
;
13474 int hpos_at_start
= it
->hpos
;
13475 int saved_face_id
= it
->face_id
;
13476 struct glyph_row
*row
= it
->glyph_row
;
13478 /* Initialize the iterator IT for iteration over STRING beginning
13479 with index START. We assume that IT may be modified here (which
13480 means that display_line has to do something when displaying a
13481 mini-buffer prompt, which it does). */
13482 reseat_to_string (it
, string
, lisp_string
, start
,
13483 precision
, field_width
, multibyte
);
13485 /* If displaying STRING, set up the face of the iterator
13486 from LISP_STRING, if that's given. */
13487 if (STRINGP (face_string
))
13493 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
13494 0, it
->region_beg_charpos
,
13495 it
->region_end_charpos
,
13496 &endptr
, it
->base_face_id
);
13497 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
13498 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
13501 /* Set max_x to the maximum allowed X position. Don't let it go
13502 beyond the right edge of the window. */
13504 max_x
= it
->last_visible_x
;
13506 max_x
= min (max_x
, it
->last_visible_x
);
13508 /* Skip over display elements that are not visible. because IT->w is
13510 if (it
->current_x
< it
->first_visible_x
)
13511 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
13512 MOVE_TO_POS
| MOVE_TO_X
);
13514 row
->ascent
= it
->max_ascent
;
13515 row
->height
= it
->max_ascent
+ it
->max_descent
;
13516 row
->phys_ascent
= it
->max_phys_ascent
;
13517 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
13519 /* This condition is for the case that we are called with current_x
13520 past last_visible_x. */
13521 while (it
->current_x
< max_x
)
13523 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
13525 /* Get the next display element. */
13526 if (!get_next_display_element (it
))
13529 /* Produce glyphs. */
13530 x_before
= it
->current_x
;
13531 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
13532 PRODUCE_GLYPHS (it
);
13534 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
13537 while (i
< nglyphs
)
13539 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
13541 if (!it
->truncate_lines_p
13542 && x
+ glyph
->pixel_width
> max_x
)
13544 /* End of continued line or max_x reached. */
13545 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
13549 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
13551 /* Glyph is at least partially visible. */
13553 if (x
< it
->first_visible_x
)
13554 it
->glyph_row
->x
= x
- it
->first_visible_x
;
13558 /* Glyph is off the left margin of the display area.
13559 Should not happen. */
13563 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
13564 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
13565 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
13566 row
->phys_height
= max (row
->phys_height
,
13567 it
->max_phys_ascent
+ it
->max_phys_descent
);
13568 x
+= glyph
->pixel_width
;
13572 /* Stop if max_x reached. */
13576 /* Stop at line ends. */
13577 if (ITERATOR_AT_END_OF_LINE_P (it
))
13579 it
->continuation_lines_width
= 0;
13583 set_iterator_to_next (it
, 1);
13585 /* Stop if truncating at the right edge. */
13586 if (it
->truncate_lines_p
13587 && it
->current_x
>= it
->last_visible_x
)
13589 /* Add truncation mark, but don't do it if the line is
13590 truncated at a padding space. */
13591 if (IT_CHARPOS (*it
) < it
->string_nchars
)
13593 if (!FRAME_WINDOW_P (it
->f
))
13594 produce_special_glyphs (it
, IT_TRUNCATION
);
13595 it
->glyph_row
->truncated_on_right_p
= 1;
13601 /* Maybe insert a truncation at the left. */
13602 if (it
->first_visible_x
13603 && IT_CHARPOS (*it
) > 0)
13605 if (!FRAME_WINDOW_P (it
->f
))
13606 insert_left_trunc_glyphs (it
);
13607 it
->glyph_row
->truncated_on_left_p
= 1;
13610 it
->face_id
= saved_face_id
;
13612 /* Value is number of columns displayed. */
13613 return it
->hpos
- hpos_at_start
;
13618 /* This is like a combination of memq and assq. Return 1 if PROPVAL
13619 appears as an element of LIST or as the car of an element of LIST.
13620 If PROPVAL is a list, compare each element against LIST in that
13621 way, and return 1 if any element of PROPVAL is found in LIST.
13622 Otherwise return 0. This function cannot quit. */
13625 invisible_p (propval
, list
)
13626 register Lisp_Object propval
;
13629 register Lisp_Object tail
, proptail
;
13631 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
13633 register Lisp_Object tem
;
13635 if (EQ (propval
, tem
))
13637 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
13641 if (CONSP (propval
))
13643 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
13645 Lisp_Object propelt
;
13646 propelt
= XCAR (proptail
);
13647 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
13649 register Lisp_Object tem
;
13651 if (EQ (propelt
, tem
))
13653 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
13663 /* Return 1 if PROPVAL appears as the car of an element of LIST and
13664 the cdr of that element is non-nil. If PROPVAL is a list, check
13665 each element of PROPVAL in that way, and the first time some
13666 element is found, return 1 if the cdr of that element is non-nil.
13667 Otherwise return 0. This function cannot quit. */
13670 invisible_ellipsis_p (propval
, list
)
13671 register Lisp_Object propval
;
13674 register Lisp_Object tail
, proptail
;
13676 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
13678 register Lisp_Object tem
;
13680 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
13681 return ! NILP (XCDR (tem
));
13684 if (CONSP (propval
))
13685 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
13687 Lisp_Object propelt
;
13688 propelt
= XCAR (proptail
);
13689 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
13691 register Lisp_Object tem
;
13693 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
13694 return ! NILP (XCDR (tem
));
13703 /***********************************************************************
13705 ***********************************************************************/
13710 Vwith_echo_area_save_vector
= Qnil
;
13711 staticpro (&Vwith_echo_area_save_vector
);
13713 Vmessage_stack
= Qnil
;
13714 staticpro (&Vmessage_stack
);
13716 Qinhibit_redisplay
= intern ("inhibit-redisplay");
13717 staticpro (&Qinhibit_redisplay
);
13720 defsubr (&Sdump_glyph_matrix
);
13721 defsubr (&Sdump_glyph_row
);
13722 defsubr (&Sdump_tool_bar_row
);
13723 defsubr (&Strace_redisplay_toggle
);
13724 defsubr (&Strace_to_stderr
);
13727 staticpro (&Qmenu_bar_update_hook
);
13728 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
13730 staticpro (&Qoverriding_terminal_local_map
);
13731 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
13733 staticpro (&Qoverriding_local_map
);
13734 Qoverriding_local_map
= intern ("overriding-local-map");
13736 staticpro (&Qwindow_scroll_functions
);
13737 Qwindow_scroll_functions
= intern ("window-scroll-functions");
13739 staticpro (&Qredisplay_end_trigger_functions
);
13740 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
13742 staticpro (&Qinhibit_point_motion_hooks
);
13743 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
13745 QCdata
= intern (":data");
13746 staticpro (&QCdata
);
13747 Qdisplay
= intern ("display");
13748 staticpro (&Qdisplay
);
13749 Qspace_width
= intern ("space-width");
13750 staticpro (&Qspace_width
);
13751 Qraise
= intern ("raise");
13752 staticpro (&Qraise
);
13753 Qspace
= intern ("space");
13754 staticpro (&Qspace
);
13755 Qmargin
= intern ("margin");
13756 staticpro (&Qmargin
);
13757 Qleft_margin
= intern ("left-margin");
13758 staticpro (&Qleft_margin
);
13759 Qright_margin
= intern ("right-margin");
13760 staticpro (&Qright_margin
);
13761 Qalign_to
= intern ("align-to");
13762 staticpro (&Qalign_to
);
13763 QCalign_to
= intern (":align-to");
13764 staticpro (&QCalign_to
);
13765 Qrelative_width
= intern ("relative-width");
13766 staticpro (&Qrelative_width
);
13767 QCrelative_width
= intern (":relative-width");
13768 staticpro (&QCrelative_width
);
13769 QCrelative_height
= intern (":relative-height");
13770 staticpro (&QCrelative_height
);
13771 QCeval
= intern (":eval");
13772 staticpro (&QCeval
);
13773 Qwhen
= intern ("when");
13774 staticpro (&Qwhen
);
13775 QCfile
= intern (":file");
13776 staticpro (&QCfile
);
13777 Qfontified
= intern ("fontified");
13778 staticpro (&Qfontified
);
13779 Qfontification_functions
= intern ("fontification-functions");
13780 staticpro (&Qfontification_functions
);
13781 Qtrailing_whitespace
= intern ("trailing-whitespace");
13782 staticpro (&Qtrailing_whitespace
);
13783 Qimage
= intern ("image");
13784 staticpro (&Qimage
);
13785 Qmessage_truncate_lines
= intern ("message-truncate-lines");
13786 staticpro (&Qmessage_truncate_lines
);
13787 Qgrow_only
= intern ("grow-only");
13788 staticpro (&Qgrow_only
);
13790 last_arrow_position
= Qnil
;
13791 last_arrow_string
= Qnil
;
13792 staticpro (&last_arrow_position
);
13793 staticpro (&last_arrow_string
);
13795 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
13796 staticpro (&echo_buffer
[0]);
13797 staticpro (&echo_buffer
[1]);
13799 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
13800 staticpro (&echo_area_buffer
[0]);
13801 staticpro (&echo_area_buffer
[1]);
13803 Vmessages_buffer_name
= build_string ("*Messages*");
13804 staticpro (&Vmessages_buffer_name
);
13806 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
13807 "Non-nil means highlight trailing whitespace.\n\
13808 The face used for trailing whitespace is `trailing-whitespace'.");
13809 Vshow_trailing_whitespace
= Qnil
;
13811 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
13812 "Non-nil means don't actually do any redisplay.\n\
13813 This is used for internal purposes.");
13814 Vinhibit_redisplay
= Qnil
;
13816 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
13817 "String (or mode line construct) included (normally) in `mode-line-format'.");
13818 Vglobal_mode_string
= Qnil
;
13820 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
13821 "Marker for where to display an arrow on top of the buffer text.\n\
13822 This must be the beginning of a line in order to work.\n\
13823 See also `overlay-arrow-string'.");
13824 Voverlay_arrow_position
= Qnil
;
13826 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
13827 "String to display as an arrow. See also `overlay-arrow-position'.");
13828 Voverlay_arrow_string
= Qnil
;
13830 DEFVAR_INT ("scroll-step", &scroll_step
,
13831 "*The number of lines to try scrolling a window by when point moves out.\n\
13832 If that fails to bring point back on frame, point is centered instead.\n\
13833 If this is zero, point is always centered after it moves off frame.\n\
13834 If you want scrolling to always be a line at a time, you should set\n\
13835 `scroll-conservatively' to a large value rather than set this to 1.");
13837 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
13838 "*Scroll up to this many lines, to bring point back on screen.\n\
13839 A value of zero means to scroll the text to center point vertically\n\
13841 scroll_conservatively
= 0;
13843 DEFVAR_INT ("scroll-margin", &scroll_margin
,
13844 "*Number of lines of margin at the top and bottom of a window.\n\
13845 Recenter the window whenever point gets within this many lines\n\
13846 of the top or bottom of the window.");
13850 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, "Don't ask");
13853 DEFVAR_BOOL ("truncate-partial-width-windows",
13854 &truncate_partial_width_windows
,
13855 "*Non-nil means truncate lines in all windows less than full frame wide.");
13856 truncate_partial_width_windows
= 1;
13858 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
13859 "nil means display the mode-line/header-line/menu-bar in the default face.\n\
13860 Any other value means to use the appropriate face, `mode-line',\n\
13861 `header-line', or `menu' respectively.\n\
13863 This variable is deprecated; please change the above faces instead.");
13864 mode_line_inverse_video
= 1;
13866 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
13867 "*Maximum buffer size for which line number should be displayed.\n\
13868 If the buffer is bigger than this, the line number does not appear\n\
13869 in the mode line. A value of nil means no limit.");
13870 Vline_number_display_limit
= Qnil
;
13872 DEFVAR_INT ("line-number-display-limit-width",
13873 &line_number_display_limit_width
,
13874 "*Maximum line width (in characters) for line number display.\n\
13875 If the average length of the lines near point is bigger than this, then the\n\
13876 line number may be omitted from the mode line.");
13877 line_number_display_limit_width
= 200;
13879 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
13880 "*Non-nil means highlight region even in nonselected windows.");
13881 highlight_nonselected_windows
= 0;
13883 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
13884 "Non-nil if more than one frame is visible on this display.\n\
13885 Minibuffer-only frames don't count, but iconified frames do.\n\
13886 This variable is not guaranteed to be accurate except while processing\n\
13887 `frame-title-format' and `icon-title-format'.");
13889 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
13890 "Template for displaying the title bar of visible frames.\n\
13891 \(Assuming the window manager supports this feature.)\n\
13892 This variable has the same structure as `mode-line-format' (which see),\n\
13893 and is used only on frames for which no explicit name has been set\n\
13894 \(see `modify-frame-parameters').");
13895 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
13896 "Template for displaying the title bar of an iconified frame.\n\
13897 \(Assuming the window manager supports this feature.)\n\
13898 This variable has the same structure as `mode-line-format' (which see),\n\
13899 and is used only on frames for which no explicit name has been set\n\
13900 \(see `modify-frame-parameters').");
13902 = Vframe_title_format
13903 = Fcons (intern ("multiple-frames"),
13904 Fcons (build_string ("%b"),
13905 Fcons (Fcons (build_string (""),
13906 Fcons (intern ("invocation-name"),
13907 Fcons (build_string ("@"),
13908 Fcons (intern ("system-name"),
13912 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
13913 "Maximum number of lines to keep in the message log buffer.\n\
13914 If nil, disable message logging. If t, log messages but don't truncate\n\
13915 the buffer when it becomes large.");
13916 XSETFASTINT (Vmessage_log_max
, 50);
13918 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
13919 "Functions called before redisplay, if window sizes have changed.\n\
13920 The value should be a list of functions that take one argument.\n\
13921 Just before redisplay, for each frame, if any of its windows have changed\n\
13922 size since the last redisplay, or have been split or deleted,\n\
13923 all the functions in the list are called, with the frame as argument.");
13924 Vwindow_size_change_functions
= Qnil
;
13926 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
13927 "List of Functions to call before redisplaying a window with scrolling.\n\
13928 Each function is called with two arguments, the window\n\
13929 and its new display-start position. Note that the value of `window-end'\n\
13930 is not valid when these functions are called.");
13931 Vwindow_scroll_functions
= Qnil
;
13933 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
13934 "*Non-nil means automatically resize tool-bars.\n\
13935 This increases a tool-bar's height if not all tool-bar items are visible.\n\
13936 It decreases a tool-bar's height when it would display blank lines\n\
13938 auto_resize_tool_bars_p
= 1;
13940 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
13941 "*Non-nil means raise tool-bar buttons when the mouse moves over them.");
13942 auto_raise_tool_bar_buttons_p
= 1;
13944 DEFVAR_INT ("tool-bar-button-margin", &tool_bar_button_margin
,
13945 "*Margin around tool-bar buttons in pixels.");
13946 tool_bar_button_margin
= 1;
13948 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
13949 "Relief thickness of tool-bar buttons.");
13950 tool_bar_button_relief
= 3;
13952 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
13953 "List of functions to call to fontify regions of text.\n\
13954 Each function is called with one argument POS. Functions must\n\
13955 fontify a region starting at POS in the current buffer, and give\n\
13956 fontified regions the property `fontified'.\n\
13957 This variable automatically becomes buffer-local when set.");
13958 Vfontification_functions
= Qnil
;
13959 Fmake_variable_buffer_local (Qfontification_functions
);
13961 DEFVAR_BOOL ("unibyte-display-via-language-environment",
13962 &unibyte_display_via_language_environment
,
13963 "*Non-nil means display unibyte text according to language environment.\n\
13964 Specifically this means that unibyte non-ASCII characters\n\
13965 are displayed by converting them to the equivalent multibyte characters\n\
13966 according to the current language environment. As a result, they are\n\
13967 displayed according to the current fontset.");
13968 unibyte_display_via_language_environment
= 0;
13970 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
13971 "*Maximum height for resizing mini-windows.\n\
13972 If a float, it specifies a fraction of the mini-window frame's height.\n\
13973 If an integer, it specifies a number of lines.");
13974 Vmax_mini_window_height
= make_float (0.25);
13976 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
13977 "*How to resize the mini-window.\n\
13978 A value of nil means don't automatically resize mini-windows.\n\
13979 A value of t means resize it to fit the text displayed in it.\n\
13980 A value of `grow-only', the default, means let mini-windows grow\n\
13981 only, until the its display becomes empty, at which point the mini-window\n\
13982 goes back to its normal size.");
13983 Vresize_mini_windows
= Qgrow_only
;
13985 DEFVAR_BOOL ("cursor-in-non-selected-windows",
13986 &cursor_in_non_selected_windows
,
13987 "*Non-nil means display a hollow cursor in non-selected windows.\n\
13988 Nil means don't display a cursor there.");
13989 cursor_in_non_selected_windows
= 1;
13991 DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p
,
13992 "*Non-nil means scroll the display automatically to make point visible.");
13993 automatic_hscrolling_p
= 1;
13995 DEFVAR_LISP ("image-types", &Vimage_types
,
13996 "List of supported image types.\n\
13997 Each element of the list is a symbol for a supported image type.");
13998 Vimage_types
= Qnil
;
14000 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
14001 "If non-nil, messages are truncated instead of resizing the echo area.\n\
14002 Bind this around calls to `message' to let it take effect.");
14003 message_truncate_lines
= 0;
14005 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
14006 "Normal hook run for clicks on menu bar, before displaying a submenu.\n\
14007 Can be used to update submenus whose contents should vary.");
14008 Vmenu_bar_update_hook
= Qnil
;
14012 /* Initialize this module when Emacs starts. */
14017 Lisp_Object root_window
;
14018 struct window
*mini_w
;
14020 current_header_line_height
= current_mode_line_height
= -1;
14022 CHARPOS (this_line_start_pos
) = 0;
14024 mini_w
= XWINDOW (minibuf_window
);
14025 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
14027 if (!noninteractive
)
14029 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
14032 XSETFASTINT (XWINDOW (root_window
)->top
, FRAME_TOP_MARGIN (f
));
14033 set_window_height (root_window
,
14034 FRAME_HEIGHT (f
) - 1 - FRAME_TOP_MARGIN (f
),
14036 XSETFASTINT (mini_w
->top
, FRAME_HEIGHT (f
) - 1);
14037 set_window_height (minibuf_window
, 1, 0);
14039 XSETFASTINT (XWINDOW (root_window
)->width
, FRAME_WIDTH (f
));
14040 XSETFASTINT (mini_w
->width
, FRAME_WIDTH (f
));
14042 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
14043 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
14044 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
14046 /* The default ellipsis glyphs `...'. */
14047 for (i
= 0; i
< 3; ++i
)
14048 XSETFASTINT (default_invis_vector
[i
], '.');
14051 #ifdef HAVE_WINDOW_SYSTEM
14053 /* Allocate the buffer for frame titles. */
14055 frame_title_buf
= (char *) xmalloc (size
);
14056 frame_title_buf_end
= frame_title_buf
+ size
;
14057 frame_title_ptr
= NULL
;
14059 #endif /* HAVE_WINDOW_SYSTEM */
14061 help_echo_showing_p
= 0;