(Info-unescape-quotes, Info-split-parameter-string)
[emacs.git] / src / xdisp.c
blobc2717552cc5340f7ddd8aaecd62d111241c252ed
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03
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)
10 any later version.
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>.
24 Redisplay.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
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 description of direct update
37 operations, below.)
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 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay do? 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
80 terminology.
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.
89 Direct operations.
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
110 Desired matrices.
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 an iterator structure (struct it)
124 argument.
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
148 Frame matrices.
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
169 #include <config.h>
170 #include <stdio.h>
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
202 Cursor No_Cursor;
203 #endif
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
209 #define INFINITY 10000000
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
217 extern int interrupt_input;
218 extern int command_loop_level;
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245 Lisp_Object Qrisky_local_variable;
247 /* Holds the list (error). */
248 Lisp_Object list_of_error;
250 /* Functions called to fontify regions of text. */
252 Lisp_Object Vfontification_functions;
253 Lisp_Object Qfontification_functions;
255 /* Non-zero means automatically select any window when the mouse
256 cursor moves into it. */
257 int mouse_autoselect_window;
259 /* Non-zero means draw tool bar buttons raised when the mouse moves
260 over them. */
262 int auto_raise_tool_bar_buttons_p;
264 /* Margin around tool bar buttons in pixels. */
266 Lisp_Object Vtool_bar_button_margin;
268 /* Thickness of shadow to draw around tool bar buttons. */
270 EMACS_INT tool_bar_button_relief;
272 /* Non-zero means automatically resize tool-bars so that all tool-bar
273 items are visible, and no blank lines remain. */
275 int auto_resize_tool_bars_p;
277 /* Non-zero means draw block and hollow cursor as wide as the glyph
278 under it. For example, if a block cursor is over a tab, it will be
279 drawn as wide as that tab on the display. */
281 int x_stretch_cursor_p;
283 /* Non-nil means don't actually do any redisplay. */
285 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
287 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
289 int inhibit_eval_during_redisplay;
291 /* Names of text properties relevant for redisplay. */
293 Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
294 extern Lisp_Object Qface, Qinvisible, Qwidth;
296 /* Symbols used in text property values. */
298 Lisp_Object Vdisplay_pixels_per_inch;
299 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
300 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
301 Lisp_Object Qmargin;
302 extern Lisp_Object Qheight;
303 extern Lisp_Object QCwidth, QCheight, QCascent;
304 extern Lisp_Object Qscroll_bar;
306 /* Non-nil means highlight trailing whitespace. */
308 Lisp_Object Vshow_trailing_whitespace;
310 /* Non-nil means show the text cursor in void text areas
311 i.e. in blank areas after eol and eob. This used to be
312 the default in 21.3. */
314 Lisp_Object Vshow_text_cursor_in_void;
316 /* Name of the face used to highlight trailing whitespace. */
318 Lisp_Object Qtrailing_whitespace;
320 /* The symbol `image' which is the car of the lists used to represent
321 images in Lisp. */
323 Lisp_Object Qimage;
325 /* Non-zero means print newline to stdout before next mini-buffer
326 message. */
328 int noninteractive_need_newline;
330 /* Non-zero means print newline to message log before next message. */
332 static int message_log_need_newline;
334 /* Three markers that message_dolog uses.
335 It could allocate them itself, but that causes trouble
336 in handling memory-full errors. */
337 static Lisp_Object message_dolog_marker1;
338 static Lisp_Object message_dolog_marker2;
339 static Lisp_Object message_dolog_marker3;
341 /* The buffer position of the first character appearing entirely or
342 partially on the line of the selected window which contains the
343 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
344 redisplay optimization in redisplay_internal. */
346 static struct text_pos this_line_start_pos;
348 /* Number of characters past the end of the line above, including the
349 terminating newline. */
351 static struct text_pos this_line_end_pos;
353 /* The vertical positions and the height of this line. */
355 static int this_line_vpos;
356 static int this_line_y;
357 static int this_line_pixel_height;
359 /* X position at which this display line starts. Usually zero;
360 negative if first character is partially visible. */
362 static int this_line_start_x;
364 /* Buffer that this_line_.* variables are referring to. */
366 static struct buffer *this_line_buffer;
368 /* Nonzero means truncate lines in all windows less wide than the
369 frame. */
371 int truncate_partial_width_windows;
373 /* A flag to control how to display unibyte 8-bit character. */
375 int unibyte_display_via_language_environment;
377 /* Nonzero means we have more than one non-mini-buffer-only frame.
378 Not guaranteed to be accurate except while parsing
379 frame-title-format. */
381 int multiple_frames;
383 Lisp_Object Vglobal_mode_string;
385 /* Marker for where to display an arrow on top of the buffer text. */
387 Lisp_Object Voverlay_arrow_position;
389 /* String to display for the arrow. Only used on terminal frames. */
391 Lisp_Object Voverlay_arrow_string;
393 /* Values of those variables at last redisplay. However, if
394 Voverlay_arrow_position is a marker, last_arrow_position is its
395 numerical position. */
397 static Lisp_Object last_arrow_position, last_arrow_string;
399 /* Like mode-line-format, but for the title bar on a visible frame. */
401 Lisp_Object Vframe_title_format;
403 /* Like mode-line-format, but for the title bar on an iconified frame. */
405 Lisp_Object Vicon_title_format;
407 /* List of functions to call when a window's size changes. These
408 functions get one arg, a frame on which one or more windows' sizes
409 have changed. */
411 static Lisp_Object Vwindow_size_change_functions;
413 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
415 /* Nonzero if overlay arrow has been displayed once in this window. */
417 static int overlay_arrow_seen;
419 /* Nonzero means highlight the region even in nonselected windows. */
421 int highlight_nonselected_windows;
423 /* If cursor motion alone moves point off frame, try scrolling this
424 many lines up or down if that will bring it back. */
426 static EMACS_INT scroll_step;
428 /* Nonzero means scroll just far enough to bring point back on the
429 screen, when appropriate. */
431 static EMACS_INT scroll_conservatively;
433 /* Recenter the window whenever point gets within this many lines of
434 the top or bottom of the window. This value is translated into a
435 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
436 that there is really a fixed pixel height scroll margin. */
438 EMACS_INT scroll_margin;
440 /* Number of windows showing the buffer of the selected window (or
441 another buffer with the same base buffer). keyboard.c refers to
442 this. */
444 int buffer_shared;
446 /* Vector containing glyphs for an ellipsis `...'. */
448 static Lisp_Object default_invis_vector[3];
450 /* Zero means display the mode-line/header-line/menu-bar in the default face
451 (this slightly odd definition is for compatibility with previous versions
452 of emacs), non-zero means display them using their respective faces.
454 This variable is deprecated. */
456 int mode_line_inverse_video;
458 /* Prompt to display in front of the mini-buffer contents. */
460 Lisp_Object minibuf_prompt;
462 /* Width of current mini-buffer prompt. Only set after display_line
463 of the line that contains the prompt. */
465 int minibuf_prompt_width;
467 /* This is the window where the echo area message was displayed. It
468 is always a mini-buffer window, but it may not be the same window
469 currently active as a mini-buffer. */
471 Lisp_Object echo_area_window;
473 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
474 pushes the current message and the value of
475 message_enable_multibyte on the stack, the function restore_message
476 pops the stack and displays MESSAGE again. */
478 Lisp_Object Vmessage_stack;
480 /* Nonzero means multibyte characters were enabled when the echo area
481 message was specified. */
483 int message_enable_multibyte;
485 /* Nonzero if we should redraw the mode lines on the next redisplay. */
487 int update_mode_lines;
489 /* Nonzero if window sizes or contents have changed since last
490 redisplay that finished. */
492 int windows_or_buffers_changed;
494 /* Nonzero means a frame's cursor type has been changed. */
496 int cursor_type_changed;
498 /* Nonzero after display_mode_line if %l was used and it displayed a
499 line number. */
501 int line_number_displayed;
503 /* Maximum buffer size for which to display line numbers. */
505 Lisp_Object Vline_number_display_limit;
507 /* Line width to consider when repositioning for line number display. */
509 static EMACS_INT line_number_display_limit_width;
511 /* Number of lines to keep in the message log buffer. t means
512 infinite. nil means don't log at all. */
514 Lisp_Object Vmessage_log_max;
516 /* The name of the *Messages* buffer, a string. */
518 static Lisp_Object Vmessages_buffer_name;
520 /* Current, index 0, and last displayed echo area message. Either
521 buffers from echo_buffers, or nil to indicate no message. */
523 Lisp_Object echo_area_buffer[2];
525 /* The buffers referenced from echo_area_buffer. */
527 static Lisp_Object echo_buffer[2];
529 /* A vector saved used in with_area_buffer to reduce consing. */
531 static Lisp_Object Vwith_echo_area_save_vector;
533 /* Non-zero means display_echo_area should display the last echo area
534 message again. Set by redisplay_preserve_echo_area. */
536 static int display_last_displayed_message_p;
538 /* Nonzero if echo area is being used by print; zero if being used by
539 message. */
541 int message_buf_print;
543 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
545 Lisp_Object Qinhibit_menubar_update;
546 int inhibit_menubar_update;
548 /* Maximum height for resizing mini-windows. Either a float
549 specifying a fraction of the available height, or an integer
550 specifying a number of lines. */
552 Lisp_Object Vmax_mini_window_height;
554 /* Non-zero means messages should be displayed with truncated
555 lines instead of being continued. */
557 int message_truncate_lines;
558 Lisp_Object Qmessage_truncate_lines;
560 /* Set to 1 in clear_message to make redisplay_internal aware
561 of an emptied echo area. */
563 static int message_cleared_p;
565 /* Non-zero means we want a hollow cursor in windows that are not
566 selected. Zero means there's no cursor in such windows. */
568 Lisp_Object Vcursor_in_non_selected_windows;
569 Lisp_Object Qcursor_in_non_selected_windows;
571 /* How to blink the default frame cursor off. */
572 Lisp_Object Vblink_cursor_alist;
574 /* A scratch glyph row with contents used for generating truncation
575 glyphs. Also used in direct_output_for_insert. */
577 #define MAX_SCRATCH_GLYPHS 100
578 struct glyph_row scratch_glyph_row;
579 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
581 /* Ascent and height of the last line processed by move_it_to. */
583 static int last_max_ascent, last_height;
585 /* Non-zero if there's a help-echo in the echo area. */
587 int help_echo_showing_p;
589 /* If >= 0, computed, exact values of mode-line and header-line height
590 to use in the macros CURRENT_MODE_LINE_HEIGHT and
591 CURRENT_HEADER_LINE_HEIGHT. */
593 int current_mode_line_height, current_header_line_height;
595 /* The maximum distance to look ahead for text properties. Values
596 that are too small let us call compute_char_face and similar
597 functions too often which is expensive. Values that are too large
598 let us call compute_char_face and alike too often because we
599 might not be interested in text properties that far away. */
601 #define TEXT_PROP_DISTANCE_LIMIT 100
603 #if GLYPH_DEBUG
605 /* Variables to turn off display optimizations from Lisp. */
607 int inhibit_try_window_id, inhibit_try_window_reusing;
608 int inhibit_try_cursor_movement;
610 /* Non-zero means print traces of redisplay if compiled with
611 GLYPH_DEBUG != 0. */
613 int trace_redisplay_p;
615 #endif /* GLYPH_DEBUG */
617 #ifdef DEBUG_TRACE_MOVE
618 /* Non-zero means trace with TRACE_MOVE to stderr. */
619 int trace_move;
621 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
622 #else
623 #define TRACE_MOVE(x) (void) 0
624 #endif
626 /* Non-zero means automatically scroll windows horizontally to make
627 point visible. */
629 int automatic_hscrolling_p;
631 /* How close to the margin can point get before the window is scrolled
632 horizontally. */
633 EMACS_INT hscroll_margin;
635 /* How much to scroll horizontally when point is inside the above margin. */
636 Lisp_Object Vhscroll_step;
638 /* A list of symbols, one for each supported image type. */
640 Lisp_Object Vimage_types;
642 /* The variable `resize-mini-windows'. If nil, don't resize
643 mini-windows. If t, always resize them to fit the text they
644 display. If `grow-only', let mini-windows grow only until they
645 become empty. */
647 Lisp_Object Vresize_mini_windows;
649 /* Buffer being redisplayed -- for redisplay_window_error. */
651 struct buffer *displayed_buffer;
653 /* Value returned from text property handlers (see below). */
655 enum prop_handled
657 HANDLED_NORMALLY,
658 HANDLED_RECOMPUTE_PROPS,
659 HANDLED_OVERLAY_STRING_CONSUMED,
660 HANDLED_RETURN
663 /* A description of text properties that redisplay is interested
664 in. */
666 struct props
668 /* The name of the property. */
669 Lisp_Object *name;
671 /* A unique index for the property. */
672 enum prop_idx idx;
674 /* A handler function called to set up iterator IT from the property
675 at IT's current position. Value is used to steer handle_stop. */
676 enum prop_handled (*handler) P_ ((struct it *it));
679 static enum prop_handled handle_face_prop P_ ((struct it *));
680 static enum prop_handled handle_invisible_prop P_ ((struct it *));
681 static enum prop_handled handle_display_prop P_ ((struct it *));
682 static enum prop_handled handle_composition_prop P_ ((struct it *));
683 static enum prop_handled handle_overlay_change P_ ((struct it *));
684 static enum prop_handled handle_fontified_prop P_ ((struct it *));
686 /* Properties handled by iterators. */
688 static struct props it_props[] =
690 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
691 /* Handle `face' before `display' because some sub-properties of
692 `display' need to know the face. */
693 {&Qface, FACE_PROP_IDX, handle_face_prop},
694 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
695 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
696 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
697 {NULL, 0, NULL}
700 /* Value is the position described by X. If X is a marker, value is
701 the marker_position of X. Otherwise, value is X. */
703 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
705 /* Enumeration returned by some move_it_.* functions internally. */
707 enum move_it_result
709 /* Not used. Undefined value. */
710 MOVE_UNDEFINED,
712 /* Move ended at the requested buffer position or ZV. */
713 MOVE_POS_MATCH_OR_ZV,
715 /* Move ended at the requested X pixel position. */
716 MOVE_X_REACHED,
718 /* Move within a line ended at the end of a line that must be
719 continued. */
720 MOVE_LINE_CONTINUED,
722 /* Move within a line ended at the end of a line that would
723 be displayed truncated. */
724 MOVE_LINE_TRUNCATED,
726 /* Move within a line ended at a line end. */
727 MOVE_NEWLINE_OR_CR
730 /* This counter is used to clear the face cache every once in a while
731 in redisplay_internal. It is incremented for each redisplay.
732 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
733 cleared. */
735 #define CLEAR_FACE_CACHE_COUNT 500
736 static int clear_face_cache_count;
738 /* Record the previous terminal frame we displayed. */
740 static struct frame *previous_terminal_frame;
742 /* Non-zero while redisplay_internal is in progress. */
744 int redisplaying_p;
746 /* Non-zero means don't free realized faces. Bound while freeing
747 realized faces is dangerous because glyph matrices might still
748 reference them. */
750 int inhibit_free_realized_faces;
751 Lisp_Object Qinhibit_free_realized_faces;
753 /* If a string, XTread_socket generates an event to display that string.
754 (The display is done in read_char.) */
756 Lisp_Object help_echo_string;
757 Lisp_Object help_echo_window;
758 Lisp_Object help_echo_object;
759 int help_echo_pos;
761 /* Temporary variable for XTread_socket. */
763 Lisp_Object previous_help_echo_string;
767 /* Function prototypes. */
769 static void setup_for_ellipsis P_ ((struct it *));
770 static void mark_window_display_accurate_1 P_ ((struct window *, int));
771 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
772 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
773 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
774 static int redisplay_mode_lines P_ ((Lisp_Object, int));
775 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
777 #if 0
778 static int invisible_text_between_p P_ ((struct it *, int, int));
779 #endif
781 static int next_element_from_ellipsis P_ ((struct it *));
782 static void pint2str P_ ((char *, int, int));
783 static void pint2hrstr P_ ((char *, int, int));
784 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
785 struct text_pos));
786 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
787 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
788 static void store_frame_title_char P_ ((char));
789 static int store_frame_title P_ ((const unsigned char *, int, int));
790 static void x_consider_frame_title P_ ((Lisp_Object));
791 static void handle_stop P_ ((struct it *));
792 static int tool_bar_lines_needed P_ ((struct frame *));
793 static int single_display_prop_intangible_p P_ ((Lisp_Object));
794 static void ensure_echo_area_buffers P_ ((void));
795 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
796 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
797 static int with_echo_area_buffer P_ ((struct window *, int,
798 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
799 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
800 static void clear_garbaged_frames P_ ((void));
801 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
802 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
803 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
804 static int display_echo_area P_ ((struct window *));
805 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
806 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
807 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
808 static int string_char_and_length P_ ((const unsigned char *, int, int *));
809 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
810 struct text_pos));
811 static int compute_window_start_on_continuation_line P_ ((struct window *));
812 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
813 static void insert_left_trunc_glyphs P_ ((struct it *));
814 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
815 static void extend_face_to_end_of_line P_ ((struct it *));
816 static int append_space P_ ((struct it *, int));
817 static int make_cursor_line_fully_visible P_ ((struct window *));
818 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
819 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
820 static int trailing_whitespace_p P_ ((int));
821 static int message_log_check_duplicate P_ ((int, int, int, int));
822 static void push_it P_ ((struct it *));
823 static void pop_it P_ ((struct it *));
824 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
825 static void select_frame_for_redisplay P_ ((Lisp_Object));
826 static void redisplay_internal P_ ((int));
827 static int echo_area_display P_ ((int));
828 static void redisplay_windows P_ ((Lisp_Object));
829 static void redisplay_window P_ ((Lisp_Object, int));
830 static Lisp_Object redisplay_window_error ();
831 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
832 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
833 static void update_menu_bar P_ ((struct frame *, int));
834 static int try_window_reusing_current_matrix P_ ((struct window *));
835 static int try_window_id P_ ((struct window *));
836 static int display_line P_ ((struct it *));
837 static int display_mode_lines P_ ((struct window *));
838 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
839 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
840 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
841 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
842 static void display_menu_bar P_ ((struct window *));
843 static int display_count_lines P_ ((int, int, int, int, int *));
844 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
845 int, int, struct it *, int, int, int, int));
846 static void compute_line_metrics P_ ((struct it *));
847 static void run_redisplay_end_trigger_hook P_ ((struct it *));
848 static int get_overlay_strings P_ ((struct it *, int));
849 static void next_overlay_string P_ ((struct it *));
850 static void reseat P_ ((struct it *, struct text_pos, int));
851 static void reseat_1 P_ ((struct it *, struct text_pos, int));
852 static void back_to_previous_visible_line_start P_ ((struct it *));
853 static void reseat_at_previous_visible_line_start P_ ((struct it *));
854 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
855 static int next_element_from_display_vector P_ ((struct it *));
856 static int next_element_from_string P_ ((struct it *));
857 static int next_element_from_c_string P_ ((struct it *));
858 static int next_element_from_buffer P_ ((struct it *));
859 static int next_element_from_composition P_ ((struct it *));
860 static int next_element_from_image P_ ((struct it *));
861 static int next_element_from_stretch P_ ((struct it *));
862 static void load_overlay_strings P_ ((struct it *, int));
863 static int init_from_display_pos P_ ((struct it *, struct window *,
864 struct display_pos *));
865 static void reseat_to_string P_ ((struct it *, unsigned char *,
866 Lisp_Object, int, int, int, int));
867 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
868 int, int, int));
869 void move_it_vertically_backward P_ ((struct it *, int));
870 static void init_to_row_start P_ ((struct it *, struct window *,
871 struct glyph_row *));
872 static int init_to_row_end P_ ((struct it *, struct window *,
873 struct glyph_row *));
874 static void back_to_previous_line_start P_ ((struct it *));
875 static int forward_to_next_line_start P_ ((struct it *, int *));
876 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
877 Lisp_Object, int));
878 static struct text_pos string_pos P_ ((int, Lisp_Object));
879 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
880 static int number_of_chars P_ ((unsigned char *, int));
881 static void compute_stop_pos P_ ((struct it *));
882 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
883 Lisp_Object));
884 static int face_before_or_after_it_pos P_ ((struct it *, int));
885 static int next_overlay_change P_ ((int));
886 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
887 Lisp_Object, struct text_pos *,
888 int));
889 static int underlying_face_id P_ ((struct it *));
890 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
891 struct window *));
893 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
894 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
896 #ifdef HAVE_WINDOW_SYSTEM
898 static void update_tool_bar P_ ((struct frame *, int));
899 static void build_desired_tool_bar_string P_ ((struct frame *f));
900 static int redisplay_tool_bar P_ ((struct frame *));
901 static void display_tool_bar_line P_ ((struct it *));
902 static void notice_overwritten_cursor P_ ((struct window *,
903 enum glyph_row_area,
904 int, int, int, int));
908 #endif /* HAVE_WINDOW_SYSTEM */
911 /***********************************************************************
912 Window display dimensions
913 ***********************************************************************/
915 /* Return the bottom boundary y-position for text lines in window W.
916 This is the first y position at which a line cannot start.
917 It is relative to the top of the window.
919 This is the height of W minus the height of a mode line, if any. */
921 INLINE int
922 window_text_bottom_y (w)
923 struct window *w;
925 int height = WINDOW_TOTAL_HEIGHT (w);
927 if (WINDOW_WANTS_MODELINE_P (w))
928 height -= CURRENT_MODE_LINE_HEIGHT (w);
929 return height;
932 /* Return the pixel width of display area AREA of window W. AREA < 0
933 means return the total width of W, not including fringes to
934 the left and right of the window. */
936 INLINE int
937 window_box_width (w, area)
938 struct window *w;
939 int area;
941 int cols = XFASTINT (w->total_cols);
942 int pixels = 0;
944 if (!w->pseudo_window_p)
946 cols -= WINDOW_SCROLL_BAR_COLS (w);
948 if (area == TEXT_AREA)
950 if (INTEGERP (w->left_margin_cols))
951 cols -= XFASTINT (w->left_margin_cols);
952 if (INTEGERP (w->right_margin_cols))
953 cols -= XFASTINT (w->right_margin_cols);
954 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
956 else if (area == LEFT_MARGIN_AREA)
958 cols = (INTEGERP (w->left_margin_cols)
959 ? XFASTINT (w->left_margin_cols) : 0);
960 pixels = 0;
962 else if (area == RIGHT_MARGIN_AREA)
964 cols = (INTEGERP (w->right_margin_cols)
965 ? XFASTINT (w->right_margin_cols) : 0);
966 pixels = 0;
970 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
974 /* Return the pixel height of the display area of window W, not
975 including mode lines of W, if any. */
977 INLINE int
978 window_box_height (w)
979 struct window *w;
981 struct frame *f = XFRAME (w->frame);
982 int height = WINDOW_TOTAL_HEIGHT (w);
984 xassert (height >= 0);
986 /* Note: the code below that determines the mode-line/header-line
987 height is essentially the same as that contained in the macro
988 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
989 the appropriate glyph row has its `mode_line_p' flag set,
990 and if it doesn't, uses estimate_mode_line_height instead. */
992 if (WINDOW_WANTS_MODELINE_P (w))
994 struct glyph_row *ml_row
995 = (w->current_matrix && w->current_matrix->rows
996 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
997 : 0);
998 if (ml_row && ml_row->mode_line_p)
999 height -= ml_row->height;
1000 else
1001 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1004 if (WINDOW_WANTS_HEADER_LINE_P (w))
1006 struct glyph_row *hl_row
1007 = (w->current_matrix && w->current_matrix->rows
1008 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1009 : 0);
1010 if (hl_row && hl_row->mode_line_p)
1011 height -= hl_row->height;
1012 else
1013 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1016 /* With a very small font and a mode-line that's taller than
1017 default, we might end up with a negative height. */
1018 return max (0, height);
1021 /* Return the window-relative coordinate of the left edge of display
1022 area AREA of window W. AREA < 0 means return the left edge of the
1023 whole window, to the right of the left fringe of W. */
1025 INLINE int
1026 window_box_left_offset (w, area)
1027 struct window *w;
1028 int area;
1030 int x;
1032 if (w->pseudo_window_p)
1033 return 0;
1035 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1037 if (area == TEXT_AREA)
1038 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1039 + window_box_width (w, LEFT_MARGIN_AREA));
1040 else if (area == RIGHT_MARGIN_AREA)
1041 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1042 + window_box_width (w, LEFT_MARGIN_AREA)
1043 + window_box_width (w, TEXT_AREA)
1044 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1046 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1047 else if (area == LEFT_MARGIN_AREA
1048 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1049 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1051 return x;
1055 /* Return the window-relative coordinate of the right edge of display
1056 area AREA of window W. AREA < 0 means return the left edge of the
1057 whole window, to the left of the right fringe of W. */
1059 INLINE int
1060 window_box_right_offset (w, area)
1061 struct window *w;
1062 int area;
1064 return window_box_left_offset (w, area) + window_box_width (w, area);
1067 /* Return the frame-relative coordinate of the left edge of display
1068 area AREA of window W. AREA < 0 means return the left edge of the
1069 whole window, to the right of the left fringe of W. */
1071 INLINE int
1072 window_box_left (w, area)
1073 struct window *w;
1074 int area;
1076 struct frame *f = XFRAME (w->frame);
1077 int x;
1079 if (w->pseudo_window_p)
1080 return FRAME_INTERNAL_BORDER_WIDTH (f);
1082 x = (WINDOW_LEFT_EDGE_X (w)
1083 + window_box_left_offset (w, area));
1085 return x;
1089 /* Return the frame-relative coordinate of the right edge of display
1090 area AREA of window W. AREA < 0 means return the left edge of the
1091 whole window, to the left of the right fringe of W. */
1093 INLINE int
1094 window_box_right (w, area)
1095 struct window *w;
1096 int area;
1098 return window_box_left (w, area) + window_box_width (w, area);
1101 /* Get the bounding box of the display area AREA of window W, without
1102 mode lines, in frame-relative coordinates. AREA < 0 means the
1103 whole window, not including the left and right fringes of
1104 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1105 coordinates of the upper-left corner of the box. Return in
1106 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1108 INLINE void
1109 window_box (w, area, box_x, box_y, box_width, box_height)
1110 struct window *w;
1111 int area;
1112 int *box_x, *box_y, *box_width, *box_height;
1114 if (box_width)
1115 *box_width = window_box_width (w, area);
1116 if (box_height)
1117 *box_height = window_box_height (w);
1118 if (box_x)
1119 *box_x = window_box_left (w, area);
1120 if (box_y)
1122 *box_y = WINDOW_TOP_EDGE_Y (w);
1123 if (WINDOW_WANTS_HEADER_LINE_P (w))
1124 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1129 /* Get the bounding box of the display area AREA of window W, without
1130 mode lines. AREA < 0 means the whole window, not including the
1131 left and right fringe of the window. Return in *TOP_LEFT_X
1132 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1133 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1134 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1135 box. */
1137 INLINE void
1138 window_box_edges (w, area, top_left_x, top_left_y,
1139 bottom_right_x, bottom_right_y)
1140 struct window *w;
1141 int area;
1142 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1144 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1145 bottom_right_y);
1146 *bottom_right_x += *top_left_x;
1147 *bottom_right_y += *top_left_y;
1152 /***********************************************************************
1153 Utilities
1154 ***********************************************************************/
1156 /* Return the bottom y-position of the line the iterator IT is in.
1157 This can modify IT's settings. */
1160 line_bottom_y (it)
1161 struct it *it;
1163 int line_height = it->max_ascent + it->max_descent;
1164 int line_top_y = it->current_y;
1166 if (line_height == 0)
1168 if (last_height)
1169 line_height = last_height;
1170 else if (IT_CHARPOS (*it) < ZV)
1172 move_it_by_lines (it, 1, 1);
1173 line_height = (it->max_ascent || it->max_descent
1174 ? it->max_ascent + it->max_descent
1175 : last_height);
1177 else
1179 struct glyph_row *row = it->glyph_row;
1181 /* Use the default character height. */
1182 it->glyph_row = NULL;
1183 it->what = IT_CHARACTER;
1184 it->c = ' ';
1185 it->len = 1;
1186 PRODUCE_GLYPHS (it);
1187 line_height = it->ascent + it->descent;
1188 it->glyph_row = row;
1192 return line_top_y + line_height;
1196 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1197 1 if POS is visible and the line containing POS is fully visible.
1198 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1199 and header-lines heights. */
1202 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1203 struct window *w;
1204 int charpos, *fully, exact_mode_line_heights_p;
1206 struct it it;
1207 struct text_pos top;
1208 int visible_p;
1209 struct buffer *old_buffer = NULL;
1211 if (XBUFFER (w->buffer) != current_buffer)
1213 old_buffer = current_buffer;
1214 set_buffer_internal_1 (XBUFFER (w->buffer));
1217 *fully = visible_p = 0;
1218 SET_TEXT_POS_FROM_MARKER (top, w->start);
1220 /* Compute exact mode line heights, if requested. */
1221 if (exact_mode_line_heights_p)
1223 if (WINDOW_WANTS_MODELINE_P (w))
1224 current_mode_line_height
1225 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1226 current_buffer->mode_line_format);
1228 if (WINDOW_WANTS_HEADER_LINE_P (w))
1229 current_header_line_height
1230 = display_mode_line (w, HEADER_LINE_FACE_ID,
1231 current_buffer->header_line_format);
1234 start_display (&it, w, top);
1235 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1236 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1238 /* Note that we may overshoot because of invisible text. */
1239 if (IT_CHARPOS (it) >= charpos)
1241 int top_y = it.current_y;
1242 int bottom_y = line_bottom_y (&it);
1243 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1245 if (top_y < window_top_y)
1246 visible_p = bottom_y > window_top_y;
1247 else if (top_y < it.last_visible_y)
1249 visible_p = 1;
1250 *fully = bottom_y <= it.last_visible_y;
1253 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1255 move_it_by_lines (&it, 1, 0);
1256 if (charpos < IT_CHARPOS (it))
1258 visible_p = 1;
1259 *fully = 0;
1263 if (old_buffer)
1264 set_buffer_internal_1 (old_buffer);
1266 current_header_line_height = current_mode_line_height = -1;
1267 return visible_p;
1271 /* Return the next character from STR which is MAXLEN bytes long.
1272 Return in *LEN the length of the character. This is like
1273 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1274 we find one, we return a `?', but with the length of the invalid
1275 character. */
1277 static INLINE int
1278 string_char_and_length (str, maxlen, len)
1279 const unsigned char *str;
1280 int maxlen, *len;
1282 int c;
1284 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1285 if (!CHAR_VALID_P (c, 1))
1286 /* We may not change the length here because other places in Emacs
1287 don't use this function, i.e. they silently accept invalid
1288 characters. */
1289 c = '?';
1291 return c;
1296 /* Given a position POS containing a valid character and byte position
1297 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1299 static struct text_pos
1300 string_pos_nchars_ahead (pos, string, nchars)
1301 struct text_pos pos;
1302 Lisp_Object string;
1303 int nchars;
1305 xassert (STRINGP (string) && nchars >= 0);
1307 if (STRING_MULTIBYTE (string))
1309 int rest = SBYTES (string) - BYTEPOS (pos);
1310 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1311 int len;
1313 while (nchars--)
1315 string_char_and_length (p, rest, &len);
1316 p += len, rest -= len;
1317 xassert (rest >= 0);
1318 CHARPOS (pos) += 1;
1319 BYTEPOS (pos) += len;
1322 else
1323 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1325 return pos;
1329 /* Value is the text position, i.e. character and byte position,
1330 for character position CHARPOS in STRING. */
1332 static INLINE struct text_pos
1333 string_pos (charpos, string)
1334 int charpos;
1335 Lisp_Object string;
1337 struct text_pos pos;
1338 xassert (STRINGP (string));
1339 xassert (charpos >= 0);
1340 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1341 return pos;
1345 /* Value is a text position, i.e. character and byte position, for
1346 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1347 means recognize multibyte characters. */
1349 static struct text_pos
1350 c_string_pos (charpos, s, multibyte_p)
1351 int charpos;
1352 unsigned char *s;
1353 int multibyte_p;
1355 struct text_pos pos;
1357 xassert (s != NULL);
1358 xassert (charpos >= 0);
1360 if (multibyte_p)
1362 int rest = strlen (s), len;
1364 SET_TEXT_POS (pos, 0, 0);
1365 while (charpos--)
1367 string_char_and_length (s, rest, &len);
1368 s += len, rest -= len;
1369 xassert (rest >= 0);
1370 CHARPOS (pos) += 1;
1371 BYTEPOS (pos) += len;
1374 else
1375 SET_TEXT_POS (pos, charpos, charpos);
1377 return pos;
1381 /* Value is the number of characters in C string S. MULTIBYTE_P
1382 non-zero means recognize multibyte characters. */
1384 static int
1385 number_of_chars (s, multibyte_p)
1386 unsigned char *s;
1387 int multibyte_p;
1389 int nchars;
1391 if (multibyte_p)
1393 int rest = strlen (s), len;
1394 unsigned char *p = (unsigned char *) s;
1396 for (nchars = 0; rest > 0; ++nchars)
1398 string_char_and_length (p, rest, &len);
1399 rest -= len, p += len;
1402 else
1403 nchars = strlen (s);
1405 return nchars;
1409 /* Compute byte position NEWPOS->bytepos corresponding to
1410 NEWPOS->charpos. POS is a known position in string STRING.
1411 NEWPOS->charpos must be >= POS.charpos. */
1413 static void
1414 compute_string_pos (newpos, pos, string)
1415 struct text_pos *newpos, pos;
1416 Lisp_Object string;
1418 xassert (STRINGP (string));
1419 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1421 if (STRING_MULTIBYTE (string))
1422 *newpos = string_pos_nchars_ahead (pos, string,
1423 CHARPOS (*newpos) - CHARPOS (pos));
1424 else
1425 BYTEPOS (*newpos) = CHARPOS (*newpos);
1428 /* EXPORT:
1429 Return an estimation of the pixel height of mode or top lines on
1430 frame F. FACE_ID specifies what line's height to estimate. */
1433 estimate_mode_line_height (f, face_id)
1434 struct frame *f;
1435 enum face_id face_id;
1437 #ifdef HAVE_WINDOW_SYSTEM
1438 if (FRAME_WINDOW_P (f))
1440 int height = FONT_HEIGHT (FRAME_FONT (f));
1442 /* This function is called so early when Emacs starts that the face
1443 cache and mode line face are not yet initialized. */
1444 if (FRAME_FACE_CACHE (f))
1446 struct face *face = FACE_FROM_ID (f, face_id);
1447 if (face)
1449 if (face->font)
1450 height = FONT_HEIGHT (face->font);
1451 if (face->box_line_width > 0)
1452 height += 2 * face->box_line_width;
1456 return height;
1458 #endif
1460 return 1;
1463 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1464 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1465 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1466 not force the value into range. */
1468 void
1469 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1470 FRAME_PTR f;
1471 register int pix_x, pix_y;
1472 int *x, *y;
1473 NativeRectangle *bounds;
1474 int noclip;
1477 #ifdef HAVE_WINDOW_SYSTEM
1478 if (FRAME_WINDOW_P (f))
1480 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1481 even for negative values. */
1482 if (pix_x < 0)
1483 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1484 if (pix_y < 0)
1485 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1487 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1488 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1490 if (bounds)
1491 STORE_NATIVE_RECT (*bounds,
1492 FRAME_COL_TO_PIXEL_X (f, pix_x),
1493 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1494 FRAME_COLUMN_WIDTH (f) - 1,
1495 FRAME_LINE_HEIGHT (f) - 1);
1497 if (!noclip)
1499 if (pix_x < 0)
1500 pix_x = 0;
1501 else if (pix_x > FRAME_TOTAL_COLS (f))
1502 pix_x = FRAME_TOTAL_COLS (f);
1504 if (pix_y < 0)
1505 pix_y = 0;
1506 else if (pix_y > FRAME_LINES (f))
1507 pix_y = FRAME_LINES (f);
1510 #endif
1512 *x = pix_x;
1513 *y = pix_y;
1517 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1518 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1519 can't tell the positions because W's display is not up to date,
1520 return 0. */
1523 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1524 struct window *w;
1525 int hpos, vpos;
1526 int *frame_x, *frame_y;
1528 #ifdef HAVE_WINDOW_SYSTEM
1529 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1531 int success_p;
1533 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1534 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1536 if (display_completed)
1538 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1539 struct glyph *glyph = row->glyphs[TEXT_AREA];
1540 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1542 hpos = row->x;
1543 vpos = row->y;
1544 while (glyph < end)
1546 hpos += glyph->pixel_width;
1547 ++glyph;
1550 /* If first glyph is partially visible, its first visible position is still 0. */
1551 if (hpos < 0)
1552 hpos = 0;
1554 success_p = 1;
1556 else
1558 hpos = vpos = 0;
1559 success_p = 0;
1562 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1563 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1564 return success_p;
1566 #endif
1568 *frame_x = hpos;
1569 *frame_y = vpos;
1570 return 1;
1574 #ifdef HAVE_WINDOW_SYSTEM
1576 /* Find the glyph under window-relative coordinates X/Y in window W.
1577 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1578 strings. Return in *HPOS and *VPOS the row and column number of
1579 the glyph found. Return in *AREA the glyph area containing X.
1580 Value is a pointer to the glyph found or null if X/Y is not on
1581 text, or we can't tell because W's current matrix is not up to
1582 date. */
1584 static struct glyph *
1585 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
1586 struct window *w;
1587 int x, y;
1588 int *hpos, *vpos, *area;
1589 int buffer_only_p;
1591 struct glyph *glyph, *end;
1592 struct glyph_row *row = NULL;
1593 int x0, i;
1595 /* Find row containing Y. Give up if some row is not enabled. */
1596 for (i = 0; i < w->current_matrix->nrows; ++i)
1598 row = MATRIX_ROW (w->current_matrix, i);
1599 if (!row->enabled_p)
1600 return NULL;
1601 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1602 break;
1605 *vpos = i;
1606 *hpos = 0;
1608 /* Give up if Y is not in the window. */
1609 if (i == w->current_matrix->nrows)
1610 return NULL;
1612 /* Get the glyph area containing X. */
1613 if (w->pseudo_window_p)
1615 *area = TEXT_AREA;
1616 x0 = 0;
1618 else
1620 if (x < window_box_left_offset (w, TEXT_AREA))
1622 *area = LEFT_MARGIN_AREA;
1623 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1625 else if (x < window_box_right_offset (w, TEXT_AREA))
1627 *area = TEXT_AREA;
1628 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1630 else
1632 *area = RIGHT_MARGIN_AREA;
1633 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1637 /* Find glyph containing X. */
1638 glyph = row->glyphs[*area];
1639 end = glyph + row->used[*area];
1640 while (glyph < end)
1642 if (x < x0 + glyph->pixel_width)
1644 if (w->pseudo_window_p)
1645 break;
1646 else if (!buffer_only_p || BUFFERP (glyph->object))
1647 break;
1650 x0 += glyph->pixel_width;
1651 ++glyph;
1654 if (glyph == end)
1655 return NULL;
1657 *hpos = glyph - row->glyphs[*area];
1658 return glyph;
1662 /* EXPORT:
1663 Convert frame-relative x/y to coordinates relative to window W.
1664 Takes pseudo-windows into account. */
1666 void
1667 frame_to_window_pixel_xy (w, x, y)
1668 struct window *w;
1669 int *x, *y;
1671 if (w->pseudo_window_p)
1673 /* A pseudo-window is always full-width, and starts at the
1674 left edge of the frame, plus a frame border. */
1675 struct frame *f = XFRAME (w->frame);
1676 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1677 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1679 else
1681 *x -= WINDOW_LEFT_EDGE_X (w);
1682 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1686 /* EXPORT:
1687 Return in *R the clipping rectangle for glyph string S. */
1689 void
1690 get_glyph_string_clip_rect (s, nr)
1691 struct glyph_string *s;
1692 NativeRectangle *nr;
1694 XRectangle r;
1696 if (s->row->full_width_p)
1698 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1699 r.x = WINDOW_LEFT_EDGE_X (s->w);
1700 r.width = WINDOW_TOTAL_WIDTH (s->w);
1702 /* Unless displaying a mode or menu bar line, which are always
1703 fully visible, clip to the visible part of the row. */
1704 if (s->w->pseudo_window_p)
1705 r.height = s->row->visible_height;
1706 else
1707 r.height = s->height;
1709 else
1711 /* This is a text line that may be partially visible. */
1712 r.x = window_box_left (s->w, s->area);
1713 r.width = window_box_width (s->w, s->area);
1714 r.height = s->row->visible_height;
1717 /* If S draws overlapping rows, it's sufficient to use the top and
1718 bottom of the window for clipping because this glyph string
1719 intentionally draws over other lines. */
1720 if (s->for_overlaps_p)
1722 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1723 r.height = window_text_bottom_y (s->w) - r.y;
1725 else
1727 /* Don't use S->y for clipping because it doesn't take partially
1728 visible lines into account. For example, it can be negative for
1729 partially visible lines at the top of a window. */
1730 if (!s->row->full_width_p
1731 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1732 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1733 else
1734 r.y = max (0, s->row->y);
1736 /* If drawing a tool-bar window, draw it over the internal border
1737 at the top of the window. */
1738 if (s->w == XWINDOW (s->f->tool_bar_window))
1739 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1742 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1744 #ifdef HAVE_NTGUI
1745 /* ++KFS: From W32 port, but it looks ok for all platforms to me. */
1746 /* If drawing the cursor, don't let glyph draw outside its
1747 advertised boundaries. Cleartype does this under some circumstances. */
1748 if (s->hl == DRAW_CURSOR)
1750 if (s->x > r.x)
1752 r.width -= s->x - r.x;
1753 r.x = s->x;
1755 r.width = min (r.width, s->first_glyph->pixel_width);
1757 #endif
1759 #ifdef CONVERT_FROM_XRECT
1760 CONVERT_FROM_XRECT (r, *nr);
1761 #else
1762 *nr = r;
1763 #endif
1766 #endif /* HAVE_WINDOW_SYSTEM */
1769 /***********************************************************************
1770 Lisp form evaluation
1771 ***********************************************************************/
1773 /* Error handler for safe_eval and safe_call. */
1775 static Lisp_Object
1776 safe_eval_handler (arg)
1777 Lisp_Object arg;
1779 add_to_log ("Error during redisplay: %s", arg, Qnil);
1780 return Qnil;
1784 /* Evaluate SEXPR and return the result, or nil if something went
1785 wrong. Prevent redisplay during the evaluation. */
1787 Lisp_Object
1788 safe_eval (sexpr)
1789 Lisp_Object sexpr;
1791 Lisp_Object val;
1793 if (inhibit_eval_during_redisplay)
1794 val = Qnil;
1795 else
1797 int count = SPECPDL_INDEX ();
1798 struct gcpro gcpro1;
1800 GCPRO1 (sexpr);
1801 specbind (Qinhibit_redisplay, Qt);
1802 /* Use Qt to ensure debugger does not run,
1803 so there is no possibility of wanting to redisplay. */
1804 val = internal_condition_case_1 (Feval, sexpr, Qt,
1805 safe_eval_handler);
1806 UNGCPRO;
1807 val = unbind_to (count, val);
1810 return val;
1814 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1815 Return the result, or nil if something went wrong. Prevent
1816 redisplay during the evaluation. */
1818 Lisp_Object
1819 safe_call (nargs, args)
1820 int nargs;
1821 Lisp_Object *args;
1823 Lisp_Object val;
1825 if (inhibit_eval_during_redisplay)
1826 val = Qnil;
1827 else
1829 int count = SPECPDL_INDEX ();
1830 struct gcpro gcpro1;
1832 GCPRO1 (args[0]);
1833 gcpro1.nvars = nargs;
1834 specbind (Qinhibit_redisplay, Qt);
1835 /* Use Qt to ensure debugger does not run,
1836 so there is no possibility of wanting to redisplay. */
1837 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1838 safe_eval_handler);
1839 UNGCPRO;
1840 val = unbind_to (count, val);
1843 return val;
1847 /* Call function FN with one argument ARG.
1848 Return the result, or nil if something went wrong. */
1850 Lisp_Object
1851 safe_call1 (fn, arg)
1852 Lisp_Object fn, arg;
1854 Lisp_Object args[2];
1855 args[0] = fn;
1856 args[1] = arg;
1857 return safe_call (2, args);
1862 /***********************************************************************
1863 Debugging
1864 ***********************************************************************/
1866 #if 0
1868 /* Define CHECK_IT to perform sanity checks on iterators.
1869 This is for debugging. It is too slow to do unconditionally. */
1871 static void
1872 check_it (it)
1873 struct it *it;
1875 if (it->method == next_element_from_string)
1877 xassert (STRINGP (it->string));
1878 xassert (IT_STRING_CHARPOS (*it) >= 0);
1880 else if (it->method == next_element_from_buffer)
1882 /* Check that character and byte positions agree. */
1883 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1886 if (it->dpvec)
1887 xassert (it->current.dpvec_index >= 0);
1888 else
1889 xassert (it->current.dpvec_index < 0);
1892 #define CHECK_IT(IT) check_it ((IT))
1894 #else /* not 0 */
1896 #define CHECK_IT(IT) (void) 0
1898 #endif /* not 0 */
1901 #if GLYPH_DEBUG
1903 /* Check that the window end of window W is what we expect it
1904 to be---the last row in the current matrix displaying text. */
1906 static void
1907 check_window_end (w)
1908 struct window *w;
1910 if (!MINI_WINDOW_P (w)
1911 && !NILP (w->window_end_valid))
1913 struct glyph_row *row;
1914 xassert ((row = MATRIX_ROW (w->current_matrix,
1915 XFASTINT (w->window_end_vpos)),
1916 !row->enabled_p
1917 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1918 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1922 #define CHECK_WINDOW_END(W) check_window_end ((W))
1924 #else /* not GLYPH_DEBUG */
1926 #define CHECK_WINDOW_END(W) (void) 0
1928 #endif /* not GLYPH_DEBUG */
1932 /***********************************************************************
1933 Iterator initialization
1934 ***********************************************************************/
1936 /* Initialize IT for displaying current_buffer in window W, starting
1937 at character position CHARPOS. CHARPOS < 0 means that no buffer
1938 position is specified which is useful when the iterator is assigned
1939 a position later. BYTEPOS is the byte position corresponding to
1940 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1942 If ROW is not null, calls to produce_glyphs with IT as parameter
1943 will produce glyphs in that row.
1945 BASE_FACE_ID is the id of a base face to use. It must be one of
1946 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1947 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1948 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1950 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1951 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1952 will be initialized to use the corresponding mode line glyph row of
1953 the desired matrix of W. */
1955 void
1956 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1957 struct it *it;
1958 struct window *w;
1959 int charpos, bytepos;
1960 struct glyph_row *row;
1961 enum face_id base_face_id;
1963 int highlight_region_p;
1965 /* Some precondition checks. */
1966 xassert (w != NULL && it != NULL);
1967 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1968 && charpos <= ZV));
1970 /* If face attributes have been changed since the last redisplay,
1971 free realized faces now because they depend on face definitions
1972 that might have changed. Don't free faces while there might be
1973 desired matrices pending which reference these faces. */
1974 if (face_change_count && !inhibit_free_realized_faces)
1976 face_change_count = 0;
1977 free_all_realized_faces (Qnil);
1980 /* Use one of the mode line rows of W's desired matrix if
1981 appropriate. */
1982 if (row == NULL)
1984 if (base_face_id == MODE_LINE_FACE_ID
1985 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
1986 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1987 else if (base_face_id == HEADER_LINE_FACE_ID)
1988 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1991 /* Clear IT. */
1992 bzero (it, sizeof *it);
1993 it->current.overlay_string_index = -1;
1994 it->current.dpvec_index = -1;
1995 it->base_face_id = base_face_id;
1997 /* The window in which we iterate over current_buffer: */
1998 XSETWINDOW (it->window, w);
1999 it->w = w;
2000 it->f = XFRAME (w->frame);
2002 /* Extra space between lines (on window systems only). */
2003 if (base_face_id == DEFAULT_FACE_ID
2004 && FRAME_WINDOW_P (it->f))
2006 if (NATNUMP (current_buffer->extra_line_spacing))
2007 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2008 else if (it->f->extra_line_spacing > 0)
2009 it->extra_line_spacing = it->f->extra_line_spacing;
2012 /* If realized faces have been removed, e.g. because of face
2013 attribute changes of named faces, recompute them. When running
2014 in batch mode, the face cache of Vterminal_frame is null. If
2015 we happen to get called, make a dummy face cache. */
2016 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2017 init_frame_faces (it->f);
2018 if (FRAME_FACE_CACHE (it->f)->used == 0)
2019 recompute_basic_faces (it->f);
2021 /* Current value of the `space-width', and 'height' properties. */
2022 it->space_width = Qnil;
2023 it->font_height = Qnil;
2025 /* Are control characters displayed as `^C'? */
2026 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2028 /* -1 means everything between a CR and the following line end
2029 is invisible. >0 means lines indented more than this value are
2030 invisible. */
2031 it->selective = (INTEGERP (current_buffer->selective_display)
2032 ? XFASTINT (current_buffer->selective_display)
2033 : (!NILP (current_buffer->selective_display)
2034 ? -1 : 0));
2035 it->selective_display_ellipsis_p
2036 = !NILP (current_buffer->selective_display_ellipses);
2038 /* Display table to use. */
2039 it->dp = window_display_table (w);
2041 /* Are multibyte characters enabled in current_buffer? */
2042 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2044 /* Non-zero if we should highlight the region. */
2045 highlight_region_p
2046 = (!NILP (Vtransient_mark_mode)
2047 && !NILP (current_buffer->mark_active)
2048 && XMARKER (current_buffer->mark)->buffer != 0);
2050 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2051 start and end of a visible region in window IT->w. Set both to
2052 -1 to indicate no region. */
2053 if (highlight_region_p
2054 /* Maybe highlight only in selected window. */
2055 && (/* Either show region everywhere. */
2056 highlight_nonselected_windows
2057 /* Or show region in the selected window. */
2058 || w == XWINDOW (selected_window)
2059 /* Or show the region if we are in the mini-buffer and W is
2060 the window the mini-buffer refers to. */
2061 || (MINI_WINDOW_P (XWINDOW (selected_window))
2062 && WINDOWP (minibuf_selected_window)
2063 && w == XWINDOW (minibuf_selected_window))))
2065 int charpos = marker_position (current_buffer->mark);
2066 it->region_beg_charpos = min (PT, charpos);
2067 it->region_end_charpos = max (PT, charpos);
2069 else
2070 it->region_beg_charpos = it->region_end_charpos = -1;
2072 /* Get the position at which the redisplay_end_trigger hook should
2073 be run, if it is to be run at all. */
2074 if (MARKERP (w->redisplay_end_trigger)
2075 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2076 it->redisplay_end_trigger_charpos
2077 = marker_position (w->redisplay_end_trigger);
2078 else if (INTEGERP (w->redisplay_end_trigger))
2079 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2081 /* Correct bogus values of tab_width. */
2082 it->tab_width = XINT (current_buffer->tab_width);
2083 if (it->tab_width <= 0 || it->tab_width > 1000)
2084 it->tab_width = 8;
2086 /* Are lines in the display truncated? */
2087 it->truncate_lines_p
2088 = (base_face_id != DEFAULT_FACE_ID
2089 || XINT (it->w->hscroll)
2090 || (truncate_partial_width_windows
2091 && !WINDOW_FULL_WIDTH_P (it->w))
2092 || !NILP (current_buffer->truncate_lines));
2094 /* Get dimensions of truncation and continuation glyphs. These are
2095 displayed as fringe bitmaps under X, so we don't need them for such
2096 frames. */
2097 if (!FRAME_WINDOW_P (it->f))
2099 if (it->truncate_lines_p)
2101 /* We will need the truncation glyph. */
2102 xassert (it->glyph_row == NULL);
2103 produce_special_glyphs (it, IT_TRUNCATION);
2104 it->truncation_pixel_width = it->pixel_width;
2106 else
2108 /* We will need the continuation glyph. */
2109 xassert (it->glyph_row == NULL);
2110 produce_special_glyphs (it, IT_CONTINUATION);
2111 it->continuation_pixel_width = it->pixel_width;
2114 /* Reset these values to zero because the produce_special_glyphs
2115 above has changed them. */
2116 it->pixel_width = it->ascent = it->descent = 0;
2117 it->phys_ascent = it->phys_descent = 0;
2120 /* Set this after getting the dimensions of truncation and
2121 continuation glyphs, so that we don't produce glyphs when calling
2122 produce_special_glyphs, above. */
2123 it->glyph_row = row;
2124 it->area = TEXT_AREA;
2126 /* Get the dimensions of the display area. The display area
2127 consists of the visible window area plus a horizontally scrolled
2128 part to the left of the window. All x-values are relative to the
2129 start of this total display area. */
2130 if (base_face_id != DEFAULT_FACE_ID)
2132 /* Mode lines, menu bar in terminal frames. */
2133 it->first_visible_x = 0;
2134 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2136 else
2138 it->first_visible_x
2139 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2140 it->last_visible_x = (it->first_visible_x
2141 + window_box_width (w, TEXT_AREA));
2143 /* If we truncate lines, leave room for the truncator glyph(s) at
2144 the right margin. Otherwise, leave room for the continuation
2145 glyph(s). Truncation and continuation glyphs are not inserted
2146 for window-based redisplay. */
2147 if (!FRAME_WINDOW_P (it->f))
2149 if (it->truncate_lines_p)
2150 it->last_visible_x -= it->truncation_pixel_width;
2151 else
2152 it->last_visible_x -= it->continuation_pixel_width;
2155 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2156 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2159 /* Leave room for a border glyph. */
2160 if (!FRAME_WINDOW_P (it->f)
2161 && !WINDOW_RIGHTMOST_P (it->w))
2162 it->last_visible_x -= 1;
2164 it->last_visible_y = window_text_bottom_y (w);
2166 /* For mode lines and alike, arrange for the first glyph having a
2167 left box line if the face specifies a box. */
2168 if (base_face_id != DEFAULT_FACE_ID)
2170 struct face *face;
2172 it->face_id = base_face_id;
2174 /* If we have a boxed mode line, make the first character appear
2175 with a left box line. */
2176 face = FACE_FROM_ID (it->f, base_face_id);
2177 if (face->box != FACE_NO_BOX)
2178 it->start_of_box_run_p = 1;
2181 /* If a buffer position was specified, set the iterator there,
2182 getting overlays and face properties from that position. */
2183 if (charpos >= BUF_BEG (current_buffer))
2185 it->end_charpos = ZV;
2186 it->face_id = -1;
2187 IT_CHARPOS (*it) = charpos;
2189 /* Compute byte position if not specified. */
2190 if (bytepos < charpos)
2191 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2192 else
2193 IT_BYTEPOS (*it) = bytepos;
2195 it->start = it->current;
2197 /* Compute faces etc. */
2198 reseat (it, it->current.pos, 1);
2201 CHECK_IT (it);
2205 /* Initialize IT for the display of window W with window start POS. */
2207 void
2208 start_display (it, w, pos)
2209 struct it *it;
2210 struct window *w;
2211 struct text_pos pos;
2213 struct glyph_row *row;
2214 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2216 row = w->desired_matrix->rows + first_vpos;
2217 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2218 it->first_vpos = first_vpos;
2220 if (!it->truncate_lines_p)
2222 int start_at_line_beg_p;
2223 int first_y = it->current_y;
2225 /* If window start is not at a line start, skip forward to POS to
2226 get the correct continuation lines width. */
2227 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2228 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2229 if (!start_at_line_beg_p)
2231 int new_x;
2233 reseat_at_previous_visible_line_start (it);
2234 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2236 new_x = it->current_x + it->pixel_width;
2238 /* If lines are continued, this line may end in the middle
2239 of a multi-glyph character (e.g. a control character
2240 displayed as \003, or in the middle of an overlay
2241 string). In this case move_it_to above will not have
2242 taken us to the start of the continuation line but to the
2243 end of the continued line. */
2244 if (it->current_x > 0
2245 && !it->truncate_lines_p /* Lines are continued. */
2246 && (/* And glyph doesn't fit on the line. */
2247 new_x > it->last_visible_x
2248 /* Or it fits exactly and we're on a window
2249 system frame. */
2250 || (new_x == it->last_visible_x
2251 && FRAME_WINDOW_P (it->f))))
2253 if (it->current.dpvec_index >= 0
2254 || it->current.overlay_string_index >= 0)
2256 set_iterator_to_next (it, 1);
2257 move_it_in_display_line_to (it, -1, -1, 0);
2260 it->continuation_lines_width += it->current_x;
2263 /* We're starting a new display line, not affected by the
2264 height of the continued line, so clear the appropriate
2265 fields in the iterator structure. */
2266 it->max_ascent = it->max_descent = 0;
2267 it->max_phys_ascent = it->max_phys_descent = 0;
2269 it->current_y = first_y;
2270 it->vpos = 0;
2271 it->current_x = it->hpos = 0;
2275 #if 0 /* Don't assert the following because start_display is sometimes
2276 called intentionally with a window start that is not at a
2277 line start. Please leave this code in as a comment. */
2279 /* Window start should be on a line start, now. */
2280 xassert (it->continuation_lines_width
2281 || IT_CHARPOS (it) == BEGV
2282 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2283 #endif /* 0 */
2287 /* Return 1 if POS is a position in ellipses displayed for invisible
2288 text. W is the window we display, for text property lookup. */
2290 static int
2291 in_ellipses_for_invisible_text_p (pos, w)
2292 struct display_pos *pos;
2293 struct window *w;
2295 Lisp_Object prop, window;
2296 int ellipses_p = 0;
2297 int charpos = CHARPOS (pos->pos);
2299 /* If POS specifies a position in a display vector, this might
2300 be for an ellipsis displayed for invisible text. We won't
2301 get the iterator set up for delivering that ellipsis unless
2302 we make sure that it gets aware of the invisible text. */
2303 if (pos->dpvec_index >= 0
2304 && pos->overlay_string_index < 0
2305 && CHARPOS (pos->string_pos) < 0
2306 && charpos > BEGV
2307 && (XSETWINDOW (window, w),
2308 prop = Fget_char_property (make_number (charpos),
2309 Qinvisible, window),
2310 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2312 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2313 window);
2314 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2317 return ellipses_p;
2321 /* Initialize IT for stepping through current_buffer in window W,
2322 starting at position POS that includes overlay string and display
2323 vector/ control character translation position information. Value
2324 is zero if there are overlay strings with newlines at POS. */
2326 static int
2327 init_from_display_pos (it, w, pos)
2328 struct it *it;
2329 struct window *w;
2330 struct display_pos *pos;
2332 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2333 int i, overlay_strings_with_newlines = 0;
2335 /* If POS specifies a position in a display vector, this might
2336 be for an ellipsis displayed for invisible text. We won't
2337 get the iterator set up for delivering that ellipsis unless
2338 we make sure that it gets aware of the invisible text. */
2339 if (in_ellipses_for_invisible_text_p (pos, w))
2341 --charpos;
2342 bytepos = 0;
2345 /* Keep in mind: the call to reseat in init_iterator skips invisible
2346 text, so we might end up at a position different from POS. This
2347 is only a problem when POS is a row start after a newline and an
2348 overlay starts there with an after-string, and the overlay has an
2349 invisible property. Since we don't skip invisible text in
2350 display_line and elsewhere immediately after consuming the
2351 newline before the row start, such a POS will not be in a string,
2352 but the call to init_iterator below will move us to the
2353 after-string. */
2354 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2356 for (i = 0; i < it->n_overlay_strings; ++i)
2358 const char *s = SDATA (it->overlay_strings[i]);
2359 const char *e = s + SBYTES (it->overlay_strings[i]);
2361 while (s < e && *s != '\n')
2362 ++s;
2364 if (s < e)
2366 overlay_strings_with_newlines = 1;
2367 break;
2371 /* If position is within an overlay string, set up IT to the right
2372 overlay string. */
2373 if (pos->overlay_string_index >= 0)
2375 int relative_index;
2377 /* If the first overlay string happens to have a `display'
2378 property for an image, the iterator will be set up for that
2379 image, and we have to undo that setup first before we can
2380 correct the overlay string index. */
2381 if (it->method == next_element_from_image)
2382 pop_it (it);
2384 /* We already have the first chunk of overlay strings in
2385 IT->overlay_strings. Load more until the one for
2386 pos->overlay_string_index is in IT->overlay_strings. */
2387 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2389 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2390 it->current.overlay_string_index = 0;
2391 while (n--)
2393 load_overlay_strings (it, 0);
2394 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2398 it->current.overlay_string_index = pos->overlay_string_index;
2399 relative_index = (it->current.overlay_string_index
2400 % OVERLAY_STRING_CHUNK_SIZE);
2401 it->string = it->overlay_strings[relative_index];
2402 xassert (STRINGP (it->string));
2403 it->current.string_pos = pos->string_pos;
2404 it->method = next_element_from_string;
2407 #if 0 /* This is bogus because POS not having an overlay string
2408 position does not mean it's after the string. Example: A
2409 line starting with a before-string and initialization of IT
2410 to the previous row's end position. */
2411 else if (it->current.overlay_string_index >= 0)
2413 /* If POS says we're already after an overlay string ending at
2414 POS, make sure to pop the iterator because it will be in
2415 front of that overlay string. When POS is ZV, we've thereby
2416 also ``processed'' overlay strings at ZV. */
2417 while (it->sp)
2418 pop_it (it);
2419 it->current.overlay_string_index = -1;
2420 it->method = next_element_from_buffer;
2421 if (CHARPOS (pos->pos) == ZV)
2422 it->overlay_strings_at_end_processed_p = 1;
2424 #endif /* 0 */
2426 if (CHARPOS (pos->string_pos) >= 0)
2428 /* Recorded position is not in an overlay string, but in another
2429 string. This can only be a string from a `display' property.
2430 IT should already be filled with that string. */
2431 it->current.string_pos = pos->string_pos;
2432 xassert (STRINGP (it->string));
2435 /* Restore position in display vector translations, control
2436 character translations or ellipses. */
2437 if (pos->dpvec_index >= 0)
2439 if (it->dpvec == NULL)
2440 get_next_display_element (it);
2441 xassert (it->dpvec && it->current.dpvec_index == 0);
2442 it->current.dpvec_index = pos->dpvec_index;
2445 CHECK_IT (it);
2446 return !overlay_strings_with_newlines;
2450 /* Initialize IT for stepping through current_buffer in window W
2451 starting at ROW->start. */
2453 static void
2454 init_to_row_start (it, w, row)
2455 struct it *it;
2456 struct window *w;
2457 struct glyph_row *row;
2459 init_from_display_pos (it, w, &row->start);
2460 it->start = row->start;
2461 it->continuation_lines_width = row->continuation_lines_width;
2462 CHECK_IT (it);
2466 /* Initialize IT for stepping through current_buffer in window W
2467 starting in the line following ROW, i.e. starting at ROW->end.
2468 Value is zero if there are overlay strings with newlines at ROW's
2469 end position. */
2471 static int
2472 init_to_row_end (it, w, row)
2473 struct it *it;
2474 struct window *w;
2475 struct glyph_row *row;
2477 int success = 0;
2479 if (init_from_display_pos (it, w, &row->end))
2481 if (row->continued_p)
2482 it->continuation_lines_width
2483 = row->continuation_lines_width + row->pixel_width;
2484 CHECK_IT (it);
2485 success = 1;
2488 return success;
2494 /***********************************************************************
2495 Text properties
2496 ***********************************************************************/
2498 /* Called when IT reaches IT->stop_charpos. Handle text property and
2499 overlay changes. Set IT->stop_charpos to the next position where
2500 to stop. */
2502 static void
2503 handle_stop (it)
2504 struct it *it;
2506 enum prop_handled handled;
2507 int handle_overlay_change_p = 1;
2508 struct props *p;
2510 it->dpvec = NULL;
2511 it->current.dpvec_index = -1;
2515 handled = HANDLED_NORMALLY;
2517 /* Call text property handlers. */
2518 for (p = it_props; p->handler; ++p)
2520 handled = p->handler (it);
2522 if (handled == HANDLED_RECOMPUTE_PROPS)
2523 break;
2524 else if (handled == HANDLED_RETURN)
2525 return;
2526 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2527 handle_overlay_change_p = 0;
2530 if (handled != HANDLED_RECOMPUTE_PROPS)
2532 /* Don't check for overlay strings below when set to deliver
2533 characters from a display vector. */
2534 if (it->method == next_element_from_display_vector)
2535 handle_overlay_change_p = 0;
2537 /* Handle overlay changes. */
2538 if (handle_overlay_change_p)
2539 handled = handle_overlay_change (it);
2541 /* Determine where to stop next. */
2542 if (handled == HANDLED_NORMALLY)
2543 compute_stop_pos (it);
2546 while (handled == HANDLED_RECOMPUTE_PROPS);
2550 /* Compute IT->stop_charpos from text property and overlay change
2551 information for IT's current position. */
2553 static void
2554 compute_stop_pos (it)
2555 struct it *it;
2557 register INTERVAL iv, next_iv;
2558 Lisp_Object object, limit, position;
2560 /* If nowhere else, stop at the end. */
2561 it->stop_charpos = it->end_charpos;
2563 if (STRINGP (it->string))
2565 /* Strings are usually short, so don't limit the search for
2566 properties. */
2567 object = it->string;
2568 limit = Qnil;
2569 position = make_number (IT_STRING_CHARPOS (*it));
2571 else
2573 int charpos;
2575 /* If next overlay change is in front of the current stop pos
2576 (which is IT->end_charpos), stop there. Note: value of
2577 next_overlay_change is point-max if no overlay change
2578 follows. */
2579 charpos = next_overlay_change (IT_CHARPOS (*it));
2580 if (charpos < it->stop_charpos)
2581 it->stop_charpos = charpos;
2583 /* If showing the region, we have to stop at the region
2584 start or end because the face might change there. */
2585 if (it->region_beg_charpos > 0)
2587 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2588 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2589 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2590 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2593 /* Set up variables for computing the stop position from text
2594 property changes. */
2595 XSETBUFFER (object, current_buffer);
2596 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2597 position = make_number (IT_CHARPOS (*it));
2601 /* Get the interval containing IT's position. Value is a null
2602 interval if there isn't such an interval. */
2603 iv = validate_interval_range (object, &position, &position, 0);
2604 if (!NULL_INTERVAL_P (iv))
2606 Lisp_Object values_here[LAST_PROP_IDX];
2607 struct props *p;
2609 /* Get properties here. */
2610 for (p = it_props; p->handler; ++p)
2611 values_here[p->idx] = textget (iv->plist, *p->name);
2613 /* Look for an interval following iv that has different
2614 properties. */
2615 for (next_iv = next_interval (iv);
2616 (!NULL_INTERVAL_P (next_iv)
2617 && (NILP (limit)
2618 || XFASTINT (limit) > next_iv->position));
2619 next_iv = next_interval (next_iv))
2621 for (p = it_props; p->handler; ++p)
2623 Lisp_Object new_value;
2625 new_value = textget (next_iv->plist, *p->name);
2626 if (!EQ (values_here[p->idx], new_value))
2627 break;
2630 if (p->handler)
2631 break;
2634 if (!NULL_INTERVAL_P (next_iv))
2636 if (INTEGERP (limit)
2637 && next_iv->position >= XFASTINT (limit))
2638 /* No text property change up to limit. */
2639 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2640 else
2641 /* Text properties change in next_iv. */
2642 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2646 xassert (STRINGP (it->string)
2647 || (it->stop_charpos >= BEGV
2648 && it->stop_charpos >= IT_CHARPOS (*it)));
2652 /* Return the position of the next overlay change after POS in
2653 current_buffer. Value is point-max if no overlay change
2654 follows. This is like `next-overlay-change' but doesn't use
2655 xmalloc. */
2657 static int
2658 next_overlay_change (pos)
2659 int pos;
2661 int noverlays;
2662 int endpos;
2663 Lisp_Object *overlays;
2664 int len;
2665 int i;
2667 /* Get all overlays at the given position. */
2668 len = 10;
2669 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2670 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2671 if (noverlays > len)
2673 len = noverlays;
2674 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2675 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2678 /* If any of these overlays ends before endpos,
2679 use its ending point instead. */
2680 for (i = 0; i < noverlays; ++i)
2682 Lisp_Object oend;
2683 int oendpos;
2685 oend = OVERLAY_END (overlays[i]);
2686 oendpos = OVERLAY_POSITION (oend);
2687 endpos = min (endpos, oendpos);
2690 return endpos;
2695 /***********************************************************************
2696 Fontification
2697 ***********************************************************************/
2699 /* Handle changes in the `fontified' property of the current buffer by
2700 calling hook functions from Qfontification_functions to fontify
2701 regions of text. */
2703 static enum prop_handled
2704 handle_fontified_prop (it)
2705 struct it *it;
2707 Lisp_Object prop, pos;
2708 enum prop_handled handled = HANDLED_NORMALLY;
2710 /* Get the value of the `fontified' property at IT's current buffer
2711 position. (The `fontified' property doesn't have a special
2712 meaning in strings.) If the value is nil, call functions from
2713 Qfontification_functions. */
2714 if (!STRINGP (it->string)
2715 && it->s == NULL
2716 && !NILP (Vfontification_functions)
2717 && !NILP (Vrun_hooks)
2718 && (pos = make_number (IT_CHARPOS (*it)),
2719 prop = Fget_char_property (pos, Qfontified, Qnil),
2720 NILP (prop)))
2722 int count = SPECPDL_INDEX ();
2723 Lisp_Object val;
2725 val = Vfontification_functions;
2726 specbind (Qfontification_functions, Qnil);
2728 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2729 safe_call1 (val, pos);
2730 else
2732 Lisp_Object globals, fn;
2733 struct gcpro gcpro1, gcpro2;
2735 globals = Qnil;
2736 GCPRO2 (val, globals);
2738 for (; CONSP (val); val = XCDR (val))
2740 fn = XCAR (val);
2742 if (EQ (fn, Qt))
2744 /* A value of t indicates this hook has a local
2745 binding; it means to run the global binding too.
2746 In a global value, t should not occur. If it
2747 does, we must ignore it to avoid an endless
2748 loop. */
2749 for (globals = Fdefault_value (Qfontification_functions);
2750 CONSP (globals);
2751 globals = XCDR (globals))
2753 fn = XCAR (globals);
2754 if (!EQ (fn, Qt))
2755 safe_call1 (fn, pos);
2758 else
2759 safe_call1 (fn, pos);
2762 UNGCPRO;
2765 unbind_to (count, Qnil);
2767 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2768 something. This avoids an endless loop if they failed to
2769 fontify the text for which reason ever. */
2770 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2771 handled = HANDLED_RECOMPUTE_PROPS;
2774 return handled;
2779 /***********************************************************************
2780 Faces
2781 ***********************************************************************/
2783 /* Set up iterator IT from face properties at its current position.
2784 Called from handle_stop. */
2786 static enum prop_handled
2787 handle_face_prop (it)
2788 struct it *it;
2790 int new_face_id, next_stop;
2792 if (!STRINGP (it->string))
2794 new_face_id
2795 = face_at_buffer_position (it->w,
2796 IT_CHARPOS (*it),
2797 it->region_beg_charpos,
2798 it->region_end_charpos,
2799 &next_stop,
2800 (IT_CHARPOS (*it)
2801 + TEXT_PROP_DISTANCE_LIMIT),
2804 /* Is this a start of a run of characters with box face?
2805 Caveat: this can be called for a freshly initialized
2806 iterator; face_id is -1 in this case. We know that the new
2807 face will not change until limit, i.e. if the new face has a
2808 box, all characters up to limit will have one. But, as
2809 usual, we don't know whether limit is really the end. */
2810 if (new_face_id != it->face_id)
2812 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2814 /* If new face has a box but old face has not, this is
2815 the start of a run of characters with box, i.e. it has
2816 a shadow on the left side. The value of face_id of the
2817 iterator will be -1 if this is the initial call that gets
2818 the face. In this case, we have to look in front of IT's
2819 position and see whether there is a face != new_face_id. */
2820 it->start_of_box_run_p
2821 = (new_face->box != FACE_NO_BOX
2822 && (it->face_id >= 0
2823 || IT_CHARPOS (*it) == BEG
2824 || new_face_id != face_before_it_pos (it)));
2825 it->face_box_p = new_face->box != FACE_NO_BOX;
2828 else
2830 int base_face_id, bufpos;
2832 if (it->current.overlay_string_index >= 0)
2833 bufpos = IT_CHARPOS (*it);
2834 else
2835 bufpos = 0;
2837 /* For strings from a buffer, i.e. overlay strings or strings
2838 from a `display' property, use the face at IT's current
2839 buffer position as the base face to merge with, so that
2840 overlay strings appear in the same face as surrounding
2841 text, unless they specify their own faces. */
2842 base_face_id = underlying_face_id (it);
2844 new_face_id = face_at_string_position (it->w,
2845 it->string,
2846 IT_STRING_CHARPOS (*it),
2847 bufpos,
2848 it->region_beg_charpos,
2849 it->region_end_charpos,
2850 &next_stop,
2851 base_face_id, 0);
2853 #if 0 /* This shouldn't be neccessary. Let's check it. */
2854 /* If IT is used to display a mode line we would really like to
2855 use the mode line face instead of the frame's default face. */
2856 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2857 && new_face_id == DEFAULT_FACE_ID)
2858 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2859 #endif
2861 /* Is this a start of a run of characters with box? Caveat:
2862 this can be called for a freshly allocated iterator; face_id
2863 is -1 is this case. We know that the new face will not
2864 change until the next check pos, i.e. if the new face has a
2865 box, all characters up to that position will have a
2866 box. But, as usual, we don't know whether that position
2867 is really the end. */
2868 if (new_face_id != it->face_id)
2870 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2871 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2873 /* If new face has a box but old face hasn't, this is the
2874 start of a run of characters with box, i.e. it has a
2875 shadow on the left side. */
2876 it->start_of_box_run_p
2877 = new_face->box && (old_face == NULL || !old_face->box);
2878 it->face_box_p = new_face->box != FACE_NO_BOX;
2882 it->face_id = new_face_id;
2883 return HANDLED_NORMALLY;
2887 /* Return the ID of the face ``underlying'' IT's current position,
2888 which is in a string. If the iterator is associated with a
2889 buffer, return the face at IT's current buffer position.
2890 Otherwise, use the iterator's base_face_id. */
2892 static int
2893 underlying_face_id (it)
2894 struct it *it;
2896 int face_id = it->base_face_id, i;
2898 xassert (STRINGP (it->string));
2900 for (i = it->sp - 1; i >= 0; --i)
2901 if (NILP (it->stack[i].string))
2902 face_id = it->stack[i].face_id;
2904 return face_id;
2908 /* Compute the face one character before or after the current position
2909 of IT. BEFORE_P non-zero means get the face in front of IT's
2910 position. Value is the id of the face. */
2912 static int
2913 face_before_or_after_it_pos (it, before_p)
2914 struct it *it;
2915 int before_p;
2917 int face_id, limit;
2918 int next_check_charpos;
2919 struct text_pos pos;
2921 xassert (it->s == NULL);
2923 if (STRINGP (it->string))
2925 int bufpos, base_face_id;
2927 /* No face change past the end of the string (for the case
2928 we are padding with spaces). No face change before the
2929 string start. */
2930 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2931 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2932 return it->face_id;
2934 /* Set pos to the position before or after IT's current position. */
2935 if (before_p)
2936 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2937 else
2938 /* For composition, we must check the character after the
2939 composition. */
2940 pos = (it->what == IT_COMPOSITION
2941 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2942 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2944 if (it->current.overlay_string_index >= 0)
2945 bufpos = IT_CHARPOS (*it);
2946 else
2947 bufpos = 0;
2949 base_face_id = underlying_face_id (it);
2951 /* Get the face for ASCII, or unibyte. */
2952 face_id = face_at_string_position (it->w,
2953 it->string,
2954 CHARPOS (pos),
2955 bufpos,
2956 it->region_beg_charpos,
2957 it->region_end_charpos,
2958 &next_check_charpos,
2959 base_face_id, 0);
2961 /* Correct the face for charsets different from ASCII. Do it
2962 for the multibyte case only. The face returned above is
2963 suitable for unibyte text if IT->string is unibyte. */
2964 if (STRING_MULTIBYTE (it->string))
2966 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2967 int rest = SBYTES (it->string) - BYTEPOS (pos);
2968 int c, len;
2969 struct face *face = FACE_FROM_ID (it->f, face_id);
2971 c = string_char_and_length (p, rest, &len);
2972 face_id = FACE_FOR_CHAR (it->f, face, c);
2975 else
2977 if ((IT_CHARPOS (*it) >= ZV && !before_p)
2978 || (IT_CHARPOS (*it) <= BEGV && before_p))
2979 return it->face_id;
2981 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2982 pos = it->current.pos;
2984 if (before_p)
2985 DEC_TEXT_POS (pos, it->multibyte_p);
2986 else
2988 if (it->what == IT_COMPOSITION)
2989 /* For composition, we must check the position after the
2990 composition. */
2991 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2992 else
2993 INC_TEXT_POS (pos, it->multibyte_p);
2996 /* Determine face for CHARSET_ASCII, or unibyte. */
2997 face_id = face_at_buffer_position (it->w,
2998 CHARPOS (pos),
2999 it->region_beg_charpos,
3000 it->region_end_charpos,
3001 &next_check_charpos,
3002 limit, 0);
3004 /* Correct the face for charsets different from ASCII. Do it
3005 for the multibyte case only. The face returned above is
3006 suitable for unibyte text if current_buffer is unibyte. */
3007 if (it->multibyte_p)
3009 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3010 struct face *face = FACE_FROM_ID (it->f, face_id);
3011 face_id = FACE_FOR_CHAR (it->f, face, c);
3015 return face_id;
3020 /***********************************************************************
3021 Invisible text
3022 ***********************************************************************/
3024 /* Set up iterator IT from invisible properties at its current
3025 position. Called from handle_stop. */
3027 static enum prop_handled
3028 handle_invisible_prop (it)
3029 struct it *it;
3031 enum prop_handled handled = HANDLED_NORMALLY;
3033 if (STRINGP (it->string))
3035 extern Lisp_Object Qinvisible;
3036 Lisp_Object prop, end_charpos, limit, charpos;
3038 /* Get the value of the invisible text property at the
3039 current position. Value will be nil if there is no such
3040 property. */
3041 charpos = make_number (IT_STRING_CHARPOS (*it));
3042 prop = Fget_text_property (charpos, Qinvisible, it->string);
3044 if (!NILP (prop)
3045 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3047 handled = HANDLED_RECOMPUTE_PROPS;
3049 /* Get the position at which the next change of the
3050 invisible text property can be found in IT->string.
3051 Value will be nil if the property value is the same for
3052 all the rest of IT->string. */
3053 XSETINT (limit, SCHARS (it->string));
3054 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3055 it->string, limit);
3057 /* Text at current position is invisible. The next
3058 change in the property is at position end_charpos.
3059 Move IT's current position to that position. */
3060 if (INTEGERP (end_charpos)
3061 && XFASTINT (end_charpos) < XFASTINT (limit))
3063 struct text_pos old;
3064 old = it->current.string_pos;
3065 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3066 compute_string_pos (&it->current.string_pos, old, it->string);
3068 else
3070 /* The rest of the string is invisible. If this is an
3071 overlay string, proceed with the next overlay string
3072 or whatever comes and return a character from there. */
3073 if (it->current.overlay_string_index >= 0)
3075 next_overlay_string (it);
3076 /* Don't check for overlay strings when we just
3077 finished processing them. */
3078 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3080 else
3082 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3083 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3088 else
3090 int invis_p, newpos, next_stop, start_charpos;
3091 Lisp_Object pos, prop, overlay;
3093 /* First of all, is there invisible text at this position? */
3094 start_charpos = IT_CHARPOS (*it);
3095 pos = make_number (IT_CHARPOS (*it));
3096 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3097 &overlay);
3098 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3100 /* If we are on invisible text, skip over it. */
3101 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3103 /* Record whether we have to display an ellipsis for the
3104 invisible text. */
3105 int display_ellipsis_p = invis_p == 2;
3107 handled = HANDLED_RECOMPUTE_PROPS;
3109 /* Loop skipping over invisible text. The loop is left at
3110 ZV or with IT on the first char being visible again. */
3113 /* Try to skip some invisible text. Return value is the
3114 position reached which can be equal to IT's position
3115 if there is nothing invisible here. This skips both
3116 over invisible text properties and overlays with
3117 invisible property. */
3118 newpos = skip_invisible (IT_CHARPOS (*it),
3119 &next_stop, ZV, it->window);
3121 /* If we skipped nothing at all we weren't at invisible
3122 text in the first place. If everything to the end of
3123 the buffer was skipped, end the loop. */
3124 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3125 invis_p = 0;
3126 else
3128 /* We skipped some characters but not necessarily
3129 all there are. Check if we ended up on visible
3130 text. Fget_char_property returns the property of
3131 the char before the given position, i.e. if we
3132 get invis_p = 0, this means that the char at
3133 newpos is visible. */
3134 pos = make_number (newpos);
3135 prop = Fget_char_property (pos, Qinvisible, it->window);
3136 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3139 /* If we ended up on invisible text, proceed to
3140 skip starting with next_stop. */
3141 if (invis_p)
3142 IT_CHARPOS (*it) = next_stop;
3144 while (invis_p);
3146 /* The position newpos is now either ZV or on visible text. */
3147 IT_CHARPOS (*it) = newpos;
3148 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3150 /* If there are before-strings at the start of invisible
3151 text, and the text is invisible because of a text
3152 property, arrange to show before-strings because 20.x did
3153 it that way. (If the text is invisible because of an
3154 overlay property instead of a text property, this is
3155 already handled in the overlay code.) */
3156 if (NILP (overlay)
3157 && get_overlay_strings (it, start_charpos))
3159 handled = HANDLED_RECOMPUTE_PROPS;
3160 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3162 else if (display_ellipsis_p)
3163 setup_for_ellipsis (it);
3167 return handled;
3171 /* Make iterator IT return `...' next. */
3173 static void
3174 setup_for_ellipsis (it)
3175 struct it *it;
3177 if (it->dp
3178 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3180 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3181 it->dpvec = v->contents;
3182 it->dpend = v->contents + v->size;
3184 else
3186 /* Default `...'. */
3187 it->dpvec = default_invis_vector;
3188 it->dpend = default_invis_vector + 3;
3191 /* The ellipsis display does not replace the display of the
3192 character at the new position. Indicate this by setting
3193 IT->dpvec_char_len to zero. */
3194 it->dpvec_char_len = 0;
3196 it->current.dpvec_index = 0;
3197 it->method = next_element_from_display_vector;
3202 /***********************************************************************
3203 'display' property
3204 ***********************************************************************/
3206 /* Set up iterator IT from `display' property at its current position.
3207 Called from handle_stop. */
3209 static enum prop_handled
3210 handle_display_prop (it)
3211 struct it *it;
3213 Lisp_Object prop, object;
3214 struct text_pos *position;
3215 int display_replaced_p = 0;
3217 if (STRINGP (it->string))
3219 object = it->string;
3220 position = &it->current.string_pos;
3222 else
3224 object = it->w->buffer;
3225 position = &it->current.pos;
3228 /* Reset those iterator values set from display property values. */
3229 it->font_height = Qnil;
3230 it->space_width = Qnil;
3231 it->voffset = 0;
3233 /* We don't support recursive `display' properties, i.e. string
3234 values that have a string `display' property, that have a string
3235 `display' property etc. */
3236 if (!it->string_from_display_prop_p)
3237 it->area = TEXT_AREA;
3239 prop = Fget_char_property (make_number (position->charpos),
3240 Qdisplay, object);
3241 if (NILP (prop))
3242 return HANDLED_NORMALLY;
3244 if (CONSP (prop)
3245 /* Simple properties. */
3246 && !EQ (XCAR (prop), Qimage)
3247 && !EQ (XCAR (prop), Qspace)
3248 && !EQ (XCAR (prop), Qwhen)
3249 && !EQ (XCAR (prop), Qspace_width)
3250 && !EQ (XCAR (prop), Qheight)
3251 && !EQ (XCAR (prop), Qraise)
3252 /* Marginal area specifications. */
3253 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3254 && !NILP (XCAR (prop)))
3256 for (; CONSP (prop); prop = XCDR (prop))
3258 if (handle_single_display_prop (it, XCAR (prop), object,
3259 position, display_replaced_p))
3260 display_replaced_p = 1;
3263 else if (VECTORP (prop))
3265 int i;
3266 for (i = 0; i < ASIZE (prop); ++i)
3267 if (handle_single_display_prop (it, AREF (prop, i), object,
3268 position, display_replaced_p))
3269 display_replaced_p = 1;
3271 else
3273 if (handle_single_display_prop (it, prop, object, position, 0))
3274 display_replaced_p = 1;
3277 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3281 /* Value is the position of the end of the `display' property starting
3282 at START_POS in OBJECT. */
3284 static struct text_pos
3285 display_prop_end (it, object, start_pos)
3286 struct it *it;
3287 Lisp_Object object;
3288 struct text_pos start_pos;
3290 Lisp_Object end;
3291 struct text_pos end_pos;
3293 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3294 Qdisplay, object, Qnil);
3295 CHARPOS (end_pos) = XFASTINT (end);
3296 if (STRINGP (object))
3297 compute_string_pos (&end_pos, start_pos, it->string);
3298 else
3299 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3301 return end_pos;
3305 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3306 is the object in which the `display' property was found. *POSITION
3307 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3308 means that we previously saw a display sub-property which already
3309 replaced text display with something else, for example an image;
3310 ignore such properties after the first one has been processed.
3312 If PROP is a `space' or `image' sub-property, set *POSITION to the
3313 end position of the `display' property.
3315 Value is non-zero if something was found which replaces the display
3316 of buffer or string text. */
3318 static int
3319 handle_single_display_prop (it, prop, object, position,
3320 display_replaced_before_p)
3321 struct it *it;
3322 Lisp_Object prop;
3323 Lisp_Object object;
3324 struct text_pos *position;
3325 int display_replaced_before_p;
3327 Lisp_Object value;
3328 int replaces_text_display_p = 0;
3329 Lisp_Object form;
3331 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3332 evaluated. If the result is nil, VALUE is ignored. */
3333 form = Qt;
3334 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3336 prop = XCDR (prop);
3337 if (!CONSP (prop))
3338 return 0;
3339 form = XCAR (prop);
3340 prop = XCDR (prop);
3343 if (!NILP (form) && !EQ (form, Qt))
3345 int count = SPECPDL_INDEX ();
3346 struct gcpro gcpro1;
3348 /* Bind `object' to the object having the `display' property, a
3349 buffer or string. Bind `position' to the position in the
3350 object where the property was found, and `buffer-position'
3351 to the current position in the buffer. */
3352 specbind (Qobject, object);
3353 specbind (Qposition, make_number (CHARPOS (*position)));
3354 specbind (Qbuffer_position,
3355 make_number (STRINGP (object)
3356 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3357 GCPRO1 (form);
3358 form = safe_eval (form);
3359 UNGCPRO;
3360 unbind_to (count, Qnil);
3363 if (NILP (form))
3364 return 0;
3366 if (CONSP (prop)
3367 && EQ (XCAR (prop), Qheight)
3368 && CONSP (XCDR (prop)))
3370 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3371 return 0;
3373 /* `(height HEIGHT)'. */
3374 it->font_height = XCAR (XCDR (prop));
3375 if (!NILP (it->font_height))
3377 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3378 int new_height = -1;
3380 if (CONSP (it->font_height)
3381 && (EQ (XCAR (it->font_height), Qplus)
3382 || EQ (XCAR (it->font_height), Qminus))
3383 && CONSP (XCDR (it->font_height))
3384 && INTEGERP (XCAR (XCDR (it->font_height))))
3386 /* `(+ N)' or `(- N)' where N is an integer. */
3387 int steps = XINT (XCAR (XCDR (it->font_height)));
3388 if (EQ (XCAR (it->font_height), Qplus))
3389 steps = - steps;
3390 it->face_id = smaller_face (it->f, it->face_id, steps);
3392 else if (FUNCTIONP (it->font_height))
3394 /* Call function with current height as argument.
3395 Value is the new height. */
3396 Lisp_Object height;
3397 height = safe_call1 (it->font_height,
3398 face->lface[LFACE_HEIGHT_INDEX]);
3399 if (NUMBERP (height))
3400 new_height = XFLOATINT (height);
3402 else if (NUMBERP (it->font_height))
3404 /* Value is a multiple of the canonical char height. */
3405 struct face *face;
3407 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3408 new_height = (XFLOATINT (it->font_height)
3409 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3411 else
3413 /* Evaluate IT->font_height with `height' bound to the
3414 current specified height to get the new height. */
3415 Lisp_Object value;
3416 int count = SPECPDL_INDEX ();
3418 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3419 value = safe_eval (it->font_height);
3420 unbind_to (count, Qnil);
3422 if (NUMBERP (value))
3423 new_height = XFLOATINT (value);
3426 if (new_height > 0)
3427 it->face_id = face_with_height (it->f, it->face_id, new_height);
3430 else if (CONSP (prop)
3431 && EQ (XCAR (prop), Qspace_width)
3432 && CONSP (XCDR (prop)))
3434 /* `(space_width WIDTH)'. */
3435 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3436 return 0;
3438 value = XCAR (XCDR (prop));
3439 if (NUMBERP (value) && XFLOATINT (value) > 0)
3440 it->space_width = value;
3442 else if (CONSP (prop)
3443 && EQ (XCAR (prop), Qraise)
3444 && CONSP (XCDR (prop)))
3446 /* `(raise FACTOR)'. */
3447 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3448 return 0;
3450 #ifdef HAVE_WINDOW_SYSTEM
3451 value = XCAR (XCDR (prop));
3452 if (NUMBERP (value))
3454 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3455 it->voffset = - (XFLOATINT (value)
3456 * (FONT_HEIGHT (face->font)));
3458 #endif /* HAVE_WINDOW_SYSTEM */
3460 else if (!it->string_from_display_prop_p)
3462 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3463 VALUE) or `((margin nil) VALUE)' or VALUE. */
3464 Lisp_Object location, value;
3465 struct text_pos start_pos;
3466 int valid_p;
3468 /* Characters having this form of property are not displayed, so
3469 we have to find the end of the property. */
3470 start_pos = *position;
3471 *position = display_prop_end (it, object, start_pos);
3472 value = Qnil;
3474 /* Let's stop at the new position and assume that all
3475 text properties change there. */
3476 it->stop_charpos = position->charpos;
3478 location = Qunbound;
3479 if (CONSP (prop) && CONSP (XCAR (prop)))
3481 Lisp_Object tem;
3483 value = XCDR (prop);
3484 if (CONSP (value))
3485 value = XCAR (value);
3487 tem = XCAR (prop);
3488 if (EQ (XCAR (tem), Qmargin)
3489 && (tem = XCDR (tem),
3490 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3491 (NILP (tem)
3492 || EQ (tem, Qleft_margin)
3493 || EQ (tem, Qright_margin))))
3494 location = tem;
3497 if (EQ (location, Qunbound))
3499 location = Qnil;
3500 value = prop;
3503 #ifdef HAVE_WINDOW_SYSTEM
3504 if (FRAME_TERMCAP_P (it->f))
3505 valid_p = STRINGP (value);
3506 else
3507 valid_p = (STRINGP (value)
3508 || (CONSP (value) && EQ (XCAR (value), Qspace))
3509 || valid_image_p (value));
3510 #else /* not HAVE_WINDOW_SYSTEM */
3511 valid_p = STRINGP (value);
3512 #endif /* not HAVE_WINDOW_SYSTEM */
3514 if ((EQ (location, Qleft_margin)
3515 || EQ (location, Qright_margin)
3516 || NILP (location))
3517 && valid_p
3518 && !display_replaced_before_p)
3520 replaces_text_display_p = 1;
3522 /* Save current settings of IT so that we can restore them
3523 when we are finished with the glyph property value. */
3524 push_it (it);
3526 if (NILP (location))
3527 it->area = TEXT_AREA;
3528 else if (EQ (location, Qleft_margin))
3529 it->area = LEFT_MARGIN_AREA;
3530 else
3531 it->area = RIGHT_MARGIN_AREA;
3533 if (STRINGP (value))
3535 it->string = value;
3536 it->multibyte_p = STRING_MULTIBYTE (it->string);
3537 it->current.overlay_string_index = -1;
3538 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3539 it->end_charpos = it->string_nchars = SCHARS (it->string);
3540 it->method = next_element_from_string;
3541 it->stop_charpos = 0;
3542 it->string_from_display_prop_p = 1;
3543 /* Say that we haven't consumed the characters with
3544 `display' property yet. The call to pop_it in
3545 set_iterator_to_next will clean this up. */
3546 *position = start_pos;
3548 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3550 it->method = next_element_from_stretch;
3551 it->object = value;
3552 it->current.pos = it->position = start_pos;
3554 #ifdef HAVE_WINDOW_SYSTEM
3555 else
3557 it->what = IT_IMAGE;
3558 it->image_id = lookup_image (it->f, value);
3559 it->position = start_pos;
3560 it->object = NILP (object) ? it->w->buffer : object;
3561 it->method = next_element_from_image;
3563 /* Say that we haven't consumed the characters with
3564 `display' property yet. The call to pop_it in
3565 set_iterator_to_next will clean this up. */
3566 *position = start_pos;
3568 #endif /* HAVE_WINDOW_SYSTEM */
3570 else
3571 /* Invalid property or property not supported. Restore
3572 the position to what it was before. */
3573 *position = start_pos;
3576 return replaces_text_display_p;
3580 /* Check if PROP is a display sub-property value whose text should be
3581 treated as intangible. */
3583 static int
3584 single_display_prop_intangible_p (prop)
3585 Lisp_Object prop;
3587 /* Skip over `when FORM'. */
3588 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3590 prop = XCDR (prop);
3591 if (!CONSP (prop))
3592 return 0;
3593 prop = XCDR (prop);
3596 if (STRINGP (prop))
3597 return 1;
3599 if (!CONSP (prop))
3600 return 0;
3602 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3603 we don't need to treat text as intangible. */
3604 if (EQ (XCAR (prop), Qmargin))
3606 prop = XCDR (prop);
3607 if (!CONSP (prop))
3608 return 0;
3610 prop = XCDR (prop);
3611 if (!CONSP (prop)
3612 || EQ (XCAR (prop), Qleft_margin)
3613 || EQ (XCAR (prop), Qright_margin))
3614 return 0;
3617 return (CONSP (prop)
3618 && (EQ (XCAR (prop), Qimage)
3619 || EQ (XCAR (prop), Qspace)));
3623 /* Check if PROP is a display property value whose text should be
3624 treated as intangible. */
3627 display_prop_intangible_p (prop)
3628 Lisp_Object prop;
3630 if (CONSP (prop)
3631 && CONSP (XCAR (prop))
3632 && !EQ (Qmargin, XCAR (XCAR (prop))))
3634 /* A list of sub-properties. */
3635 while (CONSP (prop))
3637 if (single_display_prop_intangible_p (XCAR (prop)))
3638 return 1;
3639 prop = XCDR (prop);
3642 else if (VECTORP (prop))
3644 /* A vector of sub-properties. */
3645 int i;
3646 for (i = 0; i < ASIZE (prop); ++i)
3647 if (single_display_prop_intangible_p (AREF (prop, i)))
3648 return 1;
3650 else
3651 return single_display_prop_intangible_p (prop);
3653 return 0;
3657 /* Return 1 if PROP is a display sub-property value containing STRING. */
3659 static int
3660 single_display_prop_string_p (prop, string)
3661 Lisp_Object prop, string;
3663 if (EQ (string, prop))
3664 return 1;
3666 /* Skip over `when FORM'. */
3667 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3669 prop = XCDR (prop);
3670 if (!CONSP (prop))
3671 return 0;
3672 prop = XCDR (prop);
3675 if (CONSP (prop))
3676 /* Skip over `margin LOCATION'. */
3677 if (EQ (XCAR (prop), Qmargin))
3679 prop = XCDR (prop);
3680 if (!CONSP (prop))
3681 return 0;
3683 prop = XCDR (prop);
3684 if (!CONSP (prop))
3685 return 0;
3688 return CONSP (prop) && EQ (XCAR (prop), string);
3692 /* Return 1 if STRING appears in the `display' property PROP. */
3694 static int
3695 display_prop_string_p (prop, string)
3696 Lisp_Object prop, string;
3698 if (CONSP (prop)
3699 && CONSP (XCAR (prop))
3700 && !EQ (Qmargin, XCAR (XCAR (prop))))
3702 /* A list of sub-properties. */
3703 while (CONSP (prop))
3705 if (single_display_prop_string_p (XCAR (prop), string))
3706 return 1;
3707 prop = XCDR (prop);
3710 else if (VECTORP (prop))
3712 /* A vector of sub-properties. */
3713 int i;
3714 for (i = 0; i < ASIZE (prop); ++i)
3715 if (single_display_prop_string_p (AREF (prop, i), string))
3716 return 1;
3718 else
3719 return single_display_prop_string_p (prop, string);
3721 return 0;
3725 /* Determine from which buffer position in W's buffer STRING comes
3726 from. AROUND_CHARPOS is an approximate position where it could
3727 be from. Value is the buffer position or 0 if it couldn't be
3728 determined.
3730 W's buffer must be current.
3732 This function is necessary because we don't record buffer positions
3733 in glyphs generated from strings (to keep struct glyph small).
3734 This function may only use code that doesn't eval because it is
3735 called asynchronously from note_mouse_highlight. */
3738 string_buffer_position (w, string, around_charpos)
3739 struct window *w;
3740 Lisp_Object string;
3741 int around_charpos;
3743 Lisp_Object limit, prop, pos;
3744 const int MAX_DISTANCE = 1000;
3745 int found = 0;
3747 pos = make_number (around_charpos);
3748 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3749 while (!found && !EQ (pos, limit))
3751 prop = Fget_char_property (pos, Qdisplay, Qnil);
3752 if (!NILP (prop) && display_prop_string_p (prop, string))
3753 found = 1;
3754 else
3755 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3758 if (!found)
3760 pos = make_number (around_charpos);
3761 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3762 while (!found && !EQ (pos, limit))
3764 prop = Fget_char_property (pos, Qdisplay, Qnil);
3765 if (!NILP (prop) && display_prop_string_p (prop, string))
3766 found = 1;
3767 else
3768 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3769 limit);
3773 return found ? XINT (pos) : 0;
3778 /***********************************************************************
3779 `composition' property
3780 ***********************************************************************/
3782 /* Set up iterator IT from `composition' property at its current
3783 position. Called from handle_stop. */
3785 static enum prop_handled
3786 handle_composition_prop (it)
3787 struct it *it;
3789 Lisp_Object prop, string;
3790 int pos, pos_byte, end;
3791 enum prop_handled handled = HANDLED_NORMALLY;
3793 if (STRINGP (it->string))
3795 pos = IT_STRING_CHARPOS (*it);
3796 pos_byte = IT_STRING_BYTEPOS (*it);
3797 string = it->string;
3799 else
3801 pos = IT_CHARPOS (*it);
3802 pos_byte = IT_BYTEPOS (*it);
3803 string = Qnil;
3806 /* If there's a valid composition and point is not inside of the
3807 composition (in the case that the composition is from the current
3808 buffer), draw a glyph composed from the composition components. */
3809 if (find_composition (pos, -1, &pos, &end, &prop, string)
3810 && COMPOSITION_VALID_P (pos, end, prop)
3811 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3813 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3815 if (id >= 0)
3817 it->method = next_element_from_composition;
3818 it->cmp_id = id;
3819 it->cmp_len = COMPOSITION_LENGTH (prop);
3820 /* For a terminal, draw only the first character of the
3821 components. */
3822 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3823 it->len = (STRINGP (it->string)
3824 ? string_char_to_byte (it->string, end)
3825 : CHAR_TO_BYTE (end)) - pos_byte;
3826 it->stop_charpos = end;
3827 handled = HANDLED_RETURN;
3831 return handled;
3836 /***********************************************************************
3837 Overlay strings
3838 ***********************************************************************/
3840 /* The following structure is used to record overlay strings for
3841 later sorting in load_overlay_strings. */
3843 struct overlay_entry
3845 Lisp_Object overlay;
3846 Lisp_Object string;
3847 int priority;
3848 int after_string_p;
3852 /* Set up iterator IT from overlay strings at its current position.
3853 Called from handle_stop. */
3855 static enum prop_handled
3856 handle_overlay_change (it)
3857 struct it *it;
3859 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3860 return HANDLED_RECOMPUTE_PROPS;
3861 else
3862 return HANDLED_NORMALLY;
3866 /* Set up the next overlay string for delivery by IT, if there is an
3867 overlay string to deliver. Called by set_iterator_to_next when the
3868 end of the current overlay string is reached. If there are more
3869 overlay strings to display, IT->string and
3870 IT->current.overlay_string_index are set appropriately here.
3871 Otherwise IT->string is set to nil. */
3873 static void
3874 next_overlay_string (it)
3875 struct it *it;
3877 ++it->current.overlay_string_index;
3878 if (it->current.overlay_string_index == it->n_overlay_strings)
3880 /* No more overlay strings. Restore IT's settings to what
3881 they were before overlay strings were processed, and
3882 continue to deliver from current_buffer. */
3883 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3885 pop_it (it);
3886 xassert (it->stop_charpos >= BEGV
3887 && it->stop_charpos <= it->end_charpos);
3888 it->string = Qnil;
3889 it->current.overlay_string_index = -1;
3890 SET_TEXT_POS (it->current.string_pos, -1, -1);
3891 it->n_overlay_strings = 0;
3892 it->method = next_element_from_buffer;
3894 /* If we're at the end of the buffer, record that we have
3895 processed the overlay strings there already, so that
3896 next_element_from_buffer doesn't try it again. */
3897 if (IT_CHARPOS (*it) >= it->end_charpos)
3898 it->overlay_strings_at_end_processed_p = 1;
3900 /* If we have to display `...' for invisible text, set
3901 the iterator up for that. */
3902 if (display_ellipsis_p)
3903 setup_for_ellipsis (it);
3905 else
3907 /* There are more overlay strings to process. If
3908 IT->current.overlay_string_index has advanced to a position
3909 where we must load IT->overlay_strings with more strings, do
3910 it. */
3911 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3913 if (it->current.overlay_string_index && i == 0)
3914 load_overlay_strings (it, 0);
3916 /* Initialize IT to deliver display elements from the overlay
3917 string. */
3918 it->string = it->overlay_strings[i];
3919 it->multibyte_p = STRING_MULTIBYTE (it->string);
3920 SET_TEXT_POS (it->current.string_pos, 0, 0);
3921 it->method = next_element_from_string;
3922 it->stop_charpos = 0;
3925 CHECK_IT (it);
3929 /* Compare two overlay_entry structures E1 and E2. Used as a
3930 comparison function for qsort in load_overlay_strings. Overlay
3931 strings for the same position are sorted so that
3933 1. All after-strings come in front of before-strings, except
3934 when they come from the same overlay.
3936 2. Within after-strings, strings are sorted so that overlay strings
3937 from overlays with higher priorities come first.
3939 2. Within before-strings, strings are sorted so that overlay
3940 strings from overlays with higher priorities come last.
3942 Value is analogous to strcmp. */
3945 static int
3946 compare_overlay_entries (e1, e2)
3947 void *e1, *e2;
3949 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
3950 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
3951 int result;
3953 if (entry1->after_string_p != entry2->after_string_p)
3955 /* Let after-strings appear in front of before-strings if
3956 they come from different overlays. */
3957 if (EQ (entry1->overlay, entry2->overlay))
3958 result = entry1->after_string_p ? 1 : -1;
3959 else
3960 result = entry1->after_string_p ? -1 : 1;
3962 else if (entry1->after_string_p)
3963 /* After-strings sorted in order of decreasing priority. */
3964 result = entry2->priority - entry1->priority;
3965 else
3966 /* Before-strings sorted in order of increasing priority. */
3967 result = entry1->priority - entry2->priority;
3969 return result;
3973 /* Load the vector IT->overlay_strings with overlay strings from IT's
3974 current buffer position, or from CHARPOS if that is > 0. Set
3975 IT->n_overlays to the total number of overlay strings found.
3977 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
3978 a time. On entry into load_overlay_strings,
3979 IT->current.overlay_string_index gives the number of overlay
3980 strings that have already been loaded by previous calls to this
3981 function.
3983 IT->add_overlay_start contains an additional overlay start
3984 position to consider for taking overlay strings from, if non-zero.
3985 This position comes into play when the overlay has an `invisible'
3986 property, and both before and after-strings. When we've skipped to
3987 the end of the overlay, because of its `invisible' property, we
3988 nevertheless want its before-string to appear.
3989 IT->add_overlay_start will contain the overlay start position
3990 in this case.
3992 Overlay strings are sorted so that after-string strings come in
3993 front of before-string strings. Within before and after-strings,
3994 strings are sorted by overlay priority. See also function
3995 compare_overlay_entries. */
3997 static void
3998 load_overlay_strings (it, charpos)
3999 struct it *it;
4000 int charpos;
4002 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4003 Lisp_Object overlay, window, str, invisible;
4004 struct Lisp_Overlay *ov;
4005 int start, end;
4006 int size = 20;
4007 int n = 0, i, j, invis_p;
4008 struct overlay_entry *entries
4009 = (struct overlay_entry *) alloca (size * sizeof *entries);
4011 if (charpos <= 0)
4012 charpos = IT_CHARPOS (*it);
4014 /* Append the overlay string STRING of overlay OVERLAY to vector
4015 `entries' which has size `size' and currently contains `n'
4016 elements. AFTER_P non-zero means STRING is an after-string of
4017 OVERLAY. */
4018 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4019 do \
4021 Lisp_Object priority; \
4023 if (n == size) \
4025 int new_size = 2 * size; \
4026 struct overlay_entry *old = entries; \
4027 entries = \
4028 (struct overlay_entry *) alloca (new_size \
4029 * sizeof *entries); \
4030 bcopy (old, entries, size * sizeof *entries); \
4031 size = new_size; \
4034 entries[n].string = (STRING); \
4035 entries[n].overlay = (OVERLAY); \
4036 priority = Foverlay_get ((OVERLAY), Qpriority); \
4037 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4038 entries[n].after_string_p = (AFTER_P); \
4039 ++n; \
4041 while (0)
4043 /* Process overlay before the overlay center. */
4044 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4046 XSETMISC (overlay, ov);
4047 xassert (OVERLAYP (overlay));
4048 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4049 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4051 if (end < charpos)
4052 break;
4054 /* Skip this overlay if it doesn't start or end at IT's current
4055 position. */
4056 if (end != charpos && start != charpos)
4057 continue;
4059 /* Skip this overlay if it doesn't apply to IT->w. */
4060 window = Foverlay_get (overlay, Qwindow);
4061 if (WINDOWP (window) && XWINDOW (window) != it->w)
4062 continue;
4064 /* If the text ``under'' the overlay is invisible, both before-
4065 and after-strings from this overlay are visible; start and
4066 end position are indistinguishable. */
4067 invisible = Foverlay_get (overlay, Qinvisible);
4068 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4070 /* If overlay has a non-empty before-string, record it. */
4071 if ((start == charpos || (end == charpos && invis_p))
4072 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4073 && SCHARS (str))
4074 RECORD_OVERLAY_STRING (overlay, str, 0);
4076 /* If overlay has a non-empty after-string, record it. */
4077 if ((end == charpos || (start == charpos && invis_p))
4078 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4079 && SCHARS (str))
4080 RECORD_OVERLAY_STRING (overlay, str, 1);
4083 /* Process overlays after the overlay center. */
4084 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4086 XSETMISC (overlay, ov);
4087 xassert (OVERLAYP (overlay));
4088 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4089 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4091 if (start > charpos)
4092 break;
4094 /* Skip this overlay if it doesn't start or end at IT's current
4095 position. */
4096 if (end != charpos && start != charpos)
4097 continue;
4099 /* Skip this overlay if it doesn't apply to IT->w. */
4100 window = Foverlay_get (overlay, Qwindow);
4101 if (WINDOWP (window) && XWINDOW (window) != it->w)
4102 continue;
4104 /* If the text ``under'' the overlay is invisible, it has a zero
4105 dimension, and both before- and after-strings apply. */
4106 invisible = Foverlay_get (overlay, Qinvisible);
4107 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4109 /* If overlay has a non-empty before-string, record it. */
4110 if ((start == charpos || (end == charpos && invis_p))
4111 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4112 && SCHARS (str))
4113 RECORD_OVERLAY_STRING (overlay, str, 0);
4115 /* If overlay has a non-empty after-string, record it. */
4116 if ((end == charpos || (start == charpos && invis_p))
4117 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4118 && SCHARS (str))
4119 RECORD_OVERLAY_STRING (overlay, str, 1);
4122 #undef RECORD_OVERLAY_STRING
4124 /* Sort entries. */
4125 if (n > 1)
4126 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4128 /* Record the total number of strings to process. */
4129 it->n_overlay_strings = n;
4131 /* IT->current.overlay_string_index is the number of overlay strings
4132 that have already been consumed by IT. Copy some of the
4133 remaining overlay strings to IT->overlay_strings. */
4134 i = 0;
4135 j = it->current.overlay_string_index;
4136 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4137 it->overlay_strings[i++] = entries[j++].string;
4139 CHECK_IT (it);
4143 /* Get the first chunk of overlay strings at IT's current buffer
4144 position, or at CHARPOS if that is > 0. Value is non-zero if at
4145 least one overlay string was found. */
4147 static int
4148 get_overlay_strings (it, charpos)
4149 struct it *it;
4150 int charpos;
4152 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4153 process. This fills IT->overlay_strings with strings, and sets
4154 IT->n_overlay_strings to the total number of strings to process.
4155 IT->pos.overlay_string_index has to be set temporarily to zero
4156 because load_overlay_strings needs this; it must be set to -1
4157 when no overlay strings are found because a zero value would
4158 indicate a position in the first overlay string. */
4159 it->current.overlay_string_index = 0;
4160 load_overlay_strings (it, charpos);
4162 /* If we found overlay strings, set up IT to deliver display
4163 elements from the first one. Otherwise set up IT to deliver
4164 from current_buffer. */
4165 if (it->n_overlay_strings)
4167 /* Make sure we know settings in current_buffer, so that we can
4168 restore meaningful values when we're done with the overlay
4169 strings. */
4170 compute_stop_pos (it);
4171 xassert (it->face_id >= 0);
4173 /* Save IT's settings. They are restored after all overlay
4174 strings have been processed. */
4175 xassert (it->sp == 0);
4176 push_it (it);
4178 /* Set up IT to deliver display elements from the first overlay
4179 string. */
4180 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4181 it->string = it->overlay_strings[0];
4182 it->stop_charpos = 0;
4183 xassert (STRINGP (it->string));
4184 it->end_charpos = SCHARS (it->string);
4185 it->multibyte_p = STRING_MULTIBYTE (it->string);
4186 it->method = next_element_from_string;
4188 else
4190 it->string = Qnil;
4191 it->current.overlay_string_index = -1;
4192 it->method = next_element_from_buffer;
4195 CHECK_IT (it);
4197 /* Value is non-zero if we found at least one overlay string. */
4198 return STRINGP (it->string);
4203 /***********************************************************************
4204 Saving and restoring state
4205 ***********************************************************************/
4207 /* Save current settings of IT on IT->stack. Called, for example,
4208 before setting up IT for an overlay string, to be able to restore
4209 IT's settings to what they were after the overlay string has been
4210 processed. */
4212 static void
4213 push_it (it)
4214 struct it *it;
4216 struct iterator_stack_entry *p;
4218 xassert (it->sp < 2);
4219 p = it->stack + it->sp;
4221 p->stop_charpos = it->stop_charpos;
4222 xassert (it->face_id >= 0);
4223 p->face_id = it->face_id;
4224 p->string = it->string;
4225 p->pos = it->current;
4226 p->end_charpos = it->end_charpos;
4227 p->string_nchars = it->string_nchars;
4228 p->area = it->area;
4229 p->multibyte_p = it->multibyte_p;
4230 p->space_width = it->space_width;
4231 p->font_height = it->font_height;
4232 p->voffset = it->voffset;
4233 p->string_from_display_prop_p = it->string_from_display_prop_p;
4234 p->display_ellipsis_p = 0;
4235 ++it->sp;
4239 /* Restore IT's settings from IT->stack. Called, for example, when no
4240 more overlay strings must be processed, and we return to delivering
4241 display elements from a buffer, or when the end of a string from a
4242 `display' property is reached and we return to delivering display
4243 elements from an overlay string, or from a buffer. */
4245 static void
4246 pop_it (it)
4247 struct it *it;
4249 struct iterator_stack_entry *p;
4251 xassert (it->sp > 0);
4252 --it->sp;
4253 p = it->stack + it->sp;
4254 it->stop_charpos = p->stop_charpos;
4255 it->face_id = p->face_id;
4256 it->string = p->string;
4257 it->current = p->pos;
4258 it->end_charpos = p->end_charpos;
4259 it->string_nchars = p->string_nchars;
4260 it->area = p->area;
4261 it->multibyte_p = p->multibyte_p;
4262 it->space_width = p->space_width;
4263 it->font_height = p->font_height;
4264 it->voffset = p->voffset;
4265 it->string_from_display_prop_p = p->string_from_display_prop_p;
4270 /***********************************************************************
4271 Moving over lines
4272 ***********************************************************************/
4274 /* Set IT's current position to the previous line start. */
4276 static void
4277 back_to_previous_line_start (it)
4278 struct it *it;
4280 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4281 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4285 /* Move IT to the next line start.
4287 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4288 we skipped over part of the text (as opposed to moving the iterator
4289 continuously over the text). Otherwise, don't change the value
4290 of *SKIPPED_P.
4292 Newlines may come from buffer text, overlay strings, or strings
4293 displayed via the `display' property. That's the reason we can't
4294 simply use find_next_newline_no_quit.
4296 Note that this function may not skip over invisible text that is so
4297 because of text properties and immediately follows a newline. If
4298 it would, function reseat_at_next_visible_line_start, when called
4299 from set_iterator_to_next, would effectively make invisible
4300 characters following a newline part of the wrong glyph row, which
4301 leads to wrong cursor motion. */
4303 static int
4304 forward_to_next_line_start (it, skipped_p)
4305 struct it *it;
4306 int *skipped_p;
4308 int old_selective, newline_found_p, n;
4309 const int MAX_NEWLINE_DISTANCE = 500;
4311 /* If already on a newline, just consume it to avoid unintended
4312 skipping over invisible text below. */
4313 if (it->what == IT_CHARACTER
4314 && it->c == '\n'
4315 && CHARPOS (it->position) == IT_CHARPOS (*it))
4317 set_iterator_to_next (it, 0);
4318 it->c = 0;
4319 return 1;
4322 /* Don't handle selective display in the following. It's (a)
4323 unnecessary because it's done by the caller, and (b) leads to an
4324 infinite recursion because next_element_from_ellipsis indirectly
4325 calls this function. */
4326 old_selective = it->selective;
4327 it->selective = 0;
4329 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4330 from buffer text. */
4331 for (n = newline_found_p = 0;
4332 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4333 n += STRINGP (it->string) ? 0 : 1)
4335 if (!get_next_display_element (it))
4336 return 0;
4337 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4338 set_iterator_to_next (it, 0);
4341 /* If we didn't find a newline near enough, see if we can use a
4342 short-cut. */
4343 if (!newline_found_p)
4345 int start = IT_CHARPOS (*it);
4346 int limit = find_next_newline_no_quit (start, 1);
4347 Lisp_Object pos;
4349 xassert (!STRINGP (it->string));
4351 /* If there isn't any `display' property in sight, and no
4352 overlays, we can just use the position of the newline in
4353 buffer text. */
4354 if (it->stop_charpos >= limit
4355 || ((pos = Fnext_single_property_change (make_number (start),
4356 Qdisplay,
4357 Qnil, make_number (limit)),
4358 NILP (pos))
4359 && next_overlay_change (start) == ZV))
4361 IT_CHARPOS (*it) = limit;
4362 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4363 *skipped_p = newline_found_p = 1;
4365 else
4367 while (get_next_display_element (it)
4368 && !newline_found_p)
4370 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4371 set_iterator_to_next (it, 0);
4376 it->selective = old_selective;
4377 return newline_found_p;
4381 /* Set IT's current position to the previous visible line start. Skip
4382 invisible text that is so either due to text properties or due to
4383 selective display. Caution: this does not change IT->current_x and
4384 IT->hpos. */
4386 static void
4387 back_to_previous_visible_line_start (it)
4388 struct it *it;
4390 int visible_p = 0;
4392 /* Go back one newline if not on BEGV already. */
4393 if (IT_CHARPOS (*it) > BEGV)
4394 back_to_previous_line_start (it);
4396 /* Move over lines that are invisible because of selective display
4397 or text properties. */
4398 while (IT_CHARPOS (*it) > BEGV
4399 && !visible_p)
4401 visible_p = 1;
4403 /* If selective > 0, then lines indented more than that values
4404 are invisible. */
4405 if (it->selective > 0
4406 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4407 (double) it->selective)) /* iftc */
4408 visible_p = 0;
4409 else
4411 Lisp_Object prop;
4413 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4414 Qinvisible, it->window);
4415 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4416 visible_p = 0;
4419 /* Back one more newline if the current one is invisible. */
4420 if (!visible_p)
4421 back_to_previous_line_start (it);
4424 xassert (IT_CHARPOS (*it) >= BEGV);
4425 xassert (IT_CHARPOS (*it) == BEGV
4426 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4427 CHECK_IT (it);
4431 /* Reseat iterator IT at the previous visible line start. Skip
4432 invisible text that is so either due to text properties or due to
4433 selective display. At the end, update IT's overlay information,
4434 face information etc. */
4436 static void
4437 reseat_at_previous_visible_line_start (it)
4438 struct it *it;
4440 back_to_previous_visible_line_start (it);
4441 reseat (it, it->current.pos, 1);
4442 CHECK_IT (it);
4446 /* Reseat iterator IT on the next visible line start in the current
4447 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4448 preceding the line start. Skip over invisible text that is so
4449 because of selective display. Compute faces, overlays etc at the
4450 new position. Note that this function does not skip over text that
4451 is invisible because of text properties. */
4453 static void
4454 reseat_at_next_visible_line_start (it, on_newline_p)
4455 struct it *it;
4456 int on_newline_p;
4458 int newline_found_p, skipped_p = 0;
4460 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4462 /* Skip over lines that are invisible because they are indented
4463 more than the value of IT->selective. */
4464 if (it->selective > 0)
4465 while (IT_CHARPOS (*it) < ZV
4466 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4467 (double) it->selective)) /* iftc */
4469 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4470 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4473 /* Position on the newline if that's what's requested. */
4474 if (on_newline_p && newline_found_p)
4476 if (STRINGP (it->string))
4478 if (IT_STRING_CHARPOS (*it) > 0)
4480 --IT_STRING_CHARPOS (*it);
4481 --IT_STRING_BYTEPOS (*it);
4484 else if (IT_CHARPOS (*it) > BEGV)
4486 --IT_CHARPOS (*it);
4487 --IT_BYTEPOS (*it);
4488 reseat (it, it->current.pos, 0);
4491 else if (skipped_p)
4492 reseat (it, it->current.pos, 0);
4494 CHECK_IT (it);
4499 /***********************************************************************
4500 Changing an iterator's position
4501 ***********************************************************************/
4503 /* Change IT's current position to POS in current_buffer. If FORCE_P
4504 is non-zero, always check for text properties at the new position.
4505 Otherwise, text properties are only looked up if POS >=
4506 IT->check_charpos of a property. */
4508 static void
4509 reseat (it, pos, force_p)
4510 struct it *it;
4511 struct text_pos pos;
4512 int force_p;
4514 int original_pos = IT_CHARPOS (*it);
4516 reseat_1 (it, pos, 0);
4518 /* Determine where to check text properties. Avoid doing it
4519 where possible because text property lookup is very expensive. */
4520 if (force_p
4521 || CHARPOS (pos) > it->stop_charpos
4522 || CHARPOS (pos) < original_pos)
4523 handle_stop (it);
4525 CHECK_IT (it);
4529 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4530 IT->stop_pos to POS, also. */
4532 static void
4533 reseat_1 (it, pos, set_stop_p)
4534 struct it *it;
4535 struct text_pos pos;
4536 int set_stop_p;
4538 /* Don't call this function when scanning a C string. */
4539 xassert (it->s == NULL);
4541 /* POS must be a reasonable value. */
4542 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4544 it->current.pos = it->position = pos;
4545 XSETBUFFER (it->object, current_buffer);
4546 it->end_charpos = ZV;
4547 it->dpvec = NULL;
4548 it->current.dpvec_index = -1;
4549 it->current.overlay_string_index = -1;
4550 IT_STRING_CHARPOS (*it) = -1;
4551 IT_STRING_BYTEPOS (*it) = -1;
4552 it->string = Qnil;
4553 it->method = next_element_from_buffer;
4554 /* RMS: I added this to fix a bug in move_it_vertically_backward
4555 where it->area continued to relate to the starting point
4556 for the backward motion. Bug report from
4557 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4558 However, I am not sure whether reseat still does the right thing
4559 in general after this change. */
4560 it->area = TEXT_AREA;
4561 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4562 it->sp = 0;
4563 it->face_before_selective_p = 0;
4565 if (set_stop_p)
4566 it->stop_charpos = CHARPOS (pos);
4570 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4571 If S is non-null, it is a C string to iterate over. Otherwise,
4572 STRING gives a Lisp string to iterate over.
4574 If PRECISION > 0, don't return more then PRECISION number of
4575 characters from the string.
4577 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4578 characters have been returned. FIELD_WIDTH < 0 means an infinite
4579 field width.
4581 MULTIBYTE = 0 means disable processing of multibyte characters,
4582 MULTIBYTE > 0 means enable it,
4583 MULTIBYTE < 0 means use IT->multibyte_p.
4585 IT must be initialized via a prior call to init_iterator before
4586 calling this function. */
4588 static void
4589 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4590 struct it *it;
4591 unsigned char *s;
4592 Lisp_Object string;
4593 int charpos;
4594 int precision, field_width, multibyte;
4596 /* No region in strings. */
4597 it->region_beg_charpos = it->region_end_charpos = -1;
4599 /* No text property checks performed by default, but see below. */
4600 it->stop_charpos = -1;
4602 /* Set iterator position and end position. */
4603 bzero (&it->current, sizeof it->current);
4604 it->current.overlay_string_index = -1;
4605 it->current.dpvec_index = -1;
4606 xassert (charpos >= 0);
4608 /* If STRING is specified, use its multibyteness, otherwise use the
4609 setting of MULTIBYTE, if specified. */
4610 if (multibyte >= 0)
4611 it->multibyte_p = multibyte > 0;
4613 if (s == NULL)
4615 xassert (STRINGP (string));
4616 it->string = string;
4617 it->s = NULL;
4618 it->end_charpos = it->string_nchars = SCHARS (string);
4619 it->method = next_element_from_string;
4620 it->current.string_pos = string_pos (charpos, string);
4622 else
4624 it->s = s;
4625 it->string = Qnil;
4627 /* Note that we use IT->current.pos, not it->current.string_pos,
4628 for displaying C strings. */
4629 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4630 if (it->multibyte_p)
4632 it->current.pos = c_string_pos (charpos, s, 1);
4633 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4635 else
4637 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4638 it->end_charpos = it->string_nchars = strlen (s);
4641 it->method = next_element_from_c_string;
4644 /* PRECISION > 0 means don't return more than PRECISION characters
4645 from the string. */
4646 if (precision > 0 && it->end_charpos - charpos > precision)
4647 it->end_charpos = it->string_nchars = charpos + precision;
4649 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4650 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4651 FIELD_WIDTH < 0 means infinite field width. This is useful for
4652 padding with `-' at the end of a mode line. */
4653 if (field_width < 0)
4654 field_width = INFINITY;
4655 if (field_width > it->end_charpos - charpos)
4656 it->end_charpos = charpos + field_width;
4658 /* Use the standard display table for displaying strings. */
4659 if (DISP_TABLE_P (Vstandard_display_table))
4660 it->dp = XCHAR_TABLE (Vstandard_display_table);
4662 it->stop_charpos = charpos;
4663 CHECK_IT (it);
4668 /***********************************************************************
4669 Iteration
4670 ***********************************************************************/
4672 /* Load IT's display element fields with information about the next
4673 display element from the current position of IT. Value is zero if
4674 end of buffer (or C string) is reached. */
4677 get_next_display_element (it)
4678 struct it *it;
4680 /* Non-zero means that we found a display element. Zero means that
4681 we hit the end of what we iterate over. Performance note: the
4682 function pointer `method' used here turns out to be faster than
4683 using a sequence of if-statements. */
4684 int success_p = (*it->method) (it);
4686 if (it->what == IT_CHARACTER)
4688 /* Map via display table or translate control characters.
4689 IT->c, IT->len etc. have been set to the next character by
4690 the function call above. If we have a display table, and it
4691 contains an entry for IT->c, translate it. Don't do this if
4692 IT->c itself comes from a display table, otherwise we could
4693 end up in an infinite recursion. (An alternative could be to
4694 count the recursion depth of this function and signal an
4695 error when a certain maximum depth is reached.) Is it worth
4696 it? */
4697 if (success_p && it->dpvec == NULL)
4699 Lisp_Object dv;
4701 if (it->dp
4702 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4703 VECTORP (dv)))
4705 struct Lisp_Vector *v = XVECTOR (dv);
4707 /* Return the first character from the display table
4708 entry, if not empty. If empty, don't display the
4709 current character. */
4710 if (v->size)
4712 it->dpvec_char_len = it->len;
4713 it->dpvec = v->contents;
4714 it->dpend = v->contents + v->size;
4715 it->current.dpvec_index = 0;
4716 it->method = next_element_from_display_vector;
4717 success_p = get_next_display_element (it);
4719 else
4721 set_iterator_to_next (it, 0);
4722 success_p = get_next_display_element (it);
4726 /* Translate control characters into `\003' or `^C' form.
4727 Control characters coming from a display table entry are
4728 currently not translated because we use IT->dpvec to hold
4729 the translation. This could easily be changed but I
4730 don't believe that it is worth doing.
4732 If it->multibyte_p is nonzero, eight-bit characters and
4733 non-printable multibyte characters are also translated to
4734 octal form.
4736 If it->multibyte_p is zero, eight-bit characters that
4737 don't have corresponding multibyte char code are also
4738 translated to octal form. */
4739 else if ((it->c < ' '
4740 && (it->area != TEXT_AREA
4741 || (it->c != '\n' && it->c != '\t')))
4742 || (it->multibyte_p
4743 ? ((it->c >= 127
4744 && it->len == 1)
4745 || !CHAR_PRINTABLE_P (it->c))
4746 : (it->c >= 127
4747 && it->c == unibyte_char_to_multibyte (it->c))))
4749 /* IT->c is a control character which must be displayed
4750 either as '\003' or as `^C' where the '\\' and '^'
4751 can be defined in the display table. Fill
4752 IT->ctl_chars with glyphs for what we have to
4753 display. Then, set IT->dpvec to these glyphs. */
4754 GLYPH g;
4756 if (it->c < 128 && it->ctl_arrow_p)
4758 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4759 if (it->dp
4760 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4761 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4762 g = XINT (DISP_CTRL_GLYPH (it->dp));
4763 else
4764 g = FAST_MAKE_GLYPH ('^', 0);
4765 XSETINT (it->ctl_chars[0], g);
4767 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4768 XSETINT (it->ctl_chars[1], g);
4770 /* Set up IT->dpvec and return first character from it. */
4771 it->dpvec_char_len = it->len;
4772 it->dpvec = it->ctl_chars;
4773 it->dpend = it->dpvec + 2;
4774 it->current.dpvec_index = 0;
4775 it->method = next_element_from_display_vector;
4776 get_next_display_element (it);
4778 else
4780 unsigned char str[MAX_MULTIBYTE_LENGTH];
4781 int len;
4782 int i;
4783 GLYPH escape_glyph;
4785 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4786 if (it->dp
4787 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4788 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4789 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4790 else
4791 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4793 if (SINGLE_BYTE_CHAR_P (it->c))
4794 str[0] = it->c, len = 1;
4795 else
4797 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4798 if (len < 0)
4800 /* It's an invalid character, which
4801 shouldn't happen actually, but due to
4802 bugs it may happen. Let's print the char
4803 as is, there's not much meaningful we can
4804 do with it. */
4805 str[0] = it->c;
4806 str[1] = it->c >> 8;
4807 str[2] = it->c >> 16;
4808 str[3] = it->c >> 24;
4809 len = 4;
4813 for (i = 0; i < len; i++)
4815 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4816 /* Insert three more glyphs into IT->ctl_chars for
4817 the octal display of the character. */
4818 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4819 XSETINT (it->ctl_chars[i * 4 + 1], g);
4820 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4821 XSETINT (it->ctl_chars[i * 4 + 2], g);
4822 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4823 XSETINT (it->ctl_chars[i * 4 + 3], g);
4826 /* Set up IT->dpvec and return the first character
4827 from it. */
4828 it->dpvec_char_len = it->len;
4829 it->dpvec = it->ctl_chars;
4830 it->dpend = it->dpvec + len * 4;
4831 it->current.dpvec_index = 0;
4832 it->method = next_element_from_display_vector;
4833 get_next_display_element (it);
4838 /* Adjust face id for a multibyte character. There are no
4839 multibyte character in unibyte text. */
4840 if (it->multibyte_p
4841 && success_p
4842 && FRAME_WINDOW_P (it->f))
4844 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4845 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4849 /* Is this character the last one of a run of characters with
4850 box? If yes, set IT->end_of_box_run_p to 1. */
4851 if (it->face_box_p
4852 && it->s == NULL)
4854 int face_id;
4855 struct face *face;
4857 it->end_of_box_run_p
4858 = ((face_id = face_after_it_pos (it),
4859 face_id != it->face_id)
4860 && (face = FACE_FROM_ID (it->f, face_id),
4861 face->box == FACE_NO_BOX));
4864 /* Value is 0 if end of buffer or string reached. */
4865 return success_p;
4869 /* Move IT to the next display element.
4871 RESEAT_P non-zero means if called on a newline in buffer text,
4872 skip to the next visible line start.
4874 Functions get_next_display_element and set_iterator_to_next are
4875 separate because I find this arrangement easier to handle than a
4876 get_next_display_element function that also increments IT's
4877 position. The way it is we can first look at an iterator's current
4878 display element, decide whether it fits on a line, and if it does,
4879 increment the iterator position. The other way around we probably
4880 would either need a flag indicating whether the iterator has to be
4881 incremented the next time, or we would have to implement a
4882 decrement position function which would not be easy to write. */
4884 void
4885 set_iterator_to_next (it, reseat_p)
4886 struct it *it;
4887 int reseat_p;
4889 /* Reset flags indicating start and end of a sequence of characters
4890 with box. Reset them at the start of this function because
4891 moving the iterator to a new position might set them. */
4892 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4894 if (it->method == next_element_from_buffer)
4896 /* The current display element of IT is a character from
4897 current_buffer. Advance in the buffer, and maybe skip over
4898 invisible lines that are so because of selective display. */
4899 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4900 reseat_at_next_visible_line_start (it, 0);
4901 else
4903 xassert (it->len != 0);
4904 IT_BYTEPOS (*it) += it->len;
4905 IT_CHARPOS (*it) += 1;
4906 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4909 else if (it->method == next_element_from_composition)
4911 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4912 if (STRINGP (it->string))
4914 IT_STRING_BYTEPOS (*it) += it->len;
4915 IT_STRING_CHARPOS (*it) += it->cmp_len;
4916 it->method = next_element_from_string;
4917 goto consider_string_end;
4919 else
4921 IT_BYTEPOS (*it) += it->len;
4922 IT_CHARPOS (*it) += it->cmp_len;
4923 it->method = next_element_from_buffer;
4926 else if (it->method == next_element_from_c_string)
4928 /* Current display element of IT is from a C string. */
4929 IT_BYTEPOS (*it) += it->len;
4930 IT_CHARPOS (*it) += 1;
4932 else if (it->method == next_element_from_display_vector)
4934 /* Current display element of IT is from a display table entry.
4935 Advance in the display table definition. Reset it to null if
4936 end reached, and continue with characters from buffers/
4937 strings. */
4938 ++it->current.dpvec_index;
4940 /* Restore face of the iterator to what they were before the
4941 display vector entry (these entries may contain faces). */
4942 it->face_id = it->saved_face_id;
4944 if (it->dpvec + it->current.dpvec_index == it->dpend)
4946 if (it->s)
4947 it->method = next_element_from_c_string;
4948 else if (STRINGP (it->string))
4949 it->method = next_element_from_string;
4950 else
4951 it->method = next_element_from_buffer;
4953 it->dpvec = NULL;
4954 it->current.dpvec_index = -1;
4956 /* Skip over characters which were displayed via IT->dpvec. */
4957 if (it->dpvec_char_len < 0)
4958 reseat_at_next_visible_line_start (it, 1);
4959 else if (it->dpvec_char_len > 0)
4961 it->len = it->dpvec_char_len;
4962 set_iterator_to_next (it, reseat_p);
4966 else if (it->method == next_element_from_string)
4968 /* Current display element is a character from a Lisp string. */
4969 xassert (it->s == NULL && STRINGP (it->string));
4970 IT_STRING_BYTEPOS (*it) += it->len;
4971 IT_STRING_CHARPOS (*it) += 1;
4973 consider_string_end:
4975 if (it->current.overlay_string_index >= 0)
4977 /* IT->string is an overlay string. Advance to the
4978 next, if there is one. */
4979 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
4980 next_overlay_string (it);
4982 else
4984 /* IT->string is not an overlay string. If we reached
4985 its end, and there is something on IT->stack, proceed
4986 with what is on the stack. This can be either another
4987 string, this time an overlay string, or a buffer. */
4988 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
4989 && it->sp > 0)
4991 pop_it (it);
4992 if (!STRINGP (it->string))
4993 it->method = next_element_from_buffer;
4994 else
4995 goto consider_string_end;
4999 else if (it->method == next_element_from_image
5000 || it->method == next_element_from_stretch)
5002 /* The position etc with which we have to proceed are on
5003 the stack. The position may be at the end of a string,
5004 if the `display' property takes up the whole string. */
5005 pop_it (it);
5006 it->image_id = 0;
5007 if (STRINGP (it->string))
5009 it->method = next_element_from_string;
5010 goto consider_string_end;
5012 else
5013 it->method = next_element_from_buffer;
5015 else
5016 /* There are no other methods defined, so this should be a bug. */
5017 abort ();
5019 xassert (it->method != next_element_from_string
5020 || (STRINGP (it->string)
5021 && IT_STRING_CHARPOS (*it) >= 0));
5025 /* Load IT's display element fields with information about the next
5026 display element which comes from a display table entry or from the
5027 result of translating a control character to one of the forms `^C'
5028 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5030 static int
5031 next_element_from_display_vector (it)
5032 struct it *it;
5034 /* Precondition. */
5035 xassert (it->dpvec && it->current.dpvec_index >= 0);
5037 /* Remember the current face id in case glyphs specify faces.
5038 IT's face is restored in set_iterator_to_next. */
5039 it->saved_face_id = it->face_id;
5041 if (INTEGERP (*it->dpvec)
5042 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5044 int lface_id;
5045 GLYPH g;
5047 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5048 it->c = FAST_GLYPH_CHAR (g);
5049 it->len = CHAR_BYTES (it->c);
5051 /* The entry may contain a face id to use. Such a face id is
5052 the id of a Lisp face, not a realized face. A face id of
5053 zero means no face is specified. */
5054 lface_id = FAST_GLYPH_FACE (g);
5055 if (lface_id)
5057 /* The function returns -1 if lface_id is invalid. */
5058 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5059 if (face_id >= 0)
5060 it->face_id = face_id;
5063 else
5064 /* Display table entry is invalid. Return a space. */
5065 it->c = ' ', it->len = 1;
5067 /* Don't change position and object of the iterator here. They are
5068 still the values of the character that had this display table
5069 entry or was translated, and that's what we want. */
5070 it->what = IT_CHARACTER;
5071 return 1;
5075 /* Load IT with the next display element from Lisp string IT->string.
5076 IT->current.string_pos is the current position within the string.
5077 If IT->current.overlay_string_index >= 0, the Lisp string is an
5078 overlay string. */
5080 static int
5081 next_element_from_string (it)
5082 struct it *it;
5084 struct text_pos position;
5086 xassert (STRINGP (it->string));
5087 xassert (IT_STRING_CHARPOS (*it) >= 0);
5088 position = it->current.string_pos;
5090 /* Time to check for invisible text? */
5091 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5092 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5094 handle_stop (it);
5096 /* Since a handler may have changed IT->method, we must
5097 recurse here. */
5098 return get_next_display_element (it);
5101 if (it->current.overlay_string_index >= 0)
5103 /* Get the next character from an overlay string. In overlay
5104 strings, There is no field width or padding with spaces to
5105 do. */
5106 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5108 it->what = IT_EOB;
5109 return 0;
5111 else if (STRING_MULTIBYTE (it->string))
5113 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5114 const unsigned char *s = (SDATA (it->string)
5115 + IT_STRING_BYTEPOS (*it));
5116 it->c = string_char_and_length (s, remaining, &it->len);
5118 else
5120 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5121 it->len = 1;
5124 else
5126 /* Get the next character from a Lisp string that is not an
5127 overlay string. Such strings come from the mode line, for
5128 example. We may have to pad with spaces, or truncate the
5129 string. See also next_element_from_c_string. */
5130 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5132 it->what = IT_EOB;
5133 return 0;
5135 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5137 /* Pad with spaces. */
5138 it->c = ' ', it->len = 1;
5139 CHARPOS (position) = BYTEPOS (position) = -1;
5141 else if (STRING_MULTIBYTE (it->string))
5143 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5144 const unsigned char *s = (SDATA (it->string)
5145 + IT_STRING_BYTEPOS (*it));
5146 it->c = string_char_and_length (s, maxlen, &it->len);
5148 else
5150 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5151 it->len = 1;
5155 /* Record what we have and where it came from. Note that we store a
5156 buffer position in IT->position although it could arguably be a
5157 string position. */
5158 it->what = IT_CHARACTER;
5159 it->object = it->string;
5160 it->position = position;
5161 return 1;
5165 /* Load IT with next display element from C string IT->s.
5166 IT->string_nchars is the maximum number of characters to return
5167 from the string. IT->end_charpos may be greater than
5168 IT->string_nchars when this function is called, in which case we
5169 may have to return padding spaces. Value is zero if end of string
5170 reached, including padding spaces. */
5172 static int
5173 next_element_from_c_string (it)
5174 struct it *it;
5176 int success_p = 1;
5178 xassert (it->s);
5179 it->what = IT_CHARACTER;
5180 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5181 it->object = Qnil;
5183 /* IT's position can be greater IT->string_nchars in case a field
5184 width or precision has been specified when the iterator was
5185 initialized. */
5186 if (IT_CHARPOS (*it) >= it->end_charpos)
5188 /* End of the game. */
5189 it->what = IT_EOB;
5190 success_p = 0;
5192 else if (IT_CHARPOS (*it) >= it->string_nchars)
5194 /* Pad with spaces. */
5195 it->c = ' ', it->len = 1;
5196 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5198 else if (it->multibyte_p)
5200 /* Implementation note: The calls to strlen apparently aren't a
5201 performance problem because there is no noticeable performance
5202 difference between Emacs running in unibyte or multibyte mode. */
5203 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5204 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5205 maxlen, &it->len);
5207 else
5208 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5210 return success_p;
5214 /* Set up IT to return characters from an ellipsis, if appropriate.
5215 The definition of the ellipsis glyphs may come from a display table
5216 entry. This function Fills IT with the first glyph from the
5217 ellipsis if an ellipsis is to be displayed. */
5219 static int
5220 next_element_from_ellipsis (it)
5221 struct it *it;
5223 if (it->selective_display_ellipsis_p)
5225 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5227 /* Use the display table definition for `...'. Invalid glyphs
5228 will be handled by the method returning elements from dpvec. */
5229 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5230 it->dpvec_char_len = it->len;
5231 it->dpvec = v->contents;
5232 it->dpend = v->contents + v->size;
5233 it->current.dpvec_index = 0;
5234 it->method = next_element_from_display_vector;
5236 else
5238 /* Use default `...' which is stored in default_invis_vector. */
5239 it->dpvec_char_len = it->len;
5240 it->dpvec = default_invis_vector;
5241 it->dpend = default_invis_vector + 3;
5242 it->current.dpvec_index = 0;
5243 it->method = next_element_from_display_vector;
5246 else
5248 /* The face at the current position may be different from the
5249 face we find after the invisible text. Remember what it
5250 was in IT->saved_face_id, and signal that it's there by
5251 setting face_before_selective_p. */
5252 it->saved_face_id = it->face_id;
5253 it->method = next_element_from_buffer;
5254 reseat_at_next_visible_line_start (it, 1);
5255 it->face_before_selective_p = 1;
5258 return get_next_display_element (it);
5262 /* Deliver an image display element. The iterator IT is already
5263 filled with image information (done in handle_display_prop). Value
5264 is always 1. */
5267 static int
5268 next_element_from_image (it)
5269 struct it *it;
5271 it->what = IT_IMAGE;
5272 return 1;
5276 /* Fill iterator IT with next display element from a stretch glyph
5277 property. IT->object is the value of the text property. Value is
5278 always 1. */
5280 static int
5281 next_element_from_stretch (it)
5282 struct it *it;
5284 it->what = IT_STRETCH;
5285 return 1;
5289 /* Load IT with the next display element from current_buffer. Value
5290 is zero if end of buffer reached. IT->stop_charpos is the next
5291 position at which to stop and check for text properties or buffer
5292 end. */
5294 static int
5295 next_element_from_buffer (it)
5296 struct it *it;
5298 int success_p = 1;
5300 /* Check this assumption, otherwise, we would never enter the
5301 if-statement, below. */
5302 xassert (IT_CHARPOS (*it) >= BEGV
5303 && IT_CHARPOS (*it) <= it->stop_charpos);
5305 if (IT_CHARPOS (*it) >= it->stop_charpos)
5307 if (IT_CHARPOS (*it) >= it->end_charpos)
5309 int overlay_strings_follow_p;
5311 /* End of the game, except when overlay strings follow that
5312 haven't been returned yet. */
5313 if (it->overlay_strings_at_end_processed_p)
5314 overlay_strings_follow_p = 0;
5315 else
5317 it->overlay_strings_at_end_processed_p = 1;
5318 overlay_strings_follow_p = get_overlay_strings (it, 0);
5321 if (overlay_strings_follow_p)
5322 success_p = get_next_display_element (it);
5323 else
5325 it->what = IT_EOB;
5326 it->position = it->current.pos;
5327 success_p = 0;
5330 else
5332 handle_stop (it);
5333 return get_next_display_element (it);
5336 else
5338 /* No face changes, overlays etc. in sight, so just return a
5339 character from current_buffer. */
5340 unsigned char *p;
5342 /* Maybe run the redisplay end trigger hook. Performance note:
5343 This doesn't seem to cost measurable time. */
5344 if (it->redisplay_end_trigger_charpos
5345 && it->glyph_row
5346 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5347 run_redisplay_end_trigger_hook (it);
5349 /* Get the next character, maybe multibyte. */
5350 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5351 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5353 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5354 - IT_BYTEPOS (*it));
5355 it->c = string_char_and_length (p, maxlen, &it->len);
5357 else
5358 it->c = *p, it->len = 1;
5360 /* Record what we have and where it came from. */
5361 it->what = IT_CHARACTER;;
5362 it->object = it->w->buffer;
5363 it->position = it->current.pos;
5365 /* Normally we return the character found above, except when we
5366 really want to return an ellipsis for selective display. */
5367 if (it->selective)
5369 if (it->c == '\n')
5371 /* A value of selective > 0 means hide lines indented more
5372 than that number of columns. */
5373 if (it->selective > 0
5374 && IT_CHARPOS (*it) + 1 < ZV
5375 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5376 IT_BYTEPOS (*it) + 1,
5377 (double) it->selective)) /* iftc */
5379 success_p = next_element_from_ellipsis (it);
5380 it->dpvec_char_len = -1;
5383 else if (it->c == '\r' && it->selective == -1)
5385 /* A value of selective == -1 means that everything from the
5386 CR to the end of the line is invisible, with maybe an
5387 ellipsis displayed for it. */
5388 success_p = next_element_from_ellipsis (it);
5389 it->dpvec_char_len = -1;
5394 /* Value is zero if end of buffer reached. */
5395 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5396 return success_p;
5400 /* Run the redisplay end trigger hook for IT. */
5402 static void
5403 run_redisplay_end_trigger_hook (it)
5404 struct it *it;
5406 Lisp_Object args[3];
5408 /* IT->glyph_row should be non-null, i.e. we should be actually
5409 displaying something, or otherwise we should not run the hook. */
5410 xassert (it->glyph_row);
5412 /* Set up hook arguments. */
5413 args[0] = Qredisplay_end_trigger_functions;
5414 args[1] = it->window;
5415 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5416 it->redisplay_end_trigger_charpos = 0;
5418 /* Since we are *trying* to run these functions, don't try to run
5419 them again, even if they get an error. */
5420 it->w->redisplay_end_trigger = Qnil;
5421 Frun_hook_with_args (3, args);
5423 /* Notice if it changed the face of the character we are on. */
5424 handle_face_prop (it);
5428 /* Deliver a composition display element. The iterator IT is already
5429 filled with composition information (done in
5430 handle_composition_prop). Value is always 1. */
5432 static int
5433 next_element_from_composition (it)
5434 struct it *it;
5436 it->what = IT_COMPOSITION;
5437 it->position = (STRINGP (it->string)
5438 ? it->current.string_pos
5439 : it->current.pos);
5440 return 1;
5445 /***********************************************************************
5446 Moving an iterator without producing glyphs
5447 ***********************************************************************/
5449 /* Move iterator IT to a specified buffer or X position within one
5450 line on the display without producing glyphs.
5452 OP should be a bit mask including some or all of these bits:
5453 MOVE_TO_X: Stop on reaching x-position TO_X.
5454 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5455 Regardless of OP's value, stop in reaching the end of the display line.
5457 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5458 This means, in particular, that TO_X includes window's horizontal
5459 scroll amount.
5461 The return value has several possible values that
5462 say what condition caused the scan to stop:
5464 MOVE_POS_MATCH_OR_ZV
5465 - when TO_POS or ZV was reached.
5467 MOVE_X_REACHED
5468 -when TO_X was reached before TO_POS or ZV were reached.
5470 MOVE_LINE_CONTINUED
5471 - when we reached the end of the display area and the line must
5472 be continued.
5474 MOVE_LINE_TRUNCATED
5475 - when we reached the end of the display area and the line is
5476 truncated.
5478 MOVE_NEWLINE_OR_CR
5479 - when we stopped at a line end, i.e. a newline or a CR and selective
5480 display is on. */
5482 static enum move_it_result
5483 move_it_in_display_line_to (it, to_charpos, to_x, op)
5484 struct it *it;
5485 int to_charpos, to_x, op;
5487 enum move_it_result result = MOVE_UNDEFINED;
5488 struct glyph_row *saved_glyph_row;
5490 /* Don't produce glyphs in produce_glyphs. */
5491 saved_glyph_row = it->glyph_row;
5492 it->glyph_row = NULL;
5494 while (1)
5496 int x, i, ascent = 0, descent = 0;
5498 /* Stop when ZV or TO_CHARPOS reached. */
5499 if (!get_next_display_element (it)
5500 || ((op & MOVE_TO_POS) != 0
5501 && BUFFERP (it->object)
5502 && IT_CHARPOS (*it) >= to_charpos))
5504 result = MOVE_POS_MATCH_OR_ZV;
5505 break;
5508 /* The call to produce_glyphs will get the metrics of the
5509 display element IT is loaded with. We record in x the
5510 x-position before this display element in case it does not
5511 fit on the line. */
5512 x = it->current_x;
5514 /* Remember the line height so far in case the next element doesn't
5515 fit on the line. */
5516 if (!it->truncate_lines_p)
5518 ascent = it->max_ascent;
5519 descent = it->max_descent;
5522 PRODUCE_GLYPHS (it);
5524 if (it->area != TEXT_AREA)
5526 set_iterator_to_next (it, 1);
5527 continue;
5530 /* The number of glyphs we get back in IT->nglyphs will normally
5531 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5532 character on a terminal frame, or (iii) a line end. For the
5533 second case, IT->nglyphs - 1 padding glyphs will be present
5534 (on X frames, there is only one glyph produced for a
5535 composite character.
5537 The behavior implemented below means, for continuation lines,
5538 that as many spaces of a TAB as fit on the current line are
5539 displayed there. For terminal frames, as many glyphs of a
5540 multi-glyph character are displayed in the current line, too.
5541 This is what the old redisplay code did, and we keep it that
5542 way. Under X, the whole shape of a complex character must
5543 fit on the line or it will be completely displayed in the
5544 next line.
5546 Note that both for tabs and padding glyphs, all glyphs have
5547 the same width. */
5548 if (it->nglyphs)
5550 /* More than one glyph or glyph doesn't fit on line. All
5551 glyphs have the same width. */
5552 int single_glyph_width = it->pixel_width / it->nglyphs;
5553 int new_x;
5555 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5557 new_x = x + single_glyph_width;
5559 /* We want to leave anything reaching TO_X to the caller. */
5560 if ((op & MOVE_TO_X) && new_x > to_x)
5562 it->current_x = x;
5563 result = MOVE_X_REACHED;
5564 break;
5566 else if (/* Lines are continued. */
5567 !it->truncate_lines_p
5568 && (/* And glyph doesn't fit on the line. */
5569 new_x > it->last_visible_x
5570 /* Or it fits exactly and we're on a window
5571 system frame. */
5572 || (new_x == it->last_visible_x
5573 && FRAME_WINDOW_P (it->f))))
5575 if (/* IT->hpos == 0 means the very first glyph
5576 doesn't fit on the line, e.g. a wide image. */
5577 it->hpos == 0
5578 || (new_x == it->last_visible_x
5579 && FRAME_WINDOW_P (it->f)))
5581 ++it->hpos;
5582 it->current_x = new_x;
5583 if (i == it->nglyphs - 1)
5584 set_iterator_to_next (it, 1);
5586 else
5588 it->current_x = x;
5589 it->max_ascent = ascent;
5590 it->max_descent = descent;
5593 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5594 IT_CHARPOS (*it)));
5595 result = MOVE_LINE_CONTINUED;
5596 break;
5598 else if (new_x > it->first_visible_x)
5600 /* Glyph is visible. Increment number of glyphs that
5601 would be displayed. */
5602 ++it->hpos;
5604 else
5606 /* Glyph is completely off the left margin of the display
5607 area. Nothing to do. */
5611 if (result != MOVE_UNDEFINED)
5612 break;
5614 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5616 /* Stop when TO_X specified and reached. This check is
5617 necessary here because of lines consisting of a line end,
5618 only. The line end will not produce any glyphs and we
5619 would never get MOVE_X_REACHED. */
5620 xassert (it->nglyphs == 0);
5621 result = MOVE_X_REACHED;
5622 break;
5625 /* Is this a line end? If yes, we're done. */
5626 if (ITERATOR_AT_END_OF_LINE_P (it))
5628 result = MOVE_NEWLINE_OR_CR;
5629 break;
5632 /* The current display element has been consumed. Advance
5633 to the next. */
5634 set_iterator_to_next (it, 1);
5636 /* Stop if lines are truncated and IT's current x-position is
5637 past the right edge of the window now. */
5638 if (it->truncate_lines_p
5639 && it->current_x >= it->last_visible_x)
5641 result = MOVE_LINE_TRUNCATED;
5642 break;
5646 /* Restore the iterator settings altered at the beginning of this
5647 function. */
5648 it->glyph_row = saved_glyph_row;
5649 return result;
5653 /* Move IT forward until it satisfies one or more of the criteria in
5654 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5656 OP is a bit-mask that specifies where to stop, and in particular,
5657 which of those four position arguments makes a difference. See the
5658 description of enum move_operation_enum.
5660 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5661 screen line, this function will set IT to the next position >
5662 TO_CHARPOS. */
5664 void
5665 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5666 struct it *it;
5667 int to_charpos, to_x, to_y, to_vpos;
5668 int op;
5670 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5671 int line_height;
5672 int reached = 0;
5674 for (;;)
5676 if (op & MOVE_TO_VPOS)
5678 /* If no TO_CHARPOS and no TO_X specified, stop at the
5679 start of the line TO_VPOS. */
5680 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5682 if (it->vpos == to_vpos)
5684 reached = 1;
5685 break;
5687 else
5688 skip = move_it_in_display_line_to (it, -1, -1, 0);
5690 else
5692 /* TO_VPOS >= 0 means stop at TO_X in the line at
5693 TO_VPOS, or at TO_POS, whichever comes first. */
5694 if (it->vpos == to_vpos)
5696 reached = 2;
5697 break;
5700 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5702 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5704 reached = 3;
5705 break;
5707 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5709 /* We have reached TO_X but not in the line we want. */
5710 skip = move_it_in_display_line_to (it, to_charpos,
5711 -1, MOVE_TO_POS);
5712 if (skip == MOVE_POS_MATCH_OR_ZV)
5714 reached = 4;
5715 break;
5720 else if (op & MOVE_TO_Y)
5722 struct it it_backup;
5724 /* TO_Y specified means stop at TO_X in the line containing
5725 TO_Y---or at TO_CHARPOS if this is reached first. The
5726 problem is that we can't really tell whether the line
5727 contains TO_Y before we have completely scanned it, and
5728 this may skip past TO_X. What we do is to first scan to
5729 TO_X.
5731 If TO_X is not specified, use a TO_X of zero. The reason
5732 is to make the outcome of this function more predictable.
5733 If we didn't use TO_X == 0, we would stop at the end of
5734 the line which is probably not what a caller would expect
5735 to happen. */
5736 skip = move_it_in_display_line_to (it, to_charpos,
5737 ((op & MOVE_TO_X)
5738 ? to_x : 0),
5739 (MOVE_TO_X
5740 | (op & MOVE_TO_POS)));
5742 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5743 if (skip == MOVE_POS_MATCH_OR_ZV)
5745 reached = 5;
5746 break;
5749 /* If TO_X was reached, we would like to know whether TO_Y
5750 is in the line. This can only be said if we know the
5751 total line height which requires us to scan the rest of
5752 the line. */
5753 if (skip == MOVE_X_REACHED)
5755 it_backup = *it;
5756 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5757 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5758 op & MOVE_TO_POS);
5759 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5762 /* Now, decide whether TO_Y is in this line. */
5763 line_height = it->max_ascent + it->max_descent;
5764 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5766 if (to_y >= it->current_y
5767 && to_y < it->current_y + line_height)
5769 if (skip == MOVE_X_REACHED)
5770 /* If TO_Y is in this line and TO_X was reached above,
5771 we scanned too far. We have to restore IT's settings
5772 to the ones before skipping. */
5773 *it = it_backup;
5774 reached = 6;
5776 else if (skip == MOVE_X_REACHED)
5778 skip = skip2;
5779 if (skip == MOVE_POS_MATCH_OR_ZV)
5780 reached = 7;
5783 if (reached)
5784 break;
5786 else
5787 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5789 switch (skip)
5791 case MOVE_POS_MATCH_OR_ZV:
5792 reached = 8;
5793 goto out;
5795 case MOVE_NEWLINE_OR_CR:
5796 set_iterator_to_next (it, 1);
5797 it->continuation_lines_width = 0;
5798 break;
5800 case MOVE_LINE_TRUNCATED:
5801 it->continuation_lines_width = 0;
5802 reseat_at_next_visible_line_start (it, 0);
5803 if ((op & MOVE_TO_POS) != 0
5804 && IT_CHARPOS (*it) > to_charpos)
5806 reached = 9;
5807 goto out;
5809 break;
5811 case MOVE_LINE_CONTINUED:
5812 it->continuation_lines_width += it->current_x;
5813 break;
5815 default:
5816 abort ();
5819 /* Reset/increment for the next run. */
5820 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5821 it->current_x = it->hpos = 0;
5822 it->current_y += it->max_ascent + it->max_descent;
5823 ++it->vpos;
5824 last_height = it->max_ascent + it->max_descent;
5825 last_max_ascent = it->max_ascent;
5826 it->max_ascent = it->max_descent = 0;
5829 out:
5831 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5835 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5837 If DY > 0, move IT backward at least that many pixels. DY = 0
5838 means move IT backward to the preceding line start or BEGV. This
5839 function may move over more than DY pixels if IT->current_y - DY
5840 ends up in the middle of a line; in this case IT->current_y will be
5841 set to the top of the line moved to. */
5843 void
5844 move_it_vertically_backward (it, dy)
5845 struct it *it;
5846 int dy;
5848 int nlines, h;
5849 struct it it2, it3;
5850 int start_pos = IT_CHARPOS (*it);
5852 xassert (dy >= 0);
5854 /* Estimate how many newlines we must move back. */
5855 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5857 /* Set the iterator's position that many lines back. */
5858 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5859 back_to_previous_visible_line_start (it);
5861 /* Reseat the iterator here. When moving backward, we don't want
5862 reseat to skip forward over invisible text, set up the iterator
5863 to deliver from overlay strings at the new position etc. So,
5864 use reseat_1 here. */
5865 reseat_1 (it, it->current.pos, 1);
5867 /* We are now surely at a line start. */
5868 it->current_x = it->hpos = 0;
5869 it->continuation_lines_width = 0;
5871 /* Move forward and see what y-distance we moved. First move to the
5872 start of the next line so that we get its height. We need this
5873 height to be able to tell whether we reached the specified
5874 y-distance. */
5875 it2 = *it;
5876 it2.max_ascent = it2.max_descent = 0;
5877 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5878 MOVE_TO_POS | MOVE_TO_VPOS);
5879 xassert (IT_CHARPOS (*it) >= BEGV);
5880 it3 = it2;
5882 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5883 xassert (IT_CHARPOS (*it) >= BEGV);
5884 /* H is the actual vertical distance from the position in *IT
5885 and the starting position. */
5886 h = it2.current_y - it->current_y;
5887 /* NLINES is the distance in number of lines. */
5888 nlines = it2.vpos - it->vpos;
5890 /* Correct IT's y and vpos position
5891 so that they are relative to the starting point. */
5892 it->vpos -= nlines;
5893 it->current_y -= h;
5895 if (dy == 0)
5897 /* DY == 0 means move to the start of the screen line. The
5898 value of nlines is > 0 if continuation lines were involved. */
5899 if (nlines > 0)
5900 move_it_by_lines (it, nlines, 1);
5901 xassert (IT_CHARPOS (*it) <= start_pos);
5903 else
5905 /* The y-position we try to reach, relative to *IT.
5906 Note that H has been subtracted in front of the if-statement. */
5907 int target_y = it->current_y + h - dy;
5908 int y0 = it3.current_y;
5909 int y1 = line_bottom_y (&it3);
5910 int line_height = y1 - y0;
5912 /* If we did not reach target_y, try to move further backward if
5913 we can. If we moved too far backward, try to move forward. */
5914 if (target_y < it->current_y
5915 /* This is heuristic. In a window that's 3 lines high, with
5916 a line height of 13 pixels each, recentering with point
5917 on the bottom line will try to move -39/2 = 19 pixels
5918 backward. Try to avoid moving into the first line. */
5919 && it->current_y - target_y > line_height / 3 * 2
5920 && IT_CHARPOS (*it) > BEGV)
5922 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
5923 target_y - it->current_y));
5924 move_it_vertically (it, target_y - it->current_y);
5925 xassert (IT_CHARPOS (*it) >= BEGV);
5927 else if (target_y >= it->current_y + line_height
5928 && IT_CHARPOS (*it) < ZV)
5930 /* Should move forward by at least one line, maybe more.
5932 Note: Calling move_it_by_lines can be expensive on
5933 terminal frames, where compute_motion is used (via
5934 vmotion) to do the job, when there are very long lines
5935 and truncate-lines is nil. That's the reason for
5936 treating terminal frames specially here. */
5938 if (!FRAME_WINDOW_P (it->f))
5939 move_it_vertically (it, target_y - (it->current_y + line_height));
5940 else
5944 move_it_by_lines (it, 1, 1);
5946 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
5949 xassert (IT_CHARPOS (*it) >= BEGV);
5955 /* Move IT by a specified amount of pixel lines DY. DY negative means
5956 move backwards. DY = 0 means move to start of screen line. At the
5957 end, IT will be on the start of a screen line. */
5959 void
5960 move_it_vertically (it, dy)
5961 struct it *it;
5962 int dy;
5964 if (dy <= 0)
5965 move_it_vertically_backward (it, -dy);
5966 else if (dy > 0)
5968 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
5969 move_it_to (it, ZV, -1, it->current_y + dy, -1,
5970 MOVE_TO_POS | MOVE_TO_Y);
5971 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
5973 /* If buffer ends in ZV without a newline, move to the start of
5974 the line to satisfy the post-condition. */
5975 if (IT_CHARPOS (*it) == ZV
5976 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
5977 move_it_by_lines (it, 0, 0);
5982 /* Move iterator IT past the end of the text line it is in. */
5984 void
5985 move_it_past_eol (it)
5986 struct it *it;
5988 enum move_it_result rc;
5990 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
5991 if (rc == MOVE_NEWLINE_OR_CR)
5992 set_iterator_to_next (it, 0);
5996 #if 0 /* Currently not used. */
5998 /* Return non-zero if some text between buffer positions START_CHARPOS
5999 and END_CHARPOS is invisible. IT->window is the window for text
6000 property lookup. */
6002 static int
6003 invisible_text_between_p (it, start_charpos, end_charpos)
6004 struct it *it;
6005 int start_charpos, end_charpos;
6007 Lisp_Object prop, limit;
6008 int invisible_found_p;
6010 xassert (it != NULL && start_charpos <= end_charpos);
6012 /* Is text at START invisible? */
6013 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6014 it->window);
6015 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6016 invisible_found_p = 1;
6017 else
6019 limit = Fnext_single_char_property_change (make_number (start_charpos),
6020 Qinvisible, Qnil,
6021 make_number (end_charpos));
6022 invisible_found_p = XFASTINT (limit) < end_charpos;
6025 return invisible_found_p;
6028 #endif /* 0 */
6031 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6032 negative means move up. DVPOS == 0 means move to the start of the
6033 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6034 NEED_Y_P is zero, IT->current_y will be left unchanged.
6036 Further optimization ideas: If we would know that IT->f doesn't use
6037 a face with proportional font, we could be faster for
6038 truncate-lines nil. */
6040 void
6041 move_it_by_lines (it, dvpos, need_y_p)
6042 struct it *it;
6043 int dvpos, need_y_p;
6045 struct position pos;
6047 if (!FRAME_WINDOW_P (it->f))
6049 struct text_pos textpos;
6051 /* We can use vmotion on frames without proportional fonts. */
6052 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6053 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6054 reseat (it, textpos, 1);
6055 it->vpos += pos.vpos;
6056 it->current_y += pos.vpos;
6058 else if (dvpos == 0)
6060 /* DVPOS == 0 means move to the start of the screen line. */
6061 move_it_vertically_backward (it, 0);
6062 xassert (it->current_x == 0 && it->hpos == 0);
6064 else if (dvpos > 0)
6065 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6066 else
6068 struct it it2;
6069 int start_charpos, i;
6071 /* Start at the beginning of the screen line containing IT's
6072 position. */
6073 move_it_vertically_backward (it, 0);
6075 /* Go back -DVPOS visible lines and reseat the iterator there. */
6076 start_charpos = IT_CHARPOS (*it);
6077 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6078 back_to_previous_visible_line_start (it);
6079 reseat (it, it->current.pos, 1);
6080 it->current_x = it->hpos = 0;
6082 /* Above call may have moved too far if continuation lines
6083 are involved. Scan forward and see if it did. */
6084 it2 = *it;
6085 it2.vpos = it2.current_y = 0;
6086 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6087 it->vpos -= it2.vpos;
6088 it->current_y -= it2.current_y;
6089 it->current_x = it->hpos = 0;
6091 /* If we moved too far, move IT some lines forward. */
6092 if (it2.vpos > -dvpos)
6094 int delta = it2.vpos + dvpos;
6095 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6100 /* Return 1 if IT points into the middle of a display vector. */
6103 in_display_vector_p (it)
6104 struct it *it;
6106 return (it->method == next_element_from_display_vector
6107 && it->current.dpvec_index > 0
6108 && it->dpvec + it->current.dpvec_index != it->dpend);
6112 /***********************************************************************
6113 Messages
6114 ***********************************************************************/
6117 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6118 to *Messages*. */
6120 void
6121 add_to_log (format, arg1, arg2)
6122 char *format;
6123 Lisp_Object arg1, arg2;
6125 Lisp_Object args[3];
6126 Lisp_Object msg, fmt;
6127 char *buffer;
6128 int len;
6129 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6131 /* Do nothing if called asynchronously. Inserting text into
6132 a buffer may call after-change-functions and alike and
6133 that would means running Lisp asynchronously. */
6134 if (handling_signal)
6135 return;
6137 fmt = msg = Qnil;
6138 GCPRO4 (fmt, msg, arg1, arg2);
6140 args[0] = fmt = build_string (format);
6141 args[1] = arg1;
6142 args[2] = arg2;
6143 msg = Fformat (3, args);
6145 len = SBYTES (msg) + 1;
6146 buffer = (char *) alloca (len);
6147 bcopy (SDATA (msg), buffer, len);
6149 message_dolog (buffer, len - 1, 1, 0);
6150 UNGCPRO;
6154 /* Output a newline in the *Messages* buffer if "needs" one. */
6156 void
6157 message_log_maybe_newline ()
6159 if (message_log_need_newline)
6160 message_dolog ("", 0, 1, 0);
6164 /* Add a string M of length NBYTES to the message log, optionally
6165 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6166 nonzero, means interpret the contents of M as multibyte. This
6167 function calls low-level routines in order to bypass text property
6168 hooks, etc. which might not be safe to run. */
6170 void
6171 message_dolog (m, nbytes, nlflag, multibyte)
6172 const char *m;
6173 int nbytes, nlflag, multibyte;
6175 if (!NILP (Vmemory_full))
6176 return;
6178 if (!NILP (Vmessage_log_max))
6180 struct buffer *oldbuf;
6181 Lisp_Object oldpoint, oldbegv, oldzv;
6182 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6183 int point_at_end = 0;
6184 int zv_at_end = 0;
6185 Lisp_Object old_deactivate_mark, tem;
6186 struct gcpro gcpro1;
6188 old_deactivate_mark = Vdeactivate_mark;
6189 oldbuf = current_buffer;
6190 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6191 current_buffer->undo_list = Qt;
6193 oldpoint = message_dolog_marker1;
6194 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6195 oldbegv = message_dolog_marker2;
6196 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6197 oldzv = message_dolog_marker3;
6198 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6199 GCPRO1 (old_deactivate_mark);
6201 if (PT == Z)
6202 point_at_end = 1;
6203 if (ZV == Z)
6204 zv_at_end = 1;
6206 BEGV = BEG;
6207 BEGV_BYTE = BEG_BYTE;
6208 ZV = Z;
6209 ZV_BYTE = Z_BYTE;
6210 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6212 /* Insert the string--maybe converting multibyte to single byte
6213 or vice versa, so that all the text fits the buffer. */
6214 if (multibyte
6215 && NILP (current_buffer->enable_multibyte_characters))
6217 int i, c, char_bytes;
6218 unsigned char work[1];
6220 /* Convert a multibyte string to single-byte
6221 for the *Message* buffer. */
6222 for (i = 0; i < nbytes; i += char_bytes)
6224 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6225 work[0] = (SINGLE_BYTE_CHAR_P (c)
6227 : multibyte_char_to_unibyte (c, Qnil));
6228 insert_1_both (work, 1, 1, 1, 0, 0);
6231 else if (! multibyte
6232 && ! NILP (current_buffer->enable_multibyte_characters))
6234 int i, c, char_bytes;
6235 unsigned char *msg = (unsigned char *) m;
6236 unsigned char str[MAX_MULTIBYTE_LENGTH];
6237 /* Convert a single-byte string to multibyte
6238 for the *Message* buffer. */
6239 for (i = 0; i < nbytes; i++)
6241 c = unibyte_char_to_multibyte (msg[i]);
6242 char_bytes = CHAR_STRING (c, str);
6243 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6246 else if (nbytes)
6247 insert_1 (m, nbytes, 1, 0, 0);
6249 if (nlflag)
6251 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6252 insert_1 ("\n", 1, 1, 0, 0);
6254 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6255 this_bol = PT;
6256 this_bol_byte = PT_BYTE;
6258 /* See if this line duplicates the previous one.
6259 If so, combine duplicates. */
6260 if (this_bol > BEG)
6262 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6263 prev_bol = PT;
6264 prev_bol_byte = PT_BYTE;
6266 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6267 this_bol, this_bol_byte);
6268 if (dup)
6270 del_range_both (prev_bol, prev_bol_byte,
6271 this_bol, this_bol_byte, 0);
6272 if (dup > 1)
6274 char dupstr[40];
6275 int duplen;
6277 /* If you change this format, don't forget to also
6278 change message_log_check_duplicate. */
6279 sprintf (dupstr, " [%d times]", dup);
6280 duplen = strlen (dupstr);
6281 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6282 insert_1 (dupstr, duplen, 1, 0, 1);
6287 /* If we have more than the desired maximum number of lines
6288 in the *Messages* buffer now, delete the oldest ones.
6289 This is safe because we don't have undo in this buffer. */
6291 if (NATNUMP (Vmessage_log_max))
6293 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6294 -XFASTINT (Vmessage_log_max) - 1, 0);
6295 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6298 BEGV = XMARKER (oldbegv)->charpos;
6299 BEGV_BYTE = marker_byte_position (oldbegv);
6301 if (zv_at_end)
6303 ZV = Z;
6304 ZV_BYTE = Z_BYTE;
6306 else
6308 ZV = XMARKER (oldzv)->charpos;
6309 ZV_BYTE = marker_byte_position (oldzv);
6312 if (point_at_end)
6313 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6314 else
6315 /* We can't do Fgoto_char (oldpoint) because it will run some
6316 Lisp code. */
6317 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6318 XMARKER (oldpoint)->bytepos);
6320 UNGCPRO;
6321 unchain_marker (XMARKER (oldpoint));
6322 unchain_marker (XMARKER (oldbegv));
6323 unchain_marker (XMARKER (oldzv));
6325 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6326 set_buffer_internal (oldbuf);
6327 if (NILP (tem))
6328 windows_or_buffers_changed = old_windows_or_buffers_changed;
6329 message_log_need_newline = !nlflag;
6330 Vdeactivate_mark = old_deactivate_mark;
6335 /* We are at the end of the buffer after just having inserted a newline.
6336 (Note: We depend on the fact we won't be crossing the gap.)
6337 Check to see if the most recent message looks a lot like the previous one.
6338 Return 0 if different, 1 if the new one should just replace it, or a
6339 value N > 1 if we should also append " [N times]". */
6341 static int
6342 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6343 int prev_bol, this_bol;
6344 int prev_bol_byte, this_bol_byte;
6346 int i;
6347 int len = Z_BYTE - 1 - this_bol_byte;
6348 int seen_dots = 0;
6349 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6350 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6352 for (i = 0; i < len; i++)
6354 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6355 seen_dots = 1;
6356 if (p1[i] != p2[i])
6357 return seen_dots;
6359 p1 += len;
6360 if (*p1 == '\n')
6361 return 2;
6362 if (*p1++ == ' ' && *p1++ == '[')
6364 int n = 0;
6365 while (*p1 >= '0' && *p1 <= '9')
6366 n = n * 10 + *p1++ - '0';
6367 if (strncmp (p1, " times]\n", 8) == 0)
6368 return n+1;
6370 return 0;
6374 /* Display an echo area message M with a specified length of NBYTES
6375 bytes. The string may include null characters. If M is 0, clear
6376 out any existing message, and let the mini-buffer text show
6377 through.
6379 The buffer M must continue to exist until after the echo area gets
6380 cleared or some other message gets displayed there. This means do
6381 not pass text that is stored in a Lisp string; do not pass text in
6382 a buffer that was alloca'd. */
6384 void
6385 message2 (m, nbytes, multibyte)
6386 const char *m;
6387 int nbytes;
6388 int multibyte;
6390 /* First flush out any partial line written with print. */
6391 message_log_maybe_newline ();
6392 if (m)
6393 message_dolog (m, nbytes, 1, multibyte);
6394 message2_nolog (m, nbytes, multibyte);
6398 /* The non-logging counterpart of message2. */
6400 void
6401 message2_nolog (m, nbytes, multibyte)
6402 const char *m;
6403 int nbytes, multibyte;
6405 struct frame *sf = SELECTED_FRAME ();
6406 message_enable_multibyte = multibyte;
6408 if (noninteractive)
6410 if (noninteractive_need_newline)
6411 putc ('\n', stderr);
6412 noninteractive_need_newline = 0;
6413 if (m)
6414 fwrite (m, nbytes, 1, stderr);
6415 if (cursor_in_echo_area == 0)
6416 fprintf (stderr, "\n");
6417 fflush (stderr);
6419 /* A null message buffer means that the frame hasn't really been
6420 initialized yet. Error messages get reported properly by
6421 cmd_error, so this must be just an informative message; toss it. */
6422 else if (INTERACTIVE
6423 && sf->glyphs_initialized_p
6424 && FRAME_MESSAGE_BUF (sf))
6426 Lisp_Object mini_window;
6427 struct frame *f;
6429 /* Get the frame containing the mini-buffer
6430 that the selected frame is using. */
6431 mini_window = FRAME_MINIBUF_WINDOW (sf);
6432 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6434 FRAME_SAMPLE_VISIBILITY (f);
6435 if (FRAME_VISIBLE_P (sf)
6436 && ! FRAME_VISIBLE_P (f))
6437 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6439 if (m)
6441 set_message (m, Qnil, nbytes, multibyte);
6442 if (minibuffer_auto_raise)
6443 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6445 else
6446 clear_message (1, 1);
6448 do_pending_window_change (0);
6449 echo_area_display (1);
6450 do_pending_window_change (0);
6451 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6452 (*frame_up_to_date_hook) (f);
6457 /* Display an echo area message M with a specified length of NBYTES
6458 bytes. The string may include null characters. If M is not a
6459 string, clear out any existing message, and let the mini-buffer
6460 text show through. */
6462 void
6463 message3 (m, nbytes, multibyte)
6464 Lisp_Object m;
6465 int nbytes;
6466 int multibyte;
6468 struct gcpro gcpro1;
6470 GCPRO1 (m);
6472 /* First flush out any partial line written with print. */
6473 message_log_maybe_newline ();
6474 if (STRINGP (m))
6475 message_dolog (SDATA (m), nbytes, 1, multibyte);
6476 message3_nolog (m, nbytes, multibyte);
6478 UNGCPRO;
6482 /* The non-logging version of message3. */
6484 void
6485 message3_nolog (m, nbytes, multibyte)
6486 Lisp_Object m;
6487 int nbytes, multibyte;
6489 struct frame *sf = SELECTED_FRAME ();
6490 message_enable_multibyte = multibyte;
6492 if (noninteractive)
6494 if (noninteractive_need_newline)
6495 putc ('\n', stderr);
6496 noninteractive_need_newline = 0;
6497 if (STRINGP (m))
6498 fwrite (SDATA (m), nbytes, 1, stderr);
6499 if (cursor_in_echo_area == 0)
6500 fprintf (stderr, "\n");
6501 fflush (stderr);
6503 /* A null message buffer means that the frame hasn't really been
6504 initialized yet. Error messages get reported properly by
6505 cmd_error, so this must be just an informative message; toss it. */
6506 else if (INTERACTIVE
6507 && sf->glyphs_initialized_p
6508 && FRAME_MESSAGE_BUF (sf))
6510 Lisp_Object mini_window;
6511 Lisp_Object frame;
6512 struct frame *f;
6514 /* Get the frame containing the mini-buffer
6515 that the selected frame is using. */
6516 mini_window = FRAME_MINIBUF_WINDOW (sf);
6517 frame = XWINDOW (mini_window)->frame;
6518 f = XFRAME (frame);
6520 FRAME_SAMPLE_VISIBILITY (f);
6521 if (FRAME_VISIBLE_P (sf)
6522 && !FRAME_VISIBLE_P (f))
6523 Fmake_frame_visible (frame);
6525 if (STRINGP (m) && SCHARS (m) > 0)
6527 set_message (NULL, m, nbytes, multibyte);
6528 if (minibuffer_auto_raise)
6529 Fraise_frame (frame);
6531 else
6532 clear_message (1, 1);
6534 do_pending_window_change (0);
6535 echo_area_display (1);
6536 do_pending_window_change (0);
6537 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6538 (*frame_up_to_date_hook) (f);
6543 /* Display a null-terminated echo area message M. If M is 0, clear
6544 out any existing message, and let the mini-buffer text show through.
6546 The buffer M must continue to exist until after the echo area gets
6547 cleared or some other message gets displayed there. Do not pass
6548 text that is stored in a Lisp string. Do not pass text in a buffer
6549 that was alloca'd. */
6551 void
6552 message1 (m)
6553 char *m;
6555 message2 (m, (m ? strlen (m) : 0), 0);
6559 /* The non-logging counterpart of message1. */
6561 void
6562 message1_nolog (m)
6563 char *m;
6565 message2_nolog (m, (m ? strlen (m) : 0), 0);
6568 /* Display a message M which contains a single %s
6569 which gets replaced with STRING. */
6571 void
6572 message_with_string (m, string, log)
6573 char *m;
6574 Lisp_Object string;
6575 int log;
6577 CHECK_STRING (string);
6579 if (noninteractive)
6581 if (m)
6583 if (noninteractive_need_newline)
6584 putc ('\n', stderr);
6585 noninteractive_need_newline = 0;
6586 fprintf (stderr, m, SDATA (string));
6587 if (cursor_in_echo_area == 0)
6588 fprintf (stderr, "\n");
6589 fflush (stderr);
6592 else if (INTERACTIVE)
6594 /* The frame whose minibuffer we're going to display the message on.
6595 It may be larger than the selected frame, so we need
6596 to use its buffer, not the selected frame's buffer. */
6597 Lisp_Object mini_window;
6598 struct frame *f, *sf = SELECTED_FRAME ();
6600 /* Get the frame containing the minibuffer
6601 that the selected frame is using. */
6602 mini_window = FRAME_MINIBUF_WINDOW (sf);
6603 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6605 /* A null message buffer means that the frame hasn't really been
6606 initialized yet. Error messages get reported properly by
6607 cmd_error, so this must be just an informative message; toss it. */
6608 if (FRAME_MESSAGE_BUF (f))
6610 Lisp_Object args[2], message;
6611 struct gcpro gcpro1, gcpro2;
6613 args[0] = build_string (m);
6614 args[1] = message = string;
6615 GCPRO2 (args[0], message);
6616 gcpro1.nvars = 2;
6618 message = Fformat (2, args);
6620 if (log)
6621 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6622 else
6623 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6625 UNGCPRO;
6627 /* Print should start at the beginning of the message
6628 buffer next time. */
6629 message_buf_print = 0;
6635 /* Dump an informative message to the minibuf. If M is 0, clear out
6636 any existing message, and let the mini-buffer text show through. */
6638 /* VARARGS 1 */
6639 void
6640 message (m, a1, a2, a3)
6641 char *m;
6642 EMACS_INT a1, a2, a3;
6644 if (noninteractive)
6646 if (m)
6648 if (noninteractive_need_newline)
6649 putc ('\n', stderr);
6650 noninteractive_need_newline = 0;
6651 fprintf (stderr, m, a1, a2, a3);
6652 if (cursor_in_echo_area == 0)
6653 fprintf (stderr, "\n");
6654 fflush (stderr);
6657 else if (INTERACTIVE)
6659 /* The frame whose mini-buffer we're going to display the message
6660 on. It may be larger than the selected frame, so we need to
6661 use its buffer, not the selected frame's buffer. */
6662 Lisp_Object mini_window;
6663 struct frame *f, *sf = SELECTED_FRAME ();
6665 /* Get the frame containing the mini-buffer
6666 that the selected frame is using. */
6667 mini_window = FRAME_MINIBUF_WINDOW (sf);
6668 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6670 /* A null message buffer means that the frame hasn't really been
6671 initialized yet. Error messages get reported properly by
6672 cmd_error, so this must be just an informative message; toss
6673 it. */
6674 if (FRAME_MESSAGE_BUF (f))
6676 if (m)
6678 int len;
6679 #ifdef NO_ARG_ARRAY
6680 char *a[3];
6681 a[0] = (char *) a1;
6682 a[1] = (char *) a2;
6683 a[2] = (char *) a3;
6685 len = doprnt (FRAME_MESSAGE_BUF (f),
6686 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6687 #else
6688 len = doprnt (FRAME_MESSAGE_BUF (f),
6689 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6690 (char **) &a1);
6691 #endif /* NO_ARG_ARRAY */
6693 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6695 else
6696 message1 (0);
6698 /* Print should start at the beginning of the message
6699 buffer next time. */
6700 message_buf_print = 0;
6706 /* The non-logging version of message. */
6708 void
6709 message_nolog (m, a1, a2, a3)
6710 char *m;
6711 EMACS_INT a1, a2, a3;
6713 Lisp_Object old_log_max;
6714 old_log_max = Vmessage_log_max;
6715 Vmessage_log_max = Qnil;
6716 message (m, a1, a2, a3);
6717 Vmessage_log_max = old_log_max;
6721 /* Display the current message in the current mini-buffer. This is
6722 only called from error handlers in process.c, and is not time
6723 critical. */
6725 void
6726 update_echo_area ()
6728 if (!NILP (echo_area_buffer[0]))
6730 Lisp_Object string;
6731 string = Fcurrent_message ();
6732 message3 (string, SBYTES (string),
6733 !NILP (current_buffer->enable_multibyte_characters));
6738 /* Make sure echo area buffers in `echo_buffers' are live.
6739 If they aren't, make new ones. */
6741 static void
6742 ensure_echo_area_buffers ()
6744 int i;
6746 for (i = 0; i < 2; ++i)
6747 if (!BUFFERP (echo_buffer[i])
6748 || NILP (XBUFFER (echo_buffer[i])->name))
6750 char name[30];
6751 Lisp_Object old_buffer;
6752 int j;
6754 old_buffer = echo_buffer[i];
6755 sprintf (name, " *Echo Area %d*", i);
6756 echo_buffer[i] = Fget_buffer_create (build_string (name));
6757 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6759 for (j = 0; j < 2; ++j)
6760 if (EQ (old_buffer, echo_area_buffer[j]))
6761 echo_area_buffer[j] = echo_buffer[i];
6766 /* Call FN with args A1..A4 with either the current or last displayed
6767 echo_area_buffer as current buffer.
6769 WHICH zero means use the current message buffer
6770 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6771 from echo_buffer[] and clear it.
6773 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6774 suitable buffer from echo_buffer[] and clear it.
6776 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6777 that the current message becomes the last displayed one, make
6778 choose a suitable buffer for echo_area_buffer[0], and clear it.
6780 Value is what FN returns. */
6782 static int
6783 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6784 struct window *w;
6785 int which;
6786 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6787 EMACS_INT a1;
6788 Lisp_Object a2;
6789 EMACS_INT a3, a4;
6791 Lisp_Object buffer;
6792 int this_one, the_other, clear_buffer_p, rc;
6793 int count = SPECPDL_INDEX ();
6795 /* If buffers aren't live, make new ones. */
6796 ensure_echo_area_buffers ();
6798 clear_buffer_p = 0;
6800 if (which == 0)
6801 this_one = 0, the_other = 1;
6802 else if (which > 0)
6803 this_one = 1, the_other = 0;
6804 else
6806 this_one = 0, the_other = 1;
6807 clear_buffer_p = 1;
6809 /* We need a fresh one in case the current echo buffer equals
6810 the one containing the last displayed echo area message. */
6811 if (!NILP (echo_area_buffer[this_one])
6812 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6813 echo_area_buffer[this_one] = Qnil;
6816 /* Choose a suitable buffer from echo_buffer[] is we don't
6817 have one. */
6818 if (NILP (echo_area_buffer[this_one]))
6820 echo_area_buffer[this_one]
6821 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6822 ? echo_buffer[the_other]
6823 : echo_buffer[this_one]);
6824 clear_buffer_p = 1;
6827 buffer = echo_area_buffer[this_one];
6829 /* Don't get confused by reusing the buffer used for echoing
6830 for a different purpose. */
6831 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6832 cancel_echoing ();
6834 record_unwind_protect (unwind_with_echo_area_buffer,
6835 with_echo_area_buffer_unwind_data (w));
6837 /* Make the echo area buffer current. Note that for display
6838 purposes, it is not necessary that the displayed window's buffer
6839 == current_buffer, except for text property lookup. So, let's
6840 only set that buffer temporarily here without doing a full
6841 Fset_window_buffer. We must also change w->pointm, though,
6842 because otherwise an assertions in unshow_buffer fails, and Emacs
6843 aborts. */
6844 set_buffer_internal_1 (XBUFFER (buffer));
6845 if (w)
6847 w->buffer = buffer;
6848 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6851 current_buffer->undo_list = Qt;
6852 current_buffer->read_only = Qnil;
6853 specbind (Qinhibit_read_only, Qt);
6854 specbind (Qinhibit_modification_hooks, Qt);
6856 if (clear_buffer_p && Z > BEG)
6857 del_range (BEG, Z);
6859 xassert (BEGV >= BEG);
6860 xassert (ZV <= Z && ZV >= BEGV);
6862 rc = fn (a1, a2, a3, a4);
6864 xassert (BEGV >= BEG);
6865 xassert (ZV <= Z && ZV >= BEGV);
6867 unbind_to (count, Qnil);
6868 return rc;
6872 /* Save state that should be preserved around the call to the function
6873 FN called in with_echo_area_buffer. */
6875 static Lisp_Object
6876 with_echo_area_buffer_unwind_data (w)
6877 struct window *w;
6879 int i = 0;
6880 Lisp_Object vector;
6882 /* Reduce consing by keeping one vector in
6883 Vwith_echo_area_save_vector. */
6884 vector = Vwith_echo_area_save_vector;
6885 Vwith_echo_area_save_vector = Qnil;
6887 if (NILP (vector))
6888 vector = Fmake_vector (make_number (7), Qnil);
6890 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6891 AREF (vector, i) = Vdeactivate_mark, ++i;
6892 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6894 if (w)
6896 XSETWINDOW (AREF (vector, i), w); ++i;
6897 AREF (vector, i) = w->buffer; ++i;
6898 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6899 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6901 else
6903 int end = i + 4;
6904 for (; i < end; ++i)
6905 AREF (vector, i) = Qnil;
6908 xassert (i == ASIZE (vector));
6909 return vector;
6913 /* Restore global state from VECTOR which was created by
6914 with_echo_area_buffer_unwind_data. */
6916 static Lisp_Object
6917 unwind_with_echo_area_buffer (vector)
6918 Lisp_Object vector;
6920 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
6921 Vdeactivate_mark = AREF (vector, 1);
6922 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
6924 if (WINDOWP (AREF (vector, 3)))
6926 struct window *w;
6927 Lisp_Object buffer, charpos, bytepos;
6929 w = XWINDOW (AREF (vector, 3));
6930 buffer = AREF (vector, 4);
6931 charpos = AREF (vector, 5);
6932 bytepos = AREF (vector, 6);
6934 w->buffer = buffer;
6935 set_marker_both (w->pointm, buffer,
6936 XFASTINT (charpos), XFASTINT (bytepos));
6939 Vwith_echo_area_save_vector = vector;
6940 return Qnil;
6944 /* Set up the echo area for use by print functions. MULTIBYTE_P
6945 non-zero means we will print multibyte. */
6947 void
6948 setup_echo_area_for_printing (multibyte_p)
6949 int multibyte_p;
6951 /* If we can't find an echo area any more, exit. */
6952 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
6953 Fkill_emacs (Qnil);
6955 ensure_echo_area_buffers ();
6957 if (!message_buf_print)
6959 /* A message has been output since the last time we printed.
6960 Choose a fresh echo area buffer. */
6961 if (EQ (echo_area_buffer[1], echo_buffer[0]))
6962 echo_area_buffer[0] = echo_buffer[1];
6963 else
6964 echo_area_buffer[0] = echo_buffer[0];
6966 /* Switch to that buffer and clear it. */
6967 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
6968 current_buffer->truncate_lines = Qnil;
6970 if (Z > BEG)
6972 int count = SPECPDL_INDEX ();
6973 specbind (Qinhibit_read_only, Qt);
6974 /* Note that undo recording is always disabled. */
6975 del_range (BEG, Z);
6976 unbind_to (count, Qnil);
6978 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
6980 /* Set up the buffer for the multibyteness we need. */
6981 if (multibyte_p
6982 != !NILP (current_buffer->enable_multibyte_characters))
6983 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
6985 /* Raise the frame containing the echo area. */
6986 if (minibuffer_auto_raise)
6988 struct frame *sf = SELECTED_FRAME ();
6989 Lisp_Object mini_window;
6990 mini_window = FRAME_MINIBUF_WINDOW (sf);
6991 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6994 message_log_maybe_newline ();
6995 message_buf_print = 1;
6997 else
6999 if (NILP (echo_area_buffer[0]))
7001 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7002 echo_area_buffer[0] = echo_buffer[1];
7003 else
7004 echo_area_buffer[0] = echo_buffer[0];
7007 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7009 /* Someone switched buffers between print requests. */
7010 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7011 current_buffer->truncate_lines = Qnil;
7017 /* Display an echo area message in window W. Value is non-zero if W's
7018 height is changed. If display_last_displayed_message_p is
7019 non-zero, display the message that was last displayed, otherwise
7020 display the current message. */
7022 static int
7023 display_echo_area (w)
7024 struct window *w;
7026 int i, no_message_p, window_height_changed_p, count;
7028 /* Temporarily disable garbage collections while displaying the echo
7029 area. This is done because a GC can print a message itself.
7030 That message would modify the echo area buffer's contents while a
7031 redisplay of the buffer is going on, and seriously confuse
7032 redisplay. */
7033 count = inhibit_garbage_collection ();
7035 /* If there is no message, we must call display_echo_area_1
7036 nevertheless because it resizes the window. But we will have to
7037 reset the echo_area_buffer in question to nil at the end because
7038 with_echo_area_buffer will sets it to an empty buffer. */
7039 i = display_last_displayed_message_p ? 1 : 0;
7040 no_message_p = NILP (echo_area_buffer[i]);
7042 window_height_changed_p
7043 = with_echo_area_buffer (w, display_last_displayed_message_p,
7044 display_echo_area_1,
7045 (EMACS_INT) w, Qnil, 0, 0);
7047 if (no_message_p)
7048 echo_area_buffer[i] = Qnil;
7050 unbind_to (count, Qnil);
7051 return window_height_changed_p;
7055 /* Helper for display_echo_area. Display the current buffer which
7056 contains the current echo area message in window W, a mini-window,
7057 a pointer to which is passed in A1. A2..A4 are currently not used.
7058 Change the height of W so that all of the message is displayed.
7059 Value is non-zero if height of W was changed. */
7061 static int
7062 display_echo_area_1 (a1, a2, a3, a4)
7063 EMACS_INT a1;
7064 Lisp_Object a2;
7065 EMACS_INT a3, a4;
7067 struct window *w = (struct window *) a1;
7068 Lisp_Object window;
7069 struct text_pos start;
7070 int window_height_changed_p = 0;
7072 /* Do this before displaying, so that we have a large enough glyph
7073 matrix for the display. */
7074 window_height_changed_p = resize_mini_window (w, 0);
7076 /* Display. */
7077 clear_glyph_matrix (w->desired_matrix);
7078 XSETWINDOW (window, w);
7079 SET_TEXT_POS (start, BEG, BEG_BYTE);
7080 try_window (window, start);
7082 return window_height_changed_p;
7086 /* Resize the echo area window to exactly the size needed for the
7087 currently displayed message, if there is one. If a mini-buffer
7088 is active, don't shrink it. */
7090 void
7091 resize_echo_area_exactly ()
7093 if (BUFFERP (echo_area_buffer[0])
7094 && WINDOWP (echo_area_window))
7096 struct window *w = XWINDOW (echo_area_window);
7097 int resized_p;
7098 Lisp_Object resize_exactly;
7100 if (minibuf_level == 0)
7101 resize_exactly = Qt;
7102 else
7103 resize_exactly = Qnil;
7105 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7106 (EMACS_INT) w, resize_exactly, 0, 0);
7107 if (resized_p)
7109 ++windows_or_buffers_changed;
7110 ++update_mode_lines;
7111 redisplay_internal (0);
7117 /* Callback function for with_echo_area_buffer, when used from
7118 resize_echo_area_exactly. A1 contains a pointer to the window to
7119 resize, EXACTLY non-nil means resize the mini-window exactly to the
7120 size of the text displayed. A3 and A4 are not used. Value is what
7121 resize_mini_window returns. */
7123 static int
7124 resize_mini_window_1 (a1, exactly, a3, a4)
7125 EMACS_INT a1;
7126 Lisp_Object exactly;
7127 EMACS_INT a3, a4;
7129 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7133 /* Resize mini-window W to fit the size of its contents. EXACT:P
7134 means size the window exactly to the size needed. Otherwise, it's
7135 only enlarged until W's buffer is empty. Value is non-zero if
7136 the window height has been changed. */
7139 resize_mini_window (w, exact_p)
7140 struct window *w;
7141 int exact_p;
7143 struct frame *f = XFRAME (w->frame);
7144 int window_height_changed_p = 0;
7146 xassert (MINI_WINDOW_P (w));
7148 /* Don't resize windows while redisplaying a window; it would
7149 confuse redisplay functions when the size of the window they are
7150 displaying changes from under them. Such a resizing can happen,
7151 for instance, when which-func prints a long message while
7152 we are running fontification-functions. We're running these
7153 functions with safe_call which binds inhibit-redisplay to t. */
7154 if (!NILP (Vinhibit_redisplay))
7155 return 0;
7157 /* Nil means don't try to resize. */
7158 if (NILP (Vresize_mini_windows)
7159 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7160 return 0;
7162 if (!FRAME_MINIBUF_ONLY_P (f))
7164 struct it it;
7165 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7166 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7167 int height, max_height;
7168 int unit = FRAME_LINE_HEIGHT (f);
7169 struct text_pos start;
7170 struct buffer *old_current_buffer = NULL;
7172 if (current_buffer != XBUFFER (w->buffer))
7174 old_current_buffer = current_buffer;
7175 set_buffer_internal (XBUFFER (w->buffer));
7178 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7180 /* Compute the max. number of lines specified by the user. */
7181 if (FLOATP (Vmax_mini_window_height))
7182 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7183 else if (INTEGERP (Vmax_mini_window_height))
7184 max_height = XINT (Vmax_mini_window_height);
7185 else
7186 max_height = total_height / 4;
7188 /* Correct that max. height if it's bogus. */
7189 max_height = max (1, max_height);
7190 max_height = min (total_height, max_height);
7192 /* Find out the height of the text in the window. */
7193 if (it.truncate_lines_p)
7194 height = 1;
7195 else
7197 last_height = 0;
7198 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7199 if (it.max_ascent == 0 && it.max_descent == 0)
7200 height = it.current_y + last_height;
7201 else
7202 height = it.current_y + it.max_ascent + it.max_descent;
7203 height -= it.extra_line_spacing;
7204 height = (height + unit - 1) / unit;
7207 /* Compute a suitable window start. */
7208 if (height > max_height)
7210 height = max_height;
7211 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7212 move_it_vertically_backward (&it, (height - 1) * unit);
7213 start = it.current.pos;
7215 else
7216 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7217 SET_MARKER_FROM_TEXT_POS (w->start, start);
7219 if (EQ (Vresize_mini_windows, Qgrow_only))
7221 /* Let it grow only, until we display an empty message, in which
7222 case the window shrinks again. */
7223 if (height > WINDOW_TOTAL_LINES (w))
7225 int old_height = WINDOW_TOTAL_LINES (w);
7226 freeze_window_starts (f, 1);
7227 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7228 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7230 else if (height < WINDOW_TOTAL_LINES (w)
7231 && (exact_p || BEGV == ZV))
7233 int old_height = WINDOW_TOTAL_LINES (w);
7234 freeze_window_starts (f, 0);
7235 shrink_mini_window (w);
7236 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7239 else
7241 /* Always resize to exact size needed. */
7242 if (height > WINDOW_TOTAL_LINES (w))
7244 int old_height = WINDOW_TOTAL_LINES (w);
7245 freeze_window_starts (f, 1);
7246 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7247 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7249 else if (height < WINDOW_TOTAL_LINES (w))
7251 int old_height = WINDOW_TOTAL_LINES (w);
7252 freeze_window_starts (f, 0);
7253 shrink_mini_window (w);
7255 if (height)
7257 freeze_window_starts (f, 1);
7258 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7261 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7265 if (old_current_buffer)
7266 set_buffer_internal (old_current_buffer);
7269 return window_height_changed_p;
7273 /* Value is the current message, a string, or nil if there is no
7274 current message. */
7276 Lisp_Object
7277 current_message ()
7279 Lisp_Object msg;
7281 if (NILP (echo_area_buffer[0]))
7282 msg = Qnil;
7283 else
7285 with_echo_area_buffer (0, 0, current_message_1,
7286 (EMACS_INT) &msg, Qnil, 0, 0);
7287 if (NILP (msg))
7288 echo_area_buffer[0] = Qnil;
7291 return msg;
7295 static int
7296 current_message_1 (a1, a2, a3, a4)
7297 EMACS_INT a1;
7298 Lisp_Object a2;
7299 EMACS_INT a3, a4;
7301 Lisp_Object *msg = (Lisp_Object *) a1;
7303 if (Z > BEG)
7304 *msg = make_buffer_string (BEG, Z, 1);
7305 else
7306 *msg = Qnil;
7307 return 0;
7311 /* Push the current message on Vmessage_stack for later restauration
7312 by restore_message. Value is non-zero if the current message isn't
7313 empty. This is a relatively infrequent operation, so it's not
7314 worth optimizing. */
7317 push_message ()
7319 Lisp_Object msg;
7320 msg = current_message ();
7321 Vmessage_stack = Fcons (msg, Vmessage_stack);
7322 return STRINGP (msg);
7326 /* Restore message display from the top of Vmessage_stack. */
7328 void
7329 restore_message ()
7331 Lisp_Object msg;
7333 xassert (CONSP (Vmessage_stack));
7334 msg = XCAR (Vmessage_stack);
7335 if (STRINGP (msg))
7336 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7337 else
7338 message3_nolog (msg, 0, 0);
7342 /* Handler for record_unwind_protect calling pop_message. */
7344 Lisp_Object
7345 pop_message_unwind (dummy)
7346 Lisp_Object dummy;
7348 pop_message ();
7349 return Qnil;
7352 /* Pop the top-most entry off Vmessage_stack. */
7354 void
7355 pop_message ()
7357 xassert (CONSP (Vmessage_stack));
7358 Vmessage_stack = XCDR (Vmessage_stack);
7362 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7363 exits. If the stack is not empty, we have a missing pop_message
7364 somewhere. */
7366 void
7367 check_message_stack ()
7369 if (!NILP (Vmessage_stack))
7370 abort ();
7374 /* Truncate to NCHARS what will be displayed in the echo area the next
7375 time we display it---but don't redisplay it now. */
7377 void
7378 truncate_echo_area (nchars)
7379 int nchars;
7381 if (nchars == 0)
7382 echo_area_buffer[0] = Qnil;
7383 /* A null message buffer means that the frame hasn't really been
7384 initialized yet. Error messages get reported properly by
7385 cmd_error, so this must be just an informative message; toss it. */
7386 else if (!noninteractive
7387 && INTERACTIVE
7388 && !NILP (echo_area_buffer[0]))
7390 struct frame *sf = SELECTED_FRAME ();
7391 if (FRAME_MESSAGE_BUF (sf))
7392 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7397 /* Helper function for truncate_echo_area. Truncate the current
7398 message to at most NCHARS characters. */
7400 static int
7401 truncate_message_1 (nchars, a2, a3, a4)
7402 EMACS_INT nchars;
7403 Lisp_Object a2;
7404 EMACS_INT a3, a4;
7406 if (BEG + nchars < Z)
7407 del_range (BEG + nchars, Z);
7408 if (Z == BEG)
7409 echo_area_buffer[0] = Qnil;
7410 return 0;
7414 /* Set the current message to a substring of S or STRING.
7416 If STRING is a Lisp string, set the message to the first NBYTES
7417 bytes from STRING. NBYTES zero means use the whole string. If
7418 STRING is multibyte, the message will be displayed multibyte.
7420 If S is not null, set the message to the first LEN bytes of S. LEN
7421 zero means use the whole string. MULTIBYTE_P non-zero means S is
7422 multibyte. Display the message multibyte in that case. */
7424 void
7425 set_message (s, string, nbytes, multibyte_p)
7426 const char *s;
7427 Lisp_Object string;
7428 int nbytes, multibyte_p;
7430 message_enable_multibyte
7431 = ((s && multibyte_p)
7432 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7434 with_echo_area_buffer (0, -1, set_message_1,
7435 (EMACS_INT) s, string, nbytes, multibyte_p);
7436 message_buf_print = 0;
7437 help_echo_showing_p = 0;
7441 /* Helper function for set_message. Arguments have the same meaning
7442 as there, with A1 corresponding to S and A2 corresponding to STRING
7443 This function is called with the echo area buffer being
7444 current. */
7446 static int
7447 set_message_1 (a1, a2, nbytes, multibyte_p)
7448 EMACS_INT a1;
7449 Lisp_Object a2;
7450 EMACS_INT nbytes, multibyte_p;
7452 const char *s = (const char *) a1;
7453 Lisp_Object string = a2;
7455 xassert (BEG == Z);
7457 /* Change multibyteness of the echo buffer appropriately. */
7458 if (message_enable_multibyte
7459 != !NILP (current_buffer->enable_multibyte_characters))
7460 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7462 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7464 /* Insert new message at BEG. */
7465 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7467 if (STRINGP (string))
7469 int nchars;
7471 if (nbytes == 0)
7472 nbytes = SBYTES (string);
7473 nchars = string_byte_to_char (string, nbytes);
7475 /* This function takes care of single/multibyte conversion. We
7476 just have to ensure that the echo area buffer has the right
7477 setting of enable_multibyte_characters. */
7478 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7480 else if (s)
7482 if (nbytes == 0)
7483 nbytes = strlen (s);
7485 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7487 /* Convert from multi-byte to single-byte. */
7488 int i, c, n;
7489 unsigned char work[1];
7491 /* Convert a multibyte string to single-byte. */
7492 for (i = 0; i < nbytes; i += n)
7494 c = string_char_and_length (s + i, nbytes - i, &n);
7495 work[0] = (SINGLE_BYTE_CHAR_P (c)
7497 : multibyte_char_to_unibyte (c, Qnil));
7498 insert_1_both (work, 1, 1, 1, 0, 0);
7501 else if (!multibyte_p
7502 && !NILP (current_buffer->enable_multibyte_characters))
7504 /* Convert from single-byte to multi-byte. */
7505 int i, c, n;
7506 const unsigned char *msg = (const unsigned char *) s;
7507 unsigned char str[MAX_MULTIBYTE_LENGTH];
7509 /* Convert a single-byte string to multibyte. */
7510 for (i = 0; i < nbytes; i++)
7512 c = unibyte_char_to_multibyte (msg[i]);
7513 n = CHAR_STRING (c, str);
7514 insert_1_both (str, 1, n, 1, 0, 0);
7517 else
7518 insert_1 (s, nbytes, 1, 0, 0);
7521 return 0;
7525 /* Clear messages. CURRENT_P non-zero means clear the current
7526 message. LAST_DISPLAYED_P non-zero means clear the message
7527 last displayed. */
7529 void
7530 clear_message (current_p, last_displayed_p)
7531 int current_p, last_displayed_p;
7533 if (current_p)
7535 echo_area_buffer[0] = Qnil;
7536 message_cleared_p = 1;
7539 if (last_displayed_p)
7540 echo_area_buffer[1] = Qnil;
7542 message_buf_print = 0;
7545 /* Clear garbaged frames.
7547 This function is used where the old redisplay called
7548 redraw_garbaged_frames which in turn called redraw_frame which in
7549 turn called clear_frame. The call to clear_frame was a source of
7550 flickering. I believe a clear_frame is not necessary. It should
7551 suffice in the new redisplay to invalidate all current matrices,
7552 and ensure a complete redisplay of all windows. */
7554 static void
7555 clear_garbaged_frames ()
7557 if (frame_garbaged)
7559 Lisp_Object tail, frame;
7560 int changed_count = 0;
7562 FOR_EACH_FRAME (tail, frame)
7564 struct frame *f = XFRAME (frame);
7566 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7568 if (f->resized_p)
7569 Fredraw_frame (frame);
7570 clear_current_matrices (f);
7571 changed_count++;
7572 f->garbaged = 0;
7573 f->resized_p = 0;
7577 frame_garbaged = 0;
7578 if (changed_count)
7579 ++windows_or_buffers_changed;
7584 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7585 is non-zero update selected_frame. Value is non-zero if the
7586 mini-windows height has been changed. */
7588 static int
7589 echo_area_display (update_frame_p)
7590 int update_frame_p;
7592 Lisp_Object mini_window;
7593 struct window *w;
7594 struct frame *f;
7595 int window_height_changed_p = 0;
7596 struct frame *sf = SELECTED_FRAME ();
7598 mini_window = FRAME_MINIBUF_WINDOW (sf);
7599 w = XWINDOW (mini_window);
7600 f = XFRAME (WINDOW_FRAME (w));
7602 /* Don't display if frame is invisible or not yet initialized. */
7603 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7604 return 0;
7606 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7607 #ifndef MAC_OS8
7608 #ifdef HAVE_WINDOW_SYSTEM
7609 /* When Emacs starts, selected_frame may be a visible terminal
7610 frame, even if we run under a window system. If we let this
7611 through, a message would be displayed on the terminal. */
7612 if (EQ (selected_frame, Vterminal_frame)
7613 && !NILP (Vwindow_system))
7614 return 0;
7615 #endif /* HAVE_WINDOW_SYSTEM */
7616 #endif
7618 /* Redraw garbaged frames. */
7619 if (frame_garbaged)
7620 clear_garbaged_frames ();
7622 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7624 echo_area_window = mini_window;
7625 window_height_changed_p = display_echo_area (w);
7626 w->must_be_updated_p = 1;
7628 /* Update the display, unless called from redisplay_internal.
7629 Also don't update the screen during redisplay itself. The
7630 update will happen at the end of redisplay, and an update
7631 here could cause confusion. */
7632 if (update_frame_p && !redisplaying_p)
7634 int n = 0;
7636 /* If the display update has been interrupted by pending
7637 input, update mode lines in the frame. Due to the
7638 pending input, it might have been that redisplay hasn't
7639 been called, so that mode lines above the echo area are
7640 garbaged. This looks odd, so we prevent it here. */
7641 if (!display_completed)
7642 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7644 if (window_height_changed_p
7645 /* Don't do this if Emacs is shutting down. Redisplay
7646 needs to run hooks. */
7647 && !NILP (Vrun_hooks))
7649 /* Must update other windows. Likewise as in other
7650 cases, don't let this update be interrupted by
7651 pending input. */
7652 int count = SPECPDL_INDEX ();
7653 specbind (Qredisplay_dont_pause, Qt);
7654 windows_or_buffers_changed = 1;
7655 redisplay_internal (0);
7656 unbind_to (count, Qnil);
7658 else if (FRAME_WINDOW_P (f) && n == 0)
7660 /* Window configuration is the same as before.
7661 Can do with a display update of the echo area,
7662 unless we displayed some mode lines. */
7663 update_single_window (w, 1);
7664 rif->flush_display (f);
7666 else
7667 update_frame (f, 1, 1);
7669 /* If cursor is in the echo area, make sure that the next
7670 redisplay displays the minibuffer, so that the cursor will
7671 be replaced with what the minibuffer wants. */
7672 if (cursor_in_echo_area)
7673 ++windows_or_buffers_changed;
7676 else if (!EQ (mini_window, selected_window))
7677 windows_or_buffers_changed++;
7679 /* Last displayed message is now the current message. */
7680 echo_area_buffer[1] = echo_area_buffer[0];
7682 /* Prevent redisplay optimization in redisplay_internal by resetting
7683 this_line_start_pos. This is done because the mini-buffer now
7684 displays the message instead of its buffer text. */
7685 if (EQ (mini_window, selected_window))
7686 CHARPOS (this_line_start_pos) = 0;
7688 return window_height_changed_p;
7693 /***********************************************************************
7694 Frame Titles
7695 ***********************************************************************/
7698 /* The frame title buffering code is also used by Fformat_mode_line.
7699 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7701 /* A buffer for constructing frame titles in it; allocated from the
7702 heap in init_xdisp and resized as needed in store_frame_title_char. */
7704 static char *frame_title_buf;
7706 /* The buffer's end, and a current output position in it. */
7708 static char *frame_title_buf_end;
7709 static char *frame_title_ptr;
7712 /* Store a single character C for the frame title in frame_title_buf.
7713 Re-allocate frame_title_buf if necessary. */
7715 static void
7716 #ifdef PROTOTYPES
7717 store_frame_title_char (char c)
7718 #else
7719 store_frame_title_char (c)
7720 char c;
7721 #endif
7723 /* If output position has reached the end of the allocated buffer,
7724 double the buffer's size. */
7725 if (frame_title_ptr == frame_title_buf_end)
7727 int len = frame_title_ptr - frame_title_buf;
7728 int new_size = 2 * len * sizeof *frame_title_buf;
7729 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7730 frame_title_buf_end = frame_title_buf + new_size;
7731 frame_title_ptr = frame_title_buf + len;
7734 *frame_title_ptr++ = c;
7738 /* Store part of a frame title in frame_title_buf, beginning at
7739 frame_title_ptr. STR is the string to store. Do not copy
7740 characters that yield more columns than PRECISION; PRECISION <= 0
7741 means copy the whole string. Pad with spaces until FIELD_WIDTH
7742 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7743 pad. Called from display_mode_element when it is used to build a
7744 frame title. */
7746 static int
7747 store_frame_title (str, field_width, precision)
7748 const unsigned char *str;
7749 int field_width, precision;
7751 int n = 0;
7752 int dummy, nbytes;
7754 /* Copy at most PRECISION chars from STR. */
7755 nbytes = strlen (str);
7756 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7757 while (nbytes--)
7758 store_frame_title_char (*str++);
7760 /* Fill up with spaces until FIELD_WIDTH reached. */
7761 while (field_width > 0
7762 && n < field_width)
7764 store_frame_title_char (' ');
7765 ++n;
7768 return n;
7771 #ifdef HAVE_WINDOW_SYSTEM
7773 /* Set the title of FRAME, if it has changed. The title format is
7774 Vicon_title_format if FRAME is iconified, otherwise it is
7775 frame_title_format. */
7777 static void
7778 x_consider_frame_title (frame)
7779 Lisp_Object frame;
7781 struct frame *f = XFRAME (frame);
7783 if (FRAME_WINDOW_P (f)
7784 || FRAME_MINIBUF_ONLY_P (f)
7785 || f->explicit_name)
7787 /* Do we have more than one visible frame on this X display? */
7788 Lisp_Object tail;
7789 Lisp_Object fmt;
7790 struct buffer *obuf;
7791 int len;
7792 struct it it;
7794 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7796 Lisp_Object other_frame = XCAR (tail);
7797 struct frame *tf = XFRAME (other_frame);
7799 if (tf != f
7800 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7801 && !FRAME_MINIBUF_ONLY_P (tf)
7802 && !EQ (other_frame, tip_frame)
7803 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7804 break;
7807 /* Set global variable indicating that multiple frames exist. */
7808 multiple_frames = CONSP (tail);
7810 /* Switch to the buffer of selected window of the frame. Set up
7811 frame_title_ptr so that display_mode_element will output into it;
7812 then display the title. */
7813 obuf = current_buffer;
7814 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7815 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7816 frame_title_ptr = frame_title_buf;
7817 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7818 NULL, DEFAULT_FACE_ID);
7819 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7820 len = frame_title_ptr - frame_title_buf;
7821 frame_title_ptr = NULL;
7822 set_buffer_internal_1 (obuf);
7824 /* Set the title only if it's changed. This avoids consing in
7825 the common case where it hasn't. (If it turns out that we've
7826 already wasted too much time by walking through the list with
7827 display_mode_element, then we might need to optimize at a
7828 higher level than this.) */
7829 if (! STRINGP (f->name)
7830 || SBYTES (f->name) != len
7831 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7832 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7836 #endif /* not HAVE_WINDOW_SYSTEM */
7841 /***********************************************************************
7842 Menu Bars
7843 ***********************************************************************/
7846 /* Prepare for redisplay by updating menu-bar item lists when
7847 appropriate. This can call eval. */
7849 void
7850 prepare_menu_bars ()
7852 int all_windows;
7853 struct gcpro gcpro1, gcpro2;
7854 struct frame *f;
7855 Lisp_Object tooltip_frame;
7857 #ifdef HAVE_WINDOW_SYSTEM
7858 tooltip_frame = tip_frame;
7859 #else
7860 tooltip_frame = Qnil;
7861 #endif
7863 /* Update all frame titles based on their buffer names, etc. We do
7864 this before the menu bars so that the buffer-menu will show the
7865 up-to-date frame titles. */
7866 #ifdef HAVE_WINDOW_SYSTEM
7867 if (windows_or_buffers_changed || update_mode_lines)
7869 Lisp_Object tail, frame;
7871 FOR_EACH_FRAME (tail, frame)
7873 f = XFRAME (frame);
7874 if (!EQ (frame, tooltip_frame)
7875 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7876 x_consider_frame_title (frame);
7879 #endif /* HAVE_WINDOW_SYSTEM */
7881 /* Update the menu bar item lists, if appropriate. This has to be
7882 done before any actual redisplay or generation of display lines. */
7883 all_windows = (update_mode_lines
7884 || buffer_shared > 1
7885 || windows_or_buffers_changed);
7886 if (all_windows)
7888 Lisp_Object tail, frame;
7889 int count = SPECPDL_INDEX ();
7891 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7893 FOR_EACH_FRAME (tail, frame)
7895 f = XFRAME (frame);
7897 /* Ignore tooltip frame. */
7898 if (EQ (frame, tooltip_frame))
7899 continue;
7901 /* If a window on this frame changed size, report that to
7902 the user and clear the size-change flag. */
7903 if (FRAME_WINDOW_SIZES_CHANGED (f))
7905 Lisp_Object functions;
7907 /* Clear flag first in case we get an error below. */
7908 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
7909 functions = Vwindow_size_change_functions;
7910 GCPRO2 (tail, functions);
7912 while (CONSP (functions))
7914 call1 (XCAR (functions), frame);
7915 functions = XCDR (functions);
7917 UNGCPRO;
7920 GCPRO1 (tail);
7921 update_menu_bar (f, 0);
7922 #ifdef HAVE_WINDOW_SYSTEM
7923 update_tool_bar (f, 0);
7924 #endif
7925 UNGCPRO;
7928 unbind_to (count, Qnil);
7930 else
7932 struct frame *sf = SELECTED_FRAME ();
7933 update_menu_bar (sf, 1);
7934 #ifdef HAVE_WINDOW_SYSTEM
7935 update_tool_bar (sf, 1);
7936 #endif
7939 /* Motif needs this. See comment in xmenu.c. Turn it off when
7940 pending_menu_activation is not defined. */
7941 #ifdef USE_X_TOOLKIT
7942 pending_menu_activation = 0;
7943 #endif
7947 /* Update the menu bar item list for frame F. This has to be done
7948 before we start to fill in any display lines, because it can call
7949 eval.
7951 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
7953 static void
7954 update_menu_bar (f, save_match_data)
7955 struct frame *f;
7956 int save_match_data;
7958 Lisp_Object window;
7959 register struct window *w;
7961 /* If called recursively during a menu update, do nothing. This can
7962 happen when, for instance, an activate-menubar-hook causes a
7963 redisplay. */
7964 if (inhibit_menubar_update)
7965 return;
7967 window = FRAME_SELECTED_WINDOW (f);
7968 w = XWINDOW (window);
7970 #if 0 /* The if statement below this if statement used to include the
7971 condition !NILP (w->update_mode_line), rather than using
7972 update_mode_lines directly, and this if statement may have
7973 been added to make that condition work. Now the if
7974 statement below matches its comment, this isn't needed. */
7975 if (update_mode_lines)
7976 w->update_mode_line = Qt;
7977 #endif
7979 if (FRAME_WINDOW_P (f)
7981 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
7982 || defined (USE_GTK)
7983 FRAME_EXTERNAL_MENU_BAR (f)
7984 #else
7985 FRAME_MENU_BAR_LINES (f) > 0
7986 #endif
7987 : FRAME_MENU_BAR_LINES (f) > 0)
7989 /* If the user has switched buffers or windows, we need to
7990 recompute to reflect the new bindings. But we'll
7991 recompute when update_mode_lines is set too; that means
7992 that people can use force-mode-line-update to request
7993 that the menu bar be recomputed. The adverse effect on
7994 the rest of the redisplay algorithm is about the same as
7995 windows_or_buffers_changed anyway. */
7996 if (windows_or_buffers_changed
7997 /* This used to test w->update_mode_line, but we believe
7998 there is no need to recompute the menu in that case. */
7999 || update_mode_lines
8000 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8001 < BUF_MODIFF (XBUFFER (w->buffer)))
8002 != !NILP (w->last_had_star))
8003 || ((!NILP (Vtransient_mark_mode)
8004 && !NILP (XBUFFER (w->buffer)->mark_active))
8005 != !NILP (w->region_showing)))
8007 struct buffer *prev = current_buffer;
8008 int count = SPECPDL_INDEX ();
8010 specbind (Qinhibit_menubar_update, Qt);
8012 set_buffer_internal_1 (XBUFFER (w->buffer));
8013 if (save_match_data)
8014 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8015 if (NILP (Voverriding_local_map_menu_flag))
8017 specbind (Qoverriding_terminal_local_map, Qnil);
8018 specbind (Qoverriding_local_map, Qnil);
8021 /* Run the Lucid hook. */
8022 safe_run_hooks (Qactivate_menubar_hook);
8024 /* If it has changed current-menubar from previous value,
8025 really recompute the menu-bar from the value. */
8026 if (! NILP (Vlucid_menu_bar_dirty_flag))
8027 call0 (Qrecompute_lucid_menubar);
8029 safe_run_hooks (Qmenu_bar_update_hook);
8030 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8032 /* Redisplay the menu bar in case we changed it. */
8033 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8034 || defined (USE_GTK)
8035 if (FRAME_WINDOW_P (f)
8036 #if defined (MAC_OS)
8037 /* All frames on Mac OS share the same menubar. So only the
8038 selected frame should be allowed to set it. */
8039 && f == SELECTED_FRAME ()
8040 #endif
8042 set_frame_menubar (f, 0, 0);
8043 else
8044 /* On a terminal screen, the menu bar is an ordinary screen
8045 line, and this makes it get updated. */
8046 w->update_mode_line = Qt;
8047 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8048 /* In the non-toolkit version, the menu bar is an ordinary screen
8049 line, and this makes it get updated. */
8050 w->update_mode_line = Qt;
8051 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8053 unbind_to (count, Qnil);
8054 set_buffer_internal_1 (prev);
8061 /***********************************************************************
8062 Output Cursor
8063 ***********************************************************************/
8065 #ifdef HAVE_WINDOW_SYSTEM
8067 /* EXPORT:
8068 Nominal cursor position -- where to draw output.
8069 HPOS and VPOS are window relative glyph matrix coordinates.
8070 X and Y are window relative pixel coordinates. */
8072 struct cursor_pos output_cursor;
8075 /* EXPORT:
8076 Set the global variable output_cursor to CURSOR. All cursor
8077 positions are relative to updated_window. */
8079 void
8080 set_output_cursor (cursor)
8081 struct cursor_pos *cursor;
8083 output_cursor.hpos = cursor->hpos;
8084 output_cursor.vpos = cursor->vpos;
8085 output_cursor.x = cursor->x;
8086 output_cursor.y = cursor->y;
8090 /* EXPORT for RIF:
8091 Set a nominal cursor position.
8093 HPOS and VPOS are column/row positions in a window glyph matrix. X
8094 and Y are window text area relative pixel positions.
8096 If this is done during an update, updated_window will contain the
8097 window that is being updated and the position is the future output
8098 cursor position for that window. If updated_window is null, use
8099 selected_window and display the cursor at the given position. */
8101 void
8102 x_cursor_to (vpos, hpos, y, x)
8103 int vpos, hpos, y, x;
8105 struct window *w;
8107 /* If updated_window is not set, work on selected_window. */
8108 if (updated_window)
8109 w = updated_window;
8110 else
8111 w = XWINDOW (selected_window);
8113 /* Set the output cursor. */
8114 output_cursor.hpos = hpos;
8115 output_cursor.vpos = vpos;
8116 output_cursor.x = x;
8117 output_cursor.y = y;
8119 /* If not called as part of an update, really display the cursor.
8120 This will also set the cursor position of W. */
8121 if (updated_window == NULL)
8123 BLOCK_INPUT;
8124 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8125 if (rif->flush_display_optional)
8126 rif->flush_display_optional (SELECTED_FRAME ());
8127 UNBLOCK_INPUT;
8131 #endif /* HAVE_WINDOW_SYSTEM */
8134 /***********************************************************************
8135 Tool-bars
8136 ***********************************************************************/
8138 #ifdef HAVE_WINDOW_SYSTEM
8140 /* Where the mouse was last time we reported a mouse event. */
8142 FRAME_PTR last_mouse_frame;
8144 /* Tool-bar item index of the item on which a mouse button was pressed
8145 or -1. */
8147 int last_tool_bar_item;
8150 /* Update the tool-bar item list for frame F. This has to be done
8151 before we start to fill in any display lines. Called from
8152 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8153 and restore it here. */
8155 static void
8156 update_tool_bar (f, save_match_data)
8157 struct frame *f;
8158 int save_match_data;
8160 #ifdef USE_GTK
8161 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8162 #else
8163 int do_update = WINDOWP (f->tool_bar_window)
8164 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8165 #endif
8167 if (do_update)
8169 Lisp_Object window;
8170 struct window *w;
8172 window = FRAME_SELECTED_WINDOW (f);
8173 w = XWINDOW (window);
8175 /* If the user has switched buffers or windows, we need to
8176 recompute to reflect the new bindings. But we'll
8177 recompute when update_mode_lines is set too; that means
8178 that people can use force-mode-line-update to request
8179 that the menu bar be recomputed. The adverse effect on
8180 the rest of the redisplay algorithm is about the same as
8181 windows_or_buffers_changed anyway. */
8182 if (windows_or_buffers_changed
8183 || !NILP (w->update_mode_line)
8184 || update_mode_lines
8185 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8186 < BUF_MODIFF (XBUFFER (w->buffer)))
8187 != !NILP (w->last_had_star))
8188 || ((!NILP (Vtransient_mark_mode)
8189 && !NILP (XBUFFER (w->buffer)->mark_active))
8190 != !NILP (w->region_showing)))
8192 struct buffer *prev = current_buffer;
8193 int count = SPECPDL_INDEX ();
8194 Lisp_Object old_tool_bar;
8195 struct gcpro gcpro1;
8197 /* Set current_buffer to the buffer of the selected
8198 window of the frame, so that we get the right local
8199 keymaps. */
8200 set_buffer_internal_1 (XBUFFER (w->buffer));
8202 /* Save match data, if we must. */
8203 if (save_match_data)
8204 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8206 /* Make sure that we don't accidentally use bogus keymaps. */
8207 if (NILP (Voverriding_local_map_menu_flag))
8209 specbind (Qoverriding_terminal_local_map, Qnil);
8210 specbind (Qoverriding_local_map, Qnil);
8213 old_tool_bar = f->tool_bar_items;
8214 GCPRO1 (old_tool_bar);
8216 /* Build desired tool-bar items from keymaps. */
8217 BLOCK_INPUT;
8218 f->tool_bar_items
8219 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8220 UNBLOCK_INPUT;
8222 /* Redisplay the tool-bar if we changed it. */
8223 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8224 w->update_mode_line = Qt;
8226 UNGCPRO;
8228 unbind_to (count, Qnil);
8229 set_buffer_internal_1 (prev);
8235 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8236 F's desired tool-bar contents. F->tool_bar_items must have
8237 been set up previously by calling prepare_menu_bars. */
8239 static void
8240 build_desired_tool_bar_string (f)
8241 struct frame *f;
8243 int i, size, size_needed;
8244 struct gcpro gcpro1, gcpro2, gcpro3;
8245 Lisp_Object image, plist, props;
8247 image = plist = props = Qnil;
8248 GCPRO3 (image, plist, props);
8250 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8251 Otherwise, make a new string. */
8253 /* The size of the string we might be able to reuse. */
8254 size = (STRINGP (f->desired_tool_bar_string)
8255 ? SCHARS (f->desired_tool_bar_string)
8256 : 0);
8258 /* We need one space in the string for each image. */
8259 size_needed = f->n_tool_bar_items;
8261 /* Reuse f->desired_tool_bar_string, if possible. */
8262 if (size < size_needed || NILP (f->desired_tool_bar_string))
8263 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8264 make_number (' '));
8265 else
8267 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8268 Fremove_text_properties (make_number (0), make_number (size),
8269 props, f->desired_tool_bar_string);
8272 /* Put a `display' property on the string for the images to display,
8273 put a `menu_item' property on tool-bar items with a value that
8274 is the index of the item in F's tool-bar item vector. */
8275 for (i = 0; i < f->n_tool_bar_items; ++i)
8277 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8279 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8280 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8281 int hmargin, vmargin, relief, idx, end;
8282 extern Lisp_Object QCrelief, QCmargin, QCconversion, Qimage;
8284 /* If image is a vector, choose the image according to the
8285 button state. */
8286 image = PROP (TOOL_BAR_ITEM_IMAGES);
8287 if (VECTORP (image))
8289 if (enabled_p)
8290 idx = (selected_p
8291 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8292 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8293 else
8294 idx = (selected_p
8295 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8296 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8298 xassert (ASIZE (image) >= idx);
8299 image = AREF (image, idx);
8301 else
8302 idx = -1;
8304 /* Ignore invalid image specifications. */
8305 if (!valid_image_p (image))
8306 continue;
8308 /* Display the tool-bar button pressed, or depressed. */
8309 plist = Fcopy_sequence (XCDR (image));
8311 /* Compute margin and relief to draw. */
8312 relief = (tool_bar_button_relief >= 0
8313 ? tool_bar_button_relief
8314 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8315 hmargin = vmargin = relief;
8317 if (INTEGERP (Vtool_bar_button_margin)
8318 && XINT (Vtool_bar_button_margin) > 0)
8320 hmargin += XFASTINT (Vtool_bar_button_margin);
8321 vmargin += XFASTINT (Vtool_bar_button_margin);
8323 else if (CONSP (Vtool_bar_button_margin))
8325 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8326 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8327 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8329 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8330 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8331 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8334 if (auto_raise_tool_bar_buttons_p)
8336 /* Add a `:relief' property to the image spec if the item is
8337 selected. */
8338 if (selected_p)
8340 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8341 hmargin -= relief;
8342 vmargin -= relief;
8345 else
8347 /* If image is selected, display it pressed, i.e. with a
8348 negative relief. If it's not selected, display it with a
8349 raised relief. */
8350 plist = Fplist_put (plist, QCrelief,
8351 (selected_p
8352 ? make_number (-relief)
8353 : make_number (relief)));
8354 hmargin -= relief;
8355 vmargin -= relief;
8358 /* Put a margin around the image. */
8359 if (hmargin || vmargin)
8361 if (hmargin == vmargin)
8362 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8363 else
8364 plist = Fplist_put (plist, QCmargin,
8365 Fcons (make_number (hmargin),
8366 make_number (vmargin)));
8369 /* If button is not enabled, and we don't have special images
8370 for the disabled state, make the image appear disabled by
8371 applying an appropriate algorithm to it. */
8372 if (!enabled_p && idx < 0)
8373 plist = Fplist_put (plist, QCconversion, Qdisabled);
8375 /* Put a `display' text property on the string for the image to
8376 display. Put a `menu-item' property on the string that gives
8377 the start of this item's properties in the tool-bar items
8378 vector. */
8379 image = Fcons (Qimage, plist);
8380 props = list4 (Qdisplay, image,
8381 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8383 /* Let the last image hide all remaining spaces in the tool bar
8384 string. The string can be longer than needed when we reuse a
8385 previous string. */
8386 if (i + 1 == f->n_tool_bar_items)
8387 end = SCHARS (f->desired_tool_bar_string);
8388 else
8389 end = i + 1;
8390 Fadd_text_properties (make_number (i), make_number (end),
8391 props, f->desired_tool_bar_string);
8392 #undef PROP
8395 UNGCPRO;
8399 /* Display one line of the tool-bar of frame IT->f. */
8401 static void
8402 display_tool_bar_line (it)
8403 struct it *it;
8405 struct glyph_row *row = it->glyph_row;
8406 int max_x = it->last_visible_x;
8407 struct glyph *last;
8409 prepare_desired_row (row);
8410 row->y = it->current_y;
8412 /* Note that this isn't made use of if the face hasn't a box,
8413 so there's no need to check the face here. */
8414 it->start_of_box_run_p = 1;
8416 while (it->current_x < max_x)
8418 int x_before, x, n_glyphs_before, i, nglyphs;
8420 /* Get the next display element. */
8421 if (!get_next_display_element (it))
8422 break;
8424 /* Produce glyphs. */
8425 x_before = it->current_x;
8426 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8427 PRODUCE_GLYPHS (it);
8429 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8430 i = 0;
8431 x = x_before;
8432 while (i < nglyphs)
8434 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8436 if (x + glyph->pixel_width > max_x)
8438 /* Glyph doesn't fit on line. */
8439 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8440 it->current_x = x;
8441 goto out;
8444 ++it->hpos;
8445 x += glyph->pixel_width;
8446 ++i;
8449 /* Stop at line ends. */
8450 if (ITERATOR_AT_END_OF_LINE_P (it))
8451 break;
8453 set_iterator_to_next (it, 1);
8456 out:;
8458 row->displays_text_p = row->used[TEXT_AREA] != 0;
8459 extend_face_to_end_of_line (it);
8460 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8461 last->right_box_line_p = 1;
8462 if (last == row->glyphs[TEXT_AREA])
8463 last->left_box_line_p = 1;
8464 compute_line_metrics (it);
8466 /* If line is empty, make it occupy the rest of the tool-bar. */
8467 if (!row->displays_text_p)
8469 row->height = row->phys_height = it->last_visible_y - row->y;
8470 row->ascent = row->phys_ascent = 0;
8473 row->full_width_p = 1;
8474 row->continued_p = 0;
8475 row->truncated_on_left_p = 0;
8476 row->truncated_on_right_p = 0;
8478 it->current_x = it->hpos = 0;
8479 it->current_y += row->height;
8480 ++it->vpos;
8481 ++it->glyph_row;
8485 /* Value is the number of screen lines needed to make all tool-bar
8486 items of frame F visible. */
8488 static int
8489 tool_bar_lines_needed (f)
8490 struct frame *f;
8492 struct window *w = XWINDOW (f->tool_bar_window);
8493 struct it it;
8495 /* Initialize an iterator for iteration over
8496 F->desired_tool_bar_string in the tool-bar window of frame F. */
8497 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8498 it.first_visible_x = 0;
8499 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8500 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8502 while (!ITERATOR_AT_END_P (&it))
8504 it.glyph_row = w->desired_matrix->rows;
8505 clear_glyph_row (it.glyph_row);
8506 display_tool_bar_line (&it);
8509 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8513 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8514 0, 1, 0,
8515 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8516 (frame)
8517 Lisp_Object frame;
8519 struct frame *f;
8520 struct window *w;
8521 int nlines = 0;
8523 if (NILP (frame))
8524 frame = selected_frame;
8525 else
8526 CHECK_FRAME (frame);
8527 f = XFRAME (frame);
8529 if (WINDOWP (f->tool_bar_window)
8530 || (w = XWINDOW (f->tool_bar_window),
8531 WINDOW_TOTAL_LINES (w) > 0))
8533 update_tool_bar (f, 1);
8534 if (f->n_tool_bar_items)
8536 build_desired_tool_bar_string (f);
8537 nlines = tool_bar_lines_needed (f);
8541 return make_number (nlines);
8545 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8546 height should be changed. */
8548 static int
8549 redisplay_tool_bar (f)
8550 struct frame *f;
8552 struct window *w;
8553 struct it it;
8554 struct glyph_row *row;
8555 int change_height_p = 0;
8557 #ifdef USE_GTK
8558 if (FRAME_EXTERNAL_TOOL_BAR (f))
8559 update_frame_tool_bar (f);
8560 return 0;
8561 #endif
8563 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8564 do anything. This means you must start with tool-bar-lines
8565 non-zero to get the auto-sizing effect. Or in other words, you
8566 can turn off tool-bars by specifying tool-bar-lines zero. */
8567 if (!WINDOWP (f->tool_bar_window)
8568 || (w = XWINDOW (f->tool_bar_window),
8569 WINDOW_TOTAL_LINES (w) == 0))
8570 return 0;
8572 /* Set up an iterator for the tool-bar window. */
8573 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8574 it.first_visible_x = 0;
8575 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8576 row = it.glyph_row;
8578 /* Build a string that represents the contents of the tool-bar. */
8579 build_desired_tool_bar_string (f);
8580 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8582 /* Display as many lines as needed to display all tool-bar items. */
8583 while (it.current_y < it.last_visible_y)
8584 display_tool_bar_line (&it);
8586 /* It doesn't make much sense to try scrolling in the tool-bar
8587 window, so don't do it. */
8588 w->desired_matrix->no_scrolling_p = 1;
8589 w->must_be_updated_p = 1;
8591 if (auto_resize_tool_bars_p)
8593 int nlines;
8595 /* If we couldn't display everything, change the tool-bar's
8596 height. */
8597 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8598 change_height_p = 1;
8600 /* If there are blank lines at the end, except for a partially
8601 visible blank line at the end that is smaller than
8602 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8603 row = it.glyph_row - 1;
8604 if (!row->displays_text_p
8605 && row->height >= FRAME_LINE_HEIGHT (f))
8606 change_height_p = 1;
8608 /* If row displays tool-bar items, but is partially visible,
8609 change the tool-bar's height. */
8610 if (row->displays_text_p
8611 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8612 change_height_p = 1;
8614 /* Resize windows as needed by changing the `tool-bar-lines'
8615 frame parameter. */
8616 if (change_height_p
8617 && (nlines = tool_bar_lines_needed (f),
8618 nlines != WINDOW_TOTAL_LINES (w)))
8620 extern Lisp_Object Qtool_bar_lines;
8621 Lisp_Object frame;
8622 int old_height = WINDOW_TOTAL_LINES (w);
8624 XSETFRAME (frame, f);
8625 clear_glyph_matrix (w->desired_matrix);
8626 Fmodify_frame_parameters (frame,
8627 Fcons (Fcons (Qtool_bar_lines,
8628 make_number (nlines)),
8629 Qnil));
8630 if (WINDOW_TOTAL_LINES (w) != old_height)
8631 fonts_changed_p = 1;
8635 return change_height_p;
8639 /* Get information about the tool-bar item which is displayed in GLYPH
8640 on frame F. Return in *PROP_IDX the index where tool-bar item
8641 properties start in F->tool_bar_items. Value is zero if
8642 GLYPH doesn't display a tool-bar item. */
8644 static int
8645 tool_bar_item_info (f, glyph, prop_idx)
8646 struct frame *f;
8647 struct glyph *glyph;
8648 int *prop_idx;
8650 Lisp_Object prop;
8651 int success_p;
8652 int charpos;
8654 /* This function can be called asynchronously, which means we must
8655 exclude any possibility that Fget_text_property signals an
8656 error. */
8657 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8658 charpos = max (0, charpos);
8660 /* Get the text property `menu-item' at pos. The value of that
8661 property is the start index of this item's properties in
8662 F->tool_bar_items. */
8663 prop = Fget_text_property (make_number (charpos),
8664 Qmenu_item, f->current_tool_bar_string);
8665 if (INTEGERP (prop))
8667 *prop_idx = XINT (prop);
8668 success_p = 1;
8670 else
8671 success_p = 0;
8673 return success_p;
8677 /* Get information about the tool-bar item at position X/Y on frame F.
8678 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8679 the current matrix of the tool-bar window of F, or NULL if not
8680 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8681 item in F->tool_bar_items. Value is
8683 -1 if X/Y is not on a tool-bar item
8684 0 if X/Y is on the same item that was highlighted before.
8685 1 otherwise. */
8687 static int
8688 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8689 struct frame *f;
8690 int x, y;
8691 struct glyph **glyph;
8692 int *hpos, *vpos, *prop_idx;
8694 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8695 struct window *w = XWINDOW (f->tool_bar_window);
8696 int area;
8698 /* Find the glyph under X/Y. */
8699 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
8700 if (*glyph == NULL)
8701 return -1;
8703 /* Get the start of this tool-bar item's properties in
8704 f->tool_bar_items. */
8705 if (!tool_bar_item_info (f, *glyph, prop_idx))
8706 return -1;
8708 /* Is mouse on the highlighted item? */
8709 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8710 && *vpos >= dpyinfo->mouse_face_beg_row
8711 && *vpos <= dpyinfo->mouse_face_end_row
8712 && (*vpos > dpyinfo->mouse_face_beg_row
8713 || *hpos >= dpyinfo->mouse_face_beg_col)
8714 && (*vpos < dpyinfo->mouse_face_end_row
8715 || *hpos < dpyinfo->mouse_face_end_col
8716 || dpyinfo->mouse_face_past_end))
8717 return 0;
8719 return 1;
8723 /* EXPORT:
8724 Handle mouse button event on the tool-bar of frame F, at
8725 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8726 0 for button release. MODIFIERS is event modifiers for button
8727 release. */
8729 void
8730 handle_tool_bar_click (f, x, y, down_p, modifiers)
8731 struct frame *f;
8732 int x, y, down_p;
8733 unsigned int modifiers;
8735 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8736 struct window *w = XWINDOW (f->tool_bar_window);
8737 int hpos, vpos, prop_idx;
8738 struct glyph *glyph;
8739 Lisp_Object enabled_p;
8741 /* If not on the highlighted tool-bar item, return. */
8742 frame_to_window_pixel_xy (w, &x, &y);
8743 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8744 return;
8746 /* If item is disabled, do nothing. */
8747 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8748 if (NILP (enabled_p))
8749 return;
8751 if (down_p)
8753 /* Show item in pressed state. */
8754 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8755 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8756 last_tool_bar_item = prop_idx;
8758 else
8760 Lisp_Object key, frame;
8761 struct input_event event;
8762 EVENT_INIT (event);
8764 /* Show item in released state. */
8765 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8766 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8768 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8770 XSETFRAME (frame, f);
8771 event.kind = TOOL_BAR_EVENT;
8772 event.frame_or_window = frame;
8773 event.arg = frame;
8774 kbd_buffer_store_event (&event);
8776 event.kind = TOOL_BAR_EVENT;
8777 event.frame_or_window = frame;
8778 event.arg = key;
8779 event.modifiers = modifiers;
8780 kbd_buffer_store_event (&event);
8781 last_tool_bar_item = -1;
8786 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8787 tool-bar window-relative coordinates X/Y. Called from
8788 note_mouse_highlight. */
8790 static void
8791 note_tool_bar_highlight (f, x, y)
8792 struct frame *f;
8793 int x, y;
8795 Lisp_Object window = f->tool_bar_window;
8796 struct window *w = XWINDOW (window);
8797 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8798 int hpos, vpos;
8799 struct glyph *glyph;
8800 struct glyph_row *row;
8801 int i;
8802 Lisp_Object enabled_p;
8803 int prop_idx;
8804 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8805 int mouse_down_p, rc;
8807 /* Function note_mouse_highlight is called with negative x(y
8808 values when mouse moves outside of the frame. */
8809 if (x <= 0 || y <= 0)
8811 clear_mouse_face (dpyinfo);
8812 return;
8815 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8816 if (rc < 0)
8818 /* Not on tool-bar item. */
8819 clear_mouse_face (dpyinfo);
8820 return;
8822 else if (rc == 0)
8823 /* On same tool-bar item as before. */
8824 goto set_help_echo;
8826 clear_mouse_face (dpyinfo);
8828 /* Mouse is down, but on different tool-bar item? */
8829 mouse_down_p = (dpyinfo->grabbed
8830 && f == last_mouse_frame
8831 && FRAME_LIVE_P (f));
8832 if (mouse_down_p
8833 && last_tool_bar_item != prop_idx)
8834 return;
8836 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8837 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8839 /* If tool-bar item is not enabled, don't highlight it. */
8840 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8841 if (!NILP (enabled_p))
8843 /* Compute the x-position of the glyph. In front and past the
8844 image is a space. We include this in the highlighted area. */
8845 row = MATRIX_ROW (w->current_matrix, vpos);
8846 for (i = x = 0; i < hpos; ++i)
8847 x += row->glyphs[TEXT_AREA][i].pixel_width;
8849 /* Record this as the current active region. */
8850 dpyinfo->mouse_face_beg_col = hpos;
8851 dpyinfo->mouse_face_beg_row = vpos;
8852 dpyinfo->mouse_face_beg_x = x;
8853 dpyinfo->mouse_face_beg_y = row->y;
8854 dpyinfo->mouse_face_past_end = 0;
8856 dpyinfo->mouse_face_end_col = hpos + 1;
8857 dpyinfo->mouse_face_end_row = vpos;
8858 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8859 dpyinfo->mouse_face_end_y = row->y;
8860 dpyinfo->mouse_face_window = window;
8861 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8863 /* Display it as active. */
8864 show_mouse_face (dpyinfo, draw);
8865 dpyinfo->mouse_face_image_state = draw;
8868 set_help_echo:
8870 /* Set help_echo_string to a help string to display for this tool-bar item.
8871 XTread_socket does the rest. */
8872 help_echo_object = help_echo_window = Qnil;
8873 help_echo_pos = -1;
8874 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8875 if (NILP (help_echo_string))
8876 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8879 #endif /* HAVE_WINDOW_SYSTEM */
8883 /***********************************************************************
8884 Fringes
8885 ***********************************************************************/
8887 #ifdef HAVE_WINDOW_SYSTEM
8889 /* An arrow like this: `<-'. */
8890 static unsigned char left_bits[] = {
8891 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8893 /* Right truncation arrow bitmap `->'. */
8894 static unsigned char right_bits[] = {
8895 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8897 /* Marker for continued lines. */
8898 static unsigned char continued_bits[] = {
8899 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
8901 /* Marker for continuation lines. */
8902 static unsigned char continuation_bits[] = {
8903 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
8905 /* Overlay arrow bitmap. A triangular arrow. */
8906 static unsigned char ov_bits[] = {
8907 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
8909 /* Bitmap drawn to indicate lines not displaying text if
8910 `indicate-empty-lines' is non-nil. */
8911 static unsigned char zv_bits[] = {
8912 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8913 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8914 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8915 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8916 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8917 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8918 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
8919 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
8921 struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
8923 { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
8924 { 8, sizeof (left_bits), 0, left_bits },
8925 { 8, sizeof (right_bits), 0, right_bits },
8926 { 8, sizeof (continued_bits), 0, continued_bits },
8927 { 8, sizeof (continuation_bits), 0, continuation_bits },
8928 { 8, sizeof (ov_bits), 0, ov_bits },
8929 { 8, sizeof (zv_bits), 3, zv_bits }
8933 /* Draw the bitmap WHICH in one of the left or right fringes of
8934 window W. ROW is the glyph row for which to display the bitmap; it
8935 determines the vertical position at which the bitmap has to be
8936 drawn. */
8938 static void
8939 draw_fringe_bitmap (w, row, which, left_p)
8940 struct window *w;
8941 struct glyph_row *row;
8942 enum fringe_bitmap_type which;
8943 int left_p;
8945 struct frame *f = XFRAME (WINDOW_FRAME (w));
8946 struct draw_fringe_bitmap_params p;
8948 /* Convert row to frame coordinates. */
8949 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8951 p.which = which;
8952 p.wd = fringe_bitmaps[which].width;
8954 p.h = fringe_bitmaps[which].height;
8955 p.dh = (fringe_bitmaps[which].period
8956 ? (p.y % fringe_bitmaps[which].period)
8957 : 0);
8958 p.h -= p.dh;
8959 /* Clip bitmap if too high. */
8960 if (p.h > row->height)
8961 p.h = row->height;
8963 p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
8964 PREPARE_FACE_FOR_DISPLAY (f, p.face);
8966 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
8967 the fringe. */
8968 p.bx = -1;
8969 if (left_p)
8971 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
8972 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
8973 ? LEFT_MARGIN_AREA
8974 : TEXT_AREA));
8975 if (p.wd > wd)
8976 p.wd = wd;
8977 p.x = x - p.wd - (wd - p.wd) / 2;
8979 if (p.wd < wd || row->height > p.h)
8981 /* If W has a vertical border to its left, don't draw over it. */
8982 wd -= ((!WINDOW_LEFTMOST_P (w)
8983 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
8984 ? 1 : 0);
8985 p.bx = x - wd;
8986 p.nx = wd;
8989 else
8991 int x = window_box_right (w,
8992 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
8993 ? RIGHT_MARGIN_AREA
8994 : TEXT_AREA));
8995 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
8996 if (p.wd > wd)
8997 p.wd = wd;
8998 p.x = x + (wd - p.wd) / 2;
8999 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
9000 the fringe. */
9001 if (p.wd < wd || row->height > p.h)
9003 p.bx = x;
9004 p.nx = wd;
9008 if (p.bx >= 0)
9010 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
9012 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
9013 p.ny = row->visible_height;
9016 /* Adjust y to the offset in the row to start drawing the bitmap. */
9017 p.y += (row->height - p.h) / 2;
9019 rif->draw_fringe_bitmap (w, row, &p);
9022 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
9023 function with input blocked. */
9025 void
9026 draw_row_fringe_bitmaps (w, row)
9027 struct window *w;
9028 struct glyph_row *row;
9030 enum fringe_bitmap_type bitmap;
9032 xassert (interrupt_input_blocked);
9034 /* If row is completely invisible, because of vscrolling, we
9035 don't have to draw anything. */
9036 if (row->visible_height <= 0)
9037 return;
9039 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
9041 /* Decide which bitmap to draw in the left fringe. */
9042 if (row->overlay_arrow_p)
9043 bitmap = OVERLAY_ARROW_BITMAP;
9044 else if (row->truncated_on_left_p)
9045 bitmap = LEFT_TRUNCATION_BITMAP;
9046 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
9047 bitmap = CONTINUATION_LINE_BITMAP;
9048 else if (row->indicate_empty_line_p)
9049 bitmap = ZV_LINE_BITMAP;
9050 else
9051 bitmap = NO_FRINGE_BITMAP;
9053 draw_fringe_bitmap (w, row, bitmap, 1);
9056 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
9058 /* Decide which bitmap to draw in the right fringe. */
9059 if (row->truncated_on_right_p)
9060 bitmap = RIGHT_TRUNCATION_BITMAP;
9061 else if (row->continued_p)
9062 bitmap = CONTINUED_LINE_BITMAP;
9063 else if (row->indicate_empty_line_p && WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
9064 bitmap = ZV_LINE_BITMAP;
9065 else
9066 bitmap = NO_FRINGE_BITMAP;
9068 draw_fringe_bitmap (w, row, bitmap, 0);
9073 /* Compute actual fringe widths for frame F.
9075 If REDRAW is 1, redraw F if the fringe settings was actually
9076 modified and F is visible.
9078 Since the combined left and right fringe must occupy an integral
9079 number of columns, we may need to add some pixels to each fringe.
9080 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
9081 but a negative width value is taken literally (after negating it).
9083 We never make the fringes narrower than specified. It is planned
9084 to make fringe bitmaps customizable and expandable, and at that
9085 time, the user will typically specify the minimum number of pixels
9086 needed for his bitmaps, so we shouldn't select anything less than
9087 what is specified.
9090 void
9091 compute_fringe_widths (f, redraw)
9092 struct frame *f;
9093 int redraw;
9095 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
9096 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
9097 int o_cols = FRAME_FRINGE_COLS (f);
9099 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9100 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9101 int left_fringe_width, right_fringe_width;
9103 if (!NILP (left_fringe))
9104 left_fringe = Fcdr (left_fringe);
9105 if (!NILP (right_fringe))
9106 right_fringe = Fcdr (right_fringe);
9108 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9109 XINT (left_fringe));
9110 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9111 XINT (right_fringe));
9113 if (left_fringe_width || right_fringe_width)
9115 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9116 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9117 int conf_wid = left_wid + right_wid;
9118 int font_wid = FRAME_COLUMN_WIDTH (f);
9119 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9120 int real_wid = cols * font_wid;
9121 if (left_wid && right_wid)
9123 if (left_fringe_width < 0)
9125 /* Left fringe width is fixed, adjust right fringe if necessary */
9126 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
9127 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9129 else if (right_fringe_width < 0)
9131 /* Right fringe width is fixed, adjust left fringe if necessary */
9132 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9133 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
9135 else
9137 /* Adjust both fringes with an equal amount.
9138 Note that we are doing integer arithmetic here, so don't
9139 lose a pixel if the total width is an odd number. */
9140 int fill = real_wid - conf_wid;
9141 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9142 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9145 else if (left_fringe_width)
9147 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
9148 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9150 else
9152 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9153 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
9155 FRAME_FRINGE_COLS (f) = cols;
9157 else
9159 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9160 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9161 FRAME_FRINGE_COLS (f) = 0;
9164 if (redraw && FRAME_VISIBLE_P (f))
9165 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
9166 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
9167 o_cols != FRAME_FRINGE_COLS (f))
9168 redraw_frame (f);
9171 #endif /* HAVE_WINDOW_SYSTEM */
9175 /************************************************************************
9176 Horizontal scrolling
9177 ************************************************************************/
9179 static int hscroll_window_tree P_ ((Lisp_Object));
9180 static int hscroll_windows P_ ((Lisp_Object));
9182 /* For all leaf windows in the window tree rooted at WINDOW, set their
9183 hscroll value so that PT is (i) visible in the window, and (ii) so
9184 that it is not within a certain margin at the window's left and
9185 right border. Value is non-zero if any window's hscroll has been
9186 changed. */
9188 static int
9189 hscroll_window_tree (window)
9190 Lisp_Object window;
9192 int hscrolled_p = 0;
9193 int hscroll_relative_p = FLOATP (Vhscroll_step);
9194 int hscroll_step_abs = 0;
9195 double hscroll_step_rel = 0;
9197 if (hscroll_relative_p)
9199 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9200 if (hscroll_step_rel < 0)
9202 hscroll_relative_p = 0;
9203 hscroll_step_abs = 0;
9206 else if (INTEGERP (Vhscroll_step))
9208 hscroll_step_abs = XINT (Vhscroll_step);
9209 if (hscroll_step_abs < 0)
9210 hscroll_step_abs = 0;
9212 else
9213 hscroll_step_abs = 0;
9215 while (WINDOWP (window))
9217 struct window *w = XWINDOW (window);
9219 if (WINDOWP (w->hchild))
9220 hscrolled_p |= hscroll_window_tree (w->hchild);
9221 else if (WINDOWP (w->vchild))
9222 hscrolled_p |= hscroll_window_tree (w->vchild);
9223 else if (w->cursor.vpos >= 0)
9225 int h_margin;
9226 int text_area_width;
9227 struct glyph_row *current_cursor_row
9228 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9229 struct glyph_row *desired_cursor_row
9230 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9231 struct glyph_row *cursor_row
9232 = (desired_cursor_row->enabled_p
9233 ? desired_cursor_row
9234 : current_cursor_row);
9236 text_area_width = window_box_width (w, TEXT_AREA);
9238 /* Scroll when cursor is inside this scroll margin. */
9239 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9241 if ((XFASTINT (w->hscroll)
9242 && w->cursor.x <= h_margin)
9243 || (cursor_row->enabled_p
9244 && cursor_row->truncated_on_right_p
9245 && (w->cursor.x >= text_area_width - h_margin)))
9247 struct it it;
9248 int hscroll;
9249 struct buffer *saved_current_buffer;
9250 int pt;
9251 int wanted_x;
9253 /* Find point in a display of infinite width. */
9254 saved_current_buffer = current_buffer;
9255 current_buffer = XBUFFER (w->buffer);
9257 if (w == XWINDOW (selected_window))
9258 pt = BUF_PT (current_buffer);
9259 else
9261 pt = marker_position (w->pointm);
9262 pt = max (BEGV, pt);
9263 pt = min (ZV, pt);
9266 /* Move iterator to pt starting at cursor_row->start in
9267 a line with infinite width. */
9268 init_to_row_start (&it, w, cursor_row);
9269 it.last_visible_x = INFINITY;
9270 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9271 current_buffer = saved_current_buffer;
9273 /* Position cursor in window. */
9274 if (!hscroll_relative_p && hscroll_step_abs == 0)
9275 hscroll = max (0, it.current_x - text_area_width / 2)
9276 / FRAME_COLUMN_WIDTH (it.f);
9277 else if (w->cursor.x >= text_area_width - h_margin)
9279 if (hscroll_relative_p)
9280 wanted_x = text_area_width * (1 - hscroll_step_rel)
9281 - h_margin;
9282 else
9283 wanted_x = text_area_width
9284 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9285 - h_margin;
9286 hscroll
9287 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9289 else
9291 if (hscroll_relative_p)
9292 wanted_x = text_area_width * hscroll_step_rel
9293 + h_margin;
9294 else
9295 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9296 + h_margin;
9297 hscroll
9298 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9300 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9302 /* Don't call Fset_window_hscroll if value hasn't
9303 changed because it will prevent redisplay
9304 optimizations. */
9305 if (XFASTINT (w->hscroll) != hscroll)
9307 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9308 w->hscroll = make_number (hscroll);
9309 hscrolled_p = 1;
9314 window = w->next;
9317 /* Value is non-zero if hscroll of any leaf window has been changed. */
9318 return hscrolled_p;
9322 /* Set hscroll so that cursor is visible and not inside horizontal
9323 scroll margins for all windows in the tree rooted at WINDOW. See
9324 also hscroll_window_tree above. Value is non-zero if any window's
9325 hscroll has been changed. If it has, desired matrices on the frame
9326 of WINDOW are cleared. */
9328 static int
9329 hscroll_windows (window)
9330 Lisp_Object window;
9332 int hscrolled_p;
9334 if (automatic_hscrolling_p)
9336 hscrolled_p = hscroll_window_tree (window);
9337 if (hscrolled_p)
9338 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9340 else
9341 hscrolled_p = 0;
9342 return hscrolled_p;
9347 /************************************************************************
9348 Redisplay
9349 ************************************************************************/
9351 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9352 to a non-zero value. This is sometimes handy to have in a debugger
9353 session. */
9355 #if GLYPH_DEBUG
9357 /* First and last unchanged row for try_window_id. */
9359 int debug_first_unchanged_at_end_vpos;
9360 int debug_last_unchanged_at_beg_vpos;
9362 /* Delta vpos and y. */
9364 int debug_dvpos, debug_dy;
9366 /* Delta in characters and bytes for try_window_id. */
9368 int debug_delta, debug_delta_bytes;
9370 /* Values of window_end_pos and window_end_vpos at the end of
9371 try_window_id. */
9373 EMACS_INT debug_end_pos, debug_end_vpos;
9375 /* Append a string to W->desired_matrix->method. FMT is a printf
9376 format string. A1...A9 are a supplement for a variable-length
9377 argument list. If trace_redisplay_p is non-zero also printf the
9378 resulting string to stderr. */
9380 static void
9381 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9382 struct window *w;
9383 char *fmt;
9384 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9386 char buffer[512];
9387 char *method = w->desired_matrix->method;
9388 int len = strlen (method);
9389 int size = sizeof w->desired_matrix->method;
9390 int remaining = size - len - 1;
9392 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9393 if (len && remaining)
9395 method[len] = '|';
9396 --remaining, ++len;
9399 strncpy (method + len, buffer, remaining);
9401 if (trace_redisplay_p)
9402 fprintf (stderr, "%p (%s): %s\n",
9404 ((BUFFERP (w->buffer)
9405 && STRINGP (XBUFFER (w->buffer)->name))
9406 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9407 : "no buffer"),
9408 buffer);
9411 #endif /* GLYPH_DEBUG */
9414 /* Value is non-zero if all changes in window W, which displays
9415 current_buffer, are in the text between START and END. START is a
9416 buffer position, END is given as a distance from Z. Used in
9417 redisplay_internal for display optimization. */
9419 static INLINE int
9420 text_outside_line_unchanged_p (w, start, end)
9421 struct window *w;
9422 int start, end;
9424 int unchanged_p = 1;
9426 /* If text or overlays have changed, see where. */
9427 if (XFASTINT (w->last_modified) < MODIFF
9428 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9430 /* Gap in the line? */
9431 if (GPT < start || Z - GPT < end)
9432 unchanged_p = 0;
9434 /* Changes start in front of the line, or end after it? */
9435 if (unchanged_p
9436 && (BEG_UNCHANGED < start - 1
9437 || END_UNCHANGED < end))
9438 unchanged_p = 0;
9440 /* If selective display, can't optimize if changes start at the
9441 beginning of the line. */
9442 if (unchanged_p
9443 && INTEGERP (current_buffer->selective_display)
9444 && XINT (current_buffer->selective_display) > 0
9445 && (BEG_UNCHANGED < start || GPT <= start))
9446 unchanged_p = 0;
9448 /* If there are overlays at the start or end of the line, these
9449 may have overlay strings with newlines in them. A change at
9450 START, for instance, may actually concern the display of such
9451 overlay strings as well, and they are displayed on different
9452 lines. So, quickly rule out this case. (For the future, it
9453 might be desirable to implement something more telling than
9454 just BEG/END_UNCHANGED.) */
9455 if (unchanged_p)
9457 if (BEG + BEG_UNCHANGED == start
9458 && overlay_touches_p (start))
9459 unchanged_p = 0;
9460 if (END_UNCHANGED == end
9461 && overlay_touches_p (Z - end))
9462 unchanged_p = 0;
9466 return unchanged_p;
9470 /* Do a frame update, taking possible shortcuts into account. This is
9471 the main external entry point for redisplay.
9473 If the last redisplay displayed an echo area message and that message
9474 is no longer requested, we clear the echo area or bring back the
9475 mini-buffer if that is in use. */
9477 void
9478 redisplay ()
9480 redisplay_internal (0);
9484 /* Return 1 if point moved out of or into a composition. Otherwise
9485 return 0. PREV_BUF and PREV_PT are the last point buffer and
9486 position. BUF and PT are the current point buffer and position. */
9489 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9490 struct buffer *prev_buf, *buf;
9491 int prev_pt, pt;
9493 int start, end;
9494 Lisp_Object prop;
9495 Lisp_Object buffer;
9497 XSETBUFFER (buffer, buf);
9498 /* Check a composition at the last point if point moved within the
9499 same buffer. */
9500 if (prev_buf == buf)
9502 if (prev_pt == pt)
9503 /* Point didn't move. */
9504 return 0;
9506 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9507 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9508 && COMPOSITION_VALID_P (start, end, prop)
9509 && start < prev_pt && end > prev_pt)
9510 /* The last point was within the composition. Return 1 iff
9511 point moved out of the composition. */
9512 return (pt <= start || pt >= end);
9515 /* Check a composition at the current point. */
9516 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9517 && find_composition (pt, -1, &start, &end, &prop, buffer)
9518 && COMPOSITION_VALID_P (start, end, prop)
9519 && start < pt && end > pt);
9523 /* Reconsider the setting of B->clip_changed which is displayed
9524 in window W. */
9526 static INLINE void
9527 reconsider_clip_changes (w, b)
9528 struct window *w;
9529 struct buffer *b;
9531 if (b->clip_changed
9532 && !NILP (w->window_end_valid)
9533 && w->current_matrix->buffer == b
9534 && w->current_matrix->zv == BUF_ZV (b)
9535 && w->current_matrix->begv == BUF_BEGV (b))
9536 b->clip_changed = 0;
9538 /* If display wasn't paused, and W is not a tool bar window, see if
9539 point has been moved into or out of a composition. In that case,
9540 we set b->clip_changed to 1 to force updating the screen. If
9541 b->clip_changed has already been set to 1, we can skip this
9542 check. */
9543 if (!b->clip_changed
9544 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9546 int pt;
9548 if (w == XWINDOW (selected_window))
9549 pt = BUF_PT (current_buffer);
9550 else
9551 pt = marker_position (w->pointm);
9553 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9554 || pt != XINT (w->last_point))
9555 && check_point_in_composition (w->current_matrix->buffer,
9556 XINT (w->last_point),
9557 XBUFFER (w->buffer), pt))
9558 b->clip_changed = 1;
9563 /* Select FRAME to forward the values of frame-local variables into C
9564 variables so that the redisplay routines can access those values
9565 directly. */
9567 static void
9568 select_frame_for_redisplay (frame)
9569 Lisp_Object frame;
9571 Lisp_Object tail, sym, val;
9572 Lisp_Object old = selected_frame;
9574 selected_frame = frame;
9576 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9577 if (CONSP (XCAR (tail))
9578 && (sym = XCAR (XCAR (tail)),
9579 SYMBOLP (sym))
9580 && (sym = indirect_variable (sym),
9581 val = SYMBOL_VALUE (sym),
9582 (BUFFER_LOCAL_VALUEP (val)
9583 || SOME_BUFFER_LOCAL_VALUEP (val)))
9584 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9585 Fsymbol_value (sym);
9587 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9588 if (CONSP (XCAR (tail))
9589 && (sym = XCAR (XCAR (tail)),
9590 SYMBOLP (sym))
9591 && (sym = indirect_variable (sym),
9592 val = SYMBOL_VALUE (sym),
9593 (BUFFER_LOCAL_VALUEP (val)
9594 || SOME_BUFFER_LOCAL_VALUEP (val)))
9595 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9596 Fsymbol_value (sym);
9600 #define STOP_POLLING \
9601 do { if (! polling_stopped_here) stop_polling (); \
9602 polling_stopped_here = 1; } while (0)
9604 #define RESUME_POLLING \
9605 do { if (polling_stopped_here) start_polling (); \
9606 polling_stopped_here = 0; } while (0)
9609 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9610 response to any user action; therefore, we should preserve the echo
9611 area. (Actually, our caller does that job.) Perhaps in the future
9612 avoid recentering windows if it is not necessary; currently that
9613 causes some problems. */
9615 static void
9616 redisplay_internal (preserve_echo_area)
9617 int preserve_echo_area;
9619 struct window *w = XWINDOW (selected_window);
9620 struct frame *f = XFRAME (w->frame);
9621 int pause;
9622 int must_finish = 0;
9623 struct text_pos tlbufpos, tlendpos;
9624 int number_of_visible_frames;
9625 int count;
9626 struct frame *sf = SELECTED_FRAME ();
9627 int polling_stopped_here = 0;
9629 /* Non-zero means redisplay has to consider all windows on all
9630 frames. Zero means, only selected_window is considered. */
9631 int consider_all_windows_p;
9633 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9635 /* No redisplay if running in batch mode or frame is not yet fully
9636 initialized, or redisplay is explicitly turned off by setting
9637 Vinhibit_redisplay. */
9638 if (noninteractive
9639 || !NILP (Vinhibit_redisplay)
9640 || !f->glyphs_initialized_p)
9641 return;
9643 /* The flag redisplay_performed_directly_p is set by
9644 direct_output_for_insert when it already did the whole screen
9645 update necessary. */
9646 if (redisplay_performed_directly_p)
9648 redisplay_performed_directly_p = 0;
9649 if (!hscroll_windows (selected_window))
9650 return;
9653 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9654 if (popup_activated ())
9655 return;
9656 #endif
9658 /* I don't think this happens but let's be paranoid. */
9659 if (redisplaying_p)
9660 return;
9662 /* Record a function that resets redisplaying_p to its old value
9663 when we leave this function. */
9664 count = SPECPDL_INDEX ();
9665 record_unwind_protect (unwind_redisplay,
9666 Fcons (make_number (redisplaying_p), selected_frame));
9667 ++redisplaying_p;
9668 specbind (Qinhibit_free_realized_faces, Qnil);
9670 retry:
9671 pause = 0;
9672 reconsider_clip_changes (w, current_buffer);
9674 /* If new fonts have been loaded that make a glyph matrix adjustment
9675 necessary, do it. */
9676 if (fonts_changed_p)
9678 adjust_glyphs (NULL);
9679 ++windows_or_buffers_changed;
9680 fonts_changed_p = 0;
9683 /* If face_change_count is non-zero, init_iterator will free all
9684 realized faces, which includes the faces referenced from current
9685 matrices. So, we can't reuse current matrices in this case. */
9686 if (face_change_count)
9687 ++windows_or_buffers_changed;
9689 if (! FRAME_WINDOW_P (sf)
9690 && previous_terminal_frame != sf)
9692 /* Since frames on an ASCII terminal share the same display
9693 area, displaying a different frame means redisplay the whole
9694 thing. */
9695 windows_or_buffers_changed++;
9696 SET_FRAME_GARBAGED (sf);
9697 XSETFRAME (Vterminal_frame, sf);
9699 previous_terminal_frame = sf;
9701 /* Set the visible flags for all frames. Do this before checking
9702 for resized or garbaged frames; they want to know if their frames
9703 are visible. See the comment in frame.h for
9704 FRAME_SAMPLE_VISIBILITY. */
9706 Lisp_Object tail, frame;
9708 number_of_visible_frames = 0;
9710 FOR_EACH_FRAME (tail, frame)
9712 struct frame *f = XFRAME (frame);
9714 FRAME_SAMPLE_VISIBILITY (f);
9715 if (FRAME_VISIBLE_P (f))
9716 ++number_of_visible_frames;
9717 clear_desired_matrices (f);
9721 /* Notice any pending interrupt request to change frame size. */
9722 do_pending_window_change (1);
9724 /* Clear frames marked as garbaged. */
9725 if (frame_garbaged)
9726 clear_garbaged_frames ();
9728 /* Build menubar and tool-bar items. */
9729 prepare_menu_bars ();
9731 if (windows_or_buffers_changed)
9732 update_mode_lines++;
9734 /* Detect case that we need to write or remove a star in the mode line. */
9735 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9737 w->update_mode_line = Qt;
9738 if (buffer_shared > 1)
9739 update_mode_lines++;
9742 /* If %c is in the mode line, update it if needed. */
9743 if (!NILP (w->column_number_displayed)
9744 /* This alternative quickly identifies a common case
9745 where no change is needed. */
9746 && !(PT == XFASTINT (w->last_point)
9747 && XFASTINT (w->last_modified) >= MODIFF
9748 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9749 && (XFASTINT (w->column_number_displayed)
9750 != (int) current_column ())) /* iftc */
9751 w->update_mode_line = Qt;
9753 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9755 /* The variable buffer_shared is set in redisplay_window and
9756 indicates that we redisplay a buffer in different windows. See
9757 there. */
9758 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9759 || cursor_type_changed);
9761 /* If specs for an arrow have changed, do thorough redisplay
9762 to ensure we remove any arrow that should no longer exist. */
9763 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9764 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9765 consider_all_windows_p = windows_or_buffers_changed = 1;
9767 /* Normally the message* functions will have already displayed and
9768 updated the echo area, but the frame may have been trashed, or
9769 the update may have been preempted, so display the echo area
9770 again here. Checking message_cleared_p captures the case that
9771 the echo area should be cleared. */
9772 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9773 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9774 || (message_cleared_p
9775 && minibuf_level == 0
9776 /* If the mini-window is currently selected, this means the
9777 echo-area doesn't show through. */
9778 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9780 int window_height_changed_p = echo_area_display (0);
9781 must_finish = 1;
9783 /* If we don't display the current message, don't clear the
9784 message_cleared_p flag, because, if we did, we wouldn't clear
9785 the echo area in the next redisplay which doesn't preserve
9786 the echo area. */
9787 if (!display_last_displayed_message_p)
9788 message_cleared_p = 0;
9790 if (fonts_changed_p)
9791 goto retry;
9792 else if (window_height_changed_p)
9794 consider_all_windows_p = 1;
9795 ++update_mode_lines;
9796 ++windows_or_buffers_changed;
9798 /* If window configuration was changed, frames may have been
9799 marked garbaged. Clear them or we will experience
9800 surprises wrt scrolling. */
9801 if (frame_garbaged)
9802 clear_garbaged_frames ();
9805 else if (EQ (selected_window, minibuf_window)
9806 && (current_buffer->clip_changed
9807 || XFASTINT (w->last_modified) < MODIFF
9808 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9809 && resize_mini_window (w, 0))
9811 /* Resized active mini-window to fit the size of what it is
9812 showing if its contents might have changed. */
9813 must_finish = 1;
9814 consider_all_windows_p = 1;
9815 ++windows_or_buffers_changed;
9816 ++update_mode_lines;
9818 /* If window configuration was changed, frames may have been
9819 marked garbaged. Clear them or we will experience
9820 surprises wrt scrolling. */
9821 if (frame_garbaged)
9822 clear_garbaged_frames ();
9826 /* If showing the region, and mark has changed, we must redisplay
9827 the whole window. The assignment to this_line_start_pos prevents
9828 the optimization directly below this if-statement. */
9829 if (((!NILP (Vtransient_mark_mode)
9830 && !NILP (XBUFFER (w->buffer)->mark_active))
9831 != !NILP (w->region_showing))
9832 || (!NILP (w->region_showing)
9833 && !EQ (w->region_showing,
9834 Fmarker_position (XBUFFER (w->buffer)->mark))))
9835 CHARPOS (this_line_start_pos) = 0;
9837 /* Optimize the case that only the line containing the cursor in the
9838 selected window has changed. Variables starting with this_ are
9839 set in display_line and record information about the line
9840 containing the cursor. */
9841 tlbufpos = this_line_start_pos;
9842 tlendpos = this_line_end_pos;
9843 if (!consider_all_windows_p
9844 && CHARPOS (tlbufpos) > 0
9845 && NILP (w->update_mode_line)
9846 && !current_buffer->clip_changed
9847 && !current_buffer->prevent_redisplay_optimizations_p
9848 && FRAME_VISIBLE_P (XFRAME (w->frame))
9849 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9850 /* Make sure recorded data applies to current buffer, etc. */
9851 && this_line_buffer == current_buffer
9852 && current_buffer == XBUFFER (w->buffer)
9853 && NILP (w->force_start)
9854 && NILP (w->optional_new_start)
9855 /* Point must be on the line that we have info recorded about. */
9856 && PT >= CHARPOS (tlbufpos)
9857 && PT <= Z - CHARPOS (tlendpos)
9858 /* All text outside that line, including its final newline,
9859 must be unchanged */
9860 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9861 CHARPOS (tlendpos)))
9863 if (CHARPOS (tlbufpos) > BEGV
9864 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9865 && (CHARPOS (tlbufpos) == ZV
9866 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9867 /* Former continuation line has disappeared by becoming empty */
9868 goto cancel;
9869 else if (XFASTINT (w->last_modified) < MODIFF
9870 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9871 || MINI_WINDOW_P (w))
9873 /* We have to handle the case of continuation around a
9874 wide-column character (See the comment in indent.c around
9875 line 885).
9877 For instance, in the following case:
9879 -------- Insert --------
9880 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9881 J_I_ ==> J_I_ `^^' are cursors.
9882 ^^ ^^
9883 -------- --------
9885 As we have to redraw the line above, we should goto cancel. */
9887 struct it it;
9888 int line_height_before = this_line_pixel_height;
9890 /* Note that start_display will handle the case that the
9891 line starting at tlbufpos is a continuation lines. */
9892 start_display (&it, w, tlbufpos);
9894 /* Implementation note: It this still necessary? */
9895 if (it.current_x != this_line_start_x)
9896 goto cancel;
9898 TRACE ((stderr, "trying display optimization 1\n"));
9899 w->cursor.vpos = -1;
9900 overlay_arrow_seen = 0;
9901 it.vpos = this_line_vpos;
9902 it.current_y = this_line_y;
9903 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9904 display_line (&it);
9906 /* If line contains point, is not continued,
9907 and ends at same distance from eob as before, we win */
9908 if (w->cursor.vpos >= 0
9909 /* Line is not continued, otherwise this_line_start_pos
9910 would have been set to 0 in display_line. */
9911 && CHARPOS (this_line_start_pos)
9912 /* Line ends as before. */
9913 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9914 /* Line has same height as before. Otherwise other lines
9915 would have to be shifted up or down. */
9916 && this_line_pixel_height == line_height_before)
9918 /* If this is not the window's last line, we must adjust
9919 the charstarts of the lines below. */
9920 if (it.current_y < it.last_visible_y)
9922 struct glyph_row *row
9923 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9924 int delta, delta_bytes;
9926 if (Z - CHARPOS (tlendpos) == ZV)
9928 /* This line ends at end of (accessible part of)
9929 buffer. There is no newline to count. */
9930 delta = (Z
9931 - CHARPOS (tlendpos)
9932 - MATRIX_ROW_START_CHARPOS (row));
9933 delta_bytes = (Z_BYTE
9934 - BYTEPOS (tlendpos)
9935 - MATRIX_ROW_START_BYTEPOS (row));
9937 else
9939 /* This line ends in a newline. Must take
9940 account of the newline and the rest of the
9941 text that follows. */
9942 delta = (Z
9943 - CHARPOS (tlendpos)
9944 - MATRIX_ROW_START_CHARPOS (row));
9945 delta_bytes = (Z_BYTE
9946 - BYTEPOS (tlendpos)
9947 - MATRIX_ROW_START_BYTEPOS (row));
9950 increment_matrix_positions (w->current_matrix,
9951 this_line_vpos + 1,
9952 w->current_matrix->nrows,
9953 delta, delta_bytes);
9956 /* If this row displays text now but previously didn't,
9957 or vice versa, w->window_end_vpos may have to be
9958 adjusted. */
9959 if ((it.glyph_row - 1)->displays_text_p)
9961 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9962 XSETINT (w->window_end_vpos, this_line_vpos);
9964 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9965 && this_line_vpos > 0)
9966 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9967 w->window_end_valid = Qnil;
9969 /* Update hint: No need to try to scroll in update_window. */
9970 w->desired_matrix->no_scrolling_p = 1;
9972 #if GLYPH_DEBUG
9973 *w->desired_matrix->method = 0;
9974 debug_method_add (w, "optimization 1");
9975 #endif
9976 goto update;
9978 else
9979 goto cancel;
9981 else if (/* Cursor position hasn't changed. */
9982 PT == XFASTINT (w->last_point)
9983 /* Make sure the cursor was last displayed
9984 in this window. Otherwise we have to reposition it. */
9985 && 0 <= w->cursor.vpos
9986 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
9988 if (!must_finish)
9990 do_pending_window_change (1);
9992 /* We used to always goto end_of_redisplay here, but this
9993 isn't enough if we have a blinking cursor. */
9994 if (w->cursor_off_p == w->last_cursor_off_p)
9995 goto end_of_redisplay;
9997 goto update;
9999 /* If highlighting the region, or if the cursor is in the echo area,
10000 then we can't just move the cursor. */
10001 else if (! (!NILP (Vtransient_mark_mode)
10002 && !NILP (current_buffer->mark_active))
10003 && (EQ (selected_window, current_buffer->last_selected_window)
10004 || highlight_nonselected_windows)
10005 && NILP (w->region_showing)
10006 && NILP (Vshow_trailing_whitespace)
10007 && !cursor_in_echo_area)
10009 struct it it;
10010 struct glyph_row *row;
10012 /* Skip from tlbufpos to PT and see where it is. Note that
10013 PT may be in invisible text. If so, we will end at the
10014 next visible position. */
10015 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10016 NULL, DEFAULT_FACE_ID);
10017 it.current_x = this_line_start_x;
10018 it.current_y = this_line_y;
10019 it.vpos = this_line_vpos;
10021 /* The call to move_it_to stops in front of PT, but
10022 moves over before-strings. */
10023 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10025 if (it.vpos == this_line_vpos
10026 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10027 row->enabled_p))
10029 xassert (this_line_vpos == it.vpos);
10030 xassert (this_line_y == it.current_y);
10031 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10032 #if GLYPH_DEBUG
10033 *w->desired_matrix->method = 0;
10034 debug_method_add (w, "optimization 3");
10035 #endif
10036 goto update;
10038 else
10039 goto cancel;
10042 cancel:
10043 /* Text changed drastically or point moved off of line. */
10044 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10047 CHARPOS (this_line_start_pos) = 0;
10048 consider_all_windows_p |= buffer_shared > 1;
10049 ++clear_face_cache_count;
10052 /* Build desired matrices, and update the display. If
10053 consider_all_windows_p is non-zero, do it for all windows on all
10054 frames. Otherwise do it for selected_window, only. */
10056 if (consider_all_windows_p)
10058 Lisp_Object tail, frame;
10059 int i, n = 0, size = 50;
10060 struct frame **updated
10061 = (struct frame **) alloca (size * sizeof *updated);
10063 /* Clear the face cache eventually. */
10064 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10066 clear_face_cache (0);
10067 clear_face_cache_count = 0;
10070 /* Recompute # windows showing selected buffer. This will be
10071 incremented each time such a window is displayed. */
10072 buffer_shared = 0;
10074 FOR_EACH_FRAME (tail, frame)
10076 struct frame *f = XFRAME (frame);
10078 if (FRAME_WINDOW_P (f) || f == sf)
10080 if (! EQ (frame, selected_frame))
10081 /* Select the frame, for the sake of frame-local
10082 variables. */
10083 select_frame_for_redisplay (frame);
10085 #ifdef HAVE_WINDOW_SYSTEM
10086 if (clear_face_cache_count % 50 == 0
10087 && FRAME_WINDOW_P (f))
10088 clear_image_cache (f, 0);
10089 #endif /* HAVE_WINDOW_SYSTEM */
10091 /* Mark all the scroll bars to be removed; we'll redeem
10092 the ones we want when we redisplay their windows. */
10093 if (condemn_scroll_bars_hook)
10094 condemn_scroll_bars_hook (f);
10096 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10097 redisplay_windows (FRAME_ROOT_WINDOW (f));
10099 /* Any scroll bars which redisplay_windows should have
10100 nuked should now go away. */
10101 if (judge_scroll_bars_hook)
10102 judge_scroll_bars_hook (f);
10104 /* If fonts changed, display again. */
10105 /* ??? rms: I suspect it is a mistake to jump all the way
10106 back to retry here. It should just retry this frame. */
10107 if (fonts_changed_p)
10108 goto retry;
10110 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10112 /* See if we have to hscroll. */
10113 if (hscroll_windows (f->root_window))
10114 goto retry;
10116 /* Prevent various kinds of signals during display
10117 update. stdio is not robust about handling
10118 signals, which can cause an apparent I/O
10119 error. */
10120 if (interrupt_input)
10121 unrequest_sigio ();
10122 STOP_POLLING;
10124 /* Update the display. */
10125 set_window_update_flags (XWINDOW (f->root_window), 1);
10126 pause |= update_frame (f, 0, 0);
10127 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10128 if (pause)
10129 break;
10130 #endif
10132 if (n == size)
10134 int nbytes = size * sizeof *updated;
10135 struct frame **p = (struct frame **) alloca (2 * nbytes);
10136 bcopy (updated, p, nbytes);
10137 size *= 2;
10140 updated[n++] = f;
10145 if (!pause)
10147 /* Do the mark_window_display_accurate after all windows have
10148 been redisplayed because this call resets flags in buffers
10149 which are needed for proper redisplay. */
10150 for (i = 0; i < n; ++i)
10152 struct frame *f = updated[i];
10153 mark_window_display_accurate (f->root_window, 1);
10154 if (frame_up_to_date_hook)
10155 frame_up_to_date_hook (f);
10159 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10161 Lisp_Object mini_window;
10162 struct frame *mini_frame;
10164 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10165 /* Use list_of_error, not Qerror, so that
10166 we catch only errors and don't run the debugger. */
10167 internal_condition_case_1 (redisplay_window_1, selected_window,
10168 list_of_error,
10169 redisplay_window_error);
10171 /* Compare desired and current matrices, perform output. */
10173 update:
10174 /* If fonts changed, display again. */
10175 if (fonts_changed_p)
10176 goto retry;
10178 /* Prevent various kinds of signals during display update.
10179 stdio is not robust about handling signals,
10180 which can cause an apparent I/O error. */
10181 if (interrupt_input)
10182 unrequest_sigio ();
10183 STOP_POLLING;
10185 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10187 if (hscroll_windows (selected_window))
10188 goto retry;
10190 XWINDOW (selected_window)->must_be_updated_p = 1;
10191 pause = update_frame (sf, 0, 0);
10194 /* We may have called echo_area_display at the top of this
10195 function. If the echo area is on another frame, that may
10196 have put text on a frame other than the selected one, so the
10197 above call to update_frame would not have caught it. Catch
10198 it here. */
10199 mini_window = FRAME_MINIBUF_WINDOW (sf);
10200 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10202 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10204 XWINDOW (mini_window)->must_be_updated_p = 1;
10205 pause |= update_frame (mini_frame, 0, 0);
10206 if (!pause && hscroll_windows (mini_window))
10207 goto retry;
10211 /* If display was paused because of pending input, make sure we do a
10212 thorough update the next time. */
10213 if (pause)
10215 /* Prevent the optimization at the beginning of
10216 redisplay_internal that tries a single-line update of the
10217 line containing the cursor in the selected window. */
10218 CHARPOS (this_line_start_pos) = 0;
10220 /* Let the overlay arrow be updated the next time. */
10221 if (!NILP (last_arrow_position))
10223 last_arrow_position = Qt;
10224 last_arrow_string = Qt;
10227 /* If we pause after scrolling, some rows in the current
10228 matrices of some windows are not valid. */
10229 if (!WINDOW_FULL_WIDTH_P (w)
10230 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10231 update_mode_lines = 1;
10233 else
10235 if (!consider_all_windows_p)
10237 /* This has already been done above if
10238 consider_all_windows_p is set. */
10239 mark_window_display_accurate_1 (w, 1);
10241 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10242 last_arrow_string = Voverlay_arrow_string;
10244 if (frame_up_to_date_hook != 0)
10245 frame_up_to_date_hook (sf);
10248 update_mode_lines = 0;
10249 windows_or_buffers_changed = 0;
10250 cursor_type_changed = 0;
10253 /* Start SIGIO interrupts coming again. Having them off during the
10254 code above makes it less likely one will discard output, but not
10255 impossible, since there might be stuff in the system buffer here.
10256 But it is much hairier to try to do anything about that. */
10257 if (interrupt_input)
10258 request_sigio ();
10259 RESUME_POLLING;
10261 /* If a frame has become visible which was not before, redisplay
10262 again, so that we display it. Expose events for such a frame
10263 (which it gets when becoming visible) don't call the parts of
10264 redisplay constructing glyphs, so simply exposing a frame won't
10265 display anything in this case. So, we have to display these
10266 frames here explicitly. */
10267 if (!pause)
10269 Lisp_Object tail, frame;
10270 int new_count = 0;
10272 FOR_EACH_FRAME (tail, frame)
10274 int this_is_visible = 0;
10276 if (XFRAME (frame)->visible)
10277 this_is_visible = 1;
10278 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10279 if (XFRAME (frame)->visible)
10280 this_is_visible = 1;
10282 if (this_is_visible)
10283 new_count++;
10286 if (new_count != number_of_visible_frames)
10287 windows_or_buffers_changed++;
10290 /* Change frame size now if a change is pending. */
10291 do_pending_window_change (1);
10293 /* If we just did a pending size change, or have additional
10294 visible frames, redisplay again. */
10295 if (windows_or_buffers_changed && !pause)
10296 goto retry;
10298 end_of_redisplay:
10299 unbind_to (count, Qnil);
10300 RESUME_POLLING;
10304 /* Redisplay, but leave alone any recent echo area message unless
10305 another message has been requested in its place.
10307 This is useful in situations where you need to redisplay but no
10308 user action has occurred, making it inappropriate for the message
10309 area to be cleared. See tracking_off and
10310 wait_reading_process_input for examples of these situations.
10312 FROM_WHERE is an integer saying from where this function was
10313 called. This is useful for debugging. */
10315 void
10316 redisplay_preserve_echo_area (from_where)
10317 int from_where;
10319 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10321 if (!NILP (echo_area_buffer[1]))
10323 /* We have a previously displayed message, but no current
10324 message. Redisplay the previous message. */
10325 display_last_displayed_message_p = 1;
10326 redisplay_internal (1);
10327 display_last_displayed_message_p = 0;
10329 else
10330 redisplay_internal (1);
10334 /* Function registered with record_unwind_protect in
10335 redisplay_internal. Reset redisplaying_p to the value it had
10336 before redisplay_internal was called, and clear
10337 prevent_freeing_realized_faces_p. It also selects the previously
10338 selected frame. */
10340 static Lisp_Object
10341 unwind_redisplay (val)
10342 Lisp_Object val;
10344 Lisp_Object old_redisplaying_p, old_frame;
10346 old_redisplaying_p = XCAR (val);
10347 redisplaying_p = XFASTINT (old_redisplaying_p);
10348 old_frame = XCDR (val);
10349 if (! EQ (old_frame, selected_frame))
10350 select_frame_for_redisplay (old_frame);
10351 return Qnil;
10355 /* Mark the display of window W as accurate or inaccurate. If
10356 ACCURATE_P is non-zero mark display of W as accurate. If
10357 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10358 redisplay_internal is called. */
10360 static void
10361 mark_window_display_accurate_1 (w, accurate_p)
10362 struct window *w;
10363 int accurate_p;
10365 if (BUFFERP (w->buffer))
10367 struct buffer *b = XBUFFER (w->buffer);
10369 w->last_modified
10370 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10371 w->last_overlay_modified
10372 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10373 w->last_had_star
10374 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10376 if (accurate_p)
10378 b->clip_changed = 0;
10379 b->prevent_redisplay_optimizations_p = 0;
10381 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10382 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10383 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10384 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10386 w->current_matrix->buffer = b;
10387 w->current_matrix->begv = BUF_BEGV (b);
10388 w->current_matrix->zv = BUF_ZV (b);
10390 w->last_cursor = w->cursor;
10391 w->last_cursor_off_p = w->cursor_off_p;
10393 if (w == XWINDOW (selected_window))
10394 w->last_point = make_number (BUF_PT (b));
10395 else
10396 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10400 if (accurate_p)
10402 w->window_end_valid = w->buffer;
10403 #if 0 /* This is incorrect with variable-height lines. */
10404 xassert (XINT (w->window_end_vpos)
10405 < (WINDOW_TOTAL_LINES (w)
10406 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10407 #endif
10408 w->update_mode_line = Qnil;
10413 /* Mark the display of windows in the window tree rooted at WINDOW as
10414 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10415 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10416 be redisplayed the next time redisplay_internal is called. */
10418 void
10419 mark_window_display_accurate (window, accurate_p)
10420 Lisp_Object window;
10421 int accurate_p;
10423 struct window *w;
10425 for (; !NILP (window); window = w->next)
10427 w = XWINDOW (window);
10428 mark_window_display_accurate_1 (w, accurate_p);
10430 if (!NILP (w->vchild))
10431 mark_window_display_accurate (w->vchild, accurate_p);
10432 if (!NILP (w->hchild))
10433 mark_window_display_accurate (w->hchild, accurate_p);
10436 if (accurate_p)
10438 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10439 last_arrow_string = Voverlay_arrow_string;
10441 else
10443 /* Force a thorough redisplay the next time by setting
10444 last_arrow_position and last_arrow_string to t, which is
10445 unequal to any useful value of Voverlay_arrow_... */
10446 last_arrow_position = Qt;
10447 last_arrow_string = Qt;
10452 /* Return value in display table DP (Lisp_Char_Table *) for character
10453 C. Since a display table doesn't have any parent, we don't have to
10454 follow parent. Do not call this function directly but use the
10455 macro DISP_CHAR_VECTOR. */
10457 Lisp_Object
10458 disp_char_vector (dp, c)
10459 struct Lisp_Char_Table *dp;
10460 int c;
10462 int code[4], i;
10463 Lisp_Object val;
10465 if (SINGLE_BYTE_CHAR_P (c))
10466 return (dp->contents[c]);
10468 SPLIT_CHAR (c, code[0], code[1], code[2]);
10469 if (code[1] < 32)
10470 code[1] = -1;
10471 else if (code[2] < 32)
10472 code[2] = -1;
10474 /* Here, the possible range of code[0] (== charset ID) is
10475 128..max_charset. Since the top level char table contains data
10476 for multibyte characters after 256th element, we must increment
10477 code[0] by 128 to get a correct index. */
10478 code[0] += 128;
10479 code[3] = -1; /* anchor */
10481 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10483 val = dp->contents[code[i]];
10484 if (!SUB_CHAR_TABLE_P (val))
10485 return (NILP (val) ? dp->defalt : val);
10488 /* Here, val is a sub char table. We return the default value of
10489 it. */
10490 return (dp->defalt);
10495 /***********************************************************************
10496 Window Redisplay
10497 ***********************************************************************/
10499 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10501 static void
10502 redisplay_windows (window)
10503 Lisp_Object window;
10505 while (!NILP (window))
10507 struct window *w = XWINDOW (window);
10509 if (!NILP (w->hchild))
10510 redisplay_windows (w->hchild);
10511 else if (!NILP (w->vchild))
10512 redisplay_windows (w->vchild);
10513 else
10515 displayed_buffer = XBUFFER (w->buffer);
10516 /* Use list_of_error, not Qerror, so that
10517 we catch only errors and don't run the debugger. */
10518 internal_condition_case_1 (redisplay_window_0, window,
10519 list_of_error,
10520 redisplay_window_error);
10523 window = w->next;
10527 static Lisp_Object
10528 redisplay_window_error ()
10530 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10531 return Qnil;
10534 static Lisp_Object
10535 redisplay_window_0 (window)
10536 Lisp_Object window;
10538 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10539 redisplay_window (window, 0);
10540 return Qnil;
10543 static Lisp_Object
10544 redisplay_window_1 (window)
10545 Lisp_Object window;
10547 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10548 redisplay_window (window, 1);
10549 return Qnil;
10553 /* Increment GLYPH until it reaches END or CONDITION fails while
10554 adding (GLYPH)->pixel_width to X. */
10556 #define SKIP_GLYPHS(glyph, end, x, condition) \
10557 do \
10559 (x) += (glyph)->pixel_width; \
10560 ++(glyph); \
10562 while ((glyph) < (end) && (condition))
10565 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10566 DELTA is the number of bytes by which positions recorded in ROW
10567 differ from current buffer positions. */
10569 void
10570 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10571 struct window *w;
10572 struct glyph_row *row;
10573 struct glyph_matrix *matrix;
10574 int delta, delta_bytes, dy, dvpos;
10576 struct glyph *glyph = row->glyphs[TEXT_AREA];
10577 struct glyph *end = glyph + row->used[TEXT_AREA];
10578 /* The first glyph that starts a sequence of glyphs from string. */
10579 struct glyph *string_start;
10580 /* The X coordinate of string_start. */
10581 int string_start_x;
10582 /* The last known character position. */
10583 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10584 /* The last known character position before string_start. */
10585 int string_before_pos;
10586 int x = row->x;
10587 int pt_old = PT - delta;
10589 /* Skip over glyphs not having an object at the start of the row.
10590 These are special glyphs like truncation marks on terminal
10591 frames. */
10592 if (row->displays_text_p)
10593 while (glyph < end
10594 && INTEGERP (glyph->object)
10595 && glyph->charpos < 0)
10597 x += glyph->pixel_width;
10598 ++glyph;
10601 string_start = NULL;
10602 while (glyph < end
10603 && !INTEGERP (glyph->object)
10604 && (!BUFFERP (glyph->object)
10605 || (last_pos = glyph->charpos) < pt_old))
10607 if (! STRINGP (glyph->object))
10609 string_start = NULL;
10610 x += glyph->pixel_width;
10611 ++glyph;
10613 else
10615 string_before_pos = last_pos;
10616 string_start = glyph;
10617 string_start_x = x;
10618 /* Skip all glyphs from string. */
10619 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10623 if (string_start
10624 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10626 /* We may have skipped over point because the previous glyphs
10627 are from string. As there's no easy way to know the
10628 character position of the current glyph, find the correct
10629 glyph on point by scanning from string_start again. */
10630 Lisp_Object limit;
10631 Lisp_Object string;
10632 int pos;
10634 limit = make_number (pt_old + 1);
10635 end = glyph;
10636 glyph = string_start;
10637 x = string_start_x;
10638 string = glyph->object;
10639 pos = string_buffer_position (w, string, string_before_pos);
10640 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10641 because we always put cursor after overlay strings. */
10642 while (pos == 0 && glyph < end)
10644 string = glyph->object;
10645 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10646 if (glyph < end)
10647 pos = string_buffer_position (w, glyph->object, string_before_pos);
10650 while (glyph < end)
10652 pos = XINT (Fnext_single_char_property_change
10653 (make_number (pos), Qdisplay, Qnil, limit));
10654 if (pos > pt_old)
10655 break;
10656 /* Skip glyphs from the same string. */
10657 string = glyph->object;
10658 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10659 /* Skip glyphs from an overlay. */
10660 while (glyph < end
10661 && ! string_buffer_position (w, glyph->object, pos))
10663 string = glyph->object;
10664 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10669 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10670 w->cursor.x = x;
10671 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10672 w->cursor.y = row->y + dy;
10674 if (w == XWINDOW (selected_window))
10676 if (!row->continued_p
10677 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10678 && row->x == 0)
10680 this_line_buffer = XBUFFER (w->buffer);
10682 CHARPOS (this_line_start_pos)
10683 = MATRIX_ROW_START_CHARPOS (row) + delta;
10684 BYTEPOS (this_line_start_pos)
10685 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10687 CHARPOS (this_line_end_pos)
10688 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10689 BYTEPOS (this_line_end_pos)
10690 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10692 this_line_y = w->cursor.y;
10693 this_line_pixel_height = row->height;
10694 this_line_vpos = w->cursor.vpos;
10695 this_line_start_x = row->x;
10697 else
10698 CHARPOS (this_line_start_pos) = 0;
10703 /* Run window scroll functions, if any, for WINDOW with new window
10704 start STARTP. Sets the window start of WINDOW to that position.
10706 We assume that the window's buffer is really current. */
10708 static INLINE struct text_pos
10709 run_window_scroll_functions (window, startp)
10710 Lisp_Object window;
10711 struct text_pos startp;
10713 struct window *w = XWINDOW (window);
10714 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10716 if (current_buffer != XBUFFER (w->buffer))
10717 abort ();
10719 if (!NILP (Vwindow_scroll_functions))
10721 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10722 make_number (CHARPOS (startp)));
10723 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10724 /* In case the hook functions switch buffers. */
10725 if (current_buffer != XBUFFER (w->buffer))
10726 set_buffer_internal_1 (XBUFFER (w->buffer));
10729 return startp;
10733 /* Make sure the line containing the cursor is fully visible.
10734 A value of 1 means there is nothing to be done.
10735 (Either the line is fully visible, or it cannot be made so,
10736 or we cannot tell.)
10737 A value of 0 means the caller should do scrolling
10738 as if point had gone off the screen. */
10740 static int
10741 make_cursor_line_fully_visible (w)
10742 struct window *w;
10744 struct glyph_matrix *matrix;
10745 struct glyph_row *row;
10746 int window_height;
10748 /* It's not always possible to find the cursor, e.g, when a window
10749 is full of overlay strings. Don't do anything in that case. */
10750 if (w->cursor.vpos < 0)
10751 return 1;
10753 matrix = w->desired_matrix;
10754 row = MATRIX_ROW (matrix, w->cursor.vpos);
10756 /* If the cursor row is not partially visible, there's nothing to do. */
10757 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10758 return 1;
10760 /* If the row the cursor is in is taller than the window's height,
10761 it's not clear what to do, so do nothing. */
10762 window_height = window_box_height (w);
10763 if (row->height >= window_height)
10764 return 1;
10766 return 0;
10768 #if 0
10769 /* This code used to try to scroll the window just enough to make
10770 the line visible. It returned 0 to say that the caller should
10771 allocate larger glyph matrices. */
10773 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10775 int dy = row->height - row->visible_height;
10776 w->vscroll = 0;
10777 w->cursor.y += dy;
10778 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10780 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10782 int dy = - (row->height - row->visible_height);
10783 w->vscroll = dy;
10784 w->cursor.y += dy;
10785 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10788 /* When we change the cursor y-position of the selected window,
10789 change this_line_y as well so that the display optimization for
10790 the cursor line of the selected window in redisplay_internal uses
10791 the correct y-position. */
10792 if (w == XWINDOW (selected_window))
10793 this_line_y = w->cursor.y;
10795 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10796 redisplay with larger matrices. */
10797 if (matrix->nrows < required_matrix_height (w))
10799 fonts_changed_p = 1;
10800 return 0;
10803 return 1;
10804 #endif /* 0 */
10808 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10809 non-zero means only WINDOW is redisplayed in redisplay_internal.
10810 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10811 in redisplay_window to bring a partially visible line into view in
10812 the case that only the cursor has moved.
10814 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10815 last screen line's vertical height extends past the end of the screen.
10817 Value is
10819 1 if scrolling succeeded
10821 0 if scrolling didn't find point.
10823 -1 if new fonts have been loaded so that we must interrupt
10824 redisplay, adjust glyph matrices, and try again. */
10826 enum
10828 SCROLLING_SUCCESS,
10829 SCROLLING_FAILED,
10830 SCROLLING_NEED_LARGER_MATRICES
10833 static int
10834 try_scrolling (window, just_this_one_p, scroll_conservatively,
10835 scroll_step, temp_scroll_step, last_line_misfit)
10836 Lisp_Object window;
10837 int just_this_one_p;
10838 EMACS_INT scroll_conservatively, scroll_step;
10839 int temp_scroll_step;
10840 int last_line_misfit;
10842 struct window *w = XWINDOW (window);
10843 struct frame *f = XFRAME (w->frame);
10844 struct text_pos scroll_margin_pos;
10845 struct text_pos pos;
10846 struct text_pos startp;
10847 struct it it;
10848 Lisp_Object window_end;
10849 int this_scroll_margin;
10850 int dy = 0;
10851 int scroll_max;
10852 int rc;
10853 int amount_to_scroll = 0;
10854 Lisp_Object aggressive;
10855 int height;
10856 int end_scroll_margin;
10858 #if GLYPH_DEBUG
10859 debug_method_add (w, "try_scrolling");
10860 #endif
10862 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10864 /* Compute scroll margin height in pixels. We scroll when point is
10865 within this distance from the top or bottom of the window. */
10866 if (scroll_margin > 0)
10868 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10869 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10871 else
10872 this_scroll_margin = 0;
10874 /* Compute how much we should try to scroll maximally to bring point
10875 into view. */
10876 if (scroll_step || scroll_conservatively || temp_scroll_step)
10877 scroll_max = max (scroll_step,
10878 max (scroll_conservatively, temp_scroll_step));
10879 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10880 || NUMBERP (current_buffer->scroll_up_aggressively))
10881 /* We're trying to scroll because of aggressive scrolling
10882 but no scroll_step is set. Choose an arbitrary one. Maybe
10883 there should be a variable for this. */
10884 scroll_max = 10;
10885 else
10886 scroll_max = 0;
10887 scroll_max *= FRAME_LINE_HEIGHT (f);
10889 /* Decide whether we have to scroll down. Start at the window end
10890 and move this_scroll_margin up to find the position of the scroll
10891 margin. */
10892 window_end = Fwindow_end (window, Qt);
10894 too_near_end:
10896 CHARPOS (scroll_margin_pos) = XINT (window_end);
10897 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10899 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10900 if (end_scroll_margin)
10902 start_display (&it, w, scroll_margin_pos);
10903 move_it_vertically (&it, - end_scroll_margin);
10904 scroll_margin_pos = it.current.pos;
10907 if (PT >= CHARPOS (scroll_margin_pos))
10909 int y0;
10911 /* Point is in the scroll margin at the bottom of the window, or
10912 below. Compute a new window start that makes point visible. */
10914 /* Compute the distance from the scroll margin to PT.
10915 Give up if the distance is greater than scroll_max. */
10916 start_display (&it, w, scroll_margin_pos);
10917 y0 = it.current_y;
10918 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10919 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10921 /* To make point visible, we have to move the window start
10922 down so that the line the cursor is in is visible, which
10923 means we have to add in the height of the cursor line. */
10924 dy = line_bottom_y (&it) - y0;
10926 if (dy > scroll_max)
10927 return SCROLLING_FAILED;
10929 /* Move the window start down. If scrolling conservatively,
10930 move it just enough down to make point visible. If
10931 scroll_step is set, move it down by scroll_step. */
10932 start_display (&it, w, startp);
10934 if (scroll_conservatively)
10935 /* Set AMOUNT_TO_SCROLL to at least one line,
10936 and at most scroll_conservatively lines. */
10937 amount_to_scroll
10938 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10939 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10940 else if (scroll_step || temp_scroll_step)
10941 amount_to_scroll = scroll_max;
10942 else
10944 aggressive = current_buffer->scroll_up_aggressively;
10945 height = WINDOW_BOX_TEXT_HEIGHT (w);
10946 if (NUMBERP (aggressive))
10947 amount_to_scroll = XFLOATINT (aggressive) * height;
10950 if (amount_to_scroll <= 0)
10951 return SCROLLING_FAILED;
10953 /* If moving by amount_to_scroll leaves STARTP unchanged,
10954 move it down one screen line. */
10956 move_it_vertically (&it, amount_to_scroll);
10957 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10958 move_it_by_lines (&it, 1, 1);
10959 startp = it.current.pos;
10961 else
10963 /* See if point is inside the scroll margin at the top of the
10964 window. */
10965 scroll_margin_pos = startp;
10966 if (this_scroll_margin)
10968 start_display (&it, w, startp);
10969 move_it_vertically (&it, this_scroll_margin);
10970 scroll_margin_pos = it.current.pos;
10973 if (PT < CHARPOS (scroll_margin_pos))
10975 /* Point is in the scroll margin at the top of the window or
10976 above what is displayed in the window. */
10977 int y0;
10979 /* Compute the vertical distance from PT to the scroll
10980 margin position. Give up if distance is greater than
10981 scroll_max. */
10982 SET_TEXT_POS (pos, PT, PT_BYTE);
10983 start_display (&it, w, pos);
10984 y0 = it.current_y;
10985 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10986 it.last_visible_y, -1,
10987 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10988 dy = it.current_y - y0;
10989 if (dy > scroll_max)
10990 return SCROLLING_FAILED;
10992 /* Compute new window start. */
10993 start_display (&it, w, startp);
10995 if (scroll_conservatively)
10996 amount_to_scroll =
10997 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
10998 else if (scroll_step || temp_scroll_step)
10999 amount_to_scroll = scroll_max;
11000 else
11002 aggressive = current_buffer->scroll_down_aggressively;
11003 height = WINDOW_BOX_TEXT_HEIGHT (w);
11004 if (NUMBERP (aggressive))
11005 amount_to_scroll = XFLOATINT (aggressive) * height;
11008 if (amount_to_scroll <= 0)
11009 return SCROLLING_FAILED;
11011 move_it_vertically (&it, - amount_to_scroll);
11012 startp = it.current.pos;
11016 /* Run window scroll functions. */
11017 startp = run_window_scroll_functions (window, startp);
11019 /* Display the window. Give up if new fonts are loaded, or if point
11020 doesn't appear. */
11021 if (!try_window (window, startp))
11022 rc = SCROLLING_NEED_LARGER_MATRICES;
11023 else if (w->cursor.vpos < 0)
11025 clear_glyph_matrix (w->desired_matrix);
11026 rc = SCROLLING_FAILED;
11028 else
11030 /* Maybe forget recorded base line for line number display. */
11031 if (!just_this_one_p
11032 || current_buffer->clip_changed
11033 || BEG_UNCHANGED < CHARPOS (startp))
11034 w->base_line_number = Qnil;
11036 /* If cursor ends up on a partially visible line,
11037 treat that as being off the bottom of the screen. */
11038 if (! make_cursor_line_fully_visible (w))
11040 clear_glyph_matrix (w->desired_matrix);
11041 last_line_misfit = 1;
11042 goto too_near_end;
11044 rc = SCROLLING_SUCCESS;
11047 return rc;
11051 /* Compute a suitable window start for window W if display of W starts
11052 on a continuation line. Value is non-zero if a new window start
11053 was computed.
11055 The new window start will be computed, based on W's width, starting
11056 from the start of the continued line. It is the start of the
11057 screen line with the minimum distance from the old start W->start. */
11059 static int
11060 compute_window_start_on_continuation_line (w)
11061 struct window *w;
11063 struct text_pos pos, start_pos;
11064 int window_start_changed_p = 0;
11066 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11068 /* If window start is on a continuation line... Window start may be
11069 < BEGV in case there's invisible text at the start of the
11070 buffer (M-x rmail, for example). */
11071 if (CHARPOS (start_pos) > BEGV
11072 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11074 struct it it;
11075 struct glyph_row *row;
11077 /* Handle the case that the window start is out of range. */
11078 if (CHARPOS (start_pos) < BEGV)
11079 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11080 else if (CHARPOS (start_pos) > ZV)
11081 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11083 /* Find the start of the continued line. This should be fast
11084 because scan_buffer is fast (newline cache). */
11085 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11086 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11087 row, DEFAULT_FACE_ID);
11088 reseat_at_previous_visible_line_start (&it);
11090 /* If the line start is "too far" away from the window start,
11091 say it takes too much time to compute a new window start. */
11092 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11093 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11095 int min_distance, distance;
11097 /* Move forward by display lines to find the new window
11098 start. If window width was enlarged, the new start can
11099 be expected to be > the old start. If window width was
11100 decreased, the new window start will be < the old start.
11101 So, we're looking for the display line start with the
11102 minimum distance from the old window start. */
11103 pos = it.current.pos;
11104 min_distance = INFINITY;
11105 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11106 distance < min_distance)
11108 min_distance = distance;
11109 pos = it.current.pos;
11110 move_it_by_lines (&it, 1, 0);
11113 /* Set the window start there. */
11114 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11115 window_start_changed_p = 1;
11119 return window_start_changed_p;
11123 /* Try cursor movement in case text has not changed in window WINDOW,
11124 with window start STARTP. Value is
11126 CURSOR_MOVEMENT_SUCCESS if successful
11128 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11130 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11131 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11132 we want to scroll as if scroll-step were set to 1. See the code.
11134 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11135 which case we have to abort this redisplay, and adjust matrices
11136 first. */
11138 enum
11140 CURSOR_MOVEMENT_SUCCESS,
11141 CURSOR_MOVEMENT_CANNOT_BE_USED,
11142 CURSOR_MOVEMENT_MUST_SCROLL,
11143 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11146 static int
11147 try_cursor_movement (window, startp, scroll_step)
11148 Lisp_Object window;
11149 struct text_pos startp;
11150 int *scroll_step;
11152 struct window *w = XWINDOW (window);
11153 struct frame *f = XFRAME (w->frame);
11154 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11156 #if GLYPH_DEBUG
11157 if (inhibit_try_cursor_movement)
11158 return rc;
11159 #endif
11161 /* Handle case where text has not changed, only point, and it has
11162 not moved off the frame. */
11163 if (/* Point may be in this window. */
11164 PT >= CHARPOS (startp)
11165 /* Selective display hasn't changed. */
11166 && !current_buffer->clip_changed
11167 /* Function force-mode-line-update is used to force a thorough
11168 redisplay. It sets either windows_or_buffers_changed or
11169 update_mode_lines. So don't take a shortcut here for these
11170 cases. */
11171 && !update_mode_lines
11172 && !windows_or_buffers_changed
11173 && !cursor_type_changed
11174 /* Can't use this case if highlighting a region. When a
11175 region exists, cursor movement has to do more than just
11176 set the cursor. */
11177 && !(!NILP (Vtransient_mark_mode)
11178 && !NILP (current_buffer->mark_active))
11179 && NILP (w->region_showing)
11180 && NILP (Vshow_trailing_whitespace)
11181 /* Right after splitting windows, last_point may be nil. */
11182 && INTEGERP (w->last_point)
11183 /* This code is not used for mini-buffer for the sake of the case
11184 of redisplaying to replace an echo area message; since in
11185 that case the mini-buffer contents per se are usually
11186 unchanged. This code is of no real use in the mini-buffer
11187 since the handling of this_line_start_pos, etc., in redisplay
11188 handles the same cases. */
11189 && !EQ (window, minibuf_window)
11190 /* When splitting windows or for new windows, it happens that
11191 redisplay is called with a nil window_end_vpos or one being
11192 larger than the window. This should really be fixed in
11193 window.c. I don't have this on my list, now, so we do
11194 approximately the same as the old redisplay code. --gerd. */
11195 && INTEGERP (w->window_end_vpos)
11196 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11197 && (FRAME_WINDOW_P (f)
11198 || !MARKERP (Voverlay_arrow_position)
11199 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11201 int this_scroll_margin;
11202 struct glyph_row *row = NULL;
11204 #if GLYPH_DEBUG
11205 debug_method_add (w, "cursor movement");
11206 #endif
11208 /* Scroll if point within this distance from the top or bottom
11209 of the window. This is a pixel value. */
11210 this_scroll_margin = max (0, scroll_margin);
11211 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11212 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11214 /* Start with the row the cursor was displayed during the last
11215 not paused redisplay. Give up if that row is not valid. */
11216 if (w->last_cursor.vpos < 0
11217 || w->last_cursor.vpos >= w->current_matrix->nrows)
11218 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11219 else
11221 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11222 if (row->mode_line_p)
11223 ++row;
11224 if (!row->enabled_p)
11225 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11228 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11230 int scroll_p = 0;
11231 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11233 if (PT > XFASTINT (w->last_point))
11235 /* Point has moved forward. */
11236 while (MATRIX_ROW_END_CHARPOS (row) < PT
11237 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11239 xassert (row->enabled_p);
11240 ++row;
11243 /* The end position of a row equals the start position
11244 of the next row. If PT is there, we would rather
11245 display it in the next line. */
11246 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11247 && MATRIX_ROW_END_CHARPOS (row) == PT
11248 && !cursor_row_p (w, row))
11249 ++row;
11251 /* If within the scroll margin, scroll. Note that
11252 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11253 the next line would be drawn, and that
11254 this_scroll_margin can be zero. */
11255 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11256 || PT > MATRIX_ROW_END_CHARPOS (row)
11257 /* Line is completely visible last line in window
11258 and PT is to be set in the next line. */
11259 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11260 && PT == MATRIX_ROW_END_CHARPOS (row)
11261 && !row->ends_at_zv_p
11262 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11263 scroll_p = 1;
11265 else if (PT < XFASTINT (w->last_point))
11267 /* Cursor has to be moved backward. Note that PT >=
11268 CHARPOS (startp) because of the outer
11269 if-statement. */
11270 while (!row->mode_line_p
11271 && (MATRIX_ROW_START_CHARPOS (row) > PT
11272 || (MATRIX_ROW_START_CHARPOS (row) == PT
11273 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11274 && (row->y > this_scroll_margin
11275 || CHARPOS (startp) == BEGV))
11277 xassert (row->enabled_p);
11278 --row;
11281 /* Consider the following case: Window starts at BEGV,
11282 there is invisible, intangible text at BEGV, so that
11283 display starts at some point START > BEGV. It can
11284 happen that we are called with PT somewhere between
11285 BEGV and START. Try to handle that case. */
11286 if (row < w->current_matrix->rows
11287 || row->mode_line_p)
11289 row = w->current_matrix->rows;
11290 if (row->mode_line_p)
11291 ++row;
11294 /* Due to newlines in overlay strings, we may have to
11295 skip forward over overlay strings. */
11296 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11297 && MATRIX_ROW_END_CHARPOS (row) == PT
11298 && !cursor_row_p (w, row))
11299 ++row;
11301 /* If within the scroll margin, scroll. */
11302 if (row->y < this_scroll_margin
11303 && CHARPOS (startp) != BEGV)
11304 scroll_p = 1;
11307 if (PT < MATRIX_ROW_START_CHARPOS (row)
11308 || PT > MATRIX_ROW_END_CHARPOS (row))
11310 /* if PT is not in the glyph row, give up. */
11311 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11313 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11315 if (PT == MATRIX_ROW_END_CHARPOS (row)
11316 && !row->ends_at_zv_p
11317 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11318 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11319 else if (row->height > window_box_height (w))
11321 /* If we end up in a partially visible line, let's
11322 make it fully visible, except when it's taller
11323 than the window, in which case we can't do much
11324 about it. */
11325 *scroll_step = 1;
11326 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11328 else
11330 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11331 if (!make_cursor_line_fully_visible (w))
11332 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11333 else
11334 rc = CURSOR_MOVEMENT_SUCCESS;
11337 else if (scroll_p)
11338 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11339 else
11341 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11342 rc = CURSOR_MOVEMENT_SUCCESS;
11347 return rc;
11350 void
11351 set_vertical_scroll_bar (w)
11352 struct window *w;
11354 int start, end, whole;
11356 /* Calculate the start and end positions for the current window.
11357 At some point, it would be nice to choose between scrollbars
11358 which reflect the whole buffer size, with special markers
11359 indicating narrowing, and scrollbars which reflect only the
11360 visible region.
11362 Note that mini-buffers sometimes aren't displaying any text. */
11363 if (!MINI_WINDOW_P (w)
11364 || (w == XWINDOW (minibuf_window)
11365 && NILP (echo_area_buffer[0])))
11367 struct buffer *buf = XBUFFER (w->buffer);
11368 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11369 start = marker_position (w->start) - BUF_BEGV (buf);
11370 /* I don't think this is guaranteed to be right. For the
11371 moment, we'll pretend it is. */
11372 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11374 if (end < start)
11375 end = start;
11376 if (whole < (end - start))
11377 whole = end - start;
11379 else
11380 start = end = whole = 0;
11382 /* Indicate what this scroll bar ought to be displaying now. */
11383 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11386 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11387 selected_window is redisplayed.
11389 We can return without actually redisplaying the window if
11390 fonts_changed_p is nonzero. In that case, redisplay_internal will
11391 retry. */
11393 static void
11394 redisplay_window (window, just_this_one_p)
11395 Lisp_Object window;
11396 int just_this_one_p;
11398 struct window *w = XWINDOW (window);
11399 struct frame *f = XFRAME (w->frame);
11400 struct buffer *buffer = XBUFFER (w->buffer);
11401 struct buffer *old = current_buffer;
11402 struct text_pos lpoint, opoint, startp;
11403 int update_mode_line;
11404 int tem;
11405 struct it it;
11406 /* Record it now because it's overwritten. */
11407 int current_matrix_up_to_date_p = 0;
11408 /* This is less strict than current_matrix_up_to_date_p.
11409 It indictes that the buffer contents and narrowing are unchanged. */
11410 int buffer_unchanged_p = 0;
11411 int temp_scroll_step = 0;
11412 int count = SPECPDL_INDEX ();
11413 int rc;
11414 int centering_position;
11415 int last_line_misfit = 0;
11417 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11418 opoint = lpoint;
11420 /* W must be a leaf window here. */
11421 xassert (!NILP (w->buffer));
11422 #if GLYPH_DEBUG
11423 *w->desired_matrix->method = 0;
11424 #endif
11426 specbind (Qinhibit_point_motion_hooks, Qt);
11428 reconsider_clip_changes (w, buffer);
11430 /* Has the mode line to be updated? */
11431 update_mode_line = (!NILP (w->update_mode_line)
11432 || update_mode_lines
11433 || buffer->clip_changed
11434 || buffer->prevent_redisplay_optimizations_p);
11436 if (MINI_WINDOW_P (w))
11438 if (w == XWINDOW (echo_area_window)
11439 && !NILP (echo_area_buffer[0]))
11441 if (update_mode_line)
11442 /* We may have to update a tty frame's menu bar or a
11443 tool-bar. Example `M-x C-h C-h C-g'. */
11444 goto finish_menu_bars;
11445 else
11446 /* We've already displayed the echo area glyphs in this window. */
11447 goto finish_scroll_bars;
11449 else if ((w != XWINDOW (minibuf_window)
11450 || minibuf_level == 0)
11451 /* When buffer is nonempty, redisplay window normally. */
11452 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11453 /* Quail displays non-mini buffers in minibuffer window.
11454 In that case, redisplay the window normally. */
11455 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11457 /* W is a mini-buffer window, but it's not active, so clear
11458 it. */
11459 int yb = window_text_bottom_y (w);
11460 struct glyph_row *row;
11461 int y;
11463 for (y = 0, row = w->desired_matrix->rows;
11464 y < yb;
11465 y += row->height, ++row)
11466 blank_row (w, row, y);
11467 goto finish_scroll_bars;
11470 clear_glyph_matrix (w->desired_matrix);
11473 /* Otherwise set up data on this window; select its buffer and point
11474 value. */
11475 /* Really select the buffer, for the sake of buffer-local
11476 variables. */
11477 set_buffer_internal_1 (XBUFFER (w->buffer));
11478 SET_TEXT_POS (opoint, PT, PT_BYTE);
11480 current_matrix_up_to_date_p
11481 = (!NILP (w->window_end_valid)
11482 && !current_buffer->clip_changed
11483 && !current_buffer->prevent_redisplay_optimizations_p
11484 && XFASTINT (w->last_modified) >= MODIFF
11485 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11487 buffer_unchanged_p
11488 = (!NILP (w->window_end_valid)
11489 && !current_buffer->clip_changed
11490 && XFASTINT (w->last_modified) >= MODIFF
11491 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11493 /* When windows_or_buffers_changed is non-zero, we can't rely on
11494 the window end being valid, so set it to nil there. */
11495 if (windows_or_buffers_changed)
11497 /* If window starts on a continuation line, maybe adjust the
11498 window start in case the window's width changed. */
11499 if (XMARKER (w->start)->buffer == current_buffer)
11500 compute_window_start_on_continuation_line (w);
11502 w->window_end_valid = Qnil;
11505 /* Some sanity checks. */
11506 CHECK_WINDOW_END (w);
11507 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11508 abort ();
11509 if (BYTEPOS (opoint) < CHARPOS (opoint))
11510 abort ();
11512 /* If %c is in mode line, update it if needed. */
11513 if (!NILP (w->column_number_displayed)
11514 /* This alternative quickly identifies a common case
11515 where no change is needed. */
11516 && !(PT == XFASTINT (w->last_point)
11517 && XFASTINT (w->last_modified) >= MODIFF
11518 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11519 && (XFASTINT (w->column_number_displayed)
11520 != (int) current_column ())) /* iftc */
11521 update_mode_line = 1;
11523 /* Count number of windows showing the selected buffer. An indirect
11524 buffer counts as its base buffer. */
11525 if (!just_this_one_p)
11527 struct buffer *current_base, *window_base;
11528 current_base = current_buffer;
11529 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11530 if (current_base->base_buffer)
11531 current_base = current_base->base_buffer;
11532 if (window_base->base_buffer)
11533 window_base = window_base->base_buffer;
11534 if (current_base == window_base)
11535 buffer_shared++;
11538 /* Point refers normally to the selected window. For any other
11539 window, set up appropriate value. */
11540 if (!EQ (window, selected_window))
11542 int new_pt = XMARKER (w->pointm)->charpos;
11543 int new_pt_byte = marker_byte_position (w->pointm);
11544 if (new_pt < BEGV)
11546 new_pt = BEGV;
11547 new_pt_byte = BEGV_BYTE;
11548 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11550 else if (new_pt > (ZV - 1))
11552 new_pt = ZV;
11553 new_pt_byte = ZV_BYTE;
11554 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11557 /* We don't use SET_PT so that the point-motion hooks don't run. */
11558 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11561 /* If any of the character widths specified in the display table
11562 have changed, invalidate the width run cache. It's true that
11563 this may be a bit late to catch such changes, but the rest of
11564 redisplay goes (non-fatally) haywire when the display table is
11565 changed, so why should we worry about doing any better? */
11566 if (current_buffer->width_run_cache)
11568 struct Lisp_Char_Table *disptab = buffer_display_table ();
11570 if (! disptab_matches_widthtab (disptab,
11571 XVECTOR (current_buffer->width_table)))
11573 invalidate_region_cache (current_buffer,
11574 current_buffer->width_run_cache,
11575 BEG, Z);
11576 recompute_width_table (current_buffer, disptab);
11580 /* If window-start is screwed up, choose a new one. */
11581 if (XMARKER (w->start)->buffer != current_buffer)
11582 goto recenter;
11584 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11586 /* If someone specified a new starting point but did not insist,
11587 check whether it can be used. */
11588 if (!NILP (w->optional_new_start)
11589 && CHARPOS (startp) >= BEGV
11590 && CHARPOS (startp) <= ZV)
11592 w->optional_new_start = Qnil;
11593 start_display (&it, w, startp);
11594 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11595 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11596 if (IT_CHARPOS (it) == PT)
11597 w->force_start = Qt;
11598 /* IT may overshoot PT if text at PT is invisible. */
11599 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11600 w->force_start = Qt;
11605 /* Handle case where place to start displaying has been specified,
11606 unless the specified location is outside the accessible range. */
11607 if (!NILP (w->force_start)
11608 || w->frozen_window_start_p)
11610 /* We set this later on if we have to adjust point. */
11611 int new_vpos = -1;
11613 w->force_start = Qnil;
11614 w->vscroll = 0;
11615 w->window_end_valid = Qnil;
11617 /* Forget any recorded base line for line number display. */
11618 if (!buffer_unchanged_p)
11619 w->base_line_number = Qnil;
11621 /* Redisplay the mode line. Select the buffer properly for that.
11622 Also, run the hook window-scroll-functions
11623 because we have scrolled. */
11624 /* Note, we do this after clearing force_start because
11625 if there's an error, it is better to forget about force_start
11626 than to get into an infinite loop calling the hook functions
11627 and having them get more errors. */
11628 if (!update_mode_line
11629 || ! NILP (Vwindow_scroll_functions))
11631 update_mode_line = 1;
11632 w->update_mode_line = Qt;
11633 startp = run_window_scroll_functions (window, startp);
11636 w->last_modified = make_number (0);
11637 w->last_overlay_modified = make_number (0);
11638 if (CHARPOS (startp) < BEGV)
11639 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11640 else if (CHARPOS (startp) > ZV)
11641 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11643 /* Redisplay, then check if cursor has been set during the
11644 redisplay. Give up if new fonts were loaded. */
11645 if (!try_window (window, startp))
11647 w->force_start = Qt;
11648 clear_glyph_matrix (w->desired_matrix);
11649 goto need_larger_matrices;
11652 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11654 /* If point does not appear, try to move point so it does
11655 appear. The desired matrix has been built above, so we
11656 can use it here. */
11657 new_vpos = window_box_height (w) / 2;
11660 if (!make_cursor_line_fully_visible (w))
11662 /* Point does appear, but on a line partly visible at end of window.
11663 Move it back to a fully-visible line. */
11664 new_vpos = window_box_height (w);
11667 /* If we need to move point for either of the above reasons,
11668 now actually do it. */
11669 if (new_vpos >= 0)
11671 struct glyph_row *row;
11673 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11674 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11675 ++row;
11677 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11678 MATRIX_ROW_START_BYTEPOS (row));
11680 if (w != XWINDOW (selected_window))
11681 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11682 else if (current_buffer == old)
11683 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11685 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11687 /* If we are highlighting the region, then we just changed
11688 the region, so redisplay to show it. */
11689 if (!NILP (Vtransient_mark_mode)
11690 && !NILP (current_buffer->mark_active))
11692 clear_glyph_matrix (w->desired_matrix);
11693 if (!try_window (window, startp))
11694 goto need_larger_matrices;
11698 #if GLYPH_DEBUG
11699 debug_method_add (w, "forced window start");
11700 #endif
11701 goto done;
11704 /* Handle case where text has not changed, only point, and it has
11705 not moved off the frame, and we are not retrying after hscroll.
11706 (current_matrix_up_to_date_p is nonzero when retrying.) */
11707 if (current_matrix_up_to_date_p
11708 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11709 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11711 switch (rc)
11713 case CURSOR_MOVEMENT_SUCCESS:
11714 goto done;
11716 #if 0 /* try_cursor_movement never returns this value. */
11717 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11718 goto need_larger_matrices;
11719 #endif
11721 case CURSOR_MOVEMENT_MUST_SCROLL:
11722 goto try_to_scroll;
11724 default:
11725 abort ();
11728 /* If current starting point was originally the beginning of a line
11729 but no longer is, find a new starting point. */
11730 else if (!NILP (w->start_at_line_beg)
11731 && !(CHARPOS (startp) <= BEGV
11732 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11734 #if GLYPH_DEBUG
11735 debug_method_add (w, "recenter 1");
11736 #endif
11737 goto recenter;
11740 /* Try scrolling with try_window_id. Value is > 0 if update has
11741 been done, it is -1 if we know that the same window start will
11742 not work. It is 0 if unsuccessful for some other reason. */
11743 else if ((tem = try_window_id (w)) != 0)
11745 #if GLYPH_DEBUG
11746 debug_method_add (w, "try_window_id %d", tem);
11747 #endif
11749 if (fonts_changed_p)
11750 goto need_larger_matrices;
11751 if (tem > 0)
11752 goto done;
11754 /* Otherwise try_window_id has returned -1 which means that we
11755 don't want the alternative below this comment to execute. */
11757 else if (CHARPOS (startp) >= BEGV
11758 && CHARPOS (startp) <= ZV
11759 && PT >= CHARPOS (startp)
11760 && (CHARPOS (startp) < ZV
11761 /* Avoid starting at end of buffer. */
11762 || CHARPOS (startp) == BEGV
11763 || (XFASTINT (w->last_modified) >= MODIFF
11764 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11766 #if GLYPH_DEBUG
11767 debug_method_add (w, "same window start");
11768 #endif
11770 /* Try to redisplay starting at same place as before.
11771 If point has not moved off frame, accept the results. */
11772 if (!current_matrix_up_to_date_p
11773 /* Don't use try_window_reusing_current_matrix in this case
11774 because a window scroll function can have changed the
11775 buffer. */
11776 || !NILP (Vwindow_scroll_functions)
11777 || MINI_WINDOW_P (w)
11778 || !try_window_reusing_current_matrix (w))
11780 IF_DEBUG (debug_method_add (w, "1"));
11781 try_window (window, startp);
11784 if (fonts_changed_p)
11785 goto need_larger_matrices;
11787 if (w->cursor.vpos >= 0)
11789 if (!just_this_one_p
11790 || current_buffer->clip_changed
11791 || BEG_UNCHANGED < CHARPOS (startp))
11792 /* Forget any recorded base line for line number display. */
11793 w->base_line_number = Qnil;
11795 if (!make_cursor_line_fully_visible (w))
11797 clear_glyph_matrix (w->desired_matrix);
11798 last_line_misfit = 1;
11800 /* Drop through and scroll. */
11801 else
11802 goto done;
11804 else
11805 clear_glyph_matrix (w->desired_matrix);
11808 try_to_scroll:
11810 w->last_modified = make_number (0);
11811 w->last_overlay_modified = make_number (0);
11813 /* Redisplay the mode line. Select the buffer properly for that. */
11814 if (!update_mode_line)
11816 update_mode_line = 1;
11817 w->update_mode_line = Qt;
11820 /* Try to scroll by specified few lines. */
11821 if ((scroll_conservatively
11822 || scroll_step
11823 || temp_scroll_step
11824 || NUMBERP (current_buffer->scroll_up_aggressively)
11825 || NUMBERP (current_buffer->scroll_down_aggressively))
11826 && !current_buffer->clip_changed
11827 && CHARPOS (startp) >= BEGV
11828 && CHARPOS (startp) <= ZV)
11830 /* The function returns -1 if new fonts were loaded, 1 if
11831 successful, 0 if not successful. */
11832 int rc = try_scrolling (window, just_this_one_p,
11833 scroll_conservatively,
11834 scroll_step,
11835 temp_scroll_step, last_line_misfit);
11836 switch (rc)
11838 case SCROLLING_SUCCESS:
11839 goto done;
11841 case SCROLLING_NEED_LARGER_MATRICES:
11842 goto need_larger_matrices;
11844 case SCROLLING_FAILED:
11845 break;
11847 default:
11848 abort ();
11852 /* Finally, just choose place to start which centers point */
11854 recenter:
11855 centering_position = window_box_height (w) / 2;
11857 point_at_top:
11858 /* Jump here with centering_position already set to 0. */
11860 #if GLYPH_DEBUG
11861 debug_method_add (w, "recenter");
11862 #endif
11864 /* w->vscroll = 0; */
11866 /* Forget any previously recorded base line for line number display. */
11867 if (!buffer_unchanged_p)
11868 w->base_line_number = Qnil;
11870 /* Move backward half the height of the window. */
11871 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11872 it.current_y = it.last_visible_y;
11873 move_it_vertically_backward (&it, centering_position);
11874 xassert (IT_CHARPOS (it) >= BEGV);
11876 /* The function move_it_vertically_backward may move over more
11877 than the specified y-distance. If it->w is small, e.g. a
11878 mini-buffer window, we may end up in front of the window's
11879 display area. Start displaying at the start of the line
11880 containing PT in this case. */
11881 if (it.current_y <= 0)
11883 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11884 move_it_vertically (&it, 0);
11885 xassert (IT_CHARPOS (it) <= PT);
11886 it.current_y = 0;
11889 it.current_x = it.hpos = 0;
11891 /* Set startp here explicitly in case that helps avoid an infinite loop
11892 in case the window-scroll-functions functions get errors. */
11893 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11895 /* Run scroll hooks. */
11896 startp = run_window_scroll_functions (window, it.current.pos);
11898 /* Redisplay the window. */
11899 if (!current_matrix_up_to_date_p
11900 || windows_or_buffers_changed
11901 || cursor_type_changed
11902 /* Don't use try_window_reusing_current_matrix in this case
11903 because it can have changed the buffer. */
11904 || !NILP (Vwindow_scroll_functions)
11905 || !just_this_one_p
11906 || MINI_WINDOW_P (w)
11907 || !try_window_reusing_current_matrix (w))
11908 try_window (window, startp);
11910 /* If new fonts have been loaded (due to fontsets), give up. We
11911 have to start a new redisplay since we need to re-adjust glyph
11912 matrices. */
11913 if (fonts_changed_p)
11914 goto need_larger_matrices;
11916 /* If cursor did not appear assume that the middle of the window is
11917 in the first line of the window. Do it again with the next line.
11918 (Imagine a window of height 100, displaying two lines of height
11919 60. Moving back 50 from it->last_visible_y will end in the first
11920 line.) */
11921 if (w->cursor.vpos < 0)
11923 if (!NILP (w->window_end_valid)
11924 && PT >= Z - XFASTINT (w->window_end_pos))
11926 clear_glyph_matrix (w->desired_matrix);
11927 move_it_by_lines (&it, 1, 0);
11928 try_window (window, it.current.pos);
11930 else if (PT < IT_CHARPOS (it))
11932 clear_glyph_matrix (w->desired_matrix);
11933 move_it_by_lines (&it, -1, 0);
11934 try_window (window, it.current.pos);
11936 else
11938 /* Not much we can do about it. */
11942 /* Consider the following case: Window starts at BEGV, there is
11943 invisible, intangible text at BEGV, so that display starts at
11944 some point START > BEGV. It can happen that we are called with
11945 PT somewhere between BEGV and START. Try to handle that case. */
11946 if (w->cursor.vpos < 0)
11948 struct glyph_row *row = w->current_matrix->rows;
11949 if (row->mode_line_p)
11950 ++row;
11951 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11954 if (!make_cursor_line_fully_visible (w))
11956 /* If vscroll is enabled, disable it and try again. */
11957 if (w->vscroll)
11959 w->vscroll = 0;
11960 clear_glyph_matrix (w->desired_matrix);
11961 goto recenter;
11964 /* If centering point failed to make the whole line visible,
11965 put point at the top instead. That has to make the whole line
11966 visible, if it can be done. */
11967 centering_position = 0;
11968 goto point_at_top;
11971 done:
11973 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11974 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11975 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11976 ? Qt : Qnil);
11978 /* Display the mode line, if we must. */
11979 if ((update_mode_line
11980 /* If window not full width, must redo its mode line
11981 if (a) the window to its side is being redone and
11982 (b) we do a frame-based redisplay. This is a consequence
11983 of how inverted lines are drawn in frame-based redisplay. */
11984 || (!just_this_one_p
11985 && !FRAME_WINDOW_P (f)
11986 && !WINDOW_FULL_WIDTH_P (w))
11987 /* Line number to display. */
11988 || INTEGERP (w->base_line_pos)
11989 /* Column number is displayed and different from the one displayed. */
11990 || (!NILP (w->column_number_displayed)
11991 && (XFASTINT (w->column_number_displayed)
11992 != (int) current_column ()))) /* iftc */
11993 /* This means that the window has a mode line. */
11994 && (WINDOW_WANTS_MODELINE_P (w)
11995 || WINDOW_WANTS_HEADER_LINE_P (w)))
11997 display_mode_lines (w);
11999 /* If mode line height has changed, arrange for a thorough
12000 immediate redisplay using the correct mode line height. */
12001 if (WINDOW_WANTS_MODELINE_P (w)
12002 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12004 fonts_changed_p = 1;
12005 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12006 = DESIRED_MODE_LINE_HEIGHT (w);
12009 /* If top line height has changed, arrange for a thorough
12010 immediate redisplay using the correct mode line height. */
12011 if (WINDOW_WANTS_HEADER_LINE_P (w)
12012 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12014 fonts_changed_p = 1;
12015 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12016 = DESIRED_HEADER_LINE_HEIGHT (w);
12019 if (fonts_changed_p)
12020 goto need_larger_matrices;
12023 if (!line_number_displayed
12024 && !BUFFERP (w->base_line_pos))
12026 w->base_line_pos = Qnil;
12027 w->base_line_number = Qnil;
12030 finish_menu_bars:
12032 /* When we reach a frame's selected window, redo the frame's menu bar. */
12033 if (update_mode_line
12034 && EQ (FRAME_SELECTED_WINDOW (f), window))
12036 int redisplay_menu_p = 0;
12037 int redisplay_tool_bar_p = 0;
12039 if (FRAME_WINDOW_P (f))
12041 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12042 || defined (USE_GTK)
12043 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12044 #else
12045 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12046 #endif
12048 else
12049 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12051 if (redisplay_menu_p)
12052 display_menu_bar (w);
12054 #ifdef HAVE_WINDOW_SYSTEM
12055 #ifdef USE_GTK
12056 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12057 #else
12058 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12059 && (FRAME_TOOL_BAR_LINES (f) > 0
12060 || auto_resize_tool_bars_p);
12062 #endif
12064 if (redisplay_tool_bar_p)
12065 redisplay_tool_bar (f);
12066 #endif
12069 /* We go to this label, with fonts_changed_p nonzero,
12070 if it is necessary to try again using larger glyph matrices.
12071 We have to redeem the scroll bar even in this case,
12072 because the loop in redisplay_internal expects that. */
12073 need_larger_matrices:
12075 finish_scroll_bars:
12077 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12079 /* Set the thumb's position and size. */
12080 set_vertical_scroll_bar (w);
12082 /* Note that we actually used the scroll bar attached to this
12083 window, so it shouldn't be deleted at the end of redisplay. */
12084 redeem_scroll_bar_hook (w);
12087 /* Restore current_buffer and value of point in it. */
12088 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12089 set_buffer_internal_1 (old);
12090 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12092 unbind_to (count, Qnil);
12096 /* Build the complete desired matrix of WINDOW with a window start
12097 buffer position POS. Value is non-zero if successful. It is zero
12098 if fonts were loaded during redisplay which makes re-adjusting
12099 glyph matrices necessary. */
12102 try_window (window, pos)
12103 Lisp_Object window;
12104 struct text_pos pos;
12106 struct window *w = XWINDOW (window);
12107 struct it it;
12108 struct glyph_row *last_text_row = NULL;
12110 /* Make POS the new window start. */
12111 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12113 /* Mark cursor position as unknown. No overlay arrow seen. */
12114 w->cursor.vpos = -1;
12115 overlay_arrow_seen = 0;
12117 /* Initialize iterator and info to start at POS. */
12118 start_display (&it, w, pos);
12120 /* Display all lines of W. */
12121 while (it.current_y < it.last_visible_y)
12123 if (display_line (&it))
12124 last_text_row = it.glyph_row - 1;
12125 if (fonts_changed_p)
12126 return 0;
12129 /* If bottom moved off end of frame, change mode line percentage. */
12130 if (XFASTINT (w->window_end_pos) <= 0
12131 && Z != IT_CHARPOS (it))
12132 w->update_mode_line = Qt;
12134 /* Set window_end_pos to the offset of the last character displayed
12135 on the window from the end of current_buffer. Set
12136 window_end_vpos to its row number. */
12137 if (last_text_row)
12139 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12140 w->window_end_bytepos
12141 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12142 w->window_end_pos
12143 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12144 w->window_end_vpos
12145 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12146 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12147 ->displays_text_p);
12149 else
12151 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12152 w->window_end_pos = make_number (Z - ZV);
12153 w->window_end_vpos = make_number (0);
12156 /* But that is not valid info until redisplay finishes. */
12157 w->window_end_valid = Qnil;
12158 return 1;
12163 /************************************************************************
12164 Window redisplay reusing current matrix when buffer has not changed
12165 ************************************************************************/
12167 /* Try redisplay of window W showing an unchanged buffer with a
12168 different window start than the last time it was displayed by
12169 reusing its current matrix. Value is non-zero if successful.
12170 W->start is the new window start. */
12172 static int
12173 try_window_reusing_current_matrix (w)
12174 struct window *w;
12176 struct frame *f = XFRAME (w->frame);
12177 struct glyph_row *row, *bottom_row;
12178 struct it it;
12179 struct run run;
12180 struct text_pos start, new_start;
12181 int nrows_scrolled, i;
12182 struct glyph_row *last_text_row;
12183 struct glyph_row *last_reused_text_row;
12184 struct glyph_row *start_row;
12185 int start_vpos, min_y, max_y;
12187 #if GLYPH_DEBUG
12188 if (inhibit_try_window_reusing)
12189 return 0;
12190 #endif
12192 if (/* This function doesn't handle terminal frames. */
12193 !FRAME_WINDOW_P (f)
12194 /* Don't try to reuse the display if windows have been split
12195 or such. */
12196 || windows_or_buffers_changed
12197 || cursor_type_changed)
12198 return 0;
12200 /* Can't do this if region may have changed. */
12201 if ((!NILP (Vtransient_mark_mode)
12202 && !NILP (current_buffer->mark_active))
12203 || !NILP (w->region_showing)
12204 || !NILP (Vshow_trailing_whitespace))
12205 return 0;
12207 /* If top-line visibility has changed, give up. */
12208 if (WINDOW_WANTS_HEADER_LINE_P (w)
12209 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12210 return 0;
12212 /* Give up if old or new display is scrolled vertically. We could
12213 make this function handle this, but right now it doesn't. */
12214 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12215 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12216 return 0;
12218 /* The variable new_start now holds the new window start. The old
12219 start `start' can be determined from the current matrix. */
12220 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12221 start = start_row->start.pos;
12222 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12224 /* Clear the desired matrix for the display below. */
12225 clear_glyph_matrix (w->desired_matrix);
12227 if (CHARPOS (new_start) <= CHARPOS (start))
12229 int first_row_y;
12231 /* Don't use this method if the display starts with an ellipsis
12232 displayed for invisible text. It's not easy to handle that case
12233 below, and it's certainly not worth the effort since this is
12234 not a frequent case. */
12235 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12236 return 0;
12238 IF_DEBUG (debug_method_add (w, "twu1"));
12240 /* Display up to a row that can be reused. The variable
12241 last_text_row is set to the last row displayed that displays
12242 text. Note that it.vpos == 0 if or if not there is a
12243 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12244 start_display (&it, w, new_start);
12245 first_row_y = it.current_y;
12246 w->cursor.vpos = -1;
12247 last_text_row = last_reused_text_row = NULL;
12249 while (it.current_y < it.last_visible_y
12250 && IT_CHARPOS (it) < CHARPOS (start)
12251 && !fonts_changed_p)
12252 if (display_line (&it))
12253 last_text_row = it.glyph_row - 1;
12255 /* A value of current_y < last_visible_y means that we stopped
12256 at the previous window start, which in turn means that we
12257 have at least one reusable row. */
12258 if (it.current_y < it.last_visible_y)
12260 /* IT.vpos always starts from 0; it counts text lines. */
12261 nrows_scrolled = it.vpos;
12263 /* Find PT if not already found in the lines displayed. */
12264 if (w->cursor.vpos < 0)
12266 int dy = it.current_y - first_row_y;
12268 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12269 row = row_containing_pos (w, PT, row, NULL, dy);
12270 if (row)
12271 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12272 dy, nrows_scrolled);
12273 else
12275 clear_glyph_matrix (w->desired_matrix);
12276 return 0;
12280 /* Scroll the display. Do it before the current matrix is
12281 changed. The problem here is that update has not yet
12282 run, i.e. part of the current matrix is not up to date.
12283 scroll_run_hook will clear the cursor, and use the
12284 current matrix to get the height of the row the cursor is
12285 in. */
12286 run.current_y = first_row_y;
12287 run.desired_y = it.current_y;
12288 run.height = it.last_visible_y - it.current_y;
12290 if (run.height > 0 && run.current_y != run.desired_y)
12292 update_begin (f);
12293 rif->update_window_begin_hook (w);
12294 rif->clear_window_mouse_face (w);
12295 rif->scroll_run_hook (w, &run);
12296 rif->update_window_end_hook (w, 0, 0);
12297 update_end (f);
12300 /* Shift current matrix down by nrows_scrolled lines. */
12301 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12302 rotate_matrix (w->current_matrix,
12303 start_vpos,
12304 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12305 nrows_scrolled);
12307 /* Disable lines that must be updated. */
12308 for (i = 0; i < it.vpos; ++i)
12309 (start_row + i)->enabled_p = 0;
12311 /* Re-compute Y positions. */
12312 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12313 max_y = it.last_visible_y;
12314 for (row = start_row + nrows_scrolled;
12315 row < bottom_row;
12316 ++row)
12318 row->y = it.current_y;
12319 row->visible_height = row->height;
12321 if (row->y < min_y)
12322 row->visible_height -= min_y - row->y;
12323 if (row->y + row->height > max_y)
12324 row->visible_height -= row->y + row->height - max_y;
12326 it.current_y += row->height;
12328 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12329 last_reused_text_row = row;
12330 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12331 break;
12334 /* Disable lines in the current matrix which are now
12335 below the window. */
12336 for (++row; row < bottom_row; ++row)
12337 row->enabled_p = 0;
12340 /* Update window_end_pos etc.; last_reused_text_row is the last
12341 reused row from the current matrix containing text, if any.
12342 The value of last_text_row is the last displayed line
12343 containing text. */
12344 if (last_reused_text_row)
12346 w->window_end_bytepos
12347 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12348 w->window_end_pos
12349 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12350 w->window_end_vpos
12351 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12352 w->current_matrix));
12354 else if (last_text_row)
12356 w->window_end_bytepos
12357 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12358 w->window_end_pos
12359 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12360 w->window_end_vpos
12361 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12363 else
12365 /* This window must be completely empty. */
12366 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12367 w->window_end_pos = make_number (Z - ZV);
12368 w->window_end_vpos = make_number (0);
12370 w->window_end_valid = Qnil;
12372 /* Update hint: don't try scrolling again in update_window. */
12373 w->desired_matrix->no_scrolling_p = 1;
12375 #if GLYPH_DEBUG
12376 debug_method_add (w, "try_window_reusing_current_matrix 1");
12377 #endif
12378 return 1;
12380 else if (CHARPOS (new_start) > CHARPOS (start))
12382 struct glyph_row *pt_row, *row;
12383 struct glyph_row *first_reusable_row;
12384 struct glyph_row *first_row_to_display;
12385 int dy;
12386 int yb = window_text_bottom_y (w);
12388 /* Find the row starting at new_start, if there is one. Don't
12389 reuse a partially visible line at the end. */
12390 first_reusable_row = start_row;
12391 while (first_reusable_row->enabled_p
12392 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12393 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12394 < CHARPOS (new_start)))
12395 ++first_reusable_row;
12397 /* Give up if there is no row to reuse. */
12398 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12399 || !first_reusable_row->enabled_p
12400 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12401 != CHARPOS (new_start)))
12402 return 0;
12404 /* We can reuse fully visible rows beginning with
12405 first_reusable_row to the end of the window. Set
12406 first_row_to_display to the first row that cannot be reused.
12407 Set pt_row to the row containing point, if there is any. */
12408 pt_row = NULL;
12409 for (first_row_to_display = first_reusable_row;
12410 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12411 ++first_row_to_display)
12413 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12414 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12415 pt_row = first_row_to_display;
12418 /* Start displaying at the start of first_row_to_display. */
12419 xassert (first_row_to_display->y < yb);
12420 init_to_row_start (&it, w, first_row_to_display);
12422 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12423 - start_vpos);
12424 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12425 - nrows_scrolled);
12426 it.current_y = (first_row_to_display->y - first_reusable_row->y
12427 + WINDOW_HEADER_LINE_HEIGHT (w));
12429 /* Display lines beginning with first_row_to_display in the
12430 desired matrix. Set last_text_row to the last row displayed
12431 that displays text. */
12432 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12433 if (pt_row == NULL)
12434 w->cursor.vpos = -1;
12435 last_text_row = NULL;
12436 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12437 if (display_line (&it))
12438 last_text_row = it.glyph_row - 1;
12440 /* Give up If point isn't in a row displayed or reused. */
12441 if (w->cursor.vpos < 0)
12443 clear_glyph_matrix (w->desired_matrix);
12444 return 0;
12447 /* If point is in a reused row, adjust y and vpos of the cursor
12448 position. */
12449 if (pt_row)
12451 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12452 w->current_matrix);
12453 w->cursor.y -= first_reusable_row->y;
12456 /* Scroll the display. */
12457 run.current_y = first_reusable_row->y;
12458 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12459 run.height = it.last_visible_y - run.current_y;
12460 dy = run.current_y - run.desired_y;
12462 if (run.height)
12464 struct frame *f = XFRAME (WINDOW_FRAME (w));
12465 update_begin (f);
12466 rif->update_window_begin_hook (w);
12467 rif->clear_window_mouse_face (w);
12468 rif->scroll_run_hook (w, &run);
12469 rif->update_window_end_hook (w, 0, 0);
12470 update_end (f);
12473 /* Adjust Y positions of reused rows. */
12474 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12475 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12476 max_y = it.last_visible_y;
12477 for (row = first_reusable_row; row < first_row_to_display; ++row)
12479 row->y -= dy;
12480 row->visible_height = row->height;
12481 if (row->y < min_y)
12482 row->visible_height -= min_y - row->y;
12483 if (row->y + row->height > max_y)
12484 row->visible_height -= row->y + row->height - max_y;
12487 /* Scroll the current matrix. */
12488 xassert (nrows_scrolled > 0);
12489 rotate_matrix (w->current_matrix,
12490 start_vpos,
12491 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12492 -nrows_scrolled);
12494 /* Disable rows not reused. */
12495 for (row -= nrows_scrolled; row < bottom_row; ++row)
12496 row->enabled_p = 0;
12498 /* Adjust window end. A null value of last_text_row means that
12499 the window end is in reused rows which in turn means that
12500 only its vpos can have changed. */
12501 if (last_text_row)
12503 w->window_end_bytepos
12504 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12505 w->window_end_pos
12506 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12507 w->window_end_vpos
12508 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12510 else
12512 w->window_end_vpos
12513 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12516 w->window_end_valid = Qnil;
12517 w->desired_matrix->no_scrolling_p = 1;
12519 #if GLYPH_DEBUG
12520 debug_method_add (w, "try_window_reusing_current_matrix 2");
12521 #endif
12522 return 1;
12525 return 0;
12530 /************************************************************************
12531 Window redisplay reusing current matrix when buffer has changed
12532 ************************************************************************/
12534 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12535 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12536 int *, int *));
12537 static struct glyph_row *
12538 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12539 struct glyph_row *));
12542 /* Return the last row in MATRIX displaying text. If row START is
12543 non-null, start searching with that row. IT gives the dimensions
12544 of the display. Value is null if matrix is empty; otherwise it is
12545 a pointer to the row found. */
12547 static struct glyph_row *
12548 find_last_row_displaying_text (matrix, it, start)
12549 struct glyph_matrix *matrix;
12550 struct it *it;
12551 struct glyph_row *start;
12553 struct glyph_row *row, *row_found;
12555 /* Set row_found to the last row in IT->w's current matrix
12556 displaying text. The loop looks funny but think of partially
12557 visible lines. */
12558 row_found = NULL;
12559 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12560 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12562 xassert (row->enabled_p);
12563 row_found = row;
12564 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12565 break;
12566 ++row;
12569 return row_found;
12573 /* Return the last row in the current matrix of W that is not affected
12574 by changes at the start of current_buffer that occurred since W's
12575 current matrix was built. Value is null if no such row exists.
12577 BEG_UNCHANGED us the number of characters unchanged at the start of
12578 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12579 first changed character in current_buffer. Characters at positions <
12580 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12581 when the current matrix was built. */
12583 static struct glyph_row *
12584 find_last_unchanged_at_beg_row (w)
12585 struct window *w;
12587 int first_changed_pos = BEG + BEG_UNCHANGED;
12588 struct glyph_row *row;
12589 struct glyph_row *row_found = NULL;
12590 int yb = window_text_bottom_y (w);
12592 /* Find the last row displaying unchanged text. */
12593 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12594 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12595 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12597 if (/* If row ends before first_changed_pos, it is unchanged,
12598 except in some case. */
12599 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12600 /* When row ends in ZV and we write at ZV it is not
12601 unchanged. */
12602 && !row->ends_at_zv_p
12603 /* When first_changed_pos is the end of a continued line,
12604 row is not unchanged because it may be no longer
12605 continued. */
12606 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12607 && row->continued_p))
12608 row_found = row;
12610 /* Stop if last visible row. */
12611 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12612 break;
12614 ++row;
12617 return row_found;
12621 /* Find the first glyph row in the current matrix of W that is not
12622 affected by changes at the end of current_buffer since the
12623 time W's current matrix was built.
12625 Return in *DELTA the number of chars by which buffer positions in
12626 unchanged text at the end of current_buffer must be adjusted.
12628 Return in *DELTA_BYTES the corresponding number of bytes.
12630 Value is null if no such row exists, i.e. all rows are affected by
12631 changes. */
12633 static struct glyph_row *
12634 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12635 struct window *w;
12636 int *delta, *delta_bytes;
12638 struct glyph_row *row;
12639 struct glyph_row *row_found = NULL;
12641 *delta = *delta_bytes = 0;
12643 /* Display must not have been paused, otherwise the current matrix
12644 is not up to date. */
12645 if (NILP (w->window_end_valid))
12646 abort ();
12648 /* A value of window_end_pos >= END_UNCHANGED means that the window
12649 end is in the range of changed text. If so, there is no
12650 unchanged row at the end of W's current matrix. */
12651 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12652 return NULL;
12654 /* Set row to the last row in W's current matrix displaying text. */
12655 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12657 /* If matrix is entirely empty, no unchanged row exists. */
12658 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12660 /* The value of row is the last glyph row in the matrix having a
12661 meaningful buffer position in it. The end position of row
12662 corresponds to window_end_pos. This allows us to translate
12663 buffer positions in the current matrix to current buffer
12664 positions for characters not in changed text. */
12665 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12666 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12667 int last_unchanged_pos, last_unchanged_pos_old;
12668 struct glyph_row *first_text_row
12669 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12671 *delta = Z - Z_old;
12672 *delta_bytes = Z_BYTE - Z_BYTE_old;
12674 /* Set last_unchanged_pos to the buffer position of the last
12675 character in the buffer that has not been changed. Z is the
12676 index + 1 of the last character in current_buffer, i.e. by
12677 subtracting END_UNCHANGED we get the index of the last
12678 unchanged character, and we have to add BEG to get its buffer
12679 position. */
12680 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12681 last_unchanged_pos_old = last_unchanged_pos - *delta;
12683 /* Search backward from ROW for a row displaying a line that
12684 starts at a minimum position >= last_unchanged_pos_old. */
12685 for (; row > first_text_row; --row)
12687 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12688 abort ();
12690 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12691 row_found = row;
12695 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12696 abort ();
12698 return row_found;
12702 /* Make sure that glyph rows in the current matrix of window W
12703 reference the same glyph memory as corresponding rows in the
12704 frame's frame matrix. This function is called after scrolling W's
12705 current matrix on a terminal frame in try_window_id and
12706 try_window_reusing_current_matrix. */
12708 static void
12709 sync_frame_with_window_matrix_rows (w)
12710 struct window *w;
12712 struct frame *f = XFRAME (w->frame);
12713 struct glyph_row *window_row, *window_row_end, *frame_row;
12715 /* Preconditions: W must be a leaf window and full-width. Its frame
12716 must have a frame matrix. */
12717 xassert (NILP (w->hchild) && NILP (w->vchild));
12718 xassert (WINDOW_FULL_WIDTH_P (w));
12719 xassert (!FRAME_WINDOW_P (f));
12721 /* If W is a full-width window, glyph pointers in W's current matrix
12722 have, by definition, to be the same as glyph pointers in the
12723 corresponding frame matrix. Note that frame matrices have no
12724 marginal areas (see build_frame_matrix). */
12725 window_row = w->current_matrix->rows;
12726 window_row_end = window_row + w->current_matrix->nrows;
12727 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12728 while (window_row < window_row_end)
12730 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12731 struct glyph *end = window_row->glyphs[LAST_AREA];
12733 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12734 frame_row->glyphs[TEXT_AREA] = start;
12735 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12736 frame_row->glyphs[LAST_AREA] = end;
12738 /* Disable frame rows whose corresponding window rows have
12739 been disabled in try_window_id. */
12740 if (!window_row->enabled_p)
12741 frame_row->enabled_p = 0;
12743 ++window_row, ++frame_row;
12748 /* Find the glyph row in window W containing CHARPOS. Consider all
12749 rows between START and END (not inclusive). END null means search
12750 all rows to the end of the display area of W. Value is the row
12751 containing CHARPOS or null. */
12753 struct glyph_row *
12754 row_containing_pos (w, charpos, start, end, dy)
12755 struct window *w;
12756 int charpos;
12757 struct glyph_row *start, *end;
12758 int dy;
12760 struct glyph_row *row = start;
12761 int last_y;
12763 /* If we happen to start on a header-line, skip that. */
12764 if (row->mode_line_p)
12765 ++row;
12767 if ((end && row >= end) || !row->enabled_p)
12768 return NULL;
12770 last_y = window_text_bottom_y (w) - dy;
12772 while (1)
12774 /* Give up if we have gone too far. */
12775 if (end && row >= end)
12776 return NULL;
12777 /* This formerly returned if they were equal.
12778 I think that both quantities are of a "last plus one" type;
12779 if so, when they are equal, the row is within the screen. -- rms. */
12780 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12781 return NULL;
12783 /* If it is in this row, return this row. */
12784 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12785 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12786 /* The end position of a row equals the start
12787 position of the next row. If CHARPOS is there, we
12788 would rather display it in the next line, except
12789 when this line ends in ZV. */
12790 && !row->ends_at_zv_p
12791 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12792 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12793 return row;
12794 ++row;
12799 /* Try to redisplay window W by reusing its existing display. W's
12800 current matrix must be up to date when this function is called,
12801 i.e. window_end_valid must not be nil.
12803 Value is
12805 1 if display has been updated
12806 0 if otherwise unsuccessful
12807 -1 if redisplay with same window start is known not to succeed
12809 The following steps are performed:
12811 1. Find the last row in the current matrix of W that is not
12812 affected by changes at the start of current_buffer. If no such row
12813 is found, give up.
12815 2. Find the first row in W's current matrix that is not affected by
12816 changes at the end of current_buffer. Maybe there is no such row.
12818 3. Display lines beginning with the row + 1 found in step 1 to the
12819 row found in step 2 or, if step 2 didn't find a row, to the end of
12820 the window.
12822 4. If cursor is not known to appear on the window, give up.
12824 5. If display stopped at the row found in step 2, scroll the
12825 display and current matrix as needed.
12827 6. Maybe display some lines at the end of W, if we must. This can
12828 happen under various circumstances, like a partially visible line
12829 becoming fully visible, or because newly displayed lines are displayed
12830 in smaller font sizes.
12832 7. Update W's window end information. */
12834 static int
12835 try_window_id (w)
12836 struct window *w;
12838 struct frame *f = XFRAME (w->frame);
12839 struct glyph_matrix *current_matrix = w->current_matrix;
12840 struct glyph_matrix *desired_matrix = w->desired_matrix;
12841 struct glyph_row *last_unchanged_at_beg_row;
12842 struct glyph_row *first_unchanged_at_end_row;
12843 struct glyph_row *row;
12844 struct glyph_row *bottom_row;
12845 int bottom_vpos;
12846 struct it it;
12847 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12848 struct text_pos start_pos;
12849 struct run run;
12850 int first_unchanged_at_end_vpos = 0;
12851 struct glyph_row *last_text_row, *last_text_row_at_end;
12852 struct text_pos start;
12853 int first_changed_charpos, last_changed_charpos;
12855 #if GLYPH_DEBUG
12856 if (inhibit_try_window_id)
12857 return 0;
12858 #endif
12860 /* This is handy for debugging. */
12861 #if 0
12862 #define GIVE_UP(X) \
12863 do { \
12864 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12865 return 0; \
12866 } while (0)
12867 #else
12868 #define GIVE_UP(X) return 0
12869 #endif
12871 SET_TEXT_POS_FROM_MARKER (start, w->start);
12873 /* Don't use this for mini-windows because these can show
12874 messages and mini-buffers, and we don't handle that here. */
12875 if (MINI_WINDOW_P (w))
12876 GIVE_UP (1);
12878 /* This flag is used to prevent redisplay optimizations. */
12879 if (windows_or_buffers_changed || cursor_type_changed)
12880 GIVE_UP (2);
12882 /* Verify that narrowing has not changed.
12883 Also verify that we were not told to prevent redisplay optimizations.
12884 It would be nice to further
12885 reduce the number of cases where this prevents try_window_id. */
12886 if (current_buffer->clip_changed
12887 || current_buffer->prevent_redisplay_optimizations_p)
12888 GIVE_UP (3);
12890 /* Window must either use window-based redisplay or be full width. */
12891 if (!FRAME_WINDOW_P (f)
12892 && (!line_ins_del_ok
12893 || !WINDOW_FULL_WIDTH_P (w)))
12894 GIVE_UP (4);
12896 /* Give up if point is not known NOT to appear in W. */
12897 if (PT < CHARPOS (start))
12898 GIVE_UP (5);
12900 /* Another way to prevent redisplay optimizations. */
12901 if (XFASTINT (w->last_modified) == 0)
12902 GIVE_UP (6);
12904 /* Verify that window is not hscrolled. */
12905 if (XFASTINT (w->hscroll) != 0)
12906 GIVE_UP (7);
12908 /* Verify that display wasn't paused. */
12909 if (NILP (w->window_end_valid))
12910 GIVE_UP (8);
12912 /* Can't use this if highlighting a region because a cursor movement
12913 will do more than just set the cursor. */
12914 if (!NILP (Vtransient_mark_mode)
12915 && !NILP (current_buffer->mark_active))
12916 GIVE_UP (9);
12918 /* Likewise if highlighting trailing whitespace. */
12919 if (!NILP (Vshow_trailing_whitespace))
12920 GIVE_UP (11);
12922 /* Likewise if showing a region. */
12923 if (!NILP (w->region_showing))
12924 GIVE_UP (10);
12926 /* Can use this if overlay arrow position and or string have changed. */
12927 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12928 || !EQ (last_arrow_string, Voverlay_arrow_string))
12929 GIVE_UP (12);
12932 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12933 only if buffer has really changed. The reason is that the gap is
12934 initially at Z for freshly visited files. The code below would
12935 set end_unchanged to 0 in that case. */
12936 if (MODIFF > SAVE_MODIFF
12937 /* This seems to happen sometimes after saving a buffer. */
12938 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12940 if (GPT - BEG < BEG_UNCHANGED)
12941 BEG_UNCHANGED = GPT - BEG;
12942 if (Z - GPT < END_UNCHANGED)
12943 END_UNCHANGED = Z - GPT;
12946 /* The position of the first and last character that has been changed. */
12947 first_changed_charpos = BEG + BEG_UNCHANGED;
12948 last_changed_charpos = Z - END_UNCHANGED;
12950 /* If window starts after a line end, and the last change is in
12951 front of that newline, then changes don't affect the display.
12952 This case happens with stealth-fontification. Note that although
12953 the display is unchanged, glyph positions in the matrix have to
12954 be adjusted, of course. */
12955 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12956 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12957 && ((last_changed_charpos < CHARPOS (start)
12958 && CHARPOS (start) == BEGV)
12959 || (last_changed_charpos < CHARPOS (start) - 1
12960 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12962 int Z_old, delta, Z_BYTE_old, delta_bytes;
12963 struct glyph_row *r0;
12965 /* Compute how many chars/bytes have been added to or removed
12966 from the buffer. */
12967 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12968 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12969 delta = Z - Z_old;
12970 delta_bytes = Z_BYTE - Z_BYTE_old;
12972 /* Give up if PT is not in the window. Note that it already has
12973 been checked at the start of try_window_id that PT is not in
12974 front of the window start. */
12975 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12976 GIVE_UP (13);
12978 /* If window start is unchanged, we can reuse the whole matrix
12979 as is, after adjusting glyph positions. No need to compute
12980 the window end again, since its offset from Z hasn't changed. */
12981 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12982 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12983 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12984 /* PT must not be in a partially visible line. */
12985 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
12986 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12988 /* Adjust positions in the glyph matrix. */
12989 if (delta || delta_bytes)
12991 struct glyph_row *r1
12992 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
12993 increment_matrix_positions (w->current_matrix,
12994 MATRIX_ROW_VPOS (r0, current_matrix),
12995 MATRIX_ROW_VPOS (r1, current_matrix),
12996 delta, delta_bytes);
12999 /* Set the cursor. */
13000 row = row_containing_pos (w, PT, r0, NULL, 0);
13001 if (row)
13002 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13003 else
13004 abort ();
13005 return 1;
13009 /* Handle the case that changes are all below what is displayed in
13010 the window, and that PT is in the window. This shortcut cannot
13011 be taken if ZV is visible in the window, and text has been added
13012 there that is visible in the window. */
13013 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13014 /* ZV is not visible in the window, or there are no
13015 changes at ZV, actually. */
13016 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13017 || first_changed_charpos == last_changed_charpos))
13019 struct glyph_row *r0;
13021 /* Give up if PT is not in the window. Note that it already has
13022 been checked at the start of try_window_id that PT is not in
13023 front of the window start. */
13024 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13025 GIVE_UP (14);
13027 /* If window start is unchanged, we can reuse the whole matrix
13028 as is, without changing glyph positions since no text has
13029 been added/removed in front of the window end. */
13030 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13031 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13032 /* PT must not be in a partially visible line. */
13033 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13034 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13036 /* We have to compute the window end anew since text
13037 can have been added/removed after it. */
13038 w->window_end_pos
13039 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13040 w->window_end_bytepos
13041 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13043 /* Set the cursor. */
13044 row = row_containing_pos (w, PT, r0, NULL, 0);
13045 if (row)
13046 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13047 else
13048 abort ();
13049 return 2;
13053 /* Give up if window start is in the changed area.
13055 The condition used to read
13057 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13059 but why that was tested escapes me at the moment. */
13060 if (CHARPOS (start) >= first_changed_charpos
13061 && CHARPOS (start) <= last_changed_charpos)
13062 GIVE_UP (15);
13064 /* Check that window start agrees with the start of the first glyph
13065 row in its current matrix. Check this after we know the window
13066 start is not in changed text, otherwise positions would not be
13067 comparable. */
13068 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13069 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13070 GIVE_UP (16);
13072 /* Give up if the window ends in strings. Overlay strings
13073 at the end are difficult to handle, so don't try. */
13074 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13075 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13076 GIVE_UP (20);
13078 /* Compute the position at which we have to start displaying new
13079 lines. Some of the lines at the top of the window might be
13080 reusable because they are not displaying changed text. Find the
13081 last row in W's current matrix not affected by changes at the
13082 start of current_buffer. Value is null if changes start in the
13083 first line of window. */
13084 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13085 if (last_unchanged_at_beg_row)
13087 /* Avoid starting to display in the moddle of a character, a TAB
13088 for instance. This is easier than to set up the iterator
13089 exactly, and it's not a frequent case, so the additional
13090 effort wouldn't really pay off. */
13091 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13092 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13093 && last_unchanged_at_beg_row > w->current_matrix->rows)
13094 --last_unchanged_at_beg_row;
13096 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13097 GIVE_UP (17);
13099 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13100 GIVE_UP (18);
13101 start_pos = it.current.pos;
13103 /* Start displaying new lines in the desired matrix at the same
13104 vpos we would use in the current matrix, i.e. below
13105 last_unchanged_at_beg_row. */
13106 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13107 current_matrix);
13108 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13109 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13111 xassert (it.hpos == 0 && it.current_x == 0);
13113 else
13115 /* There are no reusable lines at the start of the window.
13116 Start displaying in the first text line. */
13117 start_display (&it, w, start);
13118 it.vpos = it.first_vpos;
13119 start_pos = it.current.pos;
13122 /* Find the first row that is not affected by changes at the end of
13123 the buffer. Value will be null if there is no unchanged row, in
13124 which case we must redisplay to the end of the window. delta
13125 will be set to the value by which buffer positions beginning with
13126 first_unchanged_at_end_row have to be adjusted due to text
13127 changes. */
13128 first_unchanged_at_end_row
13129 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13130 IF_DEBUG (debug_delta = delta);
13131 IF_DEBUG (debug_delta_bytes = delta_bytes);
13133 /* Set stop_pos to the buffer position up to which we will have to
13134 display new lines. If first_unchanged_at_end_row != NULL, this
13135 is the buffer position of the start of the line displayed in that
13136 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13137 that we don't stop at a buffer position. */
13138 stop_pos = 0;
13139 if (first_unchanged_at_end_row)
13141 xassert (last_unchanged_at_beg_row == NULL
13142 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13144 /* If this is a continuation line, move forward to the next one
13145 that isn't. Changes in lines above affect this line.
13146 Caution: this may move first_unchanged_at_end_row to a row
13147 not displaying text. */
13148 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13149 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13150 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13151 < it.last_visible_y))
13152 ++first_unchanged_at_end_row;
13154 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13155 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13156 >= it.last_visible_y))
13157 first_unchanged_at_end_row = NULL;
13158 else
13160 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13161 + delta);
13162 first_unchanged_at_end_vpos
13163 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13164 xassert (stop_pos >= Z - END_UNCHANGED);
13167 else if (last_unchanged_at_beg_row == NULL)
13168 GIVE_UP (19);
13171 #if GLYPH_DEBUG
13173 /* Either there is no unchanged row at the end, or the one we have
13174 now displays text. This is a necessary condition for the window
13175 end pos calculation at the end of this function. */
13176 xassert (first_unchanged_at_end_row == NULL
13177 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13179 debug_last_unchanged_at_beg_vpos
13180 = (last_unchanged_at_beg_row
13181 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13182 : -1);
13183 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13185 #endif /* GLYPH_DEBUG != 0 */
13188 /* Display new lines. Set last_text_row to the last new line
13189 displayed which has text on it, i.e. might end up as being the
13190 line where the window_end_vpos is. */
13191 w->cursor.vpos = -1;
13192 last_text_row = NULL;
13193 overlay_arrow_seen = 0;
13194 while (it.current_y < it.last_visible_y
13195 && !fonts_changed_p
13196 && (first_unchanged_at_end_row == NULL
13197 || IT_CHARPOS (it) < stop_pos))
13199 if (display_line (&it))
13200 last_text_row = it.glyph_row - 1;
13203 if (fonts_changed_p)
13204 return -1;
13207 /* Compute differences in buffer positions, y-positions etc. for
13208 lines reused at the bottom of the window. Compute what we can
13209 scroll. */
13210 if (first_unchanged_at_end_row
13211 /* No lines reused because we displayed everything up to the
13212 bottom of the window. */
13213 && it.current_y < it.last_visible_y)
13215 dvpos = (it.vpos
13216 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13217 current_matrix));
13218 dy = it.current_y - first_unchanged_at_end_row->y;
13219 run.current_y = first_unchanged_at_end_row->y;
13220 run.desired_y = run.current_y + dy;
13221 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13223 else
13225 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13226 first_unchanged_at_end_row = NULL;
13228 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13231 /* Find the cursor if not already found. We have to decide whether
13232 PT will appear on this window (it sometimes doesn't, but this is
13233 not a very frequent case.) This decision has to be made before
13234 the current matrix is altered. A value of cursor.vpos < 0 means
13235 that PT is either in one of the lines beginning at
13236 first_unchanged_at_end_row or below the window. Don't care for
13237 lines that might be displayed later at the window end; as
13238 mentioned, this is not a frequent case. */
13239 if (w->cursor.vpos < 0)
13241 /* Cursor in unchanged rows at the top? */
13242 if (PT < CHARPOS (start_pos)
13243 && last_unchanged_at_beg_row)
13245 row = row_containing_pos (w, PT,
13246 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13247 last_unchanged_at_beg_row + 1, 0);
13248 if (row)
13249 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13252 /* Start from first_unchanged_at_end_row looking for PT. */
13253 else if (first_unchanged_at_end_row)
13255 row = row_containing_pos (w, PT - delta,
13256 first_unchanged_at_end_row, NULL, 0);
13257 if (row)
13258 set_cursor_from_row (w, row, w->current_matrix, delta,
13259 delta_bytes, dy, dvpos);
13262 /* Give up if cursor was not found. */
13263 if (w->cursor.vpos < 0)
13265 clear_glyph_matrix (w->desired_matrix);
13266 return -1;
13270 /* Don't let the cursor end in the scroll margins. */
13272 int this_scroll_margin, cursor_height;
13274 this_scroll_margin = max (0, scroll_margin);
13275 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13276 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13277 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13279 if ((w->cursor.y < this_scroll_margin
13280 && CHARPOS (start) > BEGV)
13281 /* Don't take scroll margin into account at the bottom because
13282 old redisplay didn't do it either. */
13283 || w->cursor.y + cursor_height > it.last_visible_y)
13285 w->cursor.vpos = -1;
13286 clear_glyph_matrix (w->desired_matrix);
13287 return -1;
13291 /* Scroll the display. Do it before changing the current matrix so
13292 that xterm.c doesn't get confused about where the cursor glyph is
13293 found. */
13294 if (dy && run.height)
13296 update_begin (f);
13298 if (FRAME_WINDOW_P (f))
13300 rif->update_window_begin_hook (w);
13301 rif->clear_window_mouse_face (w);
13302 rif->scroll_run_hook (w, &run);
13303 rif->update_window_end_hook (w, 0, 0);
13305 else
13307 /* Terminal frame. In this case, dvpos gives the number of
13308 lines to scroll by; dvpos < 0 means scroll up. */
13309 int first_unchanged_at_end_vpos
13310 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13311 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13312 int end = (WINDOW_TOP_EDGE_LINE (w)
13313 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13314 + window_internal_height (w));
13316 /* Perform the operation on the screen. */
13317 if (dvpos > 0)
13319 /* Scroll last_unchanged_at_beg_row to the end of the
13320 window down dvpos lines. */
13321 set_terminal_window (end);
13323 /* On dumb terminals delete dvpos lines at the end
13324 before inserting dvpos empty lines. */
13325 if (!scroll_region_ok)
13326 ins_del_lines (end - dvpos, -dvpos);
13328 /* Insert dvpos empty lines in front of
13329 last_unchanged_at_beg_row. */
13330 ins_del_lines (from, dvpos);
13332 else if (dvpos < 0)
13334 /* Scroll up last_unchanged_at_beg_vpos to the end of
13335 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13336 set_terminal_window (end);
13338 /* Delete dvpos lines in front of
13339 last_unchanged_at_beg_vpos. ins_del_lines will set
13340 the cursor to the given vpos and emit |dvpos| delete
13341 line sequences. */
13342 ins_del_lines (from + dvpos, dvpos);
13344 /* On a dumb terminal insert dvpos empty lines at the
13345 end. */
13346 if (!scroll_region_ok)
13347 ins_del_lines (end + dvpos, -dvpos);
13350 set_terminal_window (0);
13353 update_end (f);
13356 /* Shift reused rows of the current matrix to the right position.
13357 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13358 text. */
13359 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13360 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13361 if (dvpos < 0)
13363 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13364 bottom_vpos, dvpos);
13365 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13366 bottom_vpos, 0);
13368 else if (dvpos > 0)
13370 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13371 bottom_vpos, dvpos);
13372 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13373 first_unchanged_at_end_vpos + dvpos, 0);
13376 /* For frame-based redisplay, make sure that current frame and window
13377 matrix are in sync with respect to glyph memory. */
13378 if (!FRAME_WINDOW_P (f))
13379 sync_frame_with_window_matrix_rows (w);
13381 /* Adjust buffer positions in reused rows. */
13382 if (delta)
13383 increment_matrix_positions (current_matrix,
13384 first_unchanged_at_end_vpos + dvpos,
13385 bottom_vpos, delta, delta_bytes);
13387 /* Adjust Y positions. */
13388 if (dy)
13389 shift_glyph_matrix (w, current_matrix,
13390 first_unchanged_at_end_vpos + dvpos,
13391 bottom_vpos, dy);
13393 if (first_unchanged_at_end_row)
13394 first_unchanged_at_end_row += dvpos;
13396 /* If scrolling up, there may be some lines to display at the end of
13397 the window. */
13398 last_text_row_at_end = NULL;
13399 if (dy < 0)
13401 /* Scrolling up can leave for example a partially visible line
13402 at the end of the window to be redisplayed. */
13403 /* Set last_row to the glyph row in the current matrix where the
13404 window end line is found. It has been moved up or down in
13405 the matrix by dvpos. */
13406 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13407 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13409 /* If last_row is the window end line, it should display text. */
13410 xassert (last_row->displays_text_p);
13412 /* If window end line was partially visible before, begin
13413 displaying at that line. Otherwise begin displaying with the
13414 line following it. */
13415 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13417 init_to_row_start (&it, w, last_row);
13418 it.vpos = last_vpos;
13419 it.current_y = last_row->y;
13421 else
13423 init_to_row_end (&it, w, last_row);
13424 it.vpos = 1 + last_vpos;
13425 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13426 ++last_row;
13429 /* We may start in a continuation line. If so, we have to
13430 get the right continuation_lines_width and current_x. */
13431 it.continuation_lines_width = last_row->continuation_lines_width;
13432 it.hpos = it.current_x = 0;
13434 /* Display the rest of the lines at the window end. */
13435 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13436 while (it.current_y < it.last_visible_y
13437 && !fonts_changed_p)
13439 /* Is it always sure that the display agrees with lines in
13440 the current matrix? I don't think so, so we mark rows
13441 displayed invalid in the current matrix by setting their
13442 enabled_p flag to zero. */
13443 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13444 if (display_line (&it))
13445 last_text_row_at_end = it.glyph_row - 1;
13449 /* Update window_end_pos and window_end_vpos. */
13450 if (first_unchanged_at_end_row
13451 && first_unchanged_at_end_row->y < it.last_visible_y
13452 && !last_text_row_at_end)
13454 /* Window end line if one of the preserved rows from the current
13455 matrix. Set row to the last row displaying text in current
13456 matrix starting at first_unchanged_at_end_row, after
13457 scrolling. */
13458 xassert (first_unchanged_at_end_row->displays_text_p);
13459 row = find_last_row_displaying_text (w->current_matrix, &it,
13460 first_unchanged_at_end_row);
13461 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13463 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13464 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13465 w->window_end_vpos
13466 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13467 xassert (w->window_end_bytepos >= 0);
13468 IF_DEBUG (debug_method_add (w, "A"));
13470 else if (last_text_row_at_end)
13472 w->window_end_pos
13473 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13474 w->window_end_bytepos
13475 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13476 w->window_end_vpos
13477 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13478 xassert (w->window_end_bytepos >= 0);
13479 IF_DEBUG (debug_method_add (w, "B"));
13481 else if (last_text_row)
13483 /* We have displayed either to the end of the window or at the
13484 end of the window, i.e. the last row with text is to be found
13485 in the desired matrix. */
13486 w->window_end_pos
13487 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13488 w->window_end_bytepos
13489 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13490 w->window_end_vpos
13491 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13492 xassert (w->window_end_bytepos >= 0);
13494 else if (first_unchanged_at_end_row == NULL
13495 && last_text_row == NULL
13496 && last_text_row_at_end == NULL)
13498 /* Displayed to end of window, but no line containing text was
13499 displayed. Lines were deleted at the end of the window. */
13500 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13501 int vpos = XFASTINT (w->window_end_vpos);
13502 struct glyph_row *current_row = current_matrix->rows + vpos;
13503 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13505 for (row = NULL;
13506 row == NULL && vpos >= first_vpos;
13507 --vpos, --current_row, --desired_row)
13509 if (desired_row->enabled_p)
13511 if (desired_row->displays_text_p)
13512 row = desired_row;
13514 else if (current_row->displays_text_p)
13515 row = current_row;
13518 xassert (row != NULL);
13519 w->window_end_vpos = make_number (vpos + 1);
13520 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13521 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13522 xassert (w->window_end_bytepos >= 0);
13523 IF_DEBUG (debug_method_add (w, "C"));
13525 else
13526 abort ();
13528 #if 0 /* This leads to problems, for instance when the cursor is
13529 at ZV, and the cursor line displays no text. */
13530 /* Disable rows below what's displayed in the window. This makes
13531 debugging easier. */
13532 enable_glyph_matrix_rows (current_matrix,
13533 XFASTINT (w->window_end_vpos) + 1,
13534 bottom_vpos, 0);
13535 #endif
13537 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13538 debug_end_vpos = XFASTINT (w->window_end_vpos));
13540 /* Record that display has not been completed. */
13541 w->window_end_valid = Qnil;
13542 w->desired_matrix->no_scrolling_p = 1;
13543 return 3;
13545 #undef GIVE_UP
13550 /***********************************************************************
13551 More debugging support
13552 ***********************************************************************/
13554 #if GLYPH_DEBUG
13556 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13557 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13558 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13561 /* Dump the contents of glyph matrix MATRIX on stderr.
13563 GLYPHS 0 means don't show glyph contents.
13564 GLYPHS 1 means show glyphs in short form
13565 GLYPHS > 1 means show glyphs in long form. */
13567 void
13568 dump_glyph_matrix (matrix, glyphs)
13569 struct glyph_matrix *matrix;
13570 int glyphs;
13572 int i;
13573 for (i = 0; i < matrix->nrows; ++i)
13574 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13578 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13579 the glyph row and area where the glyph comes from. */
13581 void
13582 dump_glyph (row, glyph, area)
13583 struct glyph_row *row;
13584 struct glyph *glyph;
13585 int area;
13587 if (glyph->type == CHAR_GLYPH)
13589 fprintf (stderr,
13590 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13591 glyph - row->glyphs[TEXT_AREA],
13592 'C',
13593 glyph->charpos,
13594 (BUFFERP (glyph->object)
13595 ? 'B'
13596 : (STRINGP (glyph->object)
13597 ? 'S'
13598 : '-')),
13599 glyph->pixel_width,
13600 glyph->u.ch,
13601 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13602 ? glyph->u.ch
13603 : '.'),
13604 glyph->face_id,
13605 glyph->left_box_line_p,
13606 glyph->right_box_line_p);
13608 else if (glyph->type == STRETCH_GLYPH)
13610 fprintf (stderr,
13611 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13612 glyph - row->glyphs[TEXT_AREA],
13613 'S',
13614 glyph->charpos,
13615 (BUFFERP (glyph->object)
13616 ? 'B'
13617 : (STRINGP (glyph->object)
13618 ? 'S'
13619 : '-')),
13620 glyph->pixel_width,
13622 '.',
13623 glyph->face_id,
13624 glyph->left_box_line_p,
13625 glyph->right_box_line_p);
13627 else if (glyph->type == IMAGE_GLYPH)
13629 fprintf (stderr,
13630 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13631 glyph - row->glyphs[TEXT_AREA],
13632 'I',
13633 glyph->charpos,
13634 (BUFFERP (glyph->object)
13635 ? 'B'
13636 : (STRINGP (glyph->object)
13637 ? 'S'
13638 : '-')),
13639 glyph->pixel_width,
13640 glyph->u.img_id,
13641 '.',
13642 glyph->face_id,
13643 glyph->left_box_line_p,
13644 glyph->right_box_line_p);
13649 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13650 GLYPHS 0 means don't show glyph contents.
13651 GLYPHS 1 means show glyphs in short form
13652 GLYPHS > 1 means show glyphs in long form. */
13654 void
13655 dump_glyph_row (row, vpos, glyphs)
13656 struct glyph_row *row;
13657 int vpos, glyphs;
13659 if (glyphs != 1)
13661 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13662 fprintf (stderr, "=======================================================================\n");
13664 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13665 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13666 vpos,
13667 MATRIX_ROW_START_CHARPOS (row),
13668 MATRIX_ROW_END_CHARPOS (row),
13669 row->used[TEXT_AREA],
13670 row->contains_overlapping_glyphs_p,
13671 row->enabled_p,
13672 row->truncated_on_left_p,
13673 row->truncated_on_right_p,
13674 row->overlay_arrow_p,
13675 row->continued_p,
13676 MATRIX_ROW_CONTINUATION_LINE_P (row),
13677 row->displays_text_p,
13678 row->ends_at_zv_p,
13679 row->fill_line_p,
13680 row->ends_in_middle_of_char_p,
13681 row->starts_in_middle_of_char_p,
13682 row->mouse_face_p,
13683 row->x,
13684 row->y,
13685 row->pixel_width,
13686 row->height,
13687 row->visible_height,
13688 row->ascent,
13689 row->phys_ascent);
13690 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13691 row->end.overlay_string_index,
13692 row->continuation_lines_width);
13693 fprintf (stderr, "%9d %5d\n",
13694 CHARPOS (row->start.string_pos),
13695 CHARPOS (row->end.string_pos));
13696 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13697 row->end.dpvec_index);
13700 if (glyphs > 1)
13702 int area;
13704 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13706 struct glyph *glyph = row->glyphs[area];
13707 struct glyph *glyph_end = glyph + row->used[area];
13709 /* Glyph for a line end in text. */
13710 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13711 ++glyph_end;
13713 if (glyph < glyph_end)
13714 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13716 for (; glyph < glyph_end; ++glyph)
13717 dump_glyph (row, glyph, area);
13720 else if (glyphs == 1)
13722 int area;
13724 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13726 char *s = (char *) alloca (row->used[area] + 1);
13727 int i;
13729 for (i = 0; i < row->used[area]; ++i)
13731 struct glyph *glyph = row->glyphs[area] + i;
13732 if (glyph->type == CHAR_GLYPH
13733 && glyph->u.ch < 0x80
13734 && glyph->u.ch >= ' ')
13735 s[i] = glyph->u.ch;
13736 else
13737 s[i] = '.';
13740 s[i] = '\0';
13741 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13747 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13748 Sdump_glyph_matrix, 0, 1, "p",
13749 doc: /* Dump the current matrix of the selected window to stderr.
13750 Shows contents of glyph row structures. With non-nil
13751 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13752 glyphs in short form, otherwise show glyphs in long form. */)
13753 (glyphs)
13754 Lisp_Object glyphs;
13756 struct window *w = XWINDOW (selected_window);
13757 struct buffer *buffer = XBUFFER (w->buffer);
13759 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13760 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13761 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13762 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13763 fprintf (stderr, "=============================================\n");
13764 dump_glyph_matrix (w->current_matrix,
13765 NILP (glyphs) ? 0 : XINT (glyphs));
13766 return Qnil;
13770 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13771 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13774 struct frame *f = XFRAME (selected_frame);
13775 dump_glyph_matrix (f->current_matrix, 1);
13776 return Qnil;
13780 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13781 doc: /* Dump glyph row ROW to stderr.
13782 GLYPH 0 means don't dump glyphs.
13783 GLYPH 1 means dump glyphs in short form.
13784 GLYPH > 1 or omitted means dump glyphs in long form. */)
13785 (row, glyphs)
13786 Lisp_Object row, glyphs;
13788 struct glyph_matrix *matrix;
13789 int vpos;
13791 CHECK_NUMBER (row);
13792 matrix = XWINDOW (selected_window)->current_matrix;
13793 vpos = XINT (row);
13794 if (vpos >= 0 && vpos < matrix->nrows)
13795 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13796 vpos,
13797 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13798 return Qnil;
13802 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13803 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13804 GLYPH 0 means don't dump glyphs.
13805 GLYPH 1 means dump glyphs in short form.
13806 GLYPH > 1 or omitted means dump glyphs in long form. */)
13807 (row, glyphs)
13808 Lisp_Object row, glyphs;
13810 struct frame *sf = SELECTED_FRAME ();
13811 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13812 int vpos;
13814 CHECK_NUMBER (row);
13815 vpos = XINT (row);
13816 if (vpos >= 0 && vpos < m->nrows)
13817 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13818 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13819 return Qnil;
13823 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13824 doc: /* Toggle tracing of redisplay.
13825 With ARG, turn tracing on if and only if ARG is positive. */)
13826 (arg)
13827 Lisp_Object arg;
13829 if (NILP (arg))
13830 trace_redisplay_p = !trace_redisplay_p;
13831 else
13833 arg = Fprefix_numeric_value (arg);
13834 trace_redisplay_p = XINT (arg) > 0;
13837 return Qnil;
13841 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13842 doc: /* Like `format', but print result to stderr.
13843 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13844 (nargs, args)
13845 int nargs;
13846 Lisp_Object *args;
13848 Lisp_Object s = Fformat (nargs, args);
13849 fprintf (stderr, "%s", SDATA (s));
13850 return Qnil;
13853 #endif /* GLYPH_DEBUG */
13857 /***********************************************************************
13858 Building Desired Matrix Rows
13859 ***********************************************************************/
13861 /* Return a temporary glyph row holding the glyphs of an overlay
13862 arrow. Only used for non-window-redisplay windows. */
13864 static struct glyph_row *
13865 get_overlay_arrow_glyph_row (w)
13866 struct window *w;
13868 struct frame *f = XFRAME (WINDOW_FRAME (w));
13869 struct buffer *buffer = XBUFFER (w->buffer);
13870 struct buffer *old = current_buffer;
13871 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13872 int arrow_len = SCHARS (Voverlay_arrow_string);
13873 const unsigned char *arrow_end = arrow_string + arrow_len;
13874 const unsigned char *p;
13875 struct it it;
13876 int multibyte_p;
13877 int n_glyphs_before;
13879 set_buffer_temp (buffer);
13880 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13881 it.glyph_row->used[TEXT_AREA] = 0;
13882 SET_TEXT_POS (it.position, 0, 0);
13884 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13885 p = arrow_string;
13886 while (p < arrow_end)
13888 Lisp_Object face, ilisp;
13890 /* Get the next character. */
13891 if (multibyte_p)
13892 it.c = string_char_and_length (p, arrow_len, &it.len);
13893 else
13894 it.c = *p, it.len = 1;
13895 p += it.len;
13897 /* Get its face. */
13898 ilisp = make_number (p - arrow_string);
13899 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13900 it.face_id = compute_char_face (f, it.c, face);
13902 /* Compute its width, get its glyphs. */
13903 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13904 SET_TEXT_POS (it.position, -1, -1);
13905 PRODUCE_GLYPHS (&it);
13907 /* If this character doesn't fit any more in the line, we have
13908 to remove some glyphs. */
13909 if (it.current_x > it.last_visible_x)
13911 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13912 break;
13916 set_buffer_temp (old);
13917 return it.glyph_row;
13921 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13922 glyphs are only inserted for terminal frames since we can't really
13923 win with truncation glyphs when partially visible glyphs are
13924 involved. Which glyphs to insert is determined by
13925 produce_special_glyphs. */
13927 static void
13928 insert_left_trunc_glyphs (it)
13929 struct it *it;
13931 struct it truncate_it;
13932 struct glyph *from, *end, *to, *toend;
13934 xassert (!FRAME_WINDOW_P (it->f));
13936 /* Get the truncation glyphs. */
13937 truncate_it = *it;
13938 truncate_it.current_x = 0;
13939 truncate_it.face_id = DEFAULT_FACE_ID;
13940 truncate_it.glyph_row = &scratch_glyph_row;
13941 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13942 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13943 truncate_it.object = make_number (0);
13944 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13946 /* Overwrite glyphs from IT with truncation glyphs. */
13947 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13948 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13949 to = it->glyph_row->glyphs[TEXT_AREA];
13950 toend = to + it->glyph_row->used[TEXT_AREA];
13952 while (from < end)
13953 *to++ = *from++;
13955 /* There may be padding glyphs left over. Overwrite them too. */
13956 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13958 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13959 while (from < end)
13960 *to++ = *from++;
13963 if (to > toend)
13964 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13968 /* Compute the pixel height and width of IT->glyph_row.
13970 Most of the time, ascent and height of a display line will be equal
13971 to the max_ascent and max_height values of the display iterator
13972 structure. This is not the case if
13974 1. We hit ZV without displaying anything. In this case, max_ascent
13975 and max_height will be zero.
13977 2. We have some glyphs that don't contribute to the line height.
13978 (The glyph row flag contributes_to_line_height_p is for future
13979 pixmap extensions).
13981 The first case is easily covered by using default values because in
13982 these cases, the line height does not really matter, except that it
13983 must not be zero. */
13985 static void
13986 compute_line_metrics (it)
13987 struct it *it;
13989 struct glyph_row *row = it->glyph_row;
13990 int area, i;
13992 if (FRAME_WINDOW_P (it->f))
13994 int i, min_y, max_y;
13996 /* The line may consist of one space only, that was added to
13997 place the cursor on it. If so, the row's height hasn't been
13998 computed yet. */
13999 if (row->height == 0)
14001 if (it->max_ascent + it->max_descent == 0)
14002 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14003 row->ascent = it->max_ascent;
14004 row->height = it->max_ascent + it->max_descent;
14005 row->phys_ascent = it->max_phys_ascent;
14006 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14009 /* Compute the width of this line. */
14010 row->pixel_width = row->x;
14011 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14012 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14014 xassert (row->pixel_width >= 0);
14015 xassert (row->ascent >= 0 && row->height > 0);
14017 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14018 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14020 /* If first line's physical ascent is larger than its logical
14021 ascent, use the physical ascent, and make the row taller.
14022 This makes accented characters fully visible. */
14023 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14024 && row->phys_ascent > row->ascent)
14026 row->height += row->phys_ascent - row->ascent;
14027 row->ascent = row->phys_ascent;
14030 /* Compute how much of the line is visible. */
14031 row->visible_height = row->height;
14033 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14034 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14036 if (row->y < min_y)
14037 row->visible_height -= min_y - row->y;
14038 if (row->y + row->height > max_y)
14039 row->visible_height -= row->y + row->height - max_y;
14041 else
14043 row->pixel_width = row->used[TEXT_AREA];
14044 if (row->continued_p)
14045 row->pixel_width -= it->continuation_pixel_width;
14046 else if (row->truncated_on_right_p)
14047 row->pixel_width -= it->truncation_pixel_width;
14048 row->ascent = row->phys_ascent = 0;
14049 row->height = row->phys_height = row->visible_height = 1;
14052 /* Compute a hash code for this row. */
14053 row->hash = 0;
14054 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14055 for (i = 0; i < row->used[area]; ++i)
14056 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14057 + row->glyphs[area][i].u.val
14058 + row->glyphs[area][i].face_id
14059 + row->glyphs[area][i].padding_p
14060 + (row->glyphs[area][i].type << 2));
14062 it->max_ascent = it->max_descent = 0;
14063 it->max_phys_ascent = it->max_phys_descent = 0;
14067 /* Append one space to the glyph row of iterator IT if doing a
14068 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14069 space have the default face, otherwise let it have the same face as
14070 IT->face_id. Value is non-zero if a space was added.
14072 This function is called to make sure that there is always one glyph
14073 at the end of a glyph row that the cursor can be set on under
14074 window-systems. (If there weren't such a glyph we would not know
14075 how wide and tall a box cursor should be displayed).
14077 At the same time this space let's a nicely handle clearing to the
14078 end of the line if the row ends in italic text. */
14080 static int
14081 append_space (it, default_face_p)
14082 struct it *it;
14083 int default_face_p;
14085 if (FRAME_WINDOW_P (it->f))
14087 int n = it->glyph_row->used[TEXT_AREA];
14089 if (it->glyph_row->glyphs[TEXT_AREA] + n
14090 < it->glyph_row->glyphs[1 + TEXT_AREA])
14092 /* Save some values that must not be changed.
14093 Must save IT->c and IT->len because otherwise
14094 ITERATOR_AT_END_P wouldn't work anymore after
14095 append_space has been called. */
14096 enum display_element_type saved_what = it->what;
14097 int saved_c = it->c, saved_len = it->len;
14098 int saved_x = it->current_x;
14099 int saved_face_id = it->face_id;
14100 struct text_pos saved_pos;
14101 Lisp_Object saved_object;
14102 struct face *face;
14104 saved_object = it->object;
14105 saved_pos = it->position;
14107 it->what = IT_CHARACTER;
14108 bzero (&it->position, sizeof it->position);
14109 it->object = make_number (0);
14110 it->c = ' ';
14111 it->len = 1;
14113 if (default_face_p)
14114 it->face_id = DEFAULT_FACE_ID;
14115 else if (it->face_before_selective_p)
14116 it->face_id = it->saved_face_id;
14117 face = FACE_FROM_ID (it->f, it->face_id);
14118 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14120 PRODUCE_GLYPHS (it);
14122 it->current_x = saved_x;
14123 it->object = saved_object;
14124 it->position = saved_pos;
14125 it->what = saved_what;
14126 it->face_id = saved_face_id;
14127 it->len = saved_len;
14128 it->c = saved_c;
14129 return 1;
14133 return 0;
14137 /* Extend the face of the last glyph in the text area of IT->glyph_row
14138 to the end of the display line. Called from display_line.
14139 If the glyph row is empty, add a space glyph to it so that we
14140 know the face to draw. Set the glyph row flag fill_line_p. */
14142 static void
14143 extend_face_to_end_of_line (it)
14144 struct it *it;
14146 struct face *face;
14147 struct frame *f = it->f;
14149 /* If line is already filled, do nothing. */
14150 if (it->current_x >= it->last_visible_x)
14151 return;
14153 /* Face extension extends the background and box of IT->face_id
14154 to the end of the line. If the background equals the background
14155 of the frame, we don't have to do anything. */
14156 if (it->face_before_selective_p)
14157 face = FACE_FROM_ID (it->f, it->saved_face_id);
14158 else
14159 face = FACE_FROM_ID (f, it->face_id);
14161 if (FRAME_WINDOW_P (f)
14162 && face->box == FACE_NO_BOX
14163 && face->background == FRAME_BACKGROUND_PIXEL (f)
14164 && !face->stipple)
14165 return;
14167 /* Set the glyph row flag indicating that the face of the last glyph
14168 in the text area has to be drawn to the end of the text area. */
14169 it->glyph_row->fill_line_p = 1;
14171 /* If current character of IT is not ASCII, make sure we have the
14172 ASCII face. This will be automatically undone the next time
14173 get_next_display_element returns a multibyte character. Note
14174 that the character will always be single byte in unibyte text. */
14175 if (!SINGLE_BYTE_CHAR_P (it->c))
14177 it->face_id = FACE_FOR_CHAR (f, face, 0);
14180 if (FRAME_WINDOW_P (f))
14182 /* If the row is empty, add a space with the current face of IT,
14183 so that we know which face to draw. */
14184 if (it->glyph_row->used[TEXT_AREA] == 0)
14186 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14187 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14188 it->glyph_row->used[TEXT_AREA] = 1;
14191 else
14193 /* Save some values that must not be changed. */
14194 int saved_x = it->current_x;
14195 struct text_pos saved_pos;
14196 Lisp_Object saved_object;
14197 enum display_element_type saved_what = it->what;
14198 int saved_face_id = it->face_id;
14200 saved_object = it->object;
14201 saved_pos = it->position;
14203 it->what = IT_CHARACTER;
14204 bzero (&it->position, sizeof it->position);
14205 it->object = make_number (0);
14206 it->c = ' ';
14207 it->len = 1;
14208 it->face_id = face->id;
14210 PRODUCE_GLYPHS (it);
14212 while (it->current_x <= it->last_visible_x)
14213 PRODUCE_GLYPHS (it);
14215 /* Don't count these blanks really. It would let us insert a left
14216 truncation glyph below and make us set the cursor on them, maybe. */
14217 it->current_x = saved_x;
14218 it->object = saved_object;
14219 it->position = saved_pos;
14220 it->what = saved_what;
14221 it->face_id = saved_face_id;
14226 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14227 trailing whitespace. */
14229 static int
14230 trailing_whitespace_p (charpos)
14231 int charpos;
14233 int bytepos = CHAR_TO_BYTE (charpos);
14234 int c = 0;
14236 while (bytepos < ZV_BYTE
14237 && (c = FETCH_CHAR (bytepos),
14238 c == ' ' || c == '\t'))
14239 ++bytepos;
14241 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14243 if (bytepos != PT_BYTE)
14244 return 1;
14246 return 0;
14250 /* Highlight trailing whitespace, if any, in ROW. */
14252 void
14253 highlight_trailing_whitespace (f, row)
14254 struct frame *f;
14255 struct glyph_row *row;
14257 int used = row->used[TEXT_AREA];
14259 if (used)
14261 struct glyph *start = row->glyphs[TEXT_AREA];
14262 struct glyph *glyph = start + used - 1;
14264 /* Skip over glyphs inserted to display the cursor at the
14265 end of a line, for extending the face of the last glyph
14266 to the end of the line on terminals, and for truncation
14267 and continuation glyphs. */
14268 while (glyph >= start
14269 && glyph->type == CHAR_GLYPH
14270 && INTEGERP (glyph->object))
14271 --glyph;
14273 /* If last glyph is a space or stretch, and it's trailing
14274 whitespace, set the face of all trailing whitespace glyphs in
14275 IT->glyph_row to `trailing-whitespace'. */
14276 if (glyph >= start
14277 && BUFFERP (glyph->object)
14278 && (glyph->type == STRETCH_GLYPH
14279 || (glyph->type == CHAR_GLYPH
14280 && glyph->u.ch == ' '))
14281 && trailing_whitespace_p (glyph->charpos))
14283 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14285 while (glyph >= start
14286 && BUFFERP (glyph->object)
14287 && (glyph->type == STRETCH_GLYPH
14288 || (glyph->type == CHAR_GLYPH
14289 && glyph->u.ch == ' ')))
14290 (glyph--)->face_id = face_id;
14296 /* Value is non-zero if glyph row ROW in window W should be
14297 used to hold the cursor. */
14299 static int
14300 cursor_row_p (w, row)
14301 struct window *w;
14302 struct glyph_row *row;
14304 int cursor_row_p = 1;
14306 if (PT == MATRIX_ROW_END_CHARPOS (row))
14308 /* If the row ends with a newline from a string, we don't want
14309 the cursor there (if the row is continued it doesn't end in a
14310 newline). */
14311 if (CHARPOS (row->end.string_pos) >= 0
14312 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14313 cursor_row_p = row->continued_p;
14315 /* If the row ends at ZV, display the cursor at the end of that
14316 row instead of at the start of the row below. */
14317 else if (row->ends_at_zv_p)
14318 cursor_row_p = 1;
14319 else
14320 cursor_row_p = 0;
14323 return cursor_row_p;
14327 /* Construct the glyph row IT->glyph_row in the desired matrix of
14328 IT->w from text at the current position of IT. See dispextern.h
14329 for an overview of struct it. Value is non-zero if
14330 IT->glyph_row displays text, as opposed to a line displaying ZV
14331 only. */
14333 static int
14334 display_line (it)
14335 struct it *it;
14337 struct glyph_row *row = it->glyph_row;
14339 /* We always start displaying at hpos zero even if hscrolled. */
14340 xassert (it->hpos == 0 && it->current_x == 0);
14342 /* We must not display in a row that's not a text row. */
14343 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14344 < it->w->desired_matrix->nrows);
14346 /* Is IT->w showing the region? */
14347 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14349 /* Clear the result glyph row and enable it. */
14350 prepare_desired_row (row);
14352 row->y = it->current_y;
14353 row->start = it->start;
14354 row->continuation_lines_width = it->continuation_lines_width;
14355 row->displays_text_p = 1;
14356 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14357 it->starts_in_middle_of_char_p = 0;
14359 /* Arrange the overlays nicely for our purposes. Usually, we call
14360 display_line on only one line at a time, in which case this
14361 can't really hurt too much, or we call it on lines which appear
14362 one after another in the buffer, in which case all calls to
14363 recenter_overlay_lists but the first will be pretty cheap. */
14364 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14366 /* Move over display elements that are not visible because we are
14367 hscrolled. This may stop at an x-position < IT->first_visible_x
14368 if the first glyph is partially visible or if we hit a line end. */
14369 if (it->current_x < it->first_visible_x)
14370 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14371 MOVE_TO_POS | MOVE_TO_X);
14373 /* Get the initial row height. This is either the height of the
14374 text hscrolled, if there is any, or zero. */
14375 row->ascent = it->max_ascent;
14376 row->height = it->max_ascent + it->max_descent;
14377 row->phys_ascent = it->max_phys_ascent;
14378 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14380 /* Loop generating characters. The loop is left with IT on the next
14381 character to display. */
14382 while (1)
14384 int n_glyphs_before, hpos_before, x_before;
14385 int x, i, nglyphs;
14386 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14388 /* Retrieve the next thing to display. Value is zero if end of
14389 buffer reached. */
14390 if (!get_next_display_element (it))
14392 /* Maybe add a space at the end of this line that is used to
14393 display the cursor there under X. Set the charpos of the
14394 first glyph of blank lines not corresponding to any text
14395 to -1. */
14396 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14397 || row->used[TEXT_AREA] == 0)
14399 row->glyphs[TEXT_AREA]->charpos = -1;
14400 row->displays_text_p = 0;
14402 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14403 && (!MINI_WINDOW_P (it->w)
14404 || (minibuf_level && EQ (it->window, minibuf_window))))
14405 row->indicate_empty_line_p = 1;
14408 it->continuation_lines_width = 0;
14409 row->ends_at_zv_p = 1;
14410 break;
14413 /* Now, get the metrics of what we want to display. This also
14414 generates glyphs in `row' (which is IT->glyph_row). */
14415 n_glyphs_before = row->used[TEXT_AREA];
14416 x = it->current_x;
14418 /* Remember the line height so far in case the next element doesn't
14419 fit on the line. */
14420 if (!it->truncate_lines_p)
14422 ascent = it->max_ascent;
14423 descent = it->max_descent;
14424 phys_ascent = it->max_phys_ascent;
14425 phys_descent = it->max_phys_descent;
14428 PRODUCE_GLYPHS (it);
14430 /* If this display element was in marginal areas, continue with
14431 the next one. */
14432 if (it->area != TEXT_AREA)
14434 row->ascent = max (row->ascent, it->max_ascent);
14435 row->height = max (row->height, it->max_ascent + it->max_descent);
14436 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14437 row->phys_height = max (row->phys_height,
14438 it->max_phys_ascent + it->max_phys_descent);
14439 set_iterator_to_next (it, 1);
14440 continue;
14443 /* Does the display element fit on the line? If we truncate
14444 lines, we should draw past the right edge of the window. If
14445 we don't truncate, we want to stop so that we can display the
14446 continuation glyph before the right margin. If lines are
14447 continued, there are two possible strategies for characters
14448 resulting in more than 1 glyph (e.g. tabs): Display as many
14449 glyphs as possible in this line and leave the rest for the
14450 continuation line, or display the whole element in the next
14451 line. Original redisplay did the former, so we do it also. */
14452 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14453 hpos_before = it->hpos;
14454 x_before = x;
14456 if (/* Not a newline. */
14457 nglyphs > 0
14458 /* Glyphs produced fit entirely in the line. */
14459 && it->current_x < it->last_visible_x)
14461 it->hpos += nglyphs;
14462 row->ascent = max (row->ascent, it->max_ascent);
14463 row->height = max (row->height, it->max_ascent + it->max_descent);
14464 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14465 row->phys_height = max (row->phys_height,
14466 it->max_phys_ascent + it->max_phys_descent);
14467 if (it->current_x - it->pixel_width < it->first_visible_x)
14468 row->x = x - it->first_visible_x;
14470 else
14472 int new_x;
14473 struct glyph *glyph;
14475 for (i = 0; i < nglyphs; ++i, x = new_x)
14477 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14478 new_x = x + glyph->pixel_width;
14480 if (/* Lines are continued. */
14481 !it->truncate_lines_p
14482 && (/* Glyph doesn't fit on the line. */
14483 new_x > it->last_visible_x
14484 /* Or it fits exactly on a window system frame. */
14485 || (new_x == it->last_visible_x
14486 && FRAME_WINDOW_P (it->f))))
14488 /* End of a continued line. */
14490 if (it->hpos == 0
14491 || (new_x == it->last_visible_x
14492 && FRAME_WINDOW_P (it->f)))
14494 /* Current glyph is the only one on the line or
14495 fits exactly on the line. We must continue
14496 the line because we can't draw the cursor
14497 after the glyph. */
14498 row->continued_p = 1;
14499 it->current_x = new_x;
14500 it->continuation_lines_width += new_x;
14501 ++it->hpos;
14502 if (i == nglyphs - 1)
14503 set_iterator_to_next (it, 1);
14505 else if (CHAR_GLYPH_PADDING_P (*glyph)
14506 && !FRAME_WINDOW_P (it->f))
14508 /* A padding glyph that doesn't fit on this line.
14509 This means the whole character doesn't fit
14510 on the line. */
14511 row->used[TEXT_AREA] = n_glyphs_before;
14513 /* Fill the rest of the row with continuation
14514 glyphs like in 20.x. */
14515 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14516 < row->glyphs[1 + TEXT_AREA])
14517 produce_special_glyphs (it, IT_CONTINUATION);
14519 row->continued_p = 1;
14520 it->current_x = x_before;
14521 it->continuation_lines_width += x_before;
14523 /* Restore the height to what it was before the
14524 element not fitting on the line. */
14525 it->max_ascent = ascent;
14526 it->max_descent = descent;
14527 it->max_phys_ascent = phys_ascent;
14528 it->max_phys_descent = phys_descent;
14530 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14532 /* A TAB that extends past the right edge of the
14533 window. This produces a single glyph on
14534 window system frames. We leave the glyph in
14535 this row and let it fill the row, but don't
14536 consume the TAB. */
14537 it->continuation_lines_width += it->last_visible_x;
14538 row->ends_in_middle_of_char_p = 1;
14539 row->continued_p = 1;
14540 glyph->pixel_width = it->last_visible_x - x;
14541 it->starts_in_middle_of_char_p = 1;
14543 else
14545 /* Something other than a TAB that draws past
14546 the right edge of the window. Restore
14547 positions to values before the element. */
14548 row->used[TEXT_AREA] = n_glyphs_before + i;
14550 /* Display continuation glyphs. */
14551 if (!FRAME_WINDOW_P (it->f))
14552 produce_special_glyphs (it, IT_CONTINUATION);
14553 row->continued_p = 1;
14555 it->continuation_lines_width += x;
14557 if (nglyphs > 1 && i > 0)
14559 row->ends_in_middle_of_char_p = 1;
14560 it->starts_in_middle_of_char_p = 1;
14563 /* Restore the height to what it was before the
14564 element not fitting on the line. */
14565 it->max_ascent = ascent;
14566 it->max_descent = descent;
14567 it->max_phys_ascent = phys_ascent;
14568 it->max_phys_descent = phys_descent;
14571 break;
14573 else if (new_x > it->first_visible_x)
14575 /* Increment number of glyphs actually displayed. */
14576 ++it->hpos;
14578 if (x < it->first_visible_x)
14579 /* Glyph is partially visible, i.e. row starts at
14580 negative X position. */
14581 row->x = x - it->first_visible_x;
14583 else
14585 /* Glyph is completely off the left margin of the
14586 window. This should not happen because of the
14587 move_it_in_display_line at the start of this
14588 function, unless the text display area of the
14589 window is empty. */
14590 xassert (it->first_visible_x <= it->last_visible_x);
14594 row->ascent = max (row->ascent, it->max_ascent);
14595 row->height = max (row->height, it->max_ascent + it->max_descent);
14596 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14597 row->phys_height = max (row->phys_height,
14598 it->max_phys_ascent + it->max_phys_descent);
14600 /* End of this display line if row is continued. */
14601 if (row->continued_p)
14602 break;
14605 /* Is this a line end? If yes, we're also done, after making
14606 sure that a non-default face is extended up to the right
14607 margin of the window. */
14608 if (ITERATOR_AT_END_OF_LINE_P (it))
14610 int used_before = row->used[TEXT_AREA];
14612 row->ends_in_newline_from_string_p = STRINGP (it->object);
14614 /* Add a space at the end of the line that is used to
14615 display the cursor there. */
14616 append_space (it, 0);
14618 /* Extend the face to the end of the line. */
14619 extend_face_to_end_of_line (it);
14621 /* Make sure we have the position. */
14622 if (used_before == 0)
14623 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14625 /* Consume the line end. This skips over invisible lines. */
14626 set_iterator_to_next (it, 1);
14627 it->continuation_lines_width = 0;
14628 break;
14631 /* Proceed with next display element. Note that this skips
14632 over lines invisible because of selective display. */
14633 set_iterator_to_next (it, 1);
14635 /* If we truncate lines, we are done when the last displayed
14636 glyphs reach past the right margin of the window. */
14637 if (it->truncate_lines_p
14638 && (FRAME_WINDOW_P (it->f)
14639 ? (it->current_x >= it->last_visible_x)
14640 : (it->current_x > it->last_visible_x)))
14642 /* Maybe add truncation glyphs. */
14643 if (!FRAME_WINDOW_P (it->f))
14645 int i, n;
14647 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14648 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14649 break;
14651 for (n = row->used[TEXT_AREA]; i < n; ++i)
14653 row->used[TEXT_AREA] = i;
14654 produce_special_glyphs (it, IT_TRUNCATION);
14658 row->truncated_on_right_p = 1;
14659 it->continuation_lines_width = 0;
14660 reseat_at_next_visible_line_start (it, 0);
14661 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14662 it->hpos = hpos_before;
14663 it->current_x = x_before;
14664 break;
14668 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14669 at the left window margin. */
14670 if (it->first_visible_x
14671 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14673 if (!FRAME_WINDOW_P (it->f))
14674 insert_left_trunc_glyphs (it);
14675 row->truncated_on_left_p = 1;
14678 /* If the start of this line is the overlay arrow-position, then
14679 mark this glyph row as the one containing the overlay arrow.
14680 This is clearly a mess with variable size fonts. It would be
14681 better to let it be displayed like cursors under X. */
14682 if (MARKERP (Voverlay_arrow_position)
14683 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14684 && (MATRIX_ROW_START_CHARPOS (row)
14685 == marker_position (Voverlay_arrow_position))
14686 && STRINGP (Voverlay_arrow_string)
14687 && ! overlay_arrow_seen)
14689 /* Overlay arrow in window redisplay is a fringe bitmap. */
14690 if (!FRAME_WINDOW_P (it->f))
14692 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14693 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14694 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14695 struct glyph *p = row->glyphs[TEXT_AREA];
14696 struct glyph *p2, *end;
14698 /* Copy the arrow glyphs. */
14699 while (glyph < arrow_end)
14700 *p++ = *glyph++;
14702 /* Throw away padding glyphs. */
14703 p2 = p;
14704 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14705 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14706 ++p2;
14707 if (p2 > p)
14709 while (p2 < end)
14710 *p++ = *p2++;
14711 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14715 overlay_arrow_seen = 1;
14716 row->overlay_arrow_p = 1;
14719 /* Compute pixel dimensions of this line. */
14720 compute_line_metrics (it);
14722 /* Remember the position at which this line ends. */
14723 row->end = it->current;
14725 /* Maybe set the cursor. */
14726 if (it->w->cursor.vpos < 0
14727 && PT >= MATRIX_ROW_START_CHARPOS (row)
14728 && PT <= MATRIX_ROW_END_CHARPOS (row)
14729 && cursor_row_p (it->w, row))
14730 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14732 /* Highlight trailing whitespace. */
14733 if (!NILP (Vshow_trailing_whitespace))
14734 highlight_trailing_whitespace (it->f, it->glyph_row);
14736 /* Prepare for the next line. This line starts horizontally at (X
14737 HPOS) = (0 0). Vertical positions are incremented. As a
14738 convenience for the caller, IT->glyph_row is set to the next
14739 row to be used. */
14740 it->current_x = it->hpos = 0;
14741 it->current_y += row->height;
14742 ++it->vpos;
14743 ++it->glyph_row;
14744 it->start = it->current;
14745 return row->displays_text_p;
14750 /***********************************************************************
14751 Menu Bar
14752 ***********************************************************************/
14754 /* Redisplay the menu bar in the frame for window W.
14756 The menu bar of X frames that don't have X toolkit support is
14757 displayed in a special window W->frame->menu_bar_window.
14759 The menu bar of terminal frames is treated specially as far as
14760 glyph matrices are concerned. Menu bar lines are not part of
14761 windows, so the update is done directly on the frame matrix rows
14762 for the menu bar. */
14764 static void
14765 display_menu_bar (w)
14766 struct window *w;
14768 struct frame *f = XFRAME (WINDOW_FRAME (w));
14769 struct it it;
14770 Lisp_Object items;
14771 int i;
14773 /* Don't do all this for graphical frames. */
14774 #ifdef HAVE_NTGUI
14775 if (!NILP (Vwindow_system))
14776 return;
14777 #endif
14778 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14779 if (FRAME_X_P (f))
14780 return;
14781 #endif
14782 #ifdef MAC_OS
14783 if (FRAME_MAC_P (f))
14784 return;
14785 #endif
14787 #ifdef USE_X_TOOLKIT
14788 xassert (!FRAME_WINDOW_P (f));
14789 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14790 it.first_visible_x = 0;
14791 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14792 #else /* not USE_X_TOOLKIT */
14793 if (FRAME_WINDOW_P (f))
14795 /* Menu bar lines are displayed in the desired matrix of the
14796 dummy window menu_bar_window. */
14797 struct window *menu_w;
14798 xassert (WINDOWP (f->menu_bar_window));
14799 menu_w = XWINDOW (f->menu_bar_window);
14800 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14801 MENU_FACE_ID);
14802 it.first_visible_x = 0;
14803 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14805 else
14807 /* This is a TTY frame, i.e. character hpos/vpos are used as
14808 pixel x/y. */
14809 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14810 MENU_FACE_ID);
14811 it.first_visible_x = 0;
14812 it.last_visible_x = FRAME_COLS (f);
14814 #endif /* not USE_X_TOOLKIT */
14816 if (! mode_line_inverse_video)
14817 /* Force the menu-bar to be displayed in the default face. */
14818 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14820 /* Clear all rows of the menu bar. */
14821 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14823 struct glyph_row *row = it.glyph_row + i;
14824 clear_glyph_row (row);
14825 row->enabled_p = 1;
14826 row->full_width_p = 1;
14829 /* Display all items of the menu bar. */
14830 items = FRAME_MENU_BAR_ITEMS (it.f);
14831 for (i = 0; i < XVECTOR (items)->size; i += 4)
14833 Lisp_Object string;
14835 /* Stop at nil string. */
14836 string = AREF (items, i + 1);
14837 if (NILP (string))
14838 break;
14840 /* Remember where item was displayed. */
14841 AREF (items, i + 3) = make_number (it.hpos);
14843 /* Display the item, pad with one space. */
14844 if (it.current_x < it.last_visible_x)
14845 display_string (NULL, string, Qnil, 0, 0, &it,
14846 SCHARS (string) + 1, 0, 0, -1);
14849 /* Fill out the line with spaces. */
14850 if (it.current_x < it.last_visible_x)
14851 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14853 /* Compute the total height of the lines. */
14854 compute_line_metrics (&it);
14859 /***********************************************************************
14860 Mode Line
14861 ***********************************************************************/
14863 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14864 FORCE is non-zero, redisplay mode lines unconditionally.
14865 Otherwise, redisplay only mode lines that are garbaged. Value is
14866 the number of windows whose mode lines were redisplayed. */
14868 static int
14869 redisplay_mode_lines (window, force)
14870 Lisp_Object window;
14871 int force;
14873 int nwindows = 0;
14875 while (!NILP (window))
14877 struct window *w = XWINDOW (window);
14879 if (WINDOWP (w->hchild))
14880 nwindows += redisplay_mode_lines (w->hchild, force);
14881 else if (WINDOWP (w->vchild))
14882 nwindows += redisplay_mode_lines (w->vchild, force);
14883 else if (force
14884 || FRAME_GARBAGED_P (XFRAME (w->frame))
14885 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14887 struct text_pos lpoint;
14888 struct buffer *old = current_buffer;
14890 /* Set the window's buffer for the mode line display. */
14891 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14892 set_buffer_internal_1 (XBUFFER (w->buffer));
14894 /* Point refers normally to the selected window. For any
14895 other window, set up appropriate value. */
14896 if (!EQ (window, selected_window))
14898 struct text_pos pt;
14900 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14901 if (CHARPOS (pt) < BEGV)
14902 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14903 else if (CHARPOS (pt) > (ZV - 1))
14904 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14905 else
14906 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14909 /* Display mode lines. */
14910 clear_glyph_matrix (w->desired_matrix);
14911 if (display_mode_lines (w))
14913 ++nwindows;
14914 w->must_be_updated_p = 1;
14917 /* Restore old settings. */
14918 set_buffer_internal_1 (old);
14919 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14922 window = w->next;
14925 return nwindows;
14929 /* Display the mode and/or top line of window W. Value is the number
14930 of mode lines displayed. */
14932 static int
14933 display_mode_lines (w)
14934 struct window *w;
14936 Lisp_Object old_selected_window, old_selected_frame;
14937 int n = 0;
14939 old_selected_frame = selected_frame;
14940 selected_frame = w->frame;
14941 old_selected_window = selected_window;
14942 XSETWINDOW (selected_window, w);
14944 /* These will be set while the mode line specs are processed. */
14945 line_number_displayed = 0;
14946 w->column_number_displayed = Qnil;
14948 if (WINDOW_WANTS_MODELINE_P (w))
14950 struct window *sel_w = XWINDOW (old_selected_window);
14952 /* Select mode line face based on the real selected window. */
14953 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14954 current_buffer->mode_line_format);
14955 ++n;
14958 if (WINDOW_WANTS_HEADER_LINE_P (w))
14960 display_mode_line (w, HEADER_LINE_FACE_ID,
14961 current_buffer->header_line_format);
14962 ++n;
14965 selected_frame = old_selected_frame;
14966 selected_window = old_selected_window;
14967 return n;
14971 /* Display mode or top line of window W. FACE_ID specifies which line
14972 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14973 FORMAT is the mode line format to display. Value is the pixel
14974 height of the mode line displayed. */
14976 static int
14977 display_mode_line (w, face_id, format)
14978 struct window *w;
14979 enum face_id face_id;
14980 Lisp_Object format;
14982 struct it it;
14983 struct face *face;
14985 init_iterator (&it, w, -1, -1, NULL, face_id);
14986 prepare_desired_row (it.glyph_row);
14988 if (! mode_line_inverse_video)
14989 /* Force the mode-line to be displayed in the default face. */
14990 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14992 /* Temporarily make frame's keyboard the current kboard so that
14993 kboard-local variables in the mode_line_format will get the right
14994 values. */
14995 push_frame_kboard (it.f);
14996 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
14997 pop_frame_kboard ();
14999 /* Fill up with spaces. */
15000 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15002 compute_line_metrics (&it);
15003 it.glyph_row->full_width_p = 1;
15004 it.glyph_row->mode_line_p = 1;
15005 it.glyph_row->continued_p = 0;
15006 it.glyph_row->truncated_on_left_p = 0;
15007 it.glyph_row->truncated_on_right_p = 0;
15009 /* Make a 3D mode-line have a shadow at its right end. */
15010 face = FACE_FROM_ID (it.f, face_id);
15011 extend_face_to_end_of_line (&it);
15012 if (face->box != FACE_NO_BOX)
15014 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15015 + it.glyph_row->used[TEXT_AREA] - 1);
15016 last->right_box_line_p = 1;
15019 return it.glyph_row->height;
15022 /* Alist that caches the results of :propertize.
15023 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15024 Lisp_Object mode_line_proptrans_alist;
15026 /* List of strings making up the mode-line. */
15027 Lisp_Object mode_line_string_list;
15029 /* Base face property when building propertized mode line string. */
15030 static Lisp_Object mode_line_string_face;
15031 static Lisp_Object mode_line_string_face_prop;
15034 /* Contribute ELT to the mode line for window IT->w. How it
15035 translates into text depends on its data type.
15037 IT describes the display environment in which we display, as usual.
15039 DEPTH is the depth in recursion. It is used to prevent
15040 infinite recursion here.
15042 FIELD_WIDTH is the number of characters the display of ELT should
15043 occupy in the mode line, and PRECISION is the maximum number of
15044 characters to display from ELT's representation. See
15045 display_string for details.
15047 Returns the hpos of the end of the text generated by ELT.
15049 PROPS is a property list to add to any string we encounter.
15051 If RISKY is nonzero, remove (disregard) any properties in any string
15052 we encounter, and ignore :eval and :propertize.
15054 If the global variable `frame_title_ptr' is non-NULL, then the output
15055 is passed to `store_frame_title' instead of `display_string'. */
15057 static int
15058 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15059 struct it *it;
15060 int depth;
15061 int field_width, precision;
15062 Lisp_Object elt, props;
15063 int risky;
15065 int n = 0, field, prec;
15066 int literal = 0;
15068 tail_recurse:
15069 if (depth > 100)
15070 elt = build_string ("*too-deep*");
15072 depth++;
15074 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15076 case Lisp_String:
15078 /* A string: output it and check for %-constructs within it. */
15079 unsigned char c;
15080 const unsigned char *this, *lisp_string;
15082 if (!NILP (props) || risky)
15084 Lisp_Object oprops, aelt;
15085 oprops = Ftext_properties_at (make_number (0), elt);
15087 if (NILP (Fequal (props, oprops)) || risky)
15089 /* If the starting string has properties,
15090 merge the specified ones onto the existing ones. */
15091 if (! NILP (oprops) && !risky)
15093 Lisp_Object tem;
15095 oprops = Fcopy_sequence (oprops);
15096 tem = props;
15097 while (CONSP (tem))
15099 oprops = Fplist_put (oprops, XCAR (tem),
15100 XCAR (XCDR (tem)));
15101 tem = XCDR (XCDR (tem));
15103 props = oprops;
15106 aelt = Fassoc (elt, mode_line_proptrans_alist);
15107 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15109 mode_line_proptrans_alist
15110 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15111 elt = XCAR (aelt);
15113 else
15115 Lisp_Object tem;
15117 elt = Fcopy_sequence (elt);
15118 Fset_text_properties (make_number (0), Flength (elt),
15119 props, elt);
15120 /* Add this item to mode_line_proptrans_alist. */
15121 mode_line_proptrans_alist
15122 = Fcons (Fcons (elt, props),
15123 mode_line_proptrans_alist);
15124 /* Truncate mode_line_proptrans_alist
15125 to at most 50 elements. */
15126 tem = Fnthcdr (make_number (50),
15127 mode_line_proptrans_alist);
15128 if (! NILP (tem))
15129 XSETCDR (tem, Qnil);
15134 this = SDATA (elt);
15135 lisp_string = this;
15137 if (literal)
15139 prec = precision - n;
15140 if (frame_title_ptr)
15141 n += store_frame_title (SDATA (elt), -1, prec);
15142 else if (!NILP (mode_line_string_list))
15143 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15144 else
15145 n += display_string (NULL, elt, Qnil, 0, 0, it,
15146 0, prec, 0, STRING_MULTIBYTE (elt));
15148 break;
15151 while ((precision <= 0 || n < precision)
15152 && *this
15153 && (frame_title_ptr
15154 || !NILP (mode_line_string_list)
15155 || it->current_x < it->last_visible_x))
15157 const unsigned char *last = this;
15159 /* Advance to end of string or next format specifier. */
15160 while ((c = *this++) != '\0' && c != '%')
15163 if (this - 1 != last)
15165 /* Output to end of string or up to '%'. Field width
15166 is length of string. Don't output more than
15167 PRECISION allows us. */
15168 --this;
15170 prec = chars_in_text (last, this - last);
15171 if (precision > 0 && prec > precision - n)
15172 prec = precision - n;
15174 if (frame_title_ptr)
15175 n += store_frame_title (last, 0, prec);
15176 else if (!NILP (mode_line_string_list))
15178 int bytepos = last - lisp_string;
15179 int charpos = string_byte_to_char (elt, bytepos);
15180 n += store_mode_line_string (NULL,
15181 Fsubstring (elt, make_number (charpos),
15182 make_number (charpos + prec)),
15183 0, 0, 0, Qnil);
15185 else
15187 int bytepos = last - lisp_string;
15188 int charpos = string_byte_to_char (elt, bytepos);
15189 n += display_string (NULL, elt, Qnil, 0, charpos,
15190 it, 0, prec, 0,
15191 STRING_MULTIBYTE (elt));
15194 else /* c == '%' */
15196 const unsigned char *percent_position = this;
15198 /* Get the specified minimum width. Zero means
15199 don't pad. */
15200 field = 0;
15201 while ((c = *this++) >= '0' && c <= '9')
15202 field = field * 10 + c - '0';
15204 /* Don't pad beyond the total padding allowed. */
15205 if (field_width - n > 0 && field > field_width - n)
15206 field = field_width - n;
15208 /* Note that either PRECISION <= 0 or N < PRECISION. */
15209 prec = precision - n;
15211 if (c == 'M')
15212 n += display_mode_element (it, depth, field, prec,
15213 Vglobal_mode_string, props,
15214 risky);
15215 else if (c != 0)
15217 int multibyte;
15218 int bytepos, charpos;
15219 unsigned char *spec;
15221 bytepos = percent_position - lisp_string;
15222 charpos = (STRING_MULTIBYTE (elt)
15223 ? string_byte_to_char (elt, bytepos)
15224 : bytepos);
15226 spec
15227 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15229 if (frame_title_ptr)
15230 n += store_frame_title (spec, field, prec);
15231 else if (!NILP (mode_line_string_list))
15233 int len = strlen (spec);
15234 Lisp_Object tem = make_string (spec, len);
15235 props = Ftext_properties_at (make_number (charpos), elt);
15236 /* Should only keep face property in props */
15237 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15239 else
15241 int nglyphs_before, nwritten;
15243 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15244 nwritten = display_string (spec, Qnil, elt,
15245 charpos, 0, it,
15246 field, prec, 0,
15247 multibyte);
15249 /* Assign to the glyphs written above the
15250 string where the `%x' came from, position
15251 of the `%'. */
15252 if (nwritten > 0)
15254 struct glyph *glyph
15255 = (it->glyph_row->glyphs[TEXT_AREA]
15256 + nglyphs_before);
15257 int i;
15259 for (i = 0; i < nwritten; ++i)
15261 glyph[i].object = elt;
15262 glyph[i].charpos = charpos;
15265 n += nwritten;
15269 else /* c == 0 */
15270 break;
15274 break;
15276 case Lisp_Symbol:
15277 /* A symbol: process the value of the symbol recursively
15278 as if it appeared here directly. Avoid error if symbol void.
15279 Special case: if value of symbol is a string, output the string
15280 literally. */
15282 register Lisp_Object tem;
15284 /* If the variable is not marked as risky to set
15285 then its contents are risky to use. */
15286 if (NILP (Fget (elt, Qrisky_local_variable)))
15287 risky = 1;
15289 tem = Fboundp (elt);
15290 if (!NILP (tem))
15292 tem = Fsymbol_value (elt);
15293 /* If value is a string, output that string literally:
15294 don't check for % within it. */
15295 if (STRINGP (tem))
15296 literal = 1;
15298 if (!EQ (tem, elt))
15300 /* Give up right away for nil or t. */
15301 elt = tem;
15302 goto tail_recurse;
15306 break;
15308 case Lisp_Cons:
15310 register Lisp_Object car, tem;
15312 /* A cons cell: five distinct cases.
15313 If first element is :eval or :propertize, do something special.
15314 If first element is a string or a cons, process all the elements
15315 and effectively concatenate them.
15316 If first element is a negative number, truncate displaying cdr to
15317 at most that many characters. If positive, pad (with spaces)
15318 to at least that many characters.
15319 If first element is a symbol, process the cadr or caddr recursively
15320 according to whether the symbol's value is non-nil or nil. */
15321 car = XCAR (elt);
15322 if (EQ (car, QCeval))
15324 /* An element of the form (:eval FORM) means evaluate FORM
15325 and use the result as mode line elements. */
15327 if (risky)
15328 break;
15330 if (CONSP (XCDR (elt)))
15332 Lisp_Object spec;
15333 spec = safe_eval (XCAR (XCDR (elt)));
15334 n += display_mode_element (it, depth, field_width - n,
15335 precision - n, spec, props,
15336 risky);
15339 else if (EQ (car, QCpropertize))
15341 /* An element of the form (:propertize ELT PROPS...)
15342 means display ELT but applying properties PROPS. */
15344 if (risky)
15345 break;
15347 if (CONSP (XCDR (elt)))
15348 n += display_mode_element (it, depth, field_width - n,
15349 precision - n, XCAR (XCDR (elt)),
15350 XCDR (XCDR (elt)), risky);
15352 else if (SYMBOLP (car))
15354 tem = Fboundp (car);
15355 elt = XCDR (elt);
15356 if (!CONSP (elt))
15357 goto invalid;
15358 /* elt is now the cdr, and we know it is a cons cell.
15359 Use its car if CAR has a non-nil value. */
15360 if (!NILP (tem))
15362 tem = Fsymbol_value (car);
15363 if (!NILP (tem))
15365 elt = XCAR (elt);
15366 goto tail_recurse;
15369 /* Symbol's value is nil (or symbol is unbound)
15370 Get the cddr of the original list
15371 and if possible find the caddr and use that. */
15372 elt = XCDR (elt);
15373 if (NILP (elt))
15374 break;
15375 else if (!CONSP (elt))
15376 goto invalid;
15377 elt = XCAR (elt);
15378 goto tail_recurse;
15380 else if (INTEGERP (car))
15382 register int lim = XINT (car);
15383 elt = XCDR (elt);
15384 if (lim < 0)
15386 /* Negative int means reduce maximum width. */
15387 if (precision <= 0)
15388 precision = -lim;
15389 else
15390 precision = min (precision, -lim);
15392 else if (lim > 0)
15394 /* Padding specified. Don't let it be more than
15395 current maximum. */
15396 if (precision > 0)
15397 lim = min (precision, lim);
15399 /* If that's more padding than already wanted, queue it.
15400 But don't reduce padding already specified even if
15401 that is beyond the current truncation point. */
15402 field_width = max (lim, field_width);
15404 goto tail_recurse;
15406 else if (STRINGP (car) || CONSP (car))
15408 register int limit = 50;
15409 /* Limit is to protect against circular lists. */
15410 while (CONSP (elt)
15411 && --limit > 0
15412 && (precision <= 0 || n < precision))
15414 n += display_mode_element (it, depth, field_width - n,
15415 precision - n, XCAR (elt),
15416 props, risky);
15417 elt = XCDR (elt);
15421 break;
15423 default:
15424 invalid:
15425 elt = build_string ("*invalid*");
15426 goto tail_recurse;
15429 /* Pad to FIELD_WIDTH. */
15430 if (field_width > 0 && n < field_width)
15432 if (frame_title_ptr)
15433 n += store_frame_title ("", field_width - n, 0);
15434 else if (!NILP (mode_line_string_list))
15435 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15436 else
15437 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15438 0, 0, 0);
15441 return n;
15444 /* Store a mode-line string element in mode_line_string_list.
15446 If STRING is non-null, display that C string. Otherwise, the Lisp
15447 string LISP_STRING is displayed.
15449 FIELD_WIDTH is the minimum number of output glyphs to produce.
15450 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15451 with spaces. FIELD_WIDTH <= 0 means don't pad.
15453 PRECISION is the maximum number of characters to output from
15454 STRING. PRECISION <= 0 means don't truncate the string.
15456 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15457 properties to the string.
15459 PROPS are the properties to add to the string.
15460 The mode_line_string_face face property is always added to the string.
15463 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15464 char *string;
15465 Lisp_Object lisp_string;
15466 int copy_string;
15467 int field_width;
15468 int precision;
15469 Lisp_Object props;
15471 int len;
15472 int n = 0;
15474 if (string != NULL)
15476 len = strlen (string);
15477 if (precision > 0 && len > precision)
15478 len = precision;
15479 lisp_string = make_string (string, len);
15480 if (NILP (props))
15481 props = mode_line_string_face_prop;
15482 else if (!NILP (mode_line_string_face))
15484 Lisp_Object face = Fplist_get (props, Qface);
15485 props = Fcopy_sequence (props);
15486 if (NILP (face))
15487 face = mode_line_string_face;
15488 else
15489 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15490 props = Fplist_put (props, Qface, face);
15492 Fadd_text_properties (make_number (0), make_number (len),
15493 props, lisp_string);
15495 else
15497 len = XFASTINT (Flength (lisp_string));
15498 if (precision > 0 && len > precision)
15500 len = precision;
15501 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15502 precision = -1;
15504 if (!NILP (mode_line_string_face))
15506 Lisp_Object face;
15507 if (NILP (props))
15508 props = Ftext_properties_at (make_number (0), lisp_string);
15509 face = Fplist_get (props, Qface);
15510 if (NILP (face))
15511 face = mode_line_string_face;
15512 else
15513 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15514 props = Fcons (Qface, Fcons (face, Qnil));
15515 if (copy_string)
15516 lisp_string = Fcopy_sequence (lisp_string);
15518 if (!NILP (props))
15519 Fadd_text_properties (make_number (0), make_number (len),
15520 props, lisp_string);
15523 if (len > 0)
15525 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15526 n += len;
15529 if (field_width > len)
15531 field_width -= len;
15532 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15533 if (!NILP (props))
15534 Fadd_text_properties (make_number (0), make_number (field_width),
15535 props, lisp_string);
15536 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15537 n += field_width;
15540 return n;
15544 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15545 0, 3, 0,
15546 doc: /* Return the mode-line of selected window as a string.
15547 First optional arg FORMAT specifies a different format string (see
15548 `mode-line-format' for details) to use. If FORMAT is t, return
15549 the buffer's header-line. Second optional arg WINDOW specifies a
15550 different window to use as the context for the formatting.
15551 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15552 (format, window, no_props)
15553 Lisp_Object format, window, no_props;
15555 struct it it;
15556 int len;
15557 struct window *w;
15558 struct buffer *old_buffer = NULL;
15559 enum face_id face_id = DEFAULT_FACE_ID;
15561 if (NILP (window))
15562 window = selected_window;
15563 CHECK_WINDOW (window);
15564 w = XWINDOW (window);
15565 CHECK_BUFFER (w->buffer);
15567 if (XBUFFER (w->buffer) != current_buffer)
15569 old_buffer = current_buffer;
15570 set_buffer_internal_1 (XBUFFER (w->buffer));
15573 if (NILP (format) || EQ (format, Qt))
15575 face_id = NILP (format)
15576 ? CURRENT_MODE_LINE_FACE_ID (w) :
15577 HEADER_LINE_FACE_ID;
15578 format = NILP (format)
15579 ? current_buffer->mode_line_format
15580 : current_buffer->header_line_format;
15583 init_iterator (&it, w, -1, -1, NULL, face_id);
15585 if (NILP (no_props))
15587 mode_line_string_face =
15588 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15589 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15590 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15592 mode_line_string_face_prop =
15593 NILP (mode_line_string_face) ? Qnil :
15594 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15596 /* We need a dummy last element in mode_line_string_list to
15597 indicate we are building the propertized mode-line string.
15598 Using mode_line_string_face_prop here GC protects it. */
15599 mode_line_string_list =
15600 Fcons (mode_line_string_face_prop, Qnil);
15601 frame_title_ptr = NULL;
15603 else
15605 mode_line_string_face_prop = Qnil;
15606 mode_line_string_list = Qnil;
15607 frame_title_ptr = frame_title_buf;
15610 push_frame_kboard (it.f);
15611 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15612 pop_frame_kboard ();
15614 if (old_buffer)
15615 set_buffer_internal_1 (old_buffer);
15617 if (NILP (no_props))
15619 Lisp_Object str;
15620 mode_line_string_list = Fnreverse (mode_line_string_list);
15621 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15622 make_string ("", 0));
15623 mode_line_string_face_prop = Qnil;
15624 mode_line_string_list = Qnil;
15625 return str;
15628 len = frame_title_ptr - frame_title_buf;
15629 if (len > 0 && frame_title_ptr[-1] == '-')
15631 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15632 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15634 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15635 if (len > frame_title_ptr - frame_title_buf)
15636 len = frame_title_ptr - frame_title_buf;
15639 frame_title_ptr = NULL;
15640 return make_string (frame_title_buf, len);
15643 /* Write a null-terminated, right justified decimal representation of
15644 the positive integer D to BUF using a minimal field width WIDTH. */
15646 static void
15647 pint2str (buf, width, d)
15648 register char *buf;
15649 register int width;
15650 register int d;
15652 register char *p = buf;
15654 if (d <= 0)
15655 *p++ = '0';
15656 else
15658 while (d > 0)
15660 *p++ = d % 10 + '0';
15661 d /= 10;
15665 for (width -= (int) (p - buf); width > 0; --width)
15666 *p++ = ' ';
15667 *p-- = '\0';
15668 while (p > buf)
15670 d = *buf;
15671 *buf++ = *p;
15672 *p-- = d;
15676 /* Write a null-terminated, right justified decimal and "human
15677 readable" representation of the nonnegative integer D to BUF using
15678 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15680 static const char power_letter[] =
15682 0, /* not used */
15683 'k', /* kilo */
15684 'M', /* mega */
15685 'G', /* giga */
15686 'T', /* tera */
15687 'P', /* peta */
15688 'E', /* exa */
15689 'Z', /* zetta */
15690 'Y' /* yotta */
15693 static void
15694 pint2hrstr (buf, width, d)
15695 char *buf;
15696 int width;
15697 int d;
15699 /* We aim to represent the nonnegative integer D as
15700 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15701 int quotient = d;
15702 int remainder = 0;
15703 /* -1 means: do not use TENTHS. */
15704 int tenths = -1;
15705 int exponent = 0;
15707 /* Length of QUOTIENT.TENTHS as a string. */
15708 int length;
15710 char * psuffix;
15711 char * p;
15713 if (1000 <= quotient)
15715 /* Scale to the appropriate EXPONENT. */
15718 remainder = quotient % 1000;
15719 quotient /= 1000;
15720 exponent++;
15722 while (1000 <= quotient);
15724 /* Round to nearest and decide whether to use TENTHS or not. */
15725 if (quotient <= 9)
15727 tenths = remainder / 100;
15728 if (50 <= remainder % 100)
15729 if (tenths < 9)
15730 tenths++;
15731 else
15733 quotient++;
15734 if (quotient == 10)
15735 tenths = -1;
15736 else
15737 tenths = 0;
15740 else
15741 if (500 <= remainder)
15742 if (quotient < 999)
15743 quotient++;
15744 else
15746 quotient = 1;
15747 exponent++;
15748 tenths = 0;
15752 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15753 if (tenths == -1 && quotient <= 99)
15754 if (quotient <= 9)
15755 length = 1;
15756 else
15757 length = 2;
15758 else
15759 length = 3;
15760 p = psuffix = buf + max (width, length);
15762 /* Print EXPONENT. */
15763 if (exponent)
15764 *psuffix++ = power_letter[exponent];
15765 *psuffix = '\0';
15767 /* Print TENTHS. */
15768 if (tenths >= 0)
15770 *--p = '0' + tenths;
15771 *--p = '.';
15774 /* Print QUOTIENT. */
15777 int digit = quotient % 10;
15778 *--p = '0' + digit;
15780 while ((quotient /= 10) != 0);
15782 /* Print leading spaces. */
15783 while (buf < p)
15784 *--p = ' ';
15787 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15788 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15789 type of CODING_SYSTEM. Return updated pointer into BUF. */
15791 static unsigned char invalid_eol_type[] = "(*invalid*)";
15793 static char *
15794 decode_mode_spec_coding (coding_system, buf, eol_flag)
15795 Lisp_Object coding_system;
15796 register char *buf;
15797 int eol_flag;
15799 Lisp_Object val;
15800 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15801 const unsigned char *eol_str;
15802 int eol_str_len;
15803 /* The EOL conversion we are using. */
15804 Lisp_Object eoltype;
15806 val = Fget (coding_system, Qcoding_system);
15807 eoltype = Qnil;
15809 if (!VECTORP (val)) /* Not yet decided. */
15811 if (multibyte)
15812 *buf++ = '-';
15813 if (eol_flag)
15814 eoltype = eol_mnemonic_undecided;
15815 /* Don't mention EOL conversion if it isn't decided. */
15817 else
15819 Lisp_Object eolvalue;
15821 eolvalue = Fget (coding_system, Qeol_type);
15823 if (multibyte)
15824 *buf++ = XFASTINT (AREF (val, 1));
15826 if (eol_flag)
15828 /* The EOL conversion that is normal on this system. */
15830 if (NILP (eolvalue)) /* Not yet decided. */
15831 eoltype = eol_mnemonic_undecided;
15832 else if (VECTORP (eolvalue)) /* Not yet decided. */
15833 eoltype = eol_mnemonic_undecided;
15834 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15835 eoltype = (XFASTINT (eolvalue) == 0
15836 ? eol_mnemonic_unix
15837 : (XFASTINT (eolvalue) == 1
15838 ? eol_mnemonic_dos : eol_mnemonic_mac));
15842 if (eol_flag)
15844 /* Mention the EOL conversion if it is not the usual one. */
15845 if (STRINGP (eoltype))
15847 eol_str = SDATA (eoltype);
15848 eol_str_len = SBYTES (eoltype);
15850 else if (INTEGERP (eoltype)
15851 && CHAR_VALID_P (XINT (eoltype), 0))
15853 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15854 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15855 eol_str = tmp;
15857 else
15859 eol_str = invalid_eol_type;
15860 eol_str_len = sizeof (invalid_eol_type) - 1;
15862 bcopy (eol_str, buf, eol_str_len);
15863 buf += eol_str_len;
15866 return buf;
15869 /* Return a string for the output of a mode line %-spec for window W,
15870 generated by character C. PRECISION >= 0 means don't return a
15871 string longer than that value. FIELD_WIDTH > 0 means pad the
15872 string returned with spaces to that value. Return 1 in *MULTIBYTE
15873 if the result is multibyte text. */
15875 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15877 static char *
15878 decode_mode_spec (w, c, field_width, precision, multibyte)
15879 struct window *w;
15880 register int c;
15881 int field_width, precision;
15882 int *multibyte;
15884 Lisp_Object obj;
15885 struct frame *f = XFRAME (WINDOW_FRAME (w));
15886 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15887 struct buffer *b = XBUFFER (w->buffer);
15889 obj = Qnil;
15890 *multibyte = 0;
15892 switch (c)
15894 case '*':
15895 if (!NILP (b->read_only))
15896 return "%";
15897 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15898 return "*";
15899 return "-";
15901 case '+':
15902 /* This differs from %* only for a modified read-only buffer. */
15903 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15904 return "*";
15905 if (!NILP (b->read_only))
15906 return "%";
15907 return "-";
15909 case '&':
15910 /* This differs from %* in ignoring read-only-ness. */
15911 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15912 return "*";
15913 return "-";
15915 case '%':
15916 return "%";
15918 case '[':
15920 int i;
15921 char *p;
15923 if (command_loop_level > 5)
15924 return "[[[... ";
15925 p = decode_mode_spec_buf;
15926 for (i = 0; i < command_loop_level; i++)
15927 *p++ = '[';
15928 *p = 0;
15929 return decode_mode_spec_buf;
15932 case ']':
15934 int i;
15935 char *p;
15937 if (command_loop_level > 5)
15938 return " ...]]]";
15939 p = decode_mode_spec_buf;
15940 for (i = 0; i < command_loop_level; i++)
15941 *p++ = ']';
15942 *p = 0;
15943 return decode_mode_spec_buf;
15946 case '-':
15948 register int i;
15950 /* Let lots_of_dashes be a string of infinite length. */
15951 if (!NILP (mode_line_string_list))
15952 return "--";
15953 if (field_width <= 0
15954 || field_width > sizeof (lots_of_dashes))
15956 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15957 decode_mode_spec_buf[i] = '-';
15958 decode_mode_spec_buf[i] = '\0';
15959 return decode_mode_spec_buf;
15961 else
15962 return lots_of_dashes;
15965 case 'b':
15966 obj = b->name;
15967 break;
15969 case 'c':
15971 int col = (int) current_column (); /* iftc */
15972 w->column_number_displayed = make_number (col);
15973 pint2str (decode_mode_spec_buf, field_width, col);
15974 return decode_mode_spec_buf;
15977 case 'F':
15978 /* %F displays the frame name. */
15979 if (!NILP (f->title))
15980 return (char *) SDATA (f->title);
15981 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15982 return (char *) SDATA (f->name);
15983 return "Emacs";
15985 case 'f':
15986 obj = b->filename;
15987 break;
15989 case 'i':
15991 int size = ZV - BEGV;
15992 pint2str (decode_mode_spec_buf, field_width, size);
15993 return decode_mode_spec_buf;
15996 case 'I':
15998 int size = ZV - BEGV;
15999 pint2hrstr (decode_mode_spec_buf, field_width, size);
16000 return decode_mode_spec_buf;
16003 case 'l':
16005 int startpos = XMARKER (w->start)->charpos;
16006 int startpos_byte = marker_byte_position (w->start);
16007 int line, linepos, linepos_byte, topline;
16008 int nlines, junk;
16009 int height = WINDOW_TOTAL_LINES (w);
16011 /* If we decided that this buffer isn't suitable for line numbers,
16012 don't forget that too fast. */
16013 if (EQ (w->base_line_pos, w->buffer))
16014 goto no_value;
16015 /* But do forget it, if the window shows a different buffer now. */
16016 else if (BUFFERP (w->base_line_pos))
16017 w->base_line_pos = Qnil;
16019 /* If the buffer is very big, don't waste time. */
16020 if (INTEGERP (Vline_number_display_limit)
16021 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16023 w->base_line_pos = Qnil;
16024 w->base_line_number = Qnil;
16025 goto no_value;
16028 if (!NILP (w->base_line_number)
16029 && !NILP (w->base_line_pos)
16030 && XFASTINT (w->base_line_pos) <= startpos)
16032 line = XFASTINT (w->base_line_number);
16033 linepos = XFASTINT (w->base_line_pos);
16034 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16036 else
16038 line = 1;
16039 linepos = BUF_BEGV (b);
16040 linepos_byte = BUF_BEGV_BYTE (b);
16043 /* Count lines from base line to window start position. */
16044 nlines = display_count_lines (linepos, linepos_byte,
16045 startpos_byte,
16046 startpos, &junk);
16048 topline = nlines + line;
16050 /* Determine a new base line, if the old one is too close
16051 or too far away, or if we did not have one.
16052 "Too close" means it's plausible a scroll-down would
16053 go back past it. */
16054 if (startpos == BUF_BEGV (b))
16056 w->base_line_number = make_number (topline);
16057 w->base_line_pos = make_number (BUF_BEGV (b));
16059 else if (nlines < height + 25 || nlines > height * 3 + 50
16060 || linepos == BUF_BEGV (b))
16062 int limit = BUF_BEGV (b);
16063 int limit_byte = BUF_BEGV_BYTE (b);
16064 int position;
16065 int distance = (height * 2 + 30) * line_number_display_limit_width;
16067 if (startpos - distance > limit)
16069 limit = startpos - distance;
16070 limit_byte = CHAR_TO_BYTE (limit);
16073 nlines = display_count_lines (startpos, startpos_byte,
16074 limit_byte,
16075 - (height * 2 + 30),
16076 &position);
16077 /* If we couldn't find the lines we wanted within
16078 line_number_display_limit_width chars per line,
16079 give up on line numbers for this window. */
16080 if (position == limit_byte && limit == startpos - distance)
16082 w->base_line_pos = w->buffer;
16083 w->base_line_number = Qnil;
16084 goto no_value;
16087 w->base_line_number = make_number (topline - nlines);
16088 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16091 /* Now count lines from the start pos to point. */
16092 nlines = display_count_lines (startpos, startpos_byte,
16093 PT_BYTE, PT, &junk);
16095 /* Record that we did display the line number. */
16096 line_number_displayed = 1;
16098 /* Make the string to show. */
16099 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16100 return decode_mode_spec_buf;
16101 no_value:
16103 char* p = decode_mode_spec_buf;
16104 int pad = field_width - 2;
16105 while (pad-- > 0)
16106 *p++ = ' ';
16107 *p++ = '?';
16108 *p++ = '?';
16109 *p = '\0';
16110 return decode_mode_spec_buf;
16113 break;
16115 case 'm':
16116 obj = b->mode_name;
16117 break;
16119 case 'n':
16120 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16121 return " Narrow";
16122 break;
16124 case 'p':
16126 int pos = marker_position (w->start);
16127 int total = BUF_ZV (b) - BUF_BEGV (b);
16129 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16131 if (pos <= BUF_BEGV (b))
16132 return "All";
16133 else
16134 return "Bottom";
16136 else if (pos <= BUF_BEGV (b))
16137 return "Top";
16138 else
16140 if (total > 1000000)
16141 /* Do it differently for a large value, to avoid overflow. */
16142 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16143 else
16144 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16145 /* We can't normally display a 3-digit number,
16146 so get us a 2-digit number that is close. */
16147 if (total == 100)
16148 total = 99;
16149 sprintf (decode_mode_spec_buf, "%2d%%", total);
16150 return decode_mode_spec_buf;
16154 /* Display percentage of size above the bottom of the screen. */
16155 case 'P':
16157 int toppos = marker_position (w->start);
16158 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16159 int total = BUF_ZV (b) - BUF_BEGV (b);
16161 if (botpos >= BUF_ZV (b))
16163 if (toppos <= BUF_BEGV (b))
16164 return "All";
16165 else
16166 return "Bottom";
16168 else
16170 if (total > 1000000)
16171 /* Do it differently for a large value, to avoid overflow. */
16172 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16173 else
16174 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16175 /* We can't normally display a 3-digit number,
16176 so get us a 2-digit number that is close. */
16177 if (total == 100)
16178 total = 99;
16179 if (toppos <= BUF_BEGV (b))
16180 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16181 else
16182 sprintf (decode_mode_spec_buf, "%2d%%", total);
16183 return decode_mode_spec_buf;
16187 case 's':
16188 /* status of process */
16189 obj = Fget_buffer_process (w->buffer);
16190 if (NILP (obj))
16191 return "no process";
16192 #ifdef subprocesses
16193 obj = Fsymbol_name (Fprocess_status (obj));
16194 #endif
16195 break;
16197 case 't': /* indicate TEXT or BINARY */
16198 #ifdef MODE_LINE_BINARY_TEXT
16199 return MODE_LINE_BINARY_TEXT (b);
16200 #else
16201 return "T";
16202 #endif
16204 case 'z':
16205 /* coding-system (not including end-of-line format) */
16206 case 'Z':
16207 /* coding-system (including end-of-line type) */
16209 int eol_flag = (c == 'Z');
16210 char *p = decode_mode_spec_buf;
16212 if (! FRAME_WINDOW_P (f))
16214 /* No need to mention EOL here--the terminal never needs
16215 to do EOL conversion. */
16216 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16217 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16219 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16220 p, eol_flag);
16222 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16223 #ifdef subprocesses
16224 obj = Fget_buffer_process (Fcurrent_buffer ());
16225 if (PROCESSP (obj))
16227 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16228 p, eol_flag);
16229 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16230 p, eol_flag);
16232 #endif /* subprocesses */
16233 #endif /* 0 */
16234 *p = 0;
16235 return decode_mode_spec_buf;
16239 if (STRINGP (obj))
16241 *multibyte = STRING_MULTIBYTE (obj);
16242 return (char *) SDATA (obj);
16244 else
16245 return "";
16249 /* Count up to COUNT lines starting from START / START_BYTE.
16250 But don't go beyond LIMIT_BYTE.
16251 Return the number of lines thus found (always nonnegative).
16253 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16255 static int
16256 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16257 int start, start_byte, limit_byte, count;
16258 int *byte_pos_ptr;
16260 register unsigned char *cursor;
16261 unsigned char *base;
16263 register int ceiling;
16264 register unsigned char *ceiling_addr;
16265 int orig_count = count;
16267 /* If we are not in selective display mode,
16268 check only for newlines. */
16269 int selective_display = (!NILP (current_buffer->selective_display)
16270 && !INTEGERP (current_buffer->selective_display));
16272 if (count > 0)
16274 while (start_byte < limit_byte)
16276 ceiling = BUFFER_CEILING_OF (start_byte);
16277 ceiling = min (limit_byte - 1, ceiling);
16278 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16279 base = (cursor = BYTE_POS_ADDR (start_byte));
16280 while (1)
16282 if (selective_display)
16283 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16285 else
16286 while (*cursor != '\n' && ++cursor != ceiling_addr)
16289 if (cursor != ceiling_addr)
16291 if (--count == 0)
16293 start_byte += cursor - base + 1;
16294 *byte_pos_ptr = start_byte;
16295 return orig_count;
16297 else
16298 if (++cursor == ceiling_addr)
16299 break;
16301 else
16302 break;
16304 start_byte += cursor - base;
16307 else
16309 while (start_byte > limit_byte)
16311 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16312 ceiling = max (limit_byte, ceiling);
16313 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16314 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16315 while (1)
16317 if (selective_display)
16318 while (--cursor != ceiling_addr
16319 && *cursor != '\n' && *cursor != 015)
16321 else
16322 while (--cursor != ceiling_addr && *cursor != '\n')
16325 if (cursor != ceiling_addr)
16327 if (++count == 0)
16329 start_byte += cursor - base + 1;
16330 *byte_pos_ptr = start_byte;
16331 /* When scanning backwards, we should
16332 not count the newline posterior to which we stop. */
16333 return - orig_count - 1;
16336 else
16337 break;
16339 /* Here we add 1 to compensate for the last decrement
16340 of CURSOR, which took it past the valid range. */
16341 start_byte += cursor - base + 1;
16345 *byte_pos_ptr = limit_byte;
16347 if (count < 0)
16348 return - orig_count + count;
16349 return orig_count - count;
16355 /***********************************************************************
16356 Displaying strings
16357 ***********************************************************************/
16359 /* Display a NUL-terminated string, starting with index START.
16361 If STRING is non-null, display that C string. Otherwise, the Lisp
16362 string LISP_STRING is displayed.
16364 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16365 FACE_STRING. Display STRING or LISP_STRING with the face at
16366 FACE_STRING_POS in FACE_STRING:
16368 Display the string in the environment given by IT, but use the
16369 standard display table, temporarily.
16371 FIELD_WIDTH is the minimum number of output glyphs to produce.
16372 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16373 with spaces. If STRING has more characters, more than FIELD_WIDTH
16374 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16376 PRECISION is the maximum number of characters to output from
16377 STRING. PRECISION < 0 means don't truncate the string.
16379 This is roughly equivalent to printf format specifiers:
16381 FIELD_WIDTH PRECISION PRINTF
16382 ----------------------------------------
16383 -1 -1 %s
16384 -1 10 %.10s
16385 10 -1 %10s
16386 20 10 %20.10s
16388 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16389 display them, and < 0 means obey the current buffer's value of
16390 enable_multibyte_characters.
16392 Value is the number of glyphs produced. */
16394 static int
16395 display_string (string, lisp_string, face_string, face_string_pos,
16396 start, it, field_width, precision, max_x, multibyte)
16397 unsigned char *string;
16398 Lisp_Object lisp_string;
16399 Lisp_Object face_string;
16400 int face_string_pos;
16401 int start;
16402 struct it *it;
16403 int field_width, precision, max_x;
16404 int multibyte;
16406 int hpos_at_start = it->hpos;
16407 int saved_face_id = it->face_id;
16408 struct glyph_row *row = it->glyph_row;
16410 /* Initialize the iterator IT for iteration over STRING beginning
16411 with index START. */
16412 reseat_to_string (it, string, lisp_string, start,
16413 precision, field_width, multibyte);
16415 /* If displaying STRING, set up the face of the iterator
16416 from LISP_STRING, if that's given. */
16417 if (STRINGP (face_string))
16419 int endptr;
16420 struct face *face;
16422 it->face_id
16423 = face_at_string_position (it->w, face_string, face_string_pos,
16424 0, it->region_beg_charpos,
16425 it->region_end_charpos,
16426 &endptr, it->base_face_id, 0);
16427 face = FACE_FROM_ID (it->f, it->face_id);
16428 it->face_box_p = face->box != FACE_NO_BOX;
16431 /* Set max_x to the maximum allowed X position. Don't let it go
16432 beyond the right edge of the window. */
16433 if (max_x <= 0)
16434 max_x = it->last_visible_x;
16435 else
16436 max_x = min (max_x, it->last_visible_x);
16438 /* Skip over display elements that are not visible. because IT->w is
16439 hscrolled. */
16440 if (it->current_x < it->first_visible_x)
16441 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16442 MOVE_TO_POS | MOVE_TO_X);
16444 row->ascent = it->max_ascent;
16445 row->height = it->max_ascent + it->max_descent;
16446 row->phys_ascent = it->max_phys_ascent;
16447 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16449 /* This condition is for the case that we are called with current_x
16450 past last_visible_x. */
16451 while (it->current_x < max_x)
16453 int x_before, x, n_glyphs_before, i, nglyphs;
16455 /* Get the next display element. */
16456 if (!get_next_display_element (it))
16457 break;
16459 /* Produce glyphs. */
16460 x_before = it->current_x;
16461 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16462 PRODUCE_GLYPHS (it);
16464 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16465 i = 0;
16466 x = x_before;
16467 while (i < nglyphs)
16469 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16471 if (!it->truncate_lines_p
16472 && x + glyph->pixel_width > max_x)
16474 /* End of continued line or max_x reached. */
16475 if (CHAR_GLYPH_PADDING_P (*glyph))
16477 /* A wide character is unbreakable. */
16478 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16479 it->current_x = x_before;
16481 else
16483 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16484 it->current_x = x;
16486 break;
16488 else if (x + glyph->pixel_width > it->first_visible_x)
16490 /* Glyph is at least partially visible. */
16491 ++it->hpos;
16492 if (x < it->first_visible_x)
16493 it->glyph_row->x = x - it->first_visible_x;
16495 else
16497 /* Glyph is off the left margin of the display area.
16498 Should not happen. */
16499 abort ();
16502 row->ascent = max (row->ascent, it->max_ascent);
16503 row->height = max (row->height, it->max_ascent + it->max_descent);
16504 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16505 row->phys_height = max (row->phys_height,
16506 it->max_phys_ascent + it->max_phys_descent);
16507 x += glyph->pixel_width;
16508 ++i;
16511 /* Stop if max_x reached. */
16512 if (i < nglyphs)
16513 break;
16515 /* Stop at line ends. */
16516 if (ITERATOR_AT_END_OF_LINE_P (it))
16518 it->continuation_lines_width = 0;
16519 break;
16522 set_iterator_to_next (it, 1);
16524 /* Stop if truncating at the right edge. */
16525 if (it->truncate_lines_p
16526 && it->current_x >= it->last_visible_x)
16528 /* Add truncation mark, but don't do it if the line is
16529 truncated at a padding space. */
16530 if (IT_CHARPOS (*it) < it->string_nchars)
16532 if (!FRAME_WINDOW_P (it->f))
16534 int i, n;
16536 if (it->current_x > it->last_visible_x)
16538 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16539 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16540 break;
16541 for (n = row->used[TEXT_AREA]; i < n; ++i)
16543 row->used[TEXT_AREA] = i;
16544 produce_special_glyphs (it, IT_TRUNCATION);
16547 produce_special_glyphs (it, IT_TRUNCATION);
16549 it->glyph_row->truncated_on_right_p = 1;
16551 break;
16555 /* Maybe insert a truncation at the left. */
16556 if (it->first_visible_x
16557 && IT_CHARPOS (*it) > 0)
16559 if (!FRAME_WINDOW_P (it->f))
16560 insert_left_trunc_glyphs (it);
16561 it->glyph_row->truncated_on_left_p = 1;
16564 it->face_id = saved_face_id;
16566 /* Value is number of columns displayed. */
16567 return it->hpos - hpos_at_start;
16572 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16573 appears as an element of LIST or as the car of an element of LIST.
16574 If PROPVAL is a list, compare each element against LIST in that
16575 way, and return 1/2 if any element of PROPVAL is found in LIST.
16576 Otherwise return 0. This function cannot quit.
16577 The return value is 2 if the text is invisible but with an ellipsis
16578 and 1 if it's invisible and without an ellipsis. */
16581 invisible_p (propval, list)
16582 register Lisp_Object propval;
16583 Lisp_Object list;
16585 register Lisp_Object tail, proptail;
16587 for (tail = list; CONSP (tail); tail = XCDR (tail))
16589 register Lisp_Object tem;
16590 tem = XCAR (tail);
16591 if (EQ (propval, tem))
16592 return 1;
16593 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16594 return NILP (XCDR (tem)) ? 1 : 2;
16597 if (CONSP (propval))
16599 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16601 Lisp_Object propelt;
16602 propelt = XCAR (proptail);
16603 for (tail = list; CONSP (tail); tail = XCDR (tail))
16605 register Lisp_Object tem;
16606 tem = XCAR (tail);
16607 if (EQ (propelt, tem))
16608 return 1;
16609 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16610 return NILP (XCDR (tem)) ? 1 : 2;
16615 return 0;
16619 /***********************************************************************
16620 Glyph Display
16621 ***********************************************************************/
16623 #ifdef HAVE_WINDOW_SYSTEM
16625 #if GLYPH_DEBUG
16627 void
16628 dump_glyph_string (s)
16629 struct glyph_string *s;
16631 fprintf (stderr, "glyph string\n");
16632 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16633 s->x, s->y, s->width, s->height);
16634 fprintf (stderr, " ybase = %d\n", s->ybase);
16635 fprintf (stderr, " hl = %d\n", s->hl);
16636 fprintf (stderr, " left overhang = %d, right = %d\n",
16637 s->left_overhang, s->right_overhang);
16638 fprintf (stderr, " nchars = %d\n", s->nchars);
16639 fprintf (stderr, " extends to end of line = %d\n",
16640 s->extends_to_end_of_line_p);
16641 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16642 fprintf (stderr, " bg width = %d\n", s->background_width);
16645 #endif /* GLYPH_DEBUG */
16647 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16648 of XChar2b structures for S; it can't be allocated in
16649 init_glyph_string because it must be allocated via `alloca'. W
16650 is the window on which S is drawn. ROW and AREA are the glyph row
16651 and area within the row from which S is constructed. START is the
16652 index of the first glyph structure covered by S. HL is a
16653 face-override for drawing S. */
16655 #ifdef HAVE_NTGUI
16656 #define OPTIONAL_HDC(hdc) hdc,
16657 #define DECLARE_HDC(hdc) HDC hdc;
16658 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16659 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16660 #endif
16662 #ifndef OPTIONAL_HDC
16663 #define OPTIONAL_HDC(hdc)
16664 #define DECLARE_HDC(hdc)
16665 #define ALLOCATE_HDC(hdc, f)
16666 #define RELEASE_HDC(hdc, f)
16667 #endif
16669 static void
16670 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16671 struct glyph_string *s;
16672 DECLARE_HDC (hdc)
16673 XChar2b *char2b;
16674 struct window *w;
16675 struct glyph_row *row;
16676 enum glyph_row_area area;
16677 int start;
16678 enum draw_glyphs_face hl;
16680 bzero (s, sizeof *s);
16681 s->w = w;
16682 s->f = XFRAME (w->frame);
16683 #ifdef HAVE_NTGUI
16684 s->hdc = hdc;
16685 #endif
16686 s->display = FRAME_X_DISPLAY (s->f);
16687 s->window = FRAME_X_WINDOW (s->f);
16688 s->char2b = char2b;
16689 s->hl = hl;
16690 s->row = row;
16691 s->area = area;
16692 s->first_glyph = row->glyphs[area] + start;
16693 s->height = row->height;
16694 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16696 /* Display the internal border below the tool-bar window. */
16697 if (s->w == XWINDOW (s->f->tool_bar_window))
16698 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16700 s->ybase = s->y + row->ascent;
16704 /* Append the list of glyph strings with head H and tail T to the list
16705 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16707 static INLINE void
16708 append_glyph_string_lists (head, tail, h, t)
16709 struct glyph_string **head, **tail;
16710 struct glyph_string *h, *t;
16712 if (h)
16714 if (*head)
16715 (*tail)->next = h;
16716 else
16717 *head = h;
16718 h->prev = *tail;
16719 *tail = t;
16724 /* Prepend the list of glyph strings with head H and tail T to the
16725 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16726 result. */
16728 static INLINE void
16729 prepend_glyph_string_lists (head, tail, h, t)
16730 struct glyph_string **head, **tail;
16731 struct glyph_string *h, *t;
16733 if (h)
16735 if (*head)
16736 (*head)->prev = t;
16737 else
16738 *tail = t;
16739 t->next = *head;
16740 *head = h;
16745 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16746 Set *HEAD and *TAIL to the resulting list. */
16748 static INLINE void
16749 append_glyph_string (head, tail, s)
16750 struct glyph_string **head, **tail;
16751 struct glyph_string *s;
16753 s->next = s->prev = NULL;
16754 append_glyph_string_lists (head, tail, s, s);
16758 /* Get face and two-byte form of character glyph GLYPH on frame F.
16759 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16760 a pointer to a realized face that is ready for display. */
16762 static INLINE struct face *
16763 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16764 struct frame *f;
16765 struct glyph *glyph;
16766 XChar2b *char2b;
16767 int *two_byte_p;
16769 struct face *face;
16771 xassert (glyph->type == CHAR_GLYPH);
16772 face = FACE_FROM_ID (f, glyph->face_id);
16774 if (two_byte_p)
16775 *two_byte_p = 0;
16777 if (!glyph->multibyte_p)
16779 /* Unibyte case. We don't have to encode, but we have to make
16780 sure to use a face suitable for unibyte. */
16781 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16783 else if (glyph->u.ch < 128
16784 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16786 /* Case of ASCII in a face known to fit ASCII. */
16787 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16789 else
16791 int c1, c2, charset;
16793 /* Split characters into bytes. If c2 is -1 afterwards, C is
16794 really a one-byte character so that byte1 is zero. */
16795 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16796 if (c2 > 0)
16797 STORE_XCHAR2B (char2b, c1, c2);
16798 else
16799 STORE_XCHAR2B (char2b, 0, c1);
16801 /* Maybe encode the character in *CHAR2B. */
16802 if (charset != CHARSET_ASCII)
16804 struct font_info *font_info
16805 = FONT_INFO_FROM_ID (f, face->font_info_id);
16806 if (font_info)
16807 glyph->font_type
16808 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16812 /* Make sure X resources of the face are allocated. */
16813 xassert (face != NULL);
16814 PREPARE_FACE_FOR_DISPLAY (f, face);
16815 return face;
16819 /* Fill glyph string S with composition components specified by S->cmp.
16821 FACES is an array of faces for all components of this composition.
16822 S->gidx is the index of the first component for S.
16823 OVERLAPS_P non-zero means S should draw the foreground only, and
16824 use its physical height for clipping.
16826 Value is the index of a component not in S. */
16828 static int
16829 fill_composite_glyph_string (s, faces, overlaps_p)
16830 struct glyph_string *s;
16831 struct face **faces;
16832 int overlaps_p;
16834 int i;
16836 xassert (s);
16838 s->for_overlaps_p = overlaps_p;
16840 s->face = faces[s->gidx];
16841 s->font = s->face->font;
16842 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16844 /* For all glyphs of this composition, starting at the offset
16845 S->gidx, until we reach the end of the definition or encounter a
16846 glyph that requires the different face, add it to S. */
16847 ++s->nchars;
16848 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16849 ++s->nchars;
16851 /* All glyph strings for the same composition has the same width,
16852 i.e. the width set for the first component of the composition. */
16854 s->width = s->first_glyph->pixel_width;
16856 /* If the specified font could not be loaded, use the frame's
16857 default font, but record the fact that we couldn't load it in
16858 the glyph string so that we can draw rectangles for the
16859 characters of the glyph string. */
16860 if (s->font == NULL)
16862 s->font_not_found_p = 1;
16863 s->font = FRAME_FONT (s->f);
16866 /* Adjust base line for subscript/superscript text. */
16867 s->ybase += s->first_glyph->voffset;
16869 xassert (s->face && s->face->gc);
16871 /* This glyph string must always be drawn with 16-bit functions. */
16872 s->two_byte_p = 1;
16874 return s->gidx + s->nchars;
16878 /* Fill glyph string S from a sequence of character glyphs.
16880 FACE_ID is the face id of the string. START is the index of the
16881 first glyph to consider, END is the index of the last + 1.
16882 OVERLAPS_P non-zero means S should draw the foreground only, and
16883 use its physical height for clipping.
16885 Value is the index of the first glyph not in S. */
16887 static int
16888 fill_glyph_string (s, face_id, start, end, overlaps_p)
16889 struct glyph_string *s;
16890 int face_id;
16891 int start, end, overlaps_p;
16893 struct glyph *glyph, *last;
16894 int voffset;
16895 int glyph_not_available_p;
16897 xassert (s->f == XFRAME (s->w->frame));
16898 xassert (s->nchars == 0);
16899 xassert (start >= 0 && end > start);
16901 s->for_overlaps_p = overlaps_p,
16902 glyph = s->row->glyphs[s->area] + start;
16903 last = s->row->glyphs[s->area] + end;
16904 voffset = glyph->voffset;
16906 glyph_not_available_p = glyph->glyph_not_available_p;
16908 while (glyph < last
16909 && glyph->type == CHAR_GLYPH
16910 && glyph->voffset == voffset
16911 /* Same face id implies same font, nowadays. */
16912 && glyph->face_id == face_id
16913 && glyph->glyph_not_available_p == glyph_not_available_p)
16915 int two_byte_p;
16917 s->face = get_glyph_face_and_encoding (s->f, glyph,
16918 s->char2b + s->nchars,
16919 &two_byte_p);
16920 s->two_byte_p = two_byte_p;
16921 ++s->nchars;
16922 xassert (s->nchars <= end - start);
16923 s->width += glyph->pixel_width;
16924 ++glyph;
16927 s->font = s->face->font;
16928 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16930 /* If the specified font could not be loaded, use the frame's font,
16931 but record the fact that we couldn't load it in
16932 S->font_not_found_p so that we can draw rectangles for the
16933 characters of the glyph string. */
16934 if (s->font == NULL || glyph_not_available_p)
16936 s->font_not_found_p = 1;
16937 s->font = FRAME_FONT (s->f);
16940 /* Adjust base line for subscript/superscript text. */
16941 s->ybase += voffset;
16943 xassert (s->face && s->face->gc);
16944 return glyph - s->row->glyphs[s->area];
16948 /* Fill glyph string S from image glyph S->first_glyph. */
16950 static void
16951 fill_image_glyph_string (s)
16952 struct glyph_string *s;
16954 xassert (s->first_glyph->type == IMAGE_GLYPH);
16955 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16956 xassert (s->img);
16957 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16958 s->font = s->face->font;
16959 s->width = s->first_glyph->pixel_width;
16961 /* Adjust base line for subscript/superscript text. */
16962 s->ybase += s->first_glyph->voffset;
16966 /* Fill glyph string S from a sequence of stretch glyphs.
16968 ROW is the glyph row in which the glyphs are found, AREA is the
16969 area within the row. START is the index of the first glyph to
16970 consider, END is the index of the last + 1.
16972 Value is the index of the first glyph not in S. */
16974 static int
16975 fill_stretch_glyph_string (s, row, area, start, end)
16976 struct glyph_string *s;
16977 struct glyph_row *row;
16978 enum glyph_row_area area;
16979 int start, end;
16981 struct glyph *glyph, *last;
16982 int voffset, face_id;
16984 xassert (s->first_glyph->type == STRETCH_GLYPH);
16986 glyph = s->row->glyphs[s->area] + start;
16987 last = s->row->glyphs[s->area] + end;
16988 face_id = glyph->face_id;
16989 s->face = FACE_FROM_ID (s->f, face_id);
16990 s->font = s->face->font;
16991 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16992 s->width = glyph->pixel_width;
16993 voffset = glyph->voffset;
16995 for (++glyph;
16996 (glyph < last
16997 && glyph->type == STRETCH_GLYPH
16998 && glyph->voffset == voffset
16999 && glyph->face_id == face_id);
17000 ++glyph)
17001 s->width += glyph->pixel_width;
17003 /* Adjust base line for subscript/superscript text. */
17004 s->ybase += voffset;
17006 /* The case that face->gc == 0 is handled when drawing the glyph
17007 string by calling PREPARE_FACE_FOR_DISPLAY. */
17008 xassert (s->face);
17009 return glyph - s->row->glyphs[s->area];
17013 /* EXPORT for RIF:
17014 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17015 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17016 assumed to be zero. */
17018 void
17019 x_get_glyph_overhangs (glyph, f, left, right)
17020 struct glyph *glyph;
17021 struct frame *f;
17022 int *left, *right;
17024 *left = *right = 0;
17026 if (glyph->type == CHAR_GLYPH)
17028 XFontStruct *font;
17029 struct face *face;
17030 struct font_info *font_info;
17031 XChar2b char2b;
17032 XCharStruct *pcm;
17034 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17035 font = face->font;
17036 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17037 if (font /* ++KFS: Should this be font_info ? */
17038 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17040 if (pcm->rbearing > pcm->width)
17041 *right = pcm->rbearing - pcm->width;
17042 if (pcm->lbearing < 0)
17043 *left = -pcm->lbearing;
17049 /* Return the index of the first glyph preceding glyph string S that
17050 is overwritten by S because of S's left overhang. Value is -1
17051 if no glyphs are overwritten. */
17053 static int
17054 left_overwritten (s)
17055 struct glyph_string *s;
17057 int k;
17059 if (s->left_overhang)
17061 int x = 0, i;
17062 struct glyph *glyphs = s->row->glyphs[s->area];
17063 int first = s->first_glyph - glyphs;
17065 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17066 x -= glyphs[i].pixel_width;
17068 k = i + 1;
17070 else
17071 k = -1;
17073 return k;
17077 /* Return the index of the first glyph preceding glyph string S that
17078 is overwriting S because of its right overhang. Value is -1 if no
17079 glyph in front of S overwrites S. */
17081 static int
17082 left_overwriting (s)
17083 struct glyph_string *s;
17085 int i, k, x;
17086 struct glyph *glyphs = s->row->glyphs[s->area];
17087 int first = s->first_glyph - glyphs;
17089 k = -1;
17090 x = 0;
17091 for (i = first - 1; i >= 0; --i)
17093 int left, right;
17094 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17095 if (x + right > 0)
17096 k = i;
17097 x -= glyphs[i].pixel_width;
17100 return k;
17104 /* Return the index of the last glyph following glyph string S that is
17105 not overwritten by S because of S's right overhang. Value is -1 if
17106 no such glyph is found. */
17108 static int
17109 right_overwritten (s)
17110 struct glyph_string *s;
17112 int k = -1;
17114 if (s->right_overhang)
17116 int x = 0, i;
17117 struct glyph *glyphs = s->row->glyphs[s->area];
17118 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17119 int end = s->row->used[s->area];
17121 for (i = first; i < end && s->right_overhang > x; ++i)
17122 x += glyphs[i].pixel_width;
17124 k = i;
17127 return k;
17131 /* Return the index of the last glyph following glyph string S that
17132 overwrites S because of its left overhang. Value is negative
17133 if no such glyph is found. */
17135 static int
17136 right_overwriting (s)
17137 struct glyph_string *s;
17139 int i, k, x;
17140 int end = s->row->used[s->area];
17141 struct glyph *glyphs = s->row->glyphs[s->area];
17142 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17144 k = -1;
17145 x = 0;
17146 for (i = first; i < end; ++i)
17148 int left, right;
17149 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17150 if (x - left < 0)
17151 k = i;
17152 x += glyphs[i].pixel_width;
17155 return k;
17159 /* Get face and two-byte form of character C in face FACE_ID on frame
17160 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17161 means we want to display multibyte text. DISPLAY_P non-zero means
17162 make sure that X resources for the face returned are allocated.
17163 Value is a pointer to a realized face that is ready for display if
17164 DISPLAY_P is non-zero. */
17166 static INLINE struct face *
17167 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17168 struct frame *f;
17169 int c, face_id;
17170 XChar2b *char2b;
17171 int multibyte_p, display_p;
17173 struct face *face = FACE_FROM_ID (f, face_id);
17175 if (!multibyte_p)
17177 /* Unibyte case. We don't have to encode, but we have to make
17178 sure to use a face suitable for unibyte. */
17179 STORE_XCHAR2B (char2b, 0, c);
17180 face_id = FACE_FOR_CHAR (f, face, c);
17181 face = FACE_FROM_ID (f, face_id);
17183 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17185 /* Case of ASCII in a face known to fit ASCII. */
17186 STORE_XCHAR2B (char2b, 0, c);
17188 else
17190 int c1, c2, charset;
17192 /* Split characters into bytes. If c2 is -1 afterwards, C is
17193 really a one-byte character so that byte1 is zero. */
17194 SPLIT_CHAR (c, charset, c1, c2);
17195 if (c2 > 0)
17196 STORE_XCHAR2B (char2b, c1, c2);
17197 else
17198 STORE_XCHAR2B (char2b, 0, c1);
17200 /* Maybe encode the character in *CHAR2B. */
17201 if (face->font != NULL)
17203 struct font_info *font_info
17204 = FONT_INFO_FROM_ID (f, face->font_info_id);
17205 if (font_info)
17206 rif->encode_char (c, char2b, font_info, 0);
17210 /* Make sure X resources of the face are allocated. */
17211 #ifdef HAVE_X_WINDOWS
17212 if (display_p)
17213 #endif
17215 xassert (face != NULL);
17216 PREPARE_FACE_FOR_DISPLAY (f, face);
17219 return face;
17223 /* Set background width of glyph string S. START is the index of the
17224 first glyph following S. LAST_X is the right-most x-position + 1
17225 in the drawing area. */
17227 static INLINE void
17228 set_glyph_string_background_width (s, start, last_x)
17229 struct glyph_string *s;
17230 int start;
17231 int last_x;
17233 /* If the face of this glyph string has to be drawn to the end of
17234 the drawing area, set S->extends_to_end_of_line_p. */
17235 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17237 if (start == s->row->used[s->area]
17238 && s->area == TEXT_AREA
17239 && ((s->hl == DRAW_NORMAL_TEXT
17240 && (s->row->fill_line_p
17241 || s->face->background != default_face->background
17242 || s->face->stipple != default_face->stipple
17243 || s->row->mouse_face_p))
17244 || s->hl == DRAW_MOUSE_FACE
17245 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17246 && s->row->fill_line_p)))
17247 s->extends_to_end_of_line_p = 1;
17249 /* If S extends its face to the end of the line, set its
17250 background_width to the distance to the right edge of the drawing
17251 area. */
17252 if (s->extends_to_end_of_line_p)
17253 s->background_width = last_x - s->x + 1;
17254 else
17255 s->background_width = s->width;
17259 /* Compute overhangs and x-positions for glyph string S and its
17260 predecessors, or successors. X is the starting x-position for S.
17261 BACKWARD_P non-zero means process predecessors. */
17263 static void
17264 compute_overhangs_and_x (s, x, backward_p)
17265 struct glyph_string *s;
17266 int x;
17267 int backward_p;
17269 if (backward_p)
17271 while (s)
17273 if (rif->compute_glyph_string_overhangs)
17274 rif->compute_glyph_string_overhangs (s);
17275 x -= s->width;
17276 s->x = x;
17277 s = s->prev;
17280 else
17282 while (s)
17284 if (rif->compute_glyph_string_overhangs)
17285 rif->compute_glyph_string_overhangs (s);
17286 s->x = x;
17287 x += s->width;
17288 s = s->next;
17295 /* The following macros are only called from draw_glyphs below.
17296 They reference the following parameters of that function directly:
17297 `w', `row', `area', and `overlap_p'
17298 as well as the following local variables:
17299 `s', `f', and `hdc' (in W32) */
17301 #ifdef HAVE_NTGUI
17302 /* On W32, silently add local `hdc' variable to argument list of
17303 init_glyph_string. */
17304 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17305 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17306 #else
17307 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17308 init_glyph_string (s, char2b, w, row, area, start, hl)
17309 #endif
17311 /* Add a glyph string for a stretch glyph to the list of strings
17312 between HEAD and TAIL. START is the index of the stretch glyph in
17313 row area AREA of glyph row ROW. END is the index of the last glyph
17314 in that glyph row area. X is the current output position assigned
17315 to the new glyph string constructed. HL overrides that face of the
17316 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17317 is the right-most x-position of the drawing area. */
17319 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17320 and below -- keep them on one line. */
17321 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17322 do \
17324 s = (struct glyph_string *) alloca (sizeof *s); \
17325 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17326 START = fill_stretch_glyph_string (s, row, area, START, END); \
17327 append_glyph_string (&HEAD, &TAIL, s); \
17328 s->x = (X); \
17330 while (0)
17333 /* Add a glyph string for an image glyph to the list of strings
17334 between HEAD and TAIL. START is the index of the image glyph in
17335 row area AREA of glyph row ROW. END is the index of the last glyph
17336 in that glyph row area. X is the current output position assigned
17337 to the new glyph string constructed. HL overrides that face of the
17338 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17339 is the right-most x-position of the drawing area. */
17341 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17342 do \
17344 s = (struct glyph_string *) alloca (sizeof *s); \
17345 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17346 fill_image_glyph_string (s); \
17347 append_glyph_string (&HEAD, &TAIL, s); \
17348 ++START; \
17349 s->x = (X); \
17351 while (0)
17354 /* Add a glyph string for a sequence of character glyphs to the list
17355 of strings between HEAD and TAIL. START is the index of the first
17356 glyph in row area AREA of glyph row ROW that is part of the new
17357 glyph string. END is the index of the last glyph in that glyph row
17358 area. X is the current output position assigned to the new glyph
17359 string constructed. HL overrides that face of the glyph; e.g. it
17360 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17361 right-most x-position of the drawing area. */
17363 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17364 do \
17366 int c, face_id; \
17367 XChar2b *char2b; \
17369 c = (row)->glyphs[area][START].u.ch; \
17370 face_id = (row)->glyphs[area][START].face_id; \
17372 s = (struct glyph_string *) alloca (sizeof *s); \
17373 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17374 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17375 append_glyph_string (&HEAD, &TAIL, s); \
17376 s->x = (X); \
17377 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17379 while (0)
17382 /* Add a glyph string for a composite sequence to the list of strings
17383 between HEAD and TAIL. START is the index of the first glyph in
17384 row area AREA of glyph row ROW that is part of the new glyph
17385 string. END is the index of the last glyph in that glyph row area.
17386 X is the current output position assigned to the new glyph string
17387 constructed. HL overrides that face of the glyph; e.g. it is
17388 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17389 x-position of the drawing area. */
17391 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17392 do { \
17393 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17394 int face_id = (row)->glyphs[area][START].face_id; \
17395 struct face *base_face = FACE_FROM_ID (f, face_id); \
17396 struct composition *cmp = composition_table[cmp_id]; \
17397 int glyph_len = cmp->glyph_len; \
17398 XChar2b *char2b; \
17399 struct face **faces; \
17400 struct glyph_string *first_s = NULL; \
17401 int n; \
17403 base_face = base_face->ascii_face; \
17404 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17405 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17406 /* At first, fill in `char2b' and `faces'. */ \
17407 for (n = 0; n < glyph_len; n++) \
17409 int c = COMPOSITION_GLYPH (cmp, n); \
17410 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17411 faces[n] = FACE_FROM_ID (f, this_face_id); \
17412 get_char_face_and_encoding (f, c, this_face_id, \
17413 char2b + n, 1, 1); \
17416 /* Make glyph_strings for each glyph sequence that is drawable by \
17417 the same face, and append them to HEAD/TAIL. */ \
17418 for (n = 0; n < cmp->glyph_len;) \
17420 s = (struct glyph_string *) alloca (sizeof *s); \
17421 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17422 append_glyph_string (&(HEAD), &(TAIL), s); \
17423 s->cmp = cmp; \
17424 s->gidx = n; \
17425 s->x = (X); \
17427 if (n == 0) \
17428 first_s = s; \
17430 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17433 ++START; \
17434 s = first_s; \
17435 } while (0)
17438 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17439 of AREA of glyph row ROW on window W between indices START and END.
17440 HL overrides the face for drawing glyph strings, e.g. it is
17441 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17442 x-positions of the drawing area.
17444 This is an ugly monster macro construct because we must use alloca
17445 to allocate glyph strings (because draw_glyphs can be called
17446 asynchronously). */
17448 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17449 do \
17451 HEAD = TAIL = NULL; \
17452 while (START < END) \
17454 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17455 switch (first_glyph->type) \
17457 case CHAR_GLYPH: \
17458 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17459 HL, X, LAST_X); \
17460 break; \
17462 case COMPOSITE_GLYPH: \
17463 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17464 HL, X, LAST_X); \
17465 break; \
17467 case STRETCH_GLYPH: \
17468 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17469 HL, X, LAST_X); \
17470 break; \
17472 case IMAGE_GLYPH: \
17473 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17474 HL, X, LAST_X); \
17475 break; \
17477 default: \
17478 abort (); \
17481 set_glyph_string_background_width (s, START, LAST_X); \
17482 (X) += s->width; \
17485 while (0)
17488 /* Draw glyphs between START and END in AREA of ROW on window W,
17489 starting at x-position X. X is relative to AREA in W. HL is a
17490 face-override with the following meaning:
17492 DRAW_NORMAL_TEXT draw normally
17493 DRAW_CURSOR draw in cursor face
17494 DRAW_MOUSE_FACE draw in mouse face.
17495 DRAW_INVERSE_VIDEO draw in mode line face
17496 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17497 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17499 If OVERLAPS_P is non-zero, draw only the foreground of characters
17500 and clip to the physical height of ROW.
17502 Value is the x-position reached, relative to AREA of W. */
17504 static int
17505 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17506 struct window *w;
17507 int x;
17508 struct glyph_row *row;
17509 enum glyph_row_area area;
17510 int start, end;
17511 enum draw_glyphs_face hl;
17512 int overlaps_p;
17514 struct glyph_string *head, *tail;
17515 struct glyph_string *s;
17516 int last_x, area_width;
17517 int x_reached;
17518 int i, j;
17519 struct frame *f = XFRAME (WINDOW_FRAME (w));
17520 DECLARE_HDC (hdc);
17522 ALLOCATE_HDC (hdc, f);
17524 /* Let's rather be paranoid than getting a SEGV. */
17525 end = min (end, row->used[area]);
17526 start = max (0, start);
17527 start = min (end, start);
17529 /* Translate X to frame coordinates. Set last_x to the right
17530 end of the drawing area. */
17531 if (row->full_width_p)
17533 /* X is relative to the left edge of W, without scroll bars
17534 or fringes. */
17535 x += WINDOW_LEFT_EDGE_X (w);
17536 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17538 else
17540 int area_left = window_box_left (w, area);
17541 x += area_left;
17542 area_width = window_box_width (w, area);
17543 last_x = area_left + area_width;
17546 /* Build a doubly-linked list of glyph_string structures between
17547 head and tail from what we have to draw. Note that the macro
17548 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17549 the reason we use a separate variable `i'. */
17550 i = start;
17551 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17552 if (tail)
17553 x_reached = tail->x + tail->background_width;
17554 else
17555 x_reached = x;
17557 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17558 the row, redraw some glyphs in front or following the glyph
17559 strings built above. */
17560 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17562 int dummy_x = 0;
17563 struct glyph_string *h, *t;
17565 /* Compute overhangs for all glyph strings. */
17566 if (rif->compute_glyph_string_overhangs)
17567 for (s = head; s; s = s->next)
17568 rif->compute_glyph_string_overhangs (s);
17570 /* Prepend glyph strings for glyphs in front of the first glyph
17571 string that are overwritten because of the first glyph
17572 string's left overhang. The background of all strings
17573 prepended must be drawn because the first glyph string
17574 draws over it. */
17575 i = left_overwritten (head);
17576 if (i >= 0)
17578 j = i;
17579 BUILD_GLYPH_STRINGS (j, start, h, t,
17580 DRAW_NORMAL_TEXT, dummy_x, last_x);
17581 start = i;
17582 compute_overhangs_and_x (t, head->x, 1);
17583 prepend_glyph_string_lists (&head, &tail, h, t);
17586 /* Prepend glyph strings for glyphs in front of the first glyph
17587 string that overwrite that glyph string because of their
17588 right overhang. For these strings, only the foreground must
17589 be drawn, because it draws over the glyph string at `head'.
17590 The background must not be drawn because this would overwrite
17591 right overhangs of preceding glyphs for which no glyph
17592 strings exist. */
17593 i = left_overwriting (head);
17594 if (i >= 0)
17596 BUILD_GLYPH_STRINGS (i, start, h, t,
17597 DRAW_NORMAL_TEXT, dummy_x, last_x);
17598 for (s = h; s; s = s->next)
17599 s->background_filled_p = 1;
17600 compute_overhangs_and_x (t, head->x, 1);
17601 prepend_glyph_string_lists (&head, &tail, h, t);
17604 /* Append glyphs strings for glyphs following the last glyph
17605 string tail that are overwritten by tail. The background of
17606 these strings has to be drawn because tail's foreground draws
17607 over it. */
17608 i = right_overwritten (tail);
17609 if (i >= 0)
17611 BUILD_GLYPH_STRINGS (end, i, h, t,
17612 DRAW_NORMAL_TEXT, x, last_x);
17613 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17614 append_glyph_string_lists (&head, &tail, h, t);
17617 /* Append glyph strings for glyphs following the last glyph
17618 string tail that overwrite tail. The foreground of such
17619 glyphs has to be drawn because it writes into the background
17620 of tail. The background must not be drawn because it could
17621 paint over the foreground of following glyphs. */
17622 i = right_overwriting (tail);
17623 if (i >= 0)
17625 BUILD_GLYPH_STRINGS (end, i, h, t,
17626 DRAW_NORMAL_TEXT, x, last_x);
17627 for (s = h; s; s = s->next)
17628 s->background_filled_p = 1;
17629 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17630 append_glyph_string_lists (&head, &tail, h, t);
17634 /* Draw all strings. */
17635 for (s = head; s; s = s->next)
17636 rif->draw_glyph_string (s);
17638 if (area == TEXT_AREA
17639 && !row->full_width_p
17640 /* When drawing overlapping rows, only the glyph strings'
17641 foreground is drawn, which doesn't erase a cursor
17642 completely. */
17643 && !overlaps_p)
17645 int x0 = head ? head->x : x;
17646 int x1 = tail ? tail->x + tail->background_width : x;
17648 int text_left = window_box_left (w, TEXT_AREA);
17649 x0 -= text_left;
17650 x1 -= text_left;
17652 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17653 row->y, MATRIX_ROW_BOTTOM_Y (row));
17656 /* Value is the x-position up to which drawn, relative to AREA of W.
17657 This doesn't include parts drawn because of overhangs. */
17658 if (row->full_width_p)
17659 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17660 else
17661 x_reached -= window_box_left (w, area);
17663 RELEASE_HDC (hdc, f);
17665 return x_reached;
17669 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17670 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17672 static INLINE void
17673 append_glyph (it)
17674 struct it *it;
17676 struct glyph *glyph;
17677 enum glyph_row_area area = it->area;
17679 xassert (it->glyph_row);
17680 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17682 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17683 if (glyph < it->glyph_row->glyphs[area + 1])
17685 glyph->charpos = CHARPOS (it->position);
17686 glyph->object = it->object;
17687 glyph->pixel_width = it->pixel_width;
17688 glyph->voffset = it->voffset;
17689 glyph->type = CHAR_GLYPH;
17690 glyph->multibyte_p = it->multibyte_p;
17691 glyph->left_box_line_p = it->start_of_box_run_p;
17692 glyph->right_box_line_p = it->end_of_box_run_p;
17693 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17694 || it->phys_descent > it->descent);
17695 glyph->padding_p = 0;
17696 glyph->glyph_not_available_p = it->glyph_not_available_p;
17697 glyph->face_id = it->face_id;
17698 glyph->u.ch = it->char_to_display;
17699 glyph->font_type = FONT_TYPE_UNKNOWN;
17700 ++it->glyph_row->used[area];
17704 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17705 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17707 static INLINE void
17708 append_composite_glyph (it)
17709 struct it *it;
17711 struct glyph *glyph;
17712 enum glyph_row_area area = it->area;
17714 xassert (it->glyph_row);
17716 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17717 if (glyph < it->glyph_row->glyphs[area + 1])
17719 glyph->charpos = CHARPOS (it->position);
17720 glyph->object = it->object;
17721 glyph->pixel_width = it->pixel_width;
17722 glyph->voffset = it->voffset;
17723 glyph->type = COMPOSITE_GLYPH;
17724 glyph->multibyte_p = it->multibyte_p;
17725 glyph->left_box_line_p = it->start_of_box_run_p;
17726 glyph->right_box_line_p = it->end_of_box_run_p;
17727 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17728 || it->phys_descent > it->descent);
17729 glyph->padding_p = 0;
17730 glyph->glyph_not_available_p = 0;
17731 glyph->face_id = it->face_id;
17732 glyph->u.cmp_id = it->cmp_id;
17733 glyph->font_type = FONT_TYPE_UNKNOWN;
17734 ++it->glyph_row->used[area];
17739 /* Change IT->ascent and IT->height according to the setting of
17740 IT->voffset. */
17742 static INLINE void
17743 take_vertical_position_into_account (it)
17744 struct it *it;
17746 if (it->voffset)
17748 if (it->voffset < 0)
17749 /* Increase the ascent so that we can display the text higher
17750 in the line. */
17751 it->ascent += abs (it->voffset);
17752 else
17753 /* Increase the descent so that we can display the text lower
17754 in the line. */
17755 it->descent += it->voffset;
17760 /* Produce glyphs/get display metrics for the image IT is loaded with.
17761 See the description of struct display_iterator in dispextern.h for
17762 an overview of struct display_iterator. */
17764 static void
17765 produce_image_glyph (it)
17766 struct it *it;
17768 struct image *img;
17769 struct face *face;
17771 xassert (it->what == IT_IMAGE);
17773 face = FACE_FROM_ID (it->f, it->face_id);
17774 img = IMAGE_FROM_ID (it->f, it->image_id);
17775 xassert (img);
17777 /* Make sure X resources of the face and image are loaded. */
17778 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17779 prepare_image_for_display (it->f, img);
17781 it->ascent = it->phys_ascent = image_ascent (img, face);
17782 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17783 it->pixel_width = img->width + 2 * img->hmargin;
17785 it->nglyphs = 1;
17787 if (face->box != FACE_NO_BOX)
17789 if (face->box_line_width > 0)
17791 it->ascent += face->box_line_width;
17792 it->descent += face->box_line_width;
17795 if (it->start_of_box_run_p)
17796 it->pixel_width += abs (face->box_line_width);
17797 if (it->end_of_box_run_p)
17798 it->pixel_width += abs (face->box_line_width);
17801 take_vertical_position_into_account (it);
17803 if (it->glyph_row)
17805 struct glyph *glyph;
17806 enum glyph_row_area area = it->area;
17808 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17809 if (glyph < it->glyph_row->glyphs[area + 1])
17811 glyph->charpos = CHARPOS (it->position);
17812 glyph->object = it->object;
17813 glyph->pixel_width = it->pixel_width;
17814 glyph->voffset = it->voffset;
17815 glyph->type = IMAGE_GLYPH;
17816 glyph->multibyte_p = it->multibyte_p;
17817 glyph->left_box_line_p = it->start_of_box_run_p;
17818 glyph->right_box_line_p = it->end_of_box_run_p;
17819 glyph->overlaps_vertically_p = 0;
17820 glyph->padding_p = 0;
17821 glyph->glyph_not_available_p = 0;
17822 glyph->face_id = it->face_id;
17823 glyph->u.img_id = img->id;
17824 glyph->font_type = FONT_TYPE_UNKNOWN;
17825 ++it->glyph_row->used[area];
17831 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17832 of the glyph, WIDTH and HEIGHT are the width and height of the
17833 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17835 static void
17836 append_stretch_glyph (it, object, width, height, ascent)
17837 struct it *it;
17838 Lisp_Object object;
17839 int width, height;
17840 int ascent;
17842 struct glyph *glyph;
17843 enum glyph_row_area area = it->area;
17845 xassert (ascent >= 0 && ascent <= height);
17847 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17848 if (glyph < it->glyph_row->glyphs[area + 1])
17850 glyph->charpos = CHARPOS (it->position);
17851 glyph->object = object;
17852 glyph->pixel_width = width;
17853 glyph->voffset = it->voffset;
17854 glyph->type = STRETCH_GLYPH;
17855 glyph->multibyte_p = it->multibyte_p;
17856 glyph->left_box_line_p = it->start_of_box_run_p;
17857 glyph->right_box_line_p = it->end_of_box_run_p;
17858 glyph->overlaps_vertically_p = 0;
17859 glyph->padding_p = 0;
17860 glyph->glyph_not_available_p = 0;
17861 glyph->face_id = it->face_id;
17862 glyph->u.stretch.ascent = ascent;
17863 glyph->u.stretch.height = height;
17864 glyph->font_type = FONT_TYPE_UNKNOWN;
17865 ++it->glyph_row->used[area];
17870 /* Calculate a width or height in pixels from a specification using
17871 the following elements:
17873 SPEC ::=
17874 NUM - a (fractional) multiple of the default font width/height
17875 (NUM) - specifies exactly NUM pixels
17876 UNIT - a fixed number of pixels, see below.
17877 ELEMENT - size of a display element in pixels, see below.
17878 (NUM . SPEC) - equals NUM * SPEC
17879 (+ SPEC SPEC ...) - add pixel values
17880 (- SPEC SPEC ...) - subtract pixel values
17881 (- SPEC) - negate pixel value
17883 NUM ::=
17884 INT or FLOAT - a number constant
17885 SYMBOL - use symbol's (buffer local) variable binding.
17887 UNIT ::=
17888 in - pixels per inch *)
17889 mm - pixels per 1/1000 meter *)
17890 cm - pixels per 1/100 meter *)
17891 width - width of current font in pixels.
17892 height - height of current font in pixels.
17894 *) using the ratio(s) defined in display-pixels-per-inch.
17896 ELEMENT ::=
17898 left-fringe - left fringe width in pixels
17899 (left-fringe . nil) - left fringe width if inside margins, else 0
17900 (left-fringe . t) - left fringe width if outside margins, else 0
17902 right-fringe - right fringe width in pixels
17903 (right-fringe . nil) - right fringe width if inside margins, else 0
17904 (right-fringe . t) - right fringe width if outside margins, else 0
17906 left-margin - left margin width in pixels
17907 right-margin - right margin width in pixels
17909 scroll-bar - scroll-bar area width in pixels
17910 (scroll-bar . left) - scroll-bar width if on left, else 0
17911 (scroll-bar . right) - scroll-bar width if on right, else 0
17913 Examples:
17915 Pixels corresponding to 5 inches:
17916 (5 . in)
17918 Total width of non-text areas on left side of window:
17919 (+ left-fringe left-margin (scroll-bar . left))
17921 Total width of fringes if inside display margins:
17922 (+ (left-fringe) (right-fringe))
17924 Width of left margin minus width of 1 character in the default font:
17925 (- left-margin 1)
17927 Width of left margin minus width of 2 characters in the current font:
17928 (- left-margin (2 . width))
17930 Width of left fringe plus left margin minus one pixel:
17931 (- (+ left-fringe left-margin) (1))
17932 (+ left-fringe left-margin (- (1)))
17933 (+ left-fringe left-margin (-1))
17937 #define NUMVAL(X) \
17938 ((INTEGERP (X) || FLOATP (X)) \
17939 ? XFLOATINT (X) \
17940 : - 1)
17942 static int
17943 calc_pixel_width_or_height (res, it, prop, font, width_p)
17944 double *res;
17945 struct it *it;
17946 Lisp_Object prop;
17947 XFontStruct *font;
17948 int width_p;
17950 double pixels;
17952 #define OK_PIXELS(val) ((*res = (val)), 1)
17954 if (SYMBOLP (prop))
17956 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17958 char *unit = SDATA (SYMBOL_NAME (prop));
17960 if (unit[0] == 'i' && unit[1] == 'n')
17961 pixels = 1.0;
17962 else if (unit[0] == 'm' && unit[1] == 'm')
17963 pixels = 25.4;
17964 else if (unit[0] == 'c' && unit[1] == 'm')
17965 pixels = 2.54;
17966 else
17967 pixels = 0;
17968 if (pixels > 0)
17970 double ppi;
17971 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17972 || (CONSP (Vdisplay_pixels_per_inch)
17973 && (ppi = (width_p
17974 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17975 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17976 ppi > 0)))
17977 return OK_PIXELS (ppi / pixels);
17979 return 0;
17983 if (EQ (prop, Qheight))
17984 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
17985 if (EQ (prop, Qwidth))
17986 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
17987 if (EQ (prop, Qleft_fringe))
17988 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17989 if (EQ (prop, Qright_fringe))
17990 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17991 if (EQ (prop, Qleft_margin))
17992 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17993 if (EQ (prop, Qright_margin))
17994 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17995 if (EQ (prop, Qscroll_bar))
17996 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17998 prop = Fbuffer_local_value (prop, it->w->buffer);
18001 if (INTEGERP (prop) || FLOATP (prop))
18003 int base_unit = (width_p
18004 ? FRAME_COLUMN_WIDTH (it->f)
18005 : FRAME_LINE_HEIGHT (it->f));
18006 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18009 if (CONSP (prop))
18011 Lisp_Object car = XCAR (prop);
18012 Lisp_Object cdr = XCDR (prop);
18014 if (SYMBOLP (car))
18016 if (EQ (car, Qplus) || EQ (car, Qminus))
18018 int first = 1;
18019 double px;
18021 pixels = 0;
18022 while (CONSP (cdr))
18024 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
18025 return 0;
18026 if (first)
18027 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18028 else
18029 pixels += px;
18030 cdr = XCDR (cdr);
18032 if (EQ (car, Qminus))
18033 pixels = -pixels;
18034 return OK_PIXELS (pixels);
18037 if (EQ (car, Qleft_fringe))
18038 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18039 == !NILP (cdr))
18040 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
18041 : 0);
18042 if (EQ (car, Qright_fringe))
18043 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18044 == !NILP (cdr))
18045 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18046 : 0);
18047 if (EQ (car, Qscroll_bar))
18048 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18049 == EQ (cdr, Qleft))
18050 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
18051 : 0);
18053 car = Fbuffer_local_value (car, it->w->buffer);
18056 if (INTEGERP (car) || FLOATP (car))
18058 double fact;
18059 pixels = XFLOATINT (car);
18060 if (NILP (cdr))
18061 return OK_PIXELS (pixels);
18062 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
18063 return OK_PIXELS (pixels * fact);
18064 return 0;
18067 return 0;
18070 return 0;
18073 /* Produce a stretch glyph for iterator IT. IT->object is the value
18074 of the glyph property displayed. The value must be a list
18075 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18076 being recognized:
18078 1. `:width WIDTH' specifies that the space should be WIDTH *
18079 canonical char width wide. WIDTH may be an integer or floating
18080 point number.
18082 2. `:relative-width FACTOR' specifies that the width of the stretch
18083 should be computed from the width of the first character having the
18084 `glyph' property, and should be FACTOR times that width.
18086 3. `:align-to HPOS' specifies that the space should be wide enough
18087 to reach HPOS, a value in canonical character units.
18089 Exactly one of the above pairs must be present.
18091 4. `:height HEIGHT' specifies that the height of the stretch produced
18092 should be HEIGHT, measured in canonical character units.
18094 5. `:relative-height FACTOR' specifies that the height of the
18095 stretch should be FACTOR times the height of the characters having
18096 the glyph property.
18098 Either none or exactly one of 4 or 5 must be present.
18100 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18101 of the stretch should be used for the ascent of the stretch.
18102 ASCENT must be in the range 0 <= ASCENT <= 100. */
18104 static void
18105 produce_stretch_glyph (it)
18106 struct it *it;
18108 /* (space :width WIDTH :height HEIGHT ...) */
18109 Lisp_Object prop, plist;
18110 int width = 0, height = 0;
18111 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18112 int ascent = 0;
18113 double tem;
18114 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18115 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18117 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18119 /* List should start with `space'. */
18120 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18121 plist = XCDR (it->object);
18123 /* Compute the width of the stretch. */
18124 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18125 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18127 /* Absolute width `:width WIDTH' specified and valid. */
18128 zero_width_ok_p = 1;
18129 width = (int)tem;
18131 else if (prop = Fplist_get (plist, QCrelative_width),
18132 NUMVAL (prop) > 0)
18134 /* Relative width `:relative-width FACTOR' specified and valid.
18135 Compute the width of the characters having the `glyph'
18136 property. */
18137 struct it it2;
18138 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18140 it2 = *it;
18141 if (it->multibyte_p)
18143 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18144 - IT_BYTEPOS (*it));
18145 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18147 else
18148 it2.c = *p, it2.len = 1;
18150 it2.glyph_row = NULL;
18151 it2.what = IT_CHARACTER;
18152 x_produce_glyphs (&it2);
18153 width = NUMVAL (prop) * it2.pixel_width;
18155 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18156 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18158 width = max (0, (int)tem - it->current_x);
18159 zero_width_ok_p = 1;
18161 else
18162 /* Nothing specified -> width defaults to canonical char width. */
18163 width = FRAME_COLUMN_WIDTH (it->f);
18165 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18166 width = 1;
18168 /* Compute height. */
18169 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18170 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18172 height = (int)tem;
18173 zero_height_ok_p = 1;
18175 else if (prop = Fplist_get (plist, QCrelative_height),
18176 NUMVAL (prop) > 0)
18177 height = FONT_HEIGHT (font) * NUMVAL (prop);
18178 else
18179 height = FONT_HEIGHT (font);
18181 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18182 height = 1;
18184 /* Compute percentage of height used for ascent. If
18185 `:ascent ASCENT' is present and valid, use that. Otherwise,
18186 derive the ascent from the font in use. */
18187 if (prop = Fplist_get (plist, QCascent),
18188 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18189 ascent = height * NUMVAL (prop) / 100.0;
18190 else if (!NILP (prop)
18191 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18192 ascent = min (max (0, (int)tem), height);
18193 else
18194 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18196 if (width > 0 && height > 0 && it->glyph_row)
18198 Lisp_Object object = it->stack[it->sp - 1].string;
18199 if (!STRINGP (object))
18200 object = it->w->buffer;
18201 append_stretch_glyph (it, object, width, height, ascent);
18204 it->pixel_width = width;
18205 it->ascent = it->phys_ascent = ascent;
18206 it->descent = it->phys_descent = height - it->ascent;
18207 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18209 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18211 if (face->box_line_width > 0)
18213 it->ascent += face->box_line_width;
18214 it->descent += face->box_line_width;
18217 if (it->start_of_box_run_p)
18218 it->pixel_width += abs (face->box_line_width);
18219 if (it->end_of_box_run_p)
18220 it->pixel_width += abs (face->box_line_width);
18223 take_vertical_position_into_account (it);
18226 /* RIF:
18227 Produce glyphs/get display metrics for the display element IT is
18228 loaded with. See the description of struct display_iterator in
18229 dispextern.h for an overview of struct display_iterator. */
18231 void
18232 x_produce_glyphs (it)
18233 struct it *it;
18235 it->glyph_not_available_p = 0;
18237 if (it->what == IT_CHARACTER)
18239 XChar2b char2b;
18240 XFontStruct *font;
18241 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18242 XCharStruct *pcm;
18243 int font_not_found_p;
18244 struct font_info *font_info;
18245 int boff; /* baseline offset */
18246 /* We may change it->multibyte_p upon unibyte<->multibyte
18247 conversion. So, save the current value now and restore it
18248 later.
18250 Note: It seems that we don't have to record multibyte_p in
18251 struct glyph because the character code itself tells if or
18252 not the character is multibyte. Thus, in the future, we must
18253 consider eliminating the field `multibyte_p' in the struct
18254 glyph. */
18255 int saved_multibyte_p = it->multibyte_p;
18257 /* Maybe translate single-byte characters to multibyte, or the
18258 other way. */
18259 it->char_to_display = it->c;
18260 if (!ASCII_BYTE_P (it->c))
18262 if (unibyte_display_via_language_environment
18263 && SINGLE_BYTE_CHAR_P (it->c)
18264 && (it->c >= 0240
18265 || !NILP (Vnonascii_translation_table)))
18267 it->char_to_display = unibyte_char_to_multibyte (it->c);
18268 it->multibyte_p = 1;
18269 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18270 face = FACE_FROM_ID (it->f, it->face_id);
18272 else if (!SINGLE_BYTE_CHAR_P (it->c)
18273 && !it->multibyte_p)
18275 it->multibyte_p = 1;
18276 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18277 face = FACE_FROM_ID (it->f, it->face_id);
18281 /* Get font to use. Encode IT->char_to_display. */
18282 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18283 &char2b, it->multibyte_p, 0);
18284 font = face->font;
18286 /* When no suitable font found, use the default font. */
18287 font_not_found_p = font == NULL;
18288 if (font_not_found_p)
18290 font = FRAME_FONT (it->f);
18291 boff = FRAME_BASELINE_OFFSET (it->f);
18292 font_info = NULL;
18294 else
18296 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18297 boff = font_info->baseline_offset;
18298 if (font_info->vertical_centering)
18299 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18302 if (it->char_to_display >= ' '
18303 && (!it->multibyte_p || it->char_to_display < 128))
18305 /* Either unibyte or ASCII. */
18306 int stretched_p;
18308 it->nglyphs = 1;
18310 pcm = rif->per_char_metric (font, &char2b,
18311 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18312 it->ascent = FONT_BASE (font) + boff;
18313 it->descent = FONT_DESCENT (font) - boff;
18315 if (pcm)
18317 it->phys_ascent = pcm->ascent + boff;
18318 it->phys_descent = pcm->descent - boff;
18319 it->pixel_width = pcm->width;
18321 else
18323 it->glyph_not_available_p = 1;
18324 it->phys_ascent = FONT_BASE (font) + boff;
18325 it->phys_descent = FONT_DESCENT (font) - boff;
18326 it->pixel_width = FONT_WIDTH (font);
18329 /* If this is a space inside a region of text with
18330 `space-width' property, change its width. */
18331 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18332 if (stretched_p)
18333 it->pixel_width *= XFLOATINT (it->space_width);
18335 /* If face has a box, add the box thickness to the character
18336 height. If character has a box line to the left and/or
18337 right, add the box line width to the character's width. */
18338 if (face->box != FACE_NO_BOX)
18340 int thick = face->box_line_width;
18342 if (thick > 0)
18344 it->ascent += thick;
18345 it->descent += thick;
18347 else
18348 thick = -thick;
18350 if (it->start_of_box_run_p)
18351 it->pixel_width += thick;
18352 if (it->end_of_box_run_p)
18353 it->pixel_width += thick;
18356 /* If face has an overline, add the height of the overline
18357 (1 pixel) and a 1 pixel margin to the character height. */
18358 if (face->overline_p)
18359 it->ascent += 2;
18361 take_vertical_position_into_account (it);
18363 /* If we have to actually produce glyphs, do it. */
18364 if (it->glyph_row)
18366 if (stretched_p)
18368 /* Translate a space with a `space-width' property
18369 into a stretch glyph. */
18370 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18371 / FONT_HEIGHT (font));
18372 append_stretch_glyph (it, it->object, it->pixel_width,
18373 it->ascent + it->descent, ascent);
18375 else
18376 append_glyph (it);
18378 /* If characters with lbearing or rbearing are displayed
18379 in this line, record that fact in a flag of the
18380 glyph row. This is used to optimize X output code. */
18381 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18382 it->glyph_row->contains_overlapping_glyphs_p = 1;
18385 else if (it->char_to_display == '\n')
18387 /* A newline has no width but we need the height of the line. */
18388 it->pixel_width = 0;
18389 it->nglyphs = 0;
18390 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18391 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18393 if (face->box != FACE_NO_BOX
18394 && face->box_line_width > 0)
18396 it->ascent += face->box_line_width;
18397 it->descent += face->box_line_width;
18400 else if (it->char_to_display == '\t')
18402 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18403 int x = it->current_x + it->continuation_lines_width;
18404 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18406 /* If the distance from the current position to the next tab
18407 stop is less than a canonical character width, use the
18408 tab stop after that. */
18409 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18410 next_tab_x += tab_width;
18412 it->pixel_width = next_tab_x - x;
18413 it->nglyphs = 1;
18414 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18415 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18417 if (it->glyph_row)
18419 append_stretch_glyph (it, it->object, it->pixel_width,
18420 it->ascent + it->descent, it->ascent);
18423 else
18425 /* A multi-byte character. Assume that the display width of the
18426 character is the width of the character multiplied by the
18427 width of the font. */
18429 /* If we found a font, this font should give us the right
18430 metrics. If we didn't find a font, use the frame's
18431 default font and calculate the width of the character
18432 from the charset width; this is what old redisplay code
18433 did. */
18435 pcm = rif->per_char_metric (font, &char2b,
18436 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18438 if (font_not_found_p || !pcm)
18440 int charset = CHAR_CHARSET (it->char_to_display);
18442 it->glyph_not_available_p = 1;
18443 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18444 * CHARSET_WIDTH (charset));
18445 it->phys_ascent = FONT_BASE (font) + boff;
18446 it->phys_descent = FONT_DESCENT (font) - boff;
18448 else
18450 it->pixel_width = pcm->width;
18451 it->phys_ascent = pcm->ascent + boff;
18452 it->phys_descent = pcm->descent - boff;
18453 if (it->glyph_row
18454 && (pcm->lbearing < 0
18455 || pcm->rbearing > pcm->width))
18456 it->glyph_row->contains_overlapping_glyphs_p = 1;
18458 it->nglyphs = 1;
18459 it->ascent = FONT_BASE (font) + boff;
18460 it->descent = FONT_DESCENT (font) - boff;
18461 if (face->box != FACE_NO_BOX)
18463 int thick = face->box_line_width;
18465 if (thick > 0)
18467 it->ascent += thick;
18468 it->descent += thick;
18470 else
18471 thick = - thick;
18473 if (it->start_of_box_run_p)
18474 it->pixel_width += thick;
18475 if (it->end_of_box_run_p)
18476 it->pixel_width += thick;
18479 /* If face has an overline, add the height of the overline
18480 (1 pixel) and a 1 pixel margin to the character height. */
18481 if (face->overline_p)
18482 it->ascent += 2;
18484 take_vertical_position_into_account (it);
18486 if (it->glyph_row)
18487 append_glyph (it);
18489 it->multibyte_p = saved_multibyte_p;
18491 else if (it->what == IT_COMPOSITION)
18493 /* Note: A composition is represented as one glyph in the
18494 glyph matrix. There are no padding glyphs. */
18495 XChar2b char2b;
18496 XFontStruct *font;
18497 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18498 XCharStruct *pcm;
18499 int font_not_found_p;
18500 struct font_info *font_info;
18501 int boff; /* baseline offset */
18502 struct composition *cmp = composition_table[it->cmp_id];
18504 /* Maybe translate single-byte characters to multibyte. */
18505 it->char_to_display = it->c;
18506 if (unibyte_display_via_language_environment
18507 && SINGLE_BYTE_CHAR_P (it->c)
18508 && (it->c >= 0240
18509 || (it->c >= 0200
18510 && !NILP (Vnonascii_translation_table))))
18512 it->char_to_display = unibyte_char_to_multibyte (it->c);
18515 /* Get face and font to use. Encode IT->char_to_display. */
18516 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18517 face = FACE_FROM_ID (it->f, it->face_id);
18518 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18519 &char2b, it->multibyte_p, 0);
18520 font = face->font;
18522 /* When no suitable font found, use the default font. */
18523 font_not_found_p = font == NULL;
18524 if (font_not_found_p)
18526 font = FRAME_FONT (it->f);
18527 boff = FRAME_BASELINE_OFFSET (it->f);
18528 font_info = NULL;
18530 else
18532 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18533 boff = font_info->baseline_offset;
18534 if (font_info->vertical_centering)
18535 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18538 /* There are no padding glyphs, so there is only one glyph to
18539 produce for the composition. Important is that pixel_width,
18540 ascent and descent are the values of what is drawn by
18541 draw_glyphs (i.e. the values of the overall glyphs composed). */
18542 it->nglyphs = 1;
18544 /* If we have not yet calculated pixel size data of glyphs of
18545 the composition for the current face font, calculate them
18546 now. Theoretically, we have to check all fonts for the
18547 glyphs, but that requires much time and memory space. So,
18548 here we check only the font of the first glyph. This leads
18549 to incorrect display very rarely, and C-l (recenter) can
18550 correct the display anyway. */
18551 if (cmp->font != (void *) font)
18553 /* Ascent and descent of the font of the first character of
18554 this composition (adjusted by baseline offset). Ascent
18555 and descent of overall glyphs should not be less than
18556 them respectively. */
18557 int font_ascent = FONT_BASE (font) + boff;
18558 int font_descent = FONT_DESCENT (font) - boff;
18559 /* Bounding box of the overall glyphs. */
18560 int leftmost, rightmost, lowest, highest;
18561 int i, width, ascent, descent;
18563 cmp->font = (void *) font;
18565 /* Initialize the bounding box. */
18566 if (font_info
18567 && (pcm = rif->per_char_metric (font, &char2b,
18568 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18570 width = pcm->width;
18571 ascent = pcm->ascent;
18572 descent = pcm->descent;
18574 else
18576 width = FONT_WIDTH (font);
18577 ascent = FONT_BASE (font);
18578 descent = FONT_DESCENT (font);
18581 rightmost = width;
18582 lowest = - descent + boff;
18583 highest = ascent + boff;
18584 leftmost = 0;
18586 if (font_info
18587 && font_info->default_ascent
18588 && CHAR_TABLE_P (Vuse_default_ascent)
18589 && !NILP (Faref (Vuse_default_ascent,
18590 make_number (it->char_to_display))))
18591 highest = font_info->default_ascent + boff;
18593 /* Draw the first glyph at the normal position. It may be
18594 shifted to right later if some other glyphs are drawn at
18595 the left. */
18596 cmp->offsets[0] = 0;
18597 cmp->offsets[1] = boff;
18599 /* Set cmp->offsets for the remaining glyphs. */
18600 for (i = 1; i < cmp->glyph_len; i++)
18602 int left, right, btm, top;
18603 int ch = COMPOSITION_GLYPH (cmp, i);
18604 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18606 face = FACE_FROM_ID (it->f, face_id);
18607 get_char_face_and_encoding (it->f, ch, face->id,
18608 &char2b, it->multibyte_p, 0);
18609 font = face->font;
18610 if (font == NULL)
18612 font = FRAME_FONT (it->f);
18613 boff = FRAME_BASELINE_OFFSET (it->f);
18614 font_info = NULL;
18616 else
18618 font_info
18619 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18620 boff = font_info->baseline_offset;
18621 if (font_info->vertical_centering)
18622 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18625 if (font_info
18626 && (pcm = rif->per_char_metric (font, &char2b,
18627 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18629 width = pcm->width;
18630 ascent = pcm->ascent;
18631 descent = pcm->descent;
18633 else
18635 width = FONT_WIDTH (font);
18636 ascent = 1;
18637 descent = 0;
18640 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18642 /* Relative composition with or without
18643 alternate chars. */
18644 left = (leftmost + rightmost - width) / 2;
18645 btm = - descent + boff;
18646 if (font_info && font_info->relative_compose
18647 && (! CHAR_TABLE_P (Vignore_relative_composition)
18648 || NILP (Faref (Vignore_relative_composition,
18649 make_number (ch)))))
18652 if (- descent >= font_info->relative_compose)
18653 /* One extra pixel between two glyphs. */
18654 btm = highest + 1;
18655 else if (ascent <= 0)
18656 /* One extra pixel between two glyphs. */
18657 btm = lowest - 1 - ascent - descent;
18660 else
18662 /* A composition rule is specified by an integer
18663 value that encodes global and new reference
18664 points (GREF and NREF). GREF and NREF are
18665 specified by numbers as below:
18667 0---1---2 -- ascent
18671 9--10--11 -- center
18673 ---3---4---5--- baseline
18675 6---7---8 -- descent
18677 int rule = COMPOSITION_RULE (cmp, i);
18678 int gref, nref, grefx, grefy, nrefx, nrefy;
18680 COMPOSITION_DECODE_RULE (rule, gref, nref);
18681 grefx = gref % 3, nrefx = nref % 3;
18682 grefy = gref / 3, nrefy = nref / 3;
18684 left = (leftmost
18685 + grefx * (rightmost - leftmost) / 2
18686 - nrefx * width / 2);
18687 btm = ((grefy == 0 ? highest
18688 : grefy == 1 ? 0
18689 : grefy == 2 ? lowest
18690 : (highest + lowest) / 2)
18691 - (nrefy == 0 ? ascent + descent
18692 : nrefy == 1 ? descent - boff
18693 : nrefy == 2 ? 0
18694 : (ascent + descent) / 2));
18697 cmp->offsets[i * 2] = left;
18698 cmp->offsets[i * 2 + 1] = btm + descent;
18700 /* Update the bounding box of the overall glyphs. */
18701 right = left + width;
18702 top = btm + descent + ascent;
18703 if (left < leftmost)
18704 leftmost = left;
18705 if (right > rightmost)
18706 rightmost = right;
18707 if (top > highest)
18708 highest = top;
18709 if (btm < lowest)
18710 lowest = btm;
18713 /* If there are glyphs whose x-offsets are negative,
18714 shift all glyphs to the right and make all x-offsets
18715 non-negative. */
18716 if (leftmost < 0)
18718 for (i = 0; i < cmp->glyph_len; i++)
18719 cmp->offsets[i * 2] -= leftmost;
18720 rightmost -= leftmost;
18723 cmp->pixel_width = rightmost;
18724 cmp->ascent = highest;
18725 cmp->descent = - lowest;
18726 if (cmp->ascent < font_ascent)
18727 cmp->ascent = font_ascent;
18728 if (cmp->descent < font_descent)
18729 cmp->descent = font_descent;
18732 it->pixel_width = cmp->pixel_width;
18733 it->ascent = it->phys_ascent = cmp->ascent;
18734 it->descent = it->phys_descent = cmp->descent;
18736 if (face->box != FACE_NO_BOX)
18738 int thick = face->box_line_width;
18740 if (thick > 0)
18742 it->ascent += thick;
18743 it->descent += thick;
18745 else
18746 thick = - thick;
18748 if (it->start_of_box_run_p)
18749 it->pixel_width += thick;
18750 if (it->end_of_box_run_p)
18751 it->pixel_width += thick;
18754 /* If face has an overline, add the height of the overline
18755 (1 pixel) and a 1 pixel margin to the character height. */
18756 if (face->overline_p)
18757 it->ascent += 2;
18759 take_vertical_position_into_account (it);
18761 if (it->glyph_row)
18762 append_composite_glyph (it);
18764 else if (it->what == IT_IMAGE)
18765 produce_image_glyph (it);
18766 else if (it->what == IT_STRETCH)
18767 produce_stretch_glyph (it);
18769 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18770 because this isn't true for images with `:ascent 100'. */
18771 xassert (it->ascent >= 0 && it->descent >= 0);
18772 if (it->area == TEXT_AREA)
18773 it->current_x += it->pixel_width;
18775 it->descent += it->extra_line_spacing;
18777 it->max_ascent = max (it->max_ascent, it->ascent);
18778 it->max_descent = max (it->max_descent, it->descent);
18779 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18780 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18783 /* EXPORT for RIF:
18784 Output LEN glyphs starting at START at the nominal cursor position.
18785 Advance the nominal cursor over the text. The global variable
18786 updated_window contains the window being updated, updated_row is
18787 the glyph row being updated, and updated_area is the area of that
18788 row being updated. */
18790 void
18791 x_write_glyphs (start, len)
18792 struct glyph *start;
18793 int len;
18795 int x, hpos;
18797 xassert (updated_window && updated_row);
18798 BLOCK_INPUT;
18800 /* Write glyphs. */
18802 hpos = start - updated_row->glyphs[updated_area];
18803 x = draw_glyphs (updated_window, output_cursor.x,
18804 updated_row, updated_area,
18805 hpos, hpos + len,
18806 DRAW_NORMAL_TEXT, 0);
18808 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18809 if (updated_area == TEXT_AREA
18810 && updated_window->phys_cursor_on_p
18811 && updated_window->phys_cursor.vpos == output_cursor.vpos
18812 && updated_window->phys_cursor.hpos >= hpos
18813 && updated_window->phys_cursor.hpos < hpos + len)
18814 updated_window->phys_cursor_on_p = 0;
18816 UNBLOCK_INPUT;
18818 /* Advance the output cursor. */
18819 output_cursor.hpos += len;
18820 output_cursor.x = x;
18824 /* EXPORT for RIF:
18825 Insert LEN glyphs from START at the nominal cursor position. */
18827 void
18828 x_insert_glyphs (start, len)
18829 struct glyph *start;
18830 int len;
18832 struct frame *f;
18833 struct window *w;
18834 int line_height, shift_by_width, shifted_region_width;
18835 struct glyph_row *row;
18836 struct glyph *glyph;
18837 int frame_x, frame_y, hpos;
18839 xassert (updated_window && updated_row);
18840 BLOCK_INPUT;
18841 w = updated_window;
18842 f = XFRAME (WINDOW_FRAME (w));
18844 /* Get the height of the line we are in. */
18845 row = updated_row;
18846 line_height = row->height;
18848 /* Get the width of the glyphs to insert. */
18849 shift_by_width = 0;
18850 for (glyph = start; glyph < start + len; ++glyph)
18851 shift_by_width += glyph->pixel_width;
18853 /* Get the width of the region to shift right. */
18854 shifted_region_width = (window_box_width (w, updated_area)
18855 - output_cursor.x
18856 - shift_by_width);
18858 /* Shift right. */
18859 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18860 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18862 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18863 line_height, shift_by_width);
18865 /* Write the glyphs. */
18866 hpos = start - row->glyphs[updated_area];
18867 draw_glyphs (w, output_cursor.x, row, updated_area,
18868 hpos, hpos + len,
18869 DRAW_NORMAL_TEXT, 0);
18871 /* Advance the output cursor. */
18872 output_cursor.hpos += len;
18873 output_cursor.x += shift_by_width;
18874 UNBLOCK_INPUT;
18878 /* EXPORT for RIF:
18879 Erase the current text line from the nominal cursor position
18880 (inclusive) to pixel column TO_X (exclusive). The idea is that
18881 everything from TO_X onward is already erased.
18883 TO_X is a pixel position relative to updated_area of
18884 updated_window. TO_X == -1 means clear to the end of this area. */
18886 void
18887 x_clear_end_of_line (to_x)
18888 int to_x;
18890 struct frame *f;
18891 struct window *w = updated_window;
18892 int max_x, min_y, max_y;
18893 int from_x, from_y, to_y;
18895 xassert (updated_window && updated_row);
18896 f = XFRAME (w->frame);
18898 if (updated_row->full_width_p)
18899 max_x = WINDOW_TOTAL_WIDTH (w);
18900 else
18901 max_x = window_box_width (w, updated_area);
18902 max_y = window_text_bottom_y (w);
18904 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18905 of window. For TO_X > 0, truncate to end of drawing area. */
18906 if (to_x == 0)
18907 return;
18908 else if (to_x < 0)
18909 to_x = max_x;
18910 else
18911 to_x = min (to_x, max_x);
18913 to_y = min (max_y, output_cursor.y + updated_row->height);
18915 /* Notice if the cursor will be cleared by this operation. */
18916 if (!updated_row->full_width_p)
18917 notice_overwritten_cursor (w, updated_area,
18918 output_cursor.x, -1,
18919 updated_row->y,
18920 MATRIX_ROW_BOTTOM_Y (updated_row));
18922 from_x = output_cursor.x;
18924 /* Translate to frame coordinates. */
18925 if (updated_row->full_width_p)
18927 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18928 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18930 else
18932 int area_left = window_box_left (w, updated_area);
18933 from_x += area_left;
18934 to_x += area_left;
18937 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18938 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18939 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18941 /* Prevent inadvertently clearing to end of the X window. */
18942 if (to_x > from_x && to_y > from_y)
18944 BLOCK_INPUT;
18945 rif->clear_frame_area (f, from_x, from_y,
18946 to_x - from_x, to_y - from_y);
18947 UNBLOCK_INPUT;
18951 #endif /* HAVE_WINDOW_SYSTEM */
18955 /***********************************************************************
18956 Cursor types
18957 ***********************************************************************/
18959 /* Value is the internal representation of the specified cursor type
18960 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18961 of the bar cursor. */
18963 static enum text_cursor_kinds
18964 get_specified_cursor_type (arg, width)
18965 Lisp_Object arg;
18966 int *width;
18968 enum text_cursor_kinds type;
18970 if (NILP (arg))
18971 return NO_CURSOR;
18973 if (EQ (arg, Qbox))
18974 return FILLED_BOX_CURSOR;
18976 if (EQ (arg, Qhollow))
18977 return HOLLOW_BOX_CURSOR;
18979 if (EQ (arg, Qbar))
18981 *width = 2;
18982 return BAR_CURSOR;
18985 if (CONSP (arg)
18986 && EQ (XCAR (arg), Qbar)
18987 && INTEGERP (XCDR (arg))
18988 && XINT (XCDR (arg)) >= 0)
18990 *width = XINT (XCDR (arg));
18991 return BAR_CURSOR;
18994 if (EQ (arg, Qhbar))
18996 *width = 2;
18997 return HBAR_CURSOR;
19000 if (CONSP (arg)
19001 && EQ (XCAR (arg), Qhbar)
19002 && INTEGERP (XCDR (arg))
19003 && XINT (XCDR (arg)) >= 0)
19005 *width = XINT (XCDR (arg));
19006 return HBAR_CURSOR;
19009 /* Treat anything unknown as "hollow box cursor".
19010 It was bad to signal an error; people have trouble fixing
19011 .Xdefaults with Emacs, when it has something bad in it. */
19012 type = HOLLOW_BOX_CURSOR;
19014 return type;
19017 /* Set the default cursor types for specified frame. */
19018 void
19019 set_frame_cursor_types (f, arg)
19020 struct frame *f;
19021 Lisp_Object arg;
19023 int width;
19024 Lisp_Object tem;
19026 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19027 FRAME_CURSOR_WIDTH (f) = width;
19029 /* By default, set up the blink-off state depending on the on-state. */
19031 tem = Fassoc (arg, Vblink_cursor_alist);
19032 if (!NILP (tem))
19034 FRAME_BLINK_OFF_CURSOR (f)
19035 = get_specified_cursor_type (XCDR (tem), &width);
19036 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19038 else
19039 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19043 /* Return the cursor we want to be displayed in window W. Return
19044 width of bar/hbar cursor through WIDTH arg. Return with
19045 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19046 (i.e. if the `system caret' should track this cursor).
19048 In a mini-buffer window, we want the cursor only to appear if we
19049 are reading input from this window. For the selected window, we
19050 want the cursor type given by the frame parameter or buffer local
19051 setting of cursor-type. If explicitly marked off, draw no cursor.
19052 In all other cases, we want a hollow box cursor. */
19054 static enum text_cursor_kinds
19055 get_window_cursor_type (w, glyph, width, active_cursor)
19056 struct window *w;
19057 struct glyph *glyph;
19058 int *width;
19059 int *active_cursor;
19061 struct frame *f = XFRAME (w->frame);
19062 struct buffer *b = XBUFFER (w->buffer);
19063 int cursor_type = DEFAULT_CURSOR;
19064 Lisp_Object alt_cursor;
19065 int non_selected = 0;
19067 *active_cursor = 1;
19069 /* Echo area */
19070 if (cursor_in_echo_area
19071 && FRAME_HAS_MINIBUF_P (f)
19072 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19074 if (w == XWINDOW (echo_area_window))
19076 *width = FRAME_CURSOR_WIDTH (f);
19077 return FRAME_DESIRED_CURSOR (f);
19080 *active_cursor = 0;
19081 non_selected = 1;
19084 /* Nonselected window or nonselected frame. */
19085 else if (w != XWINDOW (f->selected_window)
19086 #ifdef HAVE_WINDOW_SYSTEM
19087 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19088 #endif
19091 *active_cursor = 0;
19093 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19094 return NO_CURSOR;
19096 non_selected = 1;
19099 /* Never display a cursor in a window in which cursor-type is nil. */
19100 if (NILP (b->cursor_type))
19101 return NO_CURSOR;
19103 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19104 if (non_selected)
19106 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19107 return get_specified_cursor_type (alt_cursor, width);
19110 /* Get the normal cursor type for this window. */
19111 if (EQ (b->cursor_type, Qt))
19113 cursor_type = FRAME_DESIRED_CURSOR (f);
19114 *width = FRAME_CURSOR_WIDTH (f);
19116 else
19117 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19119 /* Use normal cursor if not blinked off. */
19120 if (!w->cursor_off_p)
19122 if (glyph->type == IMAGE_GLYPH) {
19123 if (cursor_type == FILLED_BOX_CURSOR)
19124 cursor_type = HOLLOW_BOX_CURSOR;
19126 return cursor_type;
19129 /* Cursor is blinked off, so determine how to "toggle" it. */
19131 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19132 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19133 return get_specified_cursor_type (XCDR (alt_cursor), width);
19135 /* Then see if frame has specified a specific blink off cursor type. */
19136 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19138 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19139 return FRAME_BLINK_OFF_CURSOR (f);
19142 #if 0
19143 /* Some people liked having a permanently visible blinking cursor,
19144 while others had very strong opinions against it. So it was
19145 decided to remove it. KFS 2003-09-03 */
19147 /* Finally perform built-in cursor blinking:
19148 filled box <-> hollow box
19149 wide [h]bar <-> narrow [h]bar
19150 narrow [h]bar <-> no cursor
19151 other type <-> no cursor */
19153 if (cursor_type == FILLED_BOX_CURSOR)
19154 return HOLLOW_BOX_CURSOR;
19156 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19158 *width = 1;
19159 return cursor_type;
19161 #endif
19163 return NO_CURSOR;
19167 #ifdef HAVE_WINDOW_SYSTEM
19169 /* Notice when the text cursor of window W has been completely
19170 overwritten by a drawing operation that outputs glyphs in AREA
19171 starting at X0 and ending at X1 in the line starting at Y0 and
19172 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19173 the rest of the line after X0 has been written. Y coordinates
19174 are window-relative. */
19176 static void
19177 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19178 struct window *w;
19179 enum glyph_row_area area;
19180 int x0, y0, x1, y1;
19182 if (area == TEXT_AREA && w->phys_cursor_on_p)
19184 int cx0 = w->phys_cursor.x;
19185 int cx1 = cx0 + w->phys_cursor_width;
19186 int cy0 = w->phys_cursor.y;
19187 int cy1 = cy0 + w->phys_cursor_height;
19189 if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
19191 /* The cursor image will be completely removed from the
19192 screen if the output area intersects the cursor area in
19193 y-direction. When we draw in [y0 y1[, and some part of
19194 the cursor is at y < y0, that part must have been drawn
19195 before. When scrolling, the cursor is erased before
19196 actually scrolling, so we don't come here. When not
19197 scrolling, the rows above the old cursor row must have
19198 changed, and in this case these rows must have written
19199 over the cursor image.
19201 Likewise if part of the cursor is below y1, with the
19202 exception of the cursor being in the first blank row at
19203 the buffer and window end because update_text_area
19204 doesn't draw that row. (Except when it does, but
19205 that's handled in update_text_area.) */
19207 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
19208 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
19209 w->phys_cursor_on_p = 0;
19214 #endif /* HAVE_WINDOW_SYSTEM */
19217 /************************************************************************
19218 Mouse Face
19219 ************************************************************************/
19221 #ifdef HAVE_WINDOW_SYSTEM
19223 /* EXPORT for RIF:
19224 Fix the display of area AREA of overlapping row ROW in window W. */
19226 void
19227 x_fix_overlapping_area (w, row, area)
19228 struct window *w;
19229 struct glyph_row *row;
19230 enum glyph_row_area area;
19232 int i, x;
19234 BLOCK_INPUT;
19236 x = 0;
19237 for (i = 0; i < row->used[area];)
19239 if (row->glyphs[area][i].overlaps_vertically_p)
19241 int start = i, start_x = x;
19245 x += row->glyphs[area][i].pixel_width;
19246 ++i;
19248 while (i < row->used[area]
19249 && row->glyphs[area][i].overlaps_vertically_p);
19251 draw_glyphs (w, start_x, row, area,
19252 start, i,
19253 DRAW_NORMAL_TEXT, 1);
19255 else
19257 x += row->glyphs[area][i].pixel_width;
19258 ++i;
19262 UNBLOCK_INPUT;
19266 /* EXPORT:
19267 Draw the cursor glyph of window W in glyph row ROW. See the
19268 comment of draw_glyphs for the meaning of HL. */
19270 void
19271 draw_phys_cursor_glyph (w, row, hl)
19272 struct window *w;
19273 struct glyph_row *row;
19274 enum draw_glyphs_face hl;
19276 /* If cursor hpos is out of bounds, don't draw garbage. This can
19277 happen in mini-buffer windows when switching between echo area
19278 glyphs and mini-buffer. */
19279 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19281 int on_p = w->phys_cursor_on_p;
19282 int x1;
19283 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19284 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19285 hl, 0);
19286 w->phys_cursor_on_p = on_p;
19288 if (hl == DRAW_CURSOR)
19289 w->phys_cursor_width = x1 - w->phys_cursor.x;
19290 /* When we erase the cursor, and ROW is overlapped by other
19291 rows, make sure that these overlapping parts of other rows
19292 are redrawn. */
19293 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19295 if (row > w->current_matrix->rows
19296 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19297 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19299 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19300 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19301 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19307 /* EXPORT:
19308 Erase the image of a cursor of window W from the screen. */
19310 void
19311 erase_phys_cursor (w)
19312 struct window *w;
19314 struct frame *f = XFRAME (w->frame);
19315 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19316 int hpos = w->phys_cursor.hpos;
19317 int vpos = w->phys_cursor.vpos;
19318 int mouse_face_here_p = 0;
19319 struct glyph_matrix *active_glyphs = w->current_matrix;
19320 struct glyph_row *cursor_row;
19321 struct glyph *cursor_glyph;
19322 enum draw_glyphs_face hl;
19324 /* No cursor displayed or row invalidated => nothing to do on the
19325 screen. */
19326 if (w->phys_cursor_type == NO_CURSOR)
19327 goto mark_cursor_off;
19329 /* VPOS >= active_glyphs->nrows means that window has been resized.
19330 Don't bother to erase the cursor. */
19331 if (vpos >= active_glyphs->nrows)
19332 goto mark_cursor_off;
19334 /* If row containing cursor is marked invalid, there is nothing we
19335 can do. */
19336 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19337 if (!cursor_row->enabled_p)
19338 goto mark_cursor_off;
19340 /* If row is completely invisible, don't attempt to delete a cursor which
19341 isn't there. This can happen if cursor is at top of a window, and
19342 we switch to a buffer with a header line in that window. */
19343 if (cursor_row->visible_height <= 0)
19344 goto mark_cursor_off;
19346 /* This can happen when the new row is shorter than the old one.
19347 In this case, either draw_glyphs or clear_end_of_line
19348 should have cleared the cursor. Note that we wouldn't be
19349 able to erase the cursor in this case because we don't have a
19350 cursor glyph at hand. */
19351 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19352 goto mark_cursor_off;
19354 /* If the cursor is in the mouse face area, redisplay that when
19355 we clear the cursor. */
19356 if (! NILP (dpyinfo->mouse_face_window)
19357 && w == XWINDOW (dpyinfo->mouse_face_window)
19358 && (vpos > dpyinfo->mouse_face_beg_row
19359 || (vpos == dpyinfo->mouse_face_beg_row
19360 && hpos >= dpyinfo->mouse_face_beg_col))
19361 && (vpos < dpyinfo->mouse_face_end_row
19362 || (vpos == dpyinfo->mouse_face_end_row
19363 && hpos < dpyinfo->mouse_face_end_col))
19364 /* Don't redraw the cursor's spot in mouse face if it is at the
19365 end of a line (on a newline). The cursor appears there, but
19366 mouse highlighting does not. */
19367 && cursor_row->used[TEXT_AREA] > hpos)
19368 mouse_face_here_p = 1;
19370 /* Maybe clear the display under the cursor. */
19371 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19373 int x, y;
19374 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19376 cursor_glyph = get_phys_cursor_glyph (w);
19377 if (cursor_glyph == NULL)
19378 goto mark_cursor_off;
19380 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19381 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19383 rif->clear_frame_area (f, x, y,
19384 cursor_glyph->pixel_width, cursor_row->visible_height);
19387 /* Erase the cursor by redrawing the character underneath it. */
19388 if (mouse_face_here_p)
19389 hl = DRAW_MOUSE_FACE;
19390 else
19391 hl = DRAW_NORMAL_TEXT;
19392 draw_phys_cursor_glyph (w, cursor_row, hl);
19394 mark_cursor_off:
19395 w->phys_cursor_on_p = 0;
19396 w->phys_cursor_type = NO_CURSOR;
19400 /* EXPORT:
19401 Display or clear cursor of window W. If ON is zero, clear the
19402 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19403 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19405 void
19406 display_and_set_cursor (w, on, hpos, vpos, x, y)
19407 struct window *w;
19408 int on, hpos, vpos, x, y;
19410 struct frame *f = XFRAME (w->frame);
19411 int new_cursor_type;
19412 int new_cursor_width;
19413 int active_cursor;
19414 struct glyph_matrix *current_glyphs;
19415 struct glyph_row *glyph_row;
19416 struct glyph *glyph;
19418 /* This is pointless on invisible frames, and dangerous on garbaged
19419 windows and frames; in the latter case, the frame or window may
19420 be in the midst of changing its size, and x and y may be off the
19421 window. */
19422 if (! FRAME_VISIBLE_P (f)
19423 || FRAME_GARBAGED_P (f)
19424 || vpos >= w->current_matrix->nrows
19425 || hpos >= w->current_matrix->matrix_w)
19426 return;
19428 /* If cursor is off and we want it off, return quickly. */
19429 if (!on && !w->phys_cursor_on_p)
19430 return;
19432 current_glyphs = w->current_matrix;
19433 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19434 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19436 /* If cursor row is not enabled, we don't really know where to
19437 display the cursor. */
19438 if (!glyph_row->enabled_p)
19440 w->phys_cursor_on_p = 0;
19441 return;
19444 xassert (interrupt_input_blocked);
19446 /* Set new_cursor_type to the cursor we want to be displayed. */
19447 new_cursor_type = get_window_cursor_type (w, glyph,
19448 &new_cursor_width, &active_cursor);
19450 /* If cursor is currently being shown and we don't want it to be or
19451 it is in the wrong place, or the cursor type is not what we want,
19452 erase it. */
19453 if (w->phys_cursor_on_p
19454 && (!on
19455 || w->phys_cursor.x != x
19456 || w->phys_cursor.y != y
19457 || new_cursor_type != w->phys_cursor_type
19458 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19459 && new_cursor_width != w->phys_cursor_width)))
19460 erase_phys_cursor (w);
19462 /* Don't check phys_cursor_on_p here because that flag is only set
19463 to zero in some cases where we know that the cursor has been
19464 completely erased, to avoid the extra work of erasing the cursor
19465 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19466 still not be visible, or it has only been partly erased. */
19467 if (on)
19469 w->phys_cursor_ascent = glyph_row->ascent;
19470 w->phys_cursor_height = glyph_row->height;
19472 /* Set phys_cursor_.* before x_draw_.* is called because some
19473 of them may need the information. */
19474 w->phys_cursor.x = x;
19475 w->phys_cursor.y = glyph_row->y;
19476 w->phys_cursor.hpos = hpos;
19477 w->phys_cursor.vpos = vpos;
19480 rif->draw_window_cursor (w, glyph_row, x, y,
19481 new_cursor_type, new_cursor_width,
19482 on, active_cursor);
19486 /* Switch the display of W's cursor on or off, according to the value
19487 of ON. */
19489 static void
19490 update_window_cursor (w, on)
19491 struct window *w;
19492 int on;
19494 /* Don't update cursor in windows whose frame is in the process
19495 of being deleted. */
19496 if (w->current_matrix)
19498 BLOCK_INPUT;
19499 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19500 w->phys_cursor.x, w->phys_cursor.y);
19501 UNBLOCK_INPUT;
19506 /* Call update_window_cursor with parameter ON_P on all leaf windows
19507 in the window tree rooted at W. */
19509 static void
19510 update_cursor_in_window_tree (w, on_p)
19511 struct window *w;
19512 int on_p;
19514 while (w)
19516 if (!NILP (w->hchild))
19517 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19518 else if (!NILP (w->vchild))
19519 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19520 else
19521 update_window_cursor (w, on_p);
19523 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19528 /* EXPORT:
19529 Display the cursor on window W, or clear it, according to ON_P.
19530 Don't change the cursor's position. */
19532 void
19533 x_update_cursor (f, on_p)
19534 struct frame *f;
19535 int on_p;
19537 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19541 /* EXPORT:
19542 Clear the cursor of window W to background color, and mark the
19543 cursor as not shown. This is used when the text where the cursor
19544 is is about to be rewritten. */
19546 void
19547 x_clear_cursor (w)
19548 struct window *w;
19550 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19551 update_window_cursor (w, 0);
19555 /* EXPORT:
19556 Display the active region described by mouse_face_* according to DRAW. */
19558 void
19559 show_mouse_face (dpyinfo, draw)
19560 Display_Info *dpyinfo;
19561 enum draw_glyphs_face draw;
19563 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19564 struct frame *f = XFRAME (WINDOW_FRAME (w));
19566 if (/* If window is in the process of being destroyed, don't bother
19567 to do anything. */
19568 w->current_matrix != NULL
19569 /* Don't update mouse highlight if hidden */
19570 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19571 /* Recognize when we are called to operate on rows that don't exist
19572 anymore. This can happen when a window is split. */
19573 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19575 int phys_cursor_on_p = w->phys_cursor_on_p;
19576 struct glyph_row *row, *first, *last;
19578 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19579 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19581 for (row = first; row <= last && row->enabled_p; ++row)
19583 int start_hpos, end_hpos, start_x;
19585 /* For all but the first row, the highlight starts at column 0. */
19586 if (row == first)
19588 start_hpos = dpyinfo->mouse_face_beg_col;
19589 start_x = dpyinfo->mouse_face_beg_x;
19591 else
19593 start_hpos = 0;
19594 start_x = 0;
19597 if (row == last)
19598 end_hpos = dpyinfo->mouse_face_end_col;
19599 else
19600 end_hpos = row->used[TEXT_AREA];
19602 if (end_hpos > start_hpos)
19604 draw_glyphs (w, start_x, row, TEXT_AREA,
19605 start_hpos, end_hpos,
19606 draw, 0);
19608 row->mouse_face_p
19609 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19613 /* When we've written over the cursor, arrange for it to
19614 be displayed again. */
19615 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19617 BLOCK_INPUT;
19618 display_and_set_cursor (w, 1,
19619 w->phys_cursor.hpos, w->phys_cursor.vpos,
19620 w->phys_cursor.x, w->phys_cursor.y);
19621 UNBLOCK_INPUT;
19625 /* Change the mouse cursor. */
19626 if (draw == DRAW_NORMAL_TEXT)
19627 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19628 else if (draw == DRAW_MOUSE_FACE)
19629 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19630 else
19631 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19634 /* EXPORT:
19635 Clear out the mouse-highlighted active region.
19636 Redraw it un-highlighted first. Value is non-zero if mouse
19637 face was actually drawn unhighlighted. */
19640 clear_mouse_face (dpyinfo)
19641 Display_Info *dpyinfo;
19643 int cleared = 0;
19645 if (!NILP (dpyinfo->mouse_face_window))
19647 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19648 cleared = 1;
19651 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19652 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19653 dpyinfo->mouse_face_window = Qnil;
19654 dpyinfo->mouse_face_overlay = Qnil;
19655 return cleared;
19659 /* EXPORT:
19660 Non-zero if physical cursor of window W is within mouse face. */
19663 cursor_in_mouse_face_p (w)
19664 struct window *w;
19666 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19667 int in_mouse_face = 0;
19669 if (WINDOWP (dpyinfo->mouse_face_window)
19670 && XWINDOW (dpyinfo->mouse_face_window) == w)
19672 int hpos = w->phys_cursor.hpos;
19673 int vpos = w->phys_cursor.vpos;
19675 if (vpos >= dpyinfo->mouse_face_beg_row
19676 && vpos <= dpyinfo->mouse_face_end_row
19677 && (vpos > dpyinfo->mouse_face_beg_row
19678 || hpos >= dpyinfo->mouse_face_beg_col)
19679 && (vpos < dpyinfo->mouse_face_end_row
19680 || hpos < dpyinfo->mouse_face_end_col
19681 || dpyinfo->mouse_face_past_end))
19682 in_mouse_face = 1;
19685 return in_mouse_face;
19691 /* Find the glyph matrix position of buffer position CHARPOS in window
19692 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19693 current glyphs must be up to date. If CHARPOS is above window
19694 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19695 of last line in W. In the row containing CHARPOS, stop before glyphs
19696 having STOP as object. */
19698 #if 1 /* This is a version of fast_find_position that's more correct
19699 in the presence of hscrolling, for example. I didn't install
19700 it right away because the problem fixed is minor, it failed
19701 in 20.x as well, and I think it's too risky to install
19702 so near the release of 21.1. 2001-09-25 gerd. */
19704 static int
19705 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19706 struct window *w;
19707 int charpos;
19708 int *hpos, *vpos, *x, *y;
19709 Lisp_Object stop;
19711 struct glyph_row *row, *first;
19712 struct glyph *glyph, *end;
19713 int past_end = 0;
19715 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19716 row = row_containing_pos (w, charpos, first, NULL, 0);
19717 if (row == NULL)
19719 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19721 *x = *y = *hpos = *vpos = 0;
19722 return 0;
19724 else
19726 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19727 past_end = 1;
19731 *x = row->x;
19732 *y = row->y;
19733 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19735 glyph = row->glyphs[TEXT_AREA];
19736 end = glyph + row->used[TEXT_AREA];
19738 /* Skip over glyphs not having an object at the start of the row.
19739 These are special glyphs like truncation marks on terminal
19740 frames. */
19741 if (row->displays_text_p)
19742 while (glyph < end
19743 && INTEGERP (glyph->object)
19744 && !EQ (stop, glyph->object)
19745 && glyph->charpos < 0)
19747 *x += glyph->pixel_width;
19748 ++glyph;
19751 while (glyph < end
19752 && !INTEGERP (glyph->object)
19753 && !EQ (stop, glyph->object)
19754 && (!BUFFERP (glyph->object)
19755 || glyph->charpos < charpos))
19757 *x += glyph->pixel_width;
19758 ++glyph;
19761 *hpos = glyph - row->glyphs[TEXT_AREA];
19762 return past_end;
19765 #else /* not 1 */
19767 static int
19768 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19769 struct window *w;
19770 int pos;
19771 int *hpos, *vpos, *x, *y;
19772 Lisp_Object stop;
19774 int i;
19775 int lastcol;
19776 int maybe_next_line_p = 0;
19777 int line_start_position;
19778 int yb = window_text_bottom_y (w);
19779 struct glyph_row *row, *best_row;
19780 int row_vpos, best_row_vpos;
19781 int current_x;
19783 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19784 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19786 while (row->y < yb)
19788 if (row->used[TEXT_AREA])
19789 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19790 else
19791 line_start_position = 0;
19793 if (line_start_position > pos)
19794 break;
19795 /* If the position sought is the end of the buffer,
19796 don't include the blank lines at the bottom of the window. */
19797 else if (line_start_position == pos
19798 && pos == BUF_ZV (XBUFFER (w->buffer)))
19800 maybe_next_line_p = 1;
19801 break;
19803 else if (line_start_position > 0)
19805 best_row = row;
19806 best_row_vpos = row_vpos;
19809 if (row->y + row->height >= yb)
19810 break;
19812 ++row;
19813 ++row_vpos;
19816 /* Find the right column within BEST_ROW. */
19817 lastcol = 0;
19818 current_x = best_row->x;
19819 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19821 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19822 int charpos = glyph->charpos;
19824 if (BUFFERP (glyph->object))
19826 if (charpos == pos)
19828 *hpos = i;
19829 *vpos = best_row_vpos;
19830 *x = current_x;
19831 *y = best_row->y;
19832 return 1;
19834 else if (charpos > pos)
19835 break;
19837 else if (EQ (glyph->object, stop))
19838 break;
19840 if (charpos > 0)
19841 lastcol = i;
19842 current_x += glyph->pixel_width;
19845 /* If we're looking for the end of the buffer,
19846 and we didn't find it in the line we scanned,
19847 use the start of the following line. */
19848 if (maybe_next_line_p)
19850 ++best_row;
19851 ++best_row_vpos;
19852 lastcol = 0;
19853 current_x = best_row->x;
19856 *vpos = best_row_vpos;
19857 *hpos = lastcol + 1;
19858 *x = current_x;
19859 *y = best_row->y;
19860 return 0;
19863 #endif /* not 1 */
19866 /* Find the position of the glyph for position POS in OBJECT in
19867 window W's current matrix, and return in *X, *Y the pixel
19868 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19870 RIGHT_P non-zero means return the position of the right edge of the
19871 glyph, RIGHT_P zero means return the left edge position.
19873 If no glyph for POS exists in the matrix, return the position of
19874 the glyph with the next smaller position that is in the matrix, if
19875 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19876 exists in the matrix, return the position of the glyph with the
19877 next larger position in OBJECT.
19879 Value is non-zero if a glyph was found. */
19881 static int
19882 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19883 struct window *w;
19884 int pos;
19885 Lisp_Object object;
19886 int *hpos, *vpos, *x, *y;
19887 int right_p;
19889 int yb = window_text_bottom_y (w);
19890 struct glyph_row *r;
19891 struct glyph *best_glyph = NULL;
19892 struct glyph_row *best_row = NULL;
19893 int best_x = 0;
19895 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19896 r->enabled_p && r->y < yb;
19897 ++r)
19899 struct glyph *g = r->glyphs[TEXT_AREA];
19900 struct glyph *e = g + r->used[TEXT_AREA];
19901 int gx;
19903 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19904 if (EQ (g->object, object))
19906 if (g->charpos == pos)
19908 best_glyph = g;
19909 best_x = gx;
19910 best_row = r;
19911 goto found;
19913 else if (best_glyph == NULL
19914 || ((abs (g->charpos - pos)
19915 < abs (best_glyph->charpos - pos))
19916 && (right_p
19917 ? g->charpos < pos
19918 : g->charpos > pos)))
19920 best_glyph = g;
19921 best_x = gx;
19922 best_row = r;
19927 found:
19929 if (best_glyph)
19931 *x = best_x;
19932 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19934 if (right_p)
19936 *x += best_glyph->pixel_width;
19937 ++*hpos;
19940 *y = best_row->y;
19941 *vpos = best_row - w->current_matrix->rows;
19944 return best_glyph != NULL;
19948 /* Take proper action when mouse has moved to the mode or header line
19949 or marginal area AREA of window W, x-position X and y-position Y.
19950 X is relative to the start of the text display area of W, so the
19951 width of bitmap areas and scroll bars must be subtracted to get a
19952 position relative to the start of the mode line. */
19954 static void
19955 note_mode_line_or_margin_highlight (w, x, y, area)
19956 struct window *w;
19957 int x, y;
19958 enum window_part area;
19960 struct frame *f = XFRAME (w->frame);
19961 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19962 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19963 int charpos;
19964 Lisp_Object string, help, map, pos;
19966 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
19967 string = mode_line_string (w, &x, &y, 0, 0, area, &charpos);
19968 else
19969 string = marginal_area_string (w, &x, &y, 0, 0, area, &charpos);
19971 if (STRINGP (string))
19973 pos = make_number (charpos);
19975 /* If we're on a string with `help-echo' text property, arrange
19976 for the help to be displayed. This is done by setting the
19977 global variable help_echo_string to the help string. */
19978 help = Fget_text_property (pos, Qhelp_echo, string);
19979 if (!NILP (help))
19981 help_echo_string = help;
19982 XSETWINDOW (help_echo_window, w);
19983 help_echo_object = string;
19984 help_echo_pos = charpos;
19987 /* Change the mouse pointer according to what is under X/Y. */
19988 if (area == ON_MODE_LINE)
19990 map = Fget_text_property (pos, Qlocal_map, string);
19991 if (!KEYMAPP (map))
19992 map = Fget_text_property (pos, Qkeymap, string);
19993 if (!KEYMAPP (map))
19994 cursor = dpyinfo->vertical_scroll_bar_cursor;
19998 rif->define_frame_cursor (f, cursor);
20002 /* EXPORT:
20003 Take proper action when the mouse has moved to position X, Y on
20004 frame F as regards highlighting characters that have mouse-face
20005 properties. Also de-highlighting chars where the mouse was before.
20006 X and Y can be negative or out of range. */
20008 void
20009 note_mouse_highlight (f, x, y)
20010 struct frame *f;
20011 int x, y;
20013 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20014 enum window_part part;
20015 Lisp_Object window;
20016 struct window *w;
20017 Cursor cursor = No_Cursor;
20018 struct buffer *b;
20020 /* When a menu is active, don't highlight because this looks odd. */
20021 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20022 if (popup_activated ())
20023 return;
20024 #endif
20026 if (NILP (Vmouse_highlight)
20027 || !f->glyphs_initialized_p)
20028 return;
20030 dpyinfo->mouse_face_mouse_x = x;
20031 dpyinfo->mouse_face_mouse_y = y;
20032 dpyinfo->mouse_face_mouse_frame = f;
20034 if (dpyinfo->mouse_face_defer)
20035 return;
20037 if (gc_in_progress)
20039 dpyinfo->mouse_face_deferred_gc = 1;
20040 return;
20043 /* Which window is that in? */
20044 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20046 /* If we were displaying active text in another window, clear that. */
20047 if (! EQ (window, dpyinfo->mouse_face_window))
20048 clear_mouse_face (dpyinfo);
20050 /* Not on a window -> return. */
20051 if (!WINDOWP (window))
20052 return;
20054 /* Reset help_echo_string. It will get recomputed below. */
20055 /* ++KFS: X version didn't do this, but it looks harmless. */
20056 help_echo_string = Qnil;
20058 /* Convert to window-relative pixel coordinates. */
20059 w = XWINDOW (window);
20060 frame_to_window_pixel_xy (w, &x, &y);
20062 /* Handle tool-bar window differently since it doesn't display a
20063 buffer. */
20064 if (EQ (window, f->tool_bar_window))
20066 note_tool_bar_highlight (f, x, y);
20067 return;
20070 /* Mouse is on the mode, header line or margin? */
20071 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20072 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20074 note_mode_line_or_margin_highlight (w, x, y, part);
20075 return;
20078 if (part == ON_VERTICAL_BORDER)
20079 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20080 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20081 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20082 else
20083 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20085 /* Are we in a window whose display is up to date?
20086 And verify the buffer's text has not changed. */
20087 b = XBUFFER (w->buffer);
20088 if (part == ON_TEXT
20089 && EQ (w->window_end_valid, w->buffer)
20090 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20091 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20093 int hpos, vpos, pos, i, area;
20094 struct glyph *glyph;
20095 Lisp_Object object;
20096 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20097 Lisp_Object *overlay_vec = NULL;
20098 int len, noverlays;
20099 struct buffer *obuf;
20100 int obegv, ozv, same_region;
20102 /* Find the glyph under X/Y. */
20103 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
20105 /* Clear mouse face if X/Y not over text. */
20106 if (glyph == NULL
20107 || area != TEXT_AREA
20108 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20110 if (clear_mouse_face (dpyinfo))
20111 cursor = No_Cursor;
20112 if (NILP (Vshow_text_cursor_in_void))
20113 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20114 goto set_cursor;
20117 pos = glyph->charpos;
20118 object = glyph->object;
20119 if (!STRINGP (object) && !BUFFERP (object))
20120 goto set_cursor;
20122 /* If we get an out-of-range value, return now; avoid an error. */
20123 if (BUFFERP (object) && pos > BUF_Z (b))
20124 goto set_cursor;
20126 if (glyph->type == IMAGE_GLYPH)
20127 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20129 /* Make the window's buffer temporarily current for
20130 overlays_at and compute_char_face. */
20131 obuf = current_buffer;
20132 current_buffer = b;
20133 obegv = BEGV;
20134 ozv = ZV;
20135 BEGV = BEG;
20136 ZV = Z;
20138 /* Is this char mouse-active or does it have help-echo? */
20139 position = make_number (pos);
20141 if (BUFFERP (object))
20143 /* Put all the overlays we want in a vector in overlay_vec.
20144 Store the length in len. If there are more than 10, make
20145 enough space for all, and try again. */
20146 len = 10;
20147 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20148 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20149 if (noverlays > len)
20151 len = noverlays;
20152 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20153 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20156 /* Sort overlays into increasing priority order. */
20157 noverlays = sort_overlays (overlay_vec, noverlays, w);
20159 else
20160 noverlays = 0;
20162 same_region = (EQ (window, dpyinfo->mouse_face_window)
20163 && vpos >= dpyinfo->mouse_face_beg_row
20164 && vpos <= dpyinfo->mouse_face_end_row
20165 && (vpos > dpyinfo->mouse_face_beg_row
20166 || hpos >= dpyinfo->mouse_face_beg_col)
20167 && (vpos < dpyinfo->mouse_face_end_row
20168 || hpos < dpyinfo->mouse_face_end_col
20169 || dpyinfo->mouse_face_past_end));
20171 if (same_region)
20172 cursor = No_Cursor;
20174 /* Check mouse-face highlighting. */
20175 if (! same_region
20176 /* If there exists an overlay with mouse-face overlapping
20177 the one we are currently highlighting, we have to
20178 check if we enter the overlapping overlay, and then
20179 highlight only that. */
20180 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20181 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20183 /* Find the highest priority overlay that has a mouse-face
20184 property. */
20185 overlay = Qnil;
20186 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20188 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20189 if (!NILP (mouse_face))
20190 overlay = overlay_vec[i];
20193 /* If we're actually highlighting the same overlay as
20194 before, there's no need to do that again. */
20195 if (!NILP (overlay)
20196 && EQ (overlay, dpyinfo->mouse_face_overlay))
20197 goto check_help_echo;
20199 dpyinfo->mouse_face_overlay = overlay;
20201 /* Clear the display of the old active region, if any. */
20202 if (clear_mouse_face (dpyinfo))
20203 cursor = No_Cursor;
20205 /* If no overlay applies, get a text property. */
20206 if (NILP (overlay))
20207 mouse_face = Fget_text_property (position, Qmouse_face, object);
20209 /* Handle the overlay case. */
20210 if (!NILP (overlay))
20212 /* Find the range of text around this char that
20213 should be active. */
20214 Lisp_Object before, after;
20215 int ignore;
20217 before = Foverlay_start (overlay);
20218 after = Foverlay_end (overlay);
20219 /* Record this as the current active region. */
20220 fast_find_position (w, XFASTINT (before),
20221 &dpyinfo->mouse_face_beg_col,
20222 &dpyinfo->mouse_face_beg_row,
20223 &dpyinfo->mouse_face_beg_x,
20224 &dpyinfo->mouse_face_beg_y, Qnil);
20226 dpyinfo->mouse_face_past_end
20227 = !fast_find_position (w, XFASTINT (after),
20228 &dpyinfo->mouse_face_end_col,
20229 &dpyinfo->mouse_face_end_row,
20230 &dpyinfo->mouse_face_end_x,
20231 &dpyinfo->mouse_face_end_y, Qnil);
20232 dpyinfo->mouse_face_window = window;
20234 dpyinfo->mouse_face_face_id
20235 = face_at_buffer_position (w, pos, 0, 0,
20236 &ignore, pos + 1,
20237 !dpyinfo->mouse_face_hidden);
20239 /* Display it as active. */
20240 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20241 cursor = No_Cursor;
20243 /* Handle the text property case. */
20244 else if (!NILP (mouse_face) && BUFFERP (object))
20246 /* Find the range of text around this char that
20247 should be active. */
20248 Lisp_Object before, after, beginning, end;
20249 int ignore;
20251 beginning = Fmarker_position (w->start);
20252 end = make_number (BUF_Z (XBUFFER (object))
20253 - XFASTINT (w->window_end_pos));
20254 before
20255 = Fprevious_single_property_change (make_number (pos + 1),
20256 Qmouse_face,
20257 object, beginning);
20258 after
20259 = Fnext_single_property_change (position, Qmouse_face,
20260 object, end);
20262 /* Record this as the current active region. */
20263 fast_find_position (w, XFASTINT (before),
20264 &dpyinfo->mouse_face_beg_col,
20265 &dpyinfo->mouse_face_beg_row,
20266 &dpyinfo->mouse_face_beg_x,
20267 &dpyinfo->mouse_face_beg_y, Qnil);
20268 dpyinfo->mouse_face_past_end
20269 = !fast_find_position (w, XFASTINT (after),
20270 &dpyinfo->mouse_face_end_col,
20271 &dpyinfo->mouse_face_end_row,
20272 &dpyinfo->mouse_face_end_x,
20273 &dpyinfo->mouse_face_end_y, Qnil);
20274 dpyinfo->mouse_face_window = window;
20276 if (BUFFERP (object))
20277 dpyinfo->mouse_face_face_id
20278 = face_at_buffer_position (w, pos, 0, 0,
20279 &ignore, pos + 1,
20280 !dpyinfo->mouse_face_hidden);
20282 /* Display it as active. */
20283 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20284 cursor = No_Cursor;
20286 else if (!NILP (mouse_face) && STRINGP (object))
20288 Lisp_Object b, e;
20289 int ignore;
20291 b = Fprevious_single_property_change (make_number (pos + 1),
20292 Qmouse_face,
20293 object, Qnil);
20294 e = Fnext_single_property_change (position, Qmouse_face,
20295 object, Qnil);
20296 if (NILP (b))
20297 b = make_number (0);
20298 if (NILP (e))
20299 e = make_number (SCHARS (object) - 1);
20300 fast_find_string_pos (w, XINT (b), object,
20301 &dpyinfo->mouse_face_beg_col,
20302 &dpyinfo->mouse_face_beg_row,
20303 &dpyinfo->mouse_face_beg_x,
20304 &dpyinfo->mouse_face_beg_y, 0);
20305 fast_find_string_pos (w, XINT (e), object,
20306 &dpyinfo->mouse_face_end_col,
20307 &dpyinfo->mouse_face_end_row,
20308 &dpyinfo->mouse_face_end_x,
20309 &dpyinfo->mouse_face_end_y, 1);
20310 dpyinfo->mouse_face_past_end = 0;
20311 dpyinfo->mouse_face_window = window;
20312 dpyinfo->mouse_face_face_id
20313 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20314 glyph->face_id, 1);
20315 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20316 cursor = No_Cursor;
20318 else if (STRINGP (object) && NILP (mouse_face))
20320 /* A string which doesn't have mouse-face, but
20321 the text ``under'' it might have. */
20322 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20323 int start = MATRIX_ROW_START_CHARPOS (r);
20325 pos = string_buffer_position (w, object, start);
20326 if (pos > 0)
20327 mouse_face = get_char_property_and_overlay (make_number (pos),
20328 Qmouse_face,
20329 w->buffer,
20330 &overlay);
20331 if (!NILP (mouse_face) && !NILP (overlay))
20333 Lisp_Object before = Foverlay_start (overlay);
20334 Lisp_Object after = Foverlay_end (overlay);
20335 int ignore;
20337 /* Note that we might not be able to find position
20338 BEFORE in the glyph matrix if the overlay is
20339 entirely covered by a `display' property. In
20340 this case, we overshoot. So let's stop in
20341 the glyph matrix before glyphs for OBJECT. */
20342 fast_find_position (w, XFASTINT (before),
20343 &dpyinfo->mouse_face_beg_col,
20344 &dpyinfo->mouse_face_beg_row,
20345 &dpyinfo->mouse_face_beg_x,
20346 &dpyinfo->mouse_face_beg_y,
20347 object);
20349 dpyinfo->mouse_face_past_end
20350 = !fast_find_position (w, XFASTINT (after),
20351 &dpyinfo->mouse_face_end_col,
20352 &dpyinfo->mouse_face_end_row,
20353 &dpyinfo->mouse_face_end_x,
20354 &dpyinfo->mouse_face_end_y,
20355 Qnil);
20356 dpyinfo->mouse_face_window = window;
20357 dpyinfo->mouse_face_face_id
20358 = face_at_buffer_position (w, pos, 0, 0,
20359 &ignore, pos + 1,
20360 !dpyinfo->mouse_face_hidden);
20362 /* Display it as active. */
20363 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20364 cursor = No_Cursor;
20369 check_help_echo:
20371 /* Look for a `help-echo' property. */
20373 Lisp_Object help, overlay;
20375 /* Check overlays first. */
20376 help = overlay = Qnil;
20377 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20379 overlay = overlay_vec[i];
20380 help = Foverlay_get (overlay, Qhelp_echo);
20383 if (!NILP (help))
20385 help_echo_string = help;
20386 help_echo_window = window;
20387 help_echo_object = overlay;
20388 help_echo_pos = pos;
20390 else
20392 Lisp_Object object = glyph->object;
20393 int charpos = glyph->charpos;
20395 /* Try text properties. */
20396 if (STRINGP (object)
20397 && charpos >= 0
20398 && charpos < SCHARS (object))
20400 help = Fget_text_property (make_number (charpos),
20401 Qhelp_echo, object);
20402 if (NILP (help))
20404 /* If the string itself doesn't specify a help-echo,
20405 see if the buffer text ``under'' it does. */
20406 struct glyph_row *r
20407 = MATRIX_ROW (w->current_matrix, vpos);
20408 int start = MATRIX_ROW_START_CHARPOS (r);
20409 int pos = string_buffer_position (w, object, start);
20410 if (pos > 0)
20412 help = Fget_char_property (make_number (pos),
20413 Qhelp_echo, w->buffer);
20414 if (!NILP (help))
20416 charpos = pos;
20417 object = w->buffer;
20422 else if (BUFFERP (object)
20423 && charpos >= BEGV
20424 && charpos < ZV)
20425 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20426 object);
20428 if (!NILP (help))
20430 help_echo_string = help;
20431 help_echo_window = window;
20432 help_echo_object = object;
20433 help_echo_pos = charpos;
20438 BEGV = obegv;
20439 ZV = ozv;
20440 current_buffer = obuf;
20443 set_cursor:
20445 #ifndef HAVE_CARBON
20446 if (cursor != No_Cursor)
20447 #else
20448 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20449 #endif
20450 rif->define_frame_cursor (f, cursor);
20454 /* EXPORT for RIF:
20455 Clear any mouse-face on window W. This function is part of the
20456 redisplay interface, and is called from try_window_id and similar
20457 functions to ensure the mouse-highlight is off. */
20459 void
20460 x_clear_window_mouse_face (w)
20461 struct window *w;
20463 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20464 Lisp_Object window;
20466 BLOCK_INPUT;
20467 XSETWINDOW (window, w);
20468 if (EQ (window, dpyinfo->mouse_face_window))
20469 clear_mouse_face (dpyinfo);
20470 UNBLOCK_INPUT;
20474 /* EXPORT:
20475 Just discard the mouse face information for frame F, if any.
20476 This is used when the size of F is changed. */
20478 void
20479 cancel_mouse_face (f)
20480 struct frame *f;
20482 Lisp_Object window;
20483 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20485 window = dpyinfo->mouse_face_window;
20486 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20488 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20489 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20490 dpyinfo->mouse_face_window = Qnil;
20495 #endif /* HAVE_WINDOW_SYSTEM */
20498 /***********************************************************************
20499 Exposure Events
20500 ***********************************************************************/
20502 #ifdef HAVE_WINDOW_SYSTEM
20504 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20505 which intersects rectangle R. R is in window-relative coordinates. */
20507 static void
20508 expose_area (w, row, r, area)
20509 struct window *w;
20510 struct glyph_row *row;
20511 XRectangle *r;
20512 enum glyph_row_area area;
20514 struct glyph *first = row->glyphs[area];
20515 struct glyph *end = row->glyphs[area] + row->used[area];
20516 struct glyph *last;
20517 int first_x, start_x, x;
20519 if (area == TEXT_AREA && row->fill_line_p)
20520 /* If row extends face to end of line write the whole line. */
20521 draw_glyphs (w, 0, row, area,
20522 0, row->used[area],
20523 DRAW_NORMAL_TEXT, 0);
20524 else
20526 /* Set START_X to the window-relative start position for drawing glyphs of
20527 AREA. The first glyph of the text area can be partially visible.
20528 The first glyphs of other areas cannot. */
20529 start_x = window_box_left_offset (w, area);
20530 x = start_x;
20531 if (area == TEXT_AREA)
20532 x += row->x;
20534 /* Find the first glyph that must be redrawn. */
20535 while (first < end
20536 && x + first->pixel_width < r->x)
20538 x += first->pixel_width;
20539 ++first;
20542 /* Find the last one. */
20543 last = first;
20544 first_x = x;
20545 while (last < end
20546 && x < r->x + r->width)
20548 x += last->pixel_width;
20549 ++last;
20552 /* Repaint. */
20553 if (last > first)
20554 draw_glyphs (w, first_x - start_x, row, area,
20555 first - row->glyphs[area], last - row->glyphs[area],
20556 DRAW_NORMAL_TEXT, 0);
20561 /* Redraw the parts of the glyph row ROW on window W intersecting
20562 rectangle R. R is in window-relative coordinates. Value is
20563 non-zero if mouse-face was overwritten. */
20565 static int
20566 expose_line (w, row, r)
20567 struct window *w;
20568 struct glyph_row *row;
20569 XRectangle *r;
20571 xassert (row->enabled_p);
20573 if (row->mode_line_p || w->pseudo_window_p)
20574 draw_glyphs (w, 0, row, TEXT_AREA,
20575 0, row->used[TEXT_AREA],
20576 DRAW_NORMAL_TEXT, 0);
20577 else
20579 if (row->used[LEFT_MARGIN_AREA])
20580 expose_area (w, row, r, LEFT_MARGIN_AREA);
20581 if (row->used[TEXT_AREA])
20582 expose_area (w, row, r, TEXT_AREA);
20583 if (row->used[RIGHT_MARGIN_AREA])
20584 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20585 draw_row_fringe_bitmaps (w, row);
20588 return row->mouse_face_p;
20592 /* Redraw those parts of glyphs rows during expose event handling that
20593 overlap other rows. Redrawing of an exposed line writes over parts
20594 of lines overlapping that exposed line; this function fixes that.
20596 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20597 row in W's current matrix that is exposed and overlaps other rows.
20598 LAST_OVERLAPPING_ROW is the last such row. */
20600 static void
20601 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20602 struct window *w;
20603 struct glyph_row *first_overlapping_row;
20604 struct glyph_row *last_overlapping_row;
20606 struct glyph_row *row;
20608 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20609 if (row->overlapping_p)
20611 xassert (row->enabled_p && !row->mode_line_p);
20613 if (row->used[LEFT_MARGIN_AREA])
20614 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20616 if (row->used[TEXT_AREA])
20617 x_fix_overlapping_area (w, row, TEXT_AREA);
20619 if (row->used[RIGHT_MARGIN_AREA])
20620 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20625 /* Return non-zero if W's cursor intersects rectangle R. */
20627 static int
20628 phys_cursor_in_rect_p (w, r)
20629 struct window *w;
20630 XRectangle *r;
20632 XRectangle cr, result;
20633 struct glyph *cursor_glyph;
20635 cursor_glyph = get_phys_cursor_glyph (w);
20636 if (cursor_glyph)
20638 /* r is relative to W's box, but w->phys_cursor.x is relative
20639 to left edge of W's TEXT area. Adjust it. */
20640 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
20641 cr.y = w->phys_cursor.y;
20642 cr.width = cursor_glyph->pixel_width;
20643 cr.height = w->phys_cursor_height;
20644 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20645 I assume the effect is the same -- and this is portable. */
20646 return x_intersect_rectangles (&cr, r, &result);
20648 else
20649 return 0;
20653 /* EXPORT:
20654 Draw a vertical window border to the right of window W if W doesn't
20655 have vertical scroll bars. */
20657 void
20658 x_draw_vertical_border (w)
20659 struct window *w;
20661 /* We could do better, if we knew what type of scroll-bar the adjacent
20662 windows (on either side) have... But we don't :-(
20663 However, I think this works ok. ++KFS 2003-04-25 */
20665 /* Redraw borders between horizontally adjacent windows. Don't
20666 do it for frames with vertical scroll bars because either the
20667 right scroll bar of a window, or the left scroll bar of its
20668 neighbor will suffice as a border. */
20669 if (!WINDOW_RIGHTMOST_P (w)
20670 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
20672 int x0, x1, y0, y1;
20674 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20675 y1 -= 1;
20677 rif->draw_vertical_window_border (w, x1, y0, y1);
20679 else if (!WINDOW_LEFTMOST_P (w)
20680 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
20682 int x0, x1, y0, y1;
20684 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20685 y1 -= 1;
20687 rif->draw_vertical_window_border (w, x0, y0, y1);
20692 /* Redraw the part of window W intersection rectangle FR. Pixel
20693 coordinates in FR are frame-relative. Call this function with
20694 input blocked. Value is non-zero if the exposure overwrites
20695 mouse-face. */
20697 static int
20698 expose_window (w, fr)
20699 struct window *w;
20700 XRectangle *fr;
20702 struct frame *f = XFRAME (w->frame);
20703 XRectangle wr, r;
20704 int mouse_face_overwritten_p = 0;
20706 /* If window is not yet fully initialized, do nothing. This can
20707 happen when toolkit scroll bars are used and a window is split.
20708 Reconfiguring the scroll bar will generate an expose for a newly
20709 created window. */
20710 if (w->current_matrix == NULL)
20711 return 0;
20713 /* When we're currently updating the window, display and current
20714 matrix usually don't agree. Arrange for a thorough display
20715 later. */
20716 if (w == updated_window)
20718 SET_FRAME_GARBAGED (f);
20719 return 0;
20722 /* Frame-relative pixel rectangle of W. */
20723 wr.x = WINDOW_LEFT_EDGE_X (w);
20724 wr.y = WINDOW_TOP_EDGE_Y (w);
20725 wr.width = WINDOW_TOTAL_WIDTH (w);
20726 wr.height = WINDOW_TOTAL_HEIGHT (w);
20728 if (x_intersect_rectangles (fr, &wr, &r))
20730 int yb = window_text_bottom_y (w);
20731 struct glyph_row *row;
20732 int cursor_cleared_p;
20733 struct glyph_row *first_overlapping_row, *last_overlapping_row;
20735 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20736 r.x, r.y, r.width, r.height));
20738 /* Convert to window coordinates. */
20739 r.x -= WINDOW_LEFT_EDGE_X (w);
20740 r.y -= WINDOW_TOP_EDGE_Y (w);
20742 /* Turn off the cursor. */
20743 if (!w->pseudo_window_p
20744 && phys_cursor_in_rect_p (w, &r))
20746 x_clear_cursor (w);
20747 cursor_cleared_p = 1;
20749 else
20750 cursor_cleared_p = 0;
20752 /* Update lines intersecting rectangle R. */
20753 first_overlapping_row = last_overlapping_row = NULL;
20754 for (row = w->current_matrix->rows;
20755 row->enabled_p;
20756 ++row)
20758 int y0 = row->y;
20759 int y1 = MATRIX_ROW_BOTTOM_Y (row);
20761 if ((y0 >= r.y && y0 < r.y + r.height)
20762 || (y1 > r.y && y1 < r.y + r.height)
20763 || (r.y >= y0 && r.y < y1)
20764 || (r.y + r.height > y0 && r.y + r.height < y1))
20766 if (row->overlapping_p)
20768 if (first_overlapping_row == NULL)
20769 first_overlapping_row = row;
20770 last_overlapping_row = row;
20773 if (expose_line (w, row, &r))
20774 mouse_face_overwritten_p = 1;
20777 if (y1 >= yb)
20778 break;
20781 /* Display the mode line if there is one. */
20782 if (WINDOW_WANTS_MODELINE_P (w)
20783 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
20784 row->enabled_p)
20785 && row->y < r.y + r.height)
20787 if (expose_line (w, row, &r))
20788 mouse_face_overwritten_p = 1;
20791 if (!w->pseudo_window_p)
20793 /* Fix the display of overlapping rows. */
20794 if (first_overlapping_row)
20795 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
20797 /* Draw border between windows. */
20798 x_draw_vertical_border (w);
20800 /* Turn the cursor on again. */
20801 if (cursor_cleared_p)
20802 update_window_cursor (w, 1);
20806 #ifdef HAVE_CARBON
20807 /* Display scroll bar for this window. */
20808 if (!NILP (w->vertical_scroll_bar))
20810 /* ++KFS:
20811 If this doesn't work here (maybe some header files are missing),
20812 make a function in macterm.c and call it to do the job! */
20813 ControlHandle ch
20814 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
20816 Draw1Control (ch);
20818 #endif
20820 return mouse_face_overwritten_p;
20825 /* Redraw (parts) of all windows in the window tree rooted at W that
20826 intersect R. R contains frame pixel coordinates. Value is
20827 non-zero if the exposure overwrites mouse-face. */
20829 static int
20830 expose_window_tree (w, r)
20831 struct window *w;
20832 XRectangle *r;
20834 struct frame *f = XFRAME (w->frame);
20835 int mouse_face_overwritten_p = 0;
20837 while (w && !FRAME_GARBAGED_P (f))
20839 if (!NILP (w->hchild))
20840 mouse_face_overwritten_p
20841 |= expose_window_tree (XWINDOW (w->hchild), r);
20842 else if (!NILP (w->vchild))
20843 mouse_face_overwritten_p
20844 |= expose_window_tree (XWINDOW (w->vchild), r);
20845 else
20846 mouse_face_overwritten_p |= expose_window (w, r);
20848 w = NILP (w->next) ? NULL : XWINDOW (w->next);
20851 return mouse_face_overwritten_p;
20855 /* EXPORT:
20856 Redisplay an exposed area of frame F. X and Y are the upper-left
20857 corner of the exposed rectangle. W and H are width and height of
20858 the exposed area. All are pixel values. W or H zero means redraw
20859 the entire frame. */
20861 void
20862 expose_frame (f, x, y, w, h)
20863 struct frame *f;
20864 int x, y, w, h;
20866 XRectangle r;
20867 int mouse_face_overwritten_p = 0;
20869 TRACE ((stderr, "expose_frame "));
20871 /* No need to redraw if frame will be redrawn soon. */
20872 if (FRAME_GARBAGED_P (f))
20874 TRACE ((stderr, " garbaged\n"));
20875 return;
20878 #ifdef HAVE_CARBON
20879 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
20880 or deactivated here, for unknown reasons, activated scroll bars
20881 are shown in deactivated frames in some instances. */
20882 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
20883 activate_scroll_bars (f);
20884 else
20885 deactivate_scroll_bars (f);
20886 #endif
20888 /* If basic faces haven't been realized yet, there is no point in
20889 trying to redraw anything. This can happen when we get an expose
20890 event while Emacs is starting, e.g. by moving another window. */
20891 if (FRAME_FACE_CACHE (f) == NULL
20892 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
20894 TRACE ((stderr, " no faces\n"));
20895 return;
20898 if (w == 0 || h == 0)
20900 r.x = r.y = 0;
20901 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
20902 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
20904 else
20906 r.x = x;
20907 r.y = y;
20908 r.width = w;
20909 r.height = h;
20912 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
20913 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
20915 if (WINDOWP (f->tool_bar_window))
20916 mouse_face_overwritten_p
20917 |= expose_window (XWINDOW (f->tool_bar_window), &r);
20919 #ifdef HAVE_X_WINDOWS
20920 #ifndef MSDOS
20921 #ifndef USE_X_TOOLKIT
20922 if (WINDOWP (f->menu_bar_window))
20923 mouse_face_overwritten_p
20924 |= expose_window (XWINDOW (f->menu_bar_window), &r);
20925 #endif /* not USE_X_TOOLKIT */
20926 #endif
20927 #endif
20929 /* Some window managers support a focus-follows-mouse style with
20930 delayed raising of frames. Imagine a partially obscured frame,
20931 and moving the mouse into partially obscured mouse-face on that
20932 frame. The visible part of the mouse-face will be highlighted,
20933 then the WM raises the obscured frame. With at least one WM, KDE
20934 2.1, Emacs is not getting any event for the raising of the frame
20935 (even tried with SubstructureRedirectMask), only Expose events.
20936 These expose events will draw text normally, i.e. not
20937 highlighted. Which means we must redo the highlight here.
20938 Subsume it under ``we love X''. --gerd 2001-08-15 */
20939 /* Included in Windows version because Windows most likely does not
20940 do the right thing if any third party tool offers
20941 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
20942 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
20944 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20945 if (f == dpyinfo->mouse_face_mouse_frame)
20947 int x = dpyinfo->mouse_face_mouse_x;
20948 int y = dpyinfo->mouse_face_mouse_y;
20949 clear_mouse_face (dpyinfo);
20950 note_mouse_highlight (f, x, y);
20956 /* EXPORT:
20957 Determine the intersection of two rectangles R1 and R2. Return
20958 the intersection in *RESULT. Value is non-zero if RESULT is not
20959 empty. */
20962 x_intersect_rectangles (r1, r2, result)
20963 XRectangle *r1, *r2, *result;
20965 XRectangle *left, *right;
20966 XRectangle *upper, *lower;
20967 int intersection_p = 0;
20969 /* Rearrange so that R1 is the left-most rectangle. */
20970 if (r1->x < r2->x)
20971 left = r1, right = r2;
20972 else
20973 left = r2, right = r1;
20975 /* X0 of the intersection is right.x0, if this is inside R1,
20976 otherwise there is no intersection. */
20977 if (right->x <= left->x + left->width)
20979 result->x = right->x;
20981 /* The right end of the intersection is the minimum of the
20982 the right ends of left and right. */
20983 result->width = (min (left->x + left->width, right->x + right->width)
20984 - result->x);
20986 /* Same game for Y. */
20987 if (r1->y < r2->y)
20988 upper = r1, lower = r2;
20989 else
20990 upper = r2, lower = r1;
20992 /* The upper end of the intersection is lower.y0, if this is inside
20993 of upper. Otherwise, there is no intersection. */
20994 if (lower->y <= upper->y + upper->height)
20996 result->y = lower->y;
20998 /* The lower end of the intersection is the minimum of the lower
20999 ends of upper and lower. */
21000 result->height = (min (lower->y + lower->height,
21001 upper->y + upper->height)
21002 - result->y);
21003 intersection_p = 1;
21007 return intersection_p;
21010 #endif /* HAVE_WINDOW_SYSTEM */
21013 /***********************************************************************
21014 Initialization
21015 ***********************************************************************/
21017 void
21018 syms_of_xdisp ()
21020 Vwith_echo_area_save_vector = Qnil;
21021 staticpro (&Vwith_echo_area_save_vector);
21023 Vmessage_stack = Qnil;
21024 staticpro (&Vmessage_stack);
21026 Qinhibit_redisplay = intern ("inhibit-redisplay");
21027 staticpro (&Qinhibit_redisplay);
21029 message_dolog_marker1 = Fmake_marker ();
21030 staticpro (&message_dolog_marker1);
21031 message_dolog_marker2 = Fmake_marker ();
21032 staticpro (&message_dolog_marker2);
21033 message_dolog_marker3 = Fmake_marker ();
21034 staticpro (&message_dolog_marker3);
21036 #if GLYPH_DEBUG
21037 defsubr (&Sdump_frame_glyph_matrix);
21038 defsubr (&Sdump_glyph_matrix);
21039 defsubr (&Sdump_glyph_row);
21040 defsubr (&Sdump_tool_bar_row);
21041 defsubr (&Strace_redisplay);
21042 defsubr (&Strace_to_stderr);
21043 #endif
21044 #ifdef HAVE_WINDOW_SYSTEM
21045 defsubr (&Stool_bar_lines_needed);
21046 #endif
21047 defsubr (&Sformat_mode_line);
21049 staticpro (&Qmenu_bar_update_hook);
21050 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21052 staticpro (&Qoverriding_terminal_local_map);
21053 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21055 staticpro (&Qoverriding_local_map);
21056 Qoverriding_local_map = intern ("overriding-local-map");
21058 staticpro (&Qwindow_scroll_functions);
21059 Qwindow_scroll_functions = intern ("window-scroll-functions");
21061 staticpro (&Qredisplay_end_trigger_functions);
21062 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21064 staticpro (&Qinhibit_point_motion_hooks);
21065 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21067 QCdata = intern (":data");
21068 staticpro (&QCdata);
21069 Qdisplay = intern ("display");
21070 staticpro (&Qdisplay);
21071 Qspace_width = intern ("space-width");
21072 staticpro (&Qspace_width);
21073 Qraise = intern ("raise");
21074 staticpro (&Qraise);
21075 Qspace = intern ("space");
21076 staticpro (&Qspace);
21077 Qmargin = intern ("margin");
21078 staticpro (&Qmargin);
21079 Qleft_margin = intern ("left-margin");
21080 staticpro (&Qleft_margin);
21081 Qright_margin = intern ("right-margin");
21082 staticpro (&Qright_margin);
21083 Qalign_to = intern ("align-to");
21084 staticpro (&Qalign_to);
21085 QCalign_to = intern (":align-to");
21086 staticpro (&QCalign_to);
21087 Qrelative_width = intern ("relative-width");
21088 staticpro (&Qrelative_width);
21089 QCrelative_width = intern (":relative-width");
21090 staticpro (&QCrelative_width);
21091 QCrelative_height = intern (":relative-height");
21092 staticpro (&QCrelative_height);
21093 QCeval = intern (":eval");
21094 staticpro (&QCeval);
21095 QCpropertize = intern (":propertize");
21096 staticpro (&QCpropertize);
21097 QCfile = intern (":file");
21098 staticpro (&QCfile);
21099 Qfontified = intern ("fontified");
21100 staticpro (&Qfontified);
21101 Qfontification_functions = intern ("fontification-functions");
21102 staticpro (&Qfontification_functions);
21103 Qtrailing_whitespace = intern ("trailing-whitespace");
21104 staticpro (&Qtrailing_whitespace);
21105 Qimage = intern ("image");
21106 staticpro (&Qimage);
21107 Qmessage_truncate_lines = intern ("message-truncate-lines");
21108 staticpro (&Qmessage_truncate_lines);
21109 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21110 staticpro (&Qcursor_in_non_selected_windows);
21111 Qgrow_only = intern ("grow-only");
21112 staticpro (&Qgrow_only);
21113 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21114 staticpro (&Qinhibit_menubar_update);
21115 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21116 staticpro (&Qinhibit_eval_during_redisplay);
21117 Qposition = intern ("position");
21118 staticpro (&Qposition);
21119 Qbuffer_position = intern ("buffer-position");
21120 staticpro (&Qbuffer_position);
21121 Qobject = intern ("object");
21122 staticpro (&Qobject);
21123 Qbar = intern ("bar");
21124 staticpro (&Qbar);
21125 Qhbar = intern ("hbar");
21126 staticpro (&Qhbar);
21127 Qbox = intern ("box");
21128 staticpro (&Qbox);
21129 Qhollow = intern ("hollow");
21130 staticpro (&Qhollow);
21131 Qrisky_local_variable = intern ("risky-local-variable");
21132 staticpro (&Qrisky_local_variable);
21133 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21134 staticpro (&Qinhibit_free_realized_faces);
21136 list_of_error = Fcons (intern ("error"), Qnil);
21137 staticpro (&list_of_error);
21139 last_arrow_position = Qnil;
21140 last_arrow_string = Qnil;
21141 staticpro (&last_arrow_position);
21142 staticpro (&last_arrow_string);
21144 echo_buffer[0] = echo_buffer[1] = Qnil;
21145 staticpro (&echo_buffer[0]);
21146 staticpro (&echo_buffer[1]);
21148 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21149 staticpro (&echo_area_buffer[0]);
21150 staticpro (&echo_area_buffer[1]);
21152 Vmessages_buffer_name = build_string ("*Messages*");
21153 staticpro (&Vmessages_buffer_name);
21155 mode_line_proptrans_alist = Qnil;
21156 staticpro (&mode_line_proptrans_alist);
21158 mode_line_string_list = Qnil;
21159 staticpro (&mode_line_string_list);
21161 help_echo_string = Qnil;
21162 staticpro (&help_echo_string);
21163 help_echo_object = Qnil;
21164 staticpro (&help_echo_object);
21165 help_echo_window = Qnil;
21166 staticpro (&help_echo_window);
21167 previous_help_echo_string = Qnil;
21168 staticpro (&previous_help_echo_string);
21169 help_echo_pos = -1;
21171 #ifdef HAVE_WINDOW_SYSTEM
21172 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21173 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21174 For example, if a block cursor is over a tab, it will be drawn as
21175 wide as that tab on the display. */);
21176 x_stretch_cursor_p = 0;
21177 #endif
21179 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21180 doc: /* Non-nil means highlight trailing whitespace.
21181 The face used for trailing whitespace is `trailing-whitespace'. */);
21182 Vshow_trailing_whitespace = Qnil;
21184 DEFVAR_LISP ("show-text-cursor-in-void", &Vshow_text_cursor_in_void,
21185 doc: /* Non-nil means show the text cursor in void text areas.
21186 The default is to show the non-text (typically arrow) cursor. */);
21187 Vshow_text_cursor_in_void = Qnil;
21189 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21190 doc: /* Non-nil means don't actually do any redisplay.
21191 This is used for internal purposes. */);
21192 Vinhibit_redisplay = Qnil;
21194 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21195 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21196 Vglobal_mode_string = Qnil;
21198 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21199 doc: /* Marker for where to display an arrow on top of the buffer text.
21200 This must be the beginning of a line in order to work.
21201 See also `overlay-arrow-string'. */);
21202 Voverlay_arrow_position = Qnil;
21204 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21205 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
21206 Voverlay_arrow_string = Qnil;
21208 DEFVAR_INT ("scroll-step", &scroll_step,
21209 doc: /* *The number of lines to try scrolling a window by when point moves out.
21210 If that fails to bring point back on frame, point is centered instead.
21211 If this is zero, point is always centered after it moves off frame.
21212 If you want scrolling to always be a line at a time, you should set
21213 `scroll-conservatively' to a large value rather than set this to 1. */);
21215 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21216 doc: /* *Scroll up to this many lines, to bring point back on screen.
21217 A value of zero means to scroll the text to center point vertically
21218 in the window. */);
21219 scroll_conservatively = 0;
21221 DEFVAR_INT ("scroll-margin", &scroll_margin,
21222 doc: /* *Number of lines of margin at the top and bottom of a window.
21223 Recenter the window whenever point gets within this many lines
21224 of the top or bottom of the window. */);
21225 scroll_margin = 0;
21227 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21228 doc: /* Pixels per inch on current display.
21229 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21230 Vdisplay_pixels_per_inch = make_float (72.0);
21232 #if GLYPH_DEBUG
21233 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21234 #endif
21236 DEFVAR_BOOL ("truncate-partial-width-windows",
21237 &truncate_partial_width_windows,
21238 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21239 truncate_partial_width_windows = 1;
21241 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21242 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21243 Any other value means to use the appropriate face, `mode-line',
21244 `header-line', or `menu' respectively. */);
21245 mode_line_inverse_video = 1;
21247 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21248 doc: /* *Maximum buffer size for which line number should be displayed.
21249 If the buffer is bigger than this, the line number does not appear
21250 in the mode line. A value of nil means no limit. */);
21251 Vline_number_display_limit = Qnil;
21253 DEFVAR_INT ("line-number-display-limit-width",
21254 &line_number_display_limit_width,
21255 doc: /* *Maximum line width (in characters) for line number display.
21256 If the average length of the lines near point is bigger than this, then the
21257 line number may be omitted from the mode line. */);
21258 line_number_display_limit_width = 200;
21260 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21261 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21262 highlight_nonselected_windows = 0;
21264 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21265 doc: /* Non-nil if more than one frame is visible on this display.
21266 Minibuffer-only frames don't count, but iconified frames do.
21267 This variable is not guaranteed to be accurate except while processing
21268 `frame-title-format' and `icon-title-format'. */);
21270 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21271 doc: /* Template for displaying the title bar of visible frames.
21272 \(Assuming the window manager supports this feature.)
21273 This variable has the same structure as `mode-line-format' (which see),
21274 and is used only on frames for which no explicit name has been set
21275 \(see `modify-frame-parameters'). */);
21277 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21278 doc: /* Template for displaying the title bar of an iconified frame.
21279 \(Assuming the window manager supports this feature.)
21280 This variable has the same structure as `mode-line-format' (which see),
21281 and is used only on frames for which no explicit name has been set
21282 \(see `modify-frame-parameters'). */);
21283 Vicon_title_format
21284 = Vframe_title_format
21285 = Fcons (intern ("multiple-frames"),
21286 Fcons (build_string ("%b"),
21287 Fcons (Fcons (empty_string,
21288 Fcons (intern ("invocation-name"),
21289 Fcons (build_string ("@"),
21290 Fcons (intern ("system-name"),
21291 Qnil)))),
21292 Qnil)));
21294 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21295 doc: /* Maximum number of lines to keep in the message log buffer.
21296 If nil, disable message logging. If t, log messages but don't truncate
21297 the buffer when it becomes large. */);
21298 Vmessage_log_max = make_number (50);
21300 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21301 doc: /* Functions called before redisplay, if window sizes have changed.
21302 The value should be a list of functions that take one argument.
21303 Just before redisplay, for each frame, if any of its windows have changed
21304 size since the last redisplay, or have been split or deleted,
21305 all the functions in the list are called, with the frame as argument. */);
21306 Vwindow_size_change_functions = Qnil;
21308 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21309 doc: /* List of Functions to call before redisplaying a window with scrolling.
21310 Each function is called with two arguments, the window
21311 and its new display-start position. Note that the value of `window-end'
21312 is not valid when these functions are called. */);
21313 Vwindow_scroll_functions = Qnil;
21315 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21316 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21317 mouse_autoselect_window = 0;
21319 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21320 doc: /* *Non-nil means automatically resize tool-bars.
21321 This increases a tool-bar's height if not all tool-bar items are visible.
21322 It decreases a tool-bar's height when it would display blank lines
21323 otherwise. */);
21324 auto_resize_tool_bars_p = 1;
21326 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21327 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21328 auto_raise_tool_bar_buttons_p = 1;
21330 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21331 doc: /* *Margin around tool-bar buttons in pixels.
21332 If an integer, use that for both horizontal and vertical margins.
21333 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21334 HORZ specifying the horizontal margin, and VERT specifying the
21335 vertical margin. */);
21336 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21338 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21339 doc: /* *Relief thickness of tool-bar buttons. */);
21340 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21342 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21343 doc: /* List of functions to call to fontify regions of text.
21344 Each function is called with one argument POS. Functions must
21345 fontify a region starting at POS in the current buffer, and give
21346 fontified regions the property `fontified'. */);
21347 Vfontification_functions = Qnil;
21348 Fmake_variable_buffer_local (Qfontification_functions);
21350 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21351 &unibyte_display_via_language_environment,
21352 doc: /* *Non-nil means display unibyte text according to language environment.
21353 Specifically this means that unibyte non-ASCII characters
21354 are displayed by converting them to the equivalent multibyte characters
21355 according to the current language environment. As a result, they are
21356 displayed according to the current fontset. */);
21357 unibyte_display_via_language_environment = 0;
21359 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21360 doc: /* *Maximum height for resizing mini-windows.
21361 If a float, it specifies a fraction of the mini-window frame's height.
21362 If an integer, it specifies a number of lines. */);
21363 Vmax_mini_window_height = make_float (0.25);
21365 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21366 doc: /* *How to resize mini-windows.
21367 A value of nil means don't automatically resize mini-windows.
21368 A value of t means resize them to fit the text displayed in them.
21369 A value of `grow-only', the default, means let mini-windows grow
21370 only, until their display becomes empty, at which point the windows
21371 go back to their normal size. */);
21372 Vresize_mini_windows = Qgrow_only;
21374 DEFVAR_LISP ("cursor-in-non-selected-windows",
21375 &Vcursor_in_non_selected_windows,
21376 doc: /* *Cursor type to display in non-selected windows.
21377 t means to use hollow box cursor. See `cursor-type' for other values. */);
21378 Vcursor_in_non_selected_windows = Qt;
21380 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21381 doc: /* Alist specifying how to blink the cursor off.
21382 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21383 `cursor-type' frame-parameter or variable equals ON-STATE,
21384 comparing using `equal', Emacs uses OFF-STATE to specify
21385 how to blink it off. */);
21386 Vblink_cursor_alist = Qnil;
21388 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21389 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21390 automatic_hscrolling_p = 1;
21392 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21393 doc: /* *How many columns away from the window edge point is allowed to get
21394 before automatic hscrolling will horizontally scroll the window. */);
21395 hscroll_margin = 5;
21397 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21398 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21399 When point is less than `automatic-hscroll-margin' columns from the window
21400 edge, automatic hscrolling will scroll the window by the amount of columns
21401 determined by this variable. If its value is a positive integer, scroll that
21402 many columns. If it's a positive floating-point number, it specifies the
21403 fraction of the window's width to scroll. If it's nil or zero, point will be
21404 centered horizontally after the scroll. Any other value, including negative
21405 numbers, are treated as if the value were zero.
21407 Automatic hscrolling always moves point outside the scroll margin, so if
21408 point was more than scroll step columns inside the margin, the window will
21409 scroll more than the value given by the scroll step.
21411 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21412 and `scroll-right' overrides this variable's effect. */);
21413 Vhscroll_step = make_number (0);
21415 DEFVAR_LISP ("image-types", &Vimage_types,
21416 doc: /* List of supported image types.
21417 Each element of the list is a symbol for a supported image type. */);
21418 Vimage_types = Qnil;
21420 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21421 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21422 Bind this around calls to `message' to let it take effect. */);
21423 message_truncate_lines = 0;
21425 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21426 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21427 Can be used to update submenus whose contents should vary. */);
21428 Vmenu_bar_update_hook = Qnil;
21430 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21431 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21432 inhibit_menubar_update = 0;
21434 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21435 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21436 inhibit_eval_during_redisplay = 0;
21438 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21439 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21440 inhibit_free_realized_faces = 0;
21442 #if GLYPH_DEBUG
21443 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21444 doc: /* Inhibit try_window_id display optimization. */);
21445 inhibit_try_window_id = 0;
21447 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21448 doc: /* Inhibit try_window_reusing display optimization. */);
21449 inhibit_try_window_reusing = 0;
21451 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21452 doc: /* Inhibit try_cursor_movement display optimization. */);
21453 inhibit_try_cursor_movement = 0;
21454 #endif /* GLYPH_DEBUG */
21458 /* Initialize this module when Emacs starts. */
21460 void
21461 init_xdisp ()
21463 Lisp_Object root_window;
21464 struct window *mini_w;
21466 current_header_line_height = current_mode_line_height = -1;
21468 CHARPOS (this_line_start_pos) = 0;
21470 mini_w = XWINDOW (minibuf_window);
21471 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21473 if (!noninteractive)
21475 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21476 int i;
21478 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21479 set_window_height (root_window,
21480 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21482 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21483 set_window_height (minibuf_window, 1, 0);
21485 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21486 mini_w->total_cols = make_number (FRAME_COLS (f));
21488 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21489 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21490 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21492 /* The default ellipsis glyphs `...'. */
21493 for (i = 0; i < 3; ++i)
21494 default_invis_vector[i] = make_number ('.');
21498 /* Allocate the buffer for frame titles.
21499 Also used for `format-mode-line'. */
21500 int size = 100;
21501 frame_title_buf = (char *) xmalloc (size);
21502 frame_title_buf_end = frame_title_buf + size;
21503 frame_title_ptr = NULL;
21506 help_echo_showing_p = 0;
21510 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21511 (do not change this comment) */