*** empty log message ***
[emacs.git] / src / xdisp.c
blob2ed455e7f6bc43cf7c9ebba3edae60c40891d89f
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,04
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"
201 #endif
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
207 #define INFINITY 10000000
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
215 extern int interrupt_input;
216 extern int command_loop_level;
218 extern Lisp_Object do_mouse_tracking;
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 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
248 Lisp_Object Qrisky_local_variable;
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
253 /* Functions called to fontify regions of text. */
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
265 int auto_raise_tool_bar_buttons_p;
267 /* Margin around tool bar buttons in pixels. */
269 Lisp_Object Vtool_bar_button_margin;
271 /* Thickness of shadow to draw around tool bar buttons. */
273 EMACS_INT tool_bar_button_relief;
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
278 int auto_resize_tool_bars_p;
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
284 int x_stretch_cursor_p;
286 /* Non-nil means don't actually do any redisplay. */
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
292 int inhibit_eval_during_redisplay;
294 /* Names of text properties relevant for redisplay. */
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
299 /* Symbols used in text property values. */
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qslice;
305 Lisp_Object Qcenter;
306 Lisp_Object Qmargin, Qpointer;
307 Lisp_Object Qline_height, Qtotal;
308 extern Lisp_Object Qheight;
309 extern Lisp_Object QCwidth, QCheight, QCascent;
310 extern Lisp_Object Qscroll_bar;
311 extern Lisp_Object Qcursor;
313 /* Non-nil means highlight trailing whitespace. */
315 Lisp_Object Vshow_trailing_whitespace;
317 #ifdef HAVE_WINDOW_SYSTEM
318 extern Lisp_Object Voverflow_newline_into_fringe;
320 /* Test if overflow newline into fringe. Called with iterator IT
321 at or past right window margin, and with IT->current_x set. */
323 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
324 (!NILP (Voverflow_newline_into_fringe) \
325 && FRAME_WINDOW_P (it->f) \
326 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
327 && it->current_x == it->last_visible_x)
329 #endif /* HAVE_WINDOW_SYSTEM */
331 /* Non-nil means show the text cursor in void text areas
332 i.e. in blank areas after eol and eob. This used to be
333 the default in 21.3. */
335 Lisp_Object Vvoid_text_area_pointer;
337 /* Name of the face used to highlight trailing whitespace. */
339 Lisp_Object Qtrailing_whitespace;
341 /* The symbol `image' which is the car of the lists used to represent
342 images in Lisp. */
344 Lisp_Object Qimage;
346 /* The image map types. */
347 Lisp_Object QCmap, QCpointer;
348 Lisp_Object Qrect, Qcircle, Qpoly;
350 /* Non-zero means print newline to stdout before next mini-buffer
351 message. */
353 int noninteractive_need_newline;
355 /* Non-zero means print newline to message log before next message. */
357 static int message_log_need_newline;
359 /* Three markers that message_dolog uses.
360 It could allocate them itself, but that causes trouble
361 in handling memory-full errors. */
362 static Lisp_Object message_dolog_marker1;
363 static Lisp_Object message_dolog_marker2;
364 static Lisp_Object message_dolog_marker3;
366 /* The buffer position of the first character appearing entirely or
367 partially on the line of the selected window which contains the
368 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
369 redisplay optimization in redisplay_internal. */
371 static struct text_pos this_line_start_pos;
373 /* Number of characters past the end of the line above, including the
374 terminating newline. */
376 static struct text_pos this_line_end_pos;
378 /* The vertical positions and the height of this line. */
380 static int this_line_vpos;
381 static int this_line_y;
382 static int this_line_pixel_height;
384 /* X position at which this display line starts. Usually zero;
385 negative if first character is partially visible. */
387 static int this_line_start_x;
389 /* Buffer that this_line_.* variables are referring to. */
391 static struct buffer *this_line_buffer;
393 /* Nonzero means truncate lines in all windows less wide than the
394 frame. */
396 int truncate_partial_width_windows;
398 /* A flag to control how to display unibyte 8-bit character. */
400 int unibyte_display_via_language_environment;
402 /* Nonzero means we have more than one non-mini-buffer-only frame.
403 Not guaranteed to be accurate except while parsing
404 frame-title-format. */
406 int multiple_frames;
408 Lisp_Object Vglobal_mode_string;
411 /* List of variables (symbols) which hold markers for overlay arrows.
412 The symbols on this list are examined during redisplay to determine
413 where to display overlay arrows. */
415 Lisp_Object Voverlay_arrow_variable_list;
417 /* Marker for where to display an arrow on top of the buffer text. */
419 Lisp_Object Voverlay_arrow_position;
421 /* String to display for the arrow. Only used on terminal frames. */
423 Lisp_Object Voverlay_arrow_string;
425 /* Values of those variables at last redisplay are stored as
426 properties on `overlay-arrow-position' symbol. However, if
427 Voverlay_arrow_position is a marker, last-arrow-position is its
428 numerical position. */
430 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
432 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
433 properties on a symbol in overlay-arrow-variable-list. */
435 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
437 /* Like mode-line-format, but for the title bar on a visible frame. */
439 Lisp_Object Vframe_title_format;
441 /* Like mode-line-format, but for the title bar on an iconified frame. */
443 Lisp_Object Vicon_title_format;
445 /* List of functions to call when a window's size changes. These
446 functions get one arg, a frame on which one or more windows' sizes
447 have changed. */
449 static Lisp_Object Vwindow_size_change_functions;
451 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
453 /* Nonzero if overlay arrow has been displayed once in this window. */
455 static int overlay_arrow_seen;
457 /* Nonzero means highlight the region even in nonselected windows. */
459 int highlight_nonselected_windows;
461 /* If cursor motion alone moves point off frame, try scrolling this
462 many lines up or down if that will bring it back. */
464 static EMACS_INT scroll_step;
466 /* Nonzero means scroll just far enough to bring point back on the
467 screen, when appropriate. */
469 static EMACS_INT scroll_conservatively;
471 /* Recenter the window whenever point gets within this many lines of
472 the top or bottom of the window. This value is translated into a
473 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
474 that there is really a fixed pixel height scroll margin. */
476 EMACS_INT scroll_margin;
478 /* Number of windows showing the buffer of the selected window (or
479 another buffer with the same base buffer). keyboard.c refers to
480 this. */
482 int buffer_shared;
484 /* Vector containing glyphs for an ellipsis `...'. */
486 static Lisp_Object default_invis_vector[3];
488 /* Zero means display the mode-line/header-line/menu-bar in the default face
489 (this slightly odd definition is for compatibility with previous versions
490 of emacs), non-zero means display them using their respective faces.
492 This variable is deprecated. */
494 int mode_line_inverse_video;
496 /* Prompt to display in front of the mini-buffer contents. */
498 Lisp_Object minibuf_prompt;
500 /* Width of current mini-buffer prompt. Only set after display_line
501 of the line that contains the prompt. */
503 int minibuf_prompt_width;
505 /* This is the window where the echo area message was displayed. It
506 is always a mini-buffer window, but it may not be the same window
507 currently active as a mini-buffer. */
509 Lisp_Object echo_area_window;
511 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
512 pushes the current message and the value of
513 message_enable_multibyte on the stack, the function restore_message
514 pops the stack and displays MESSAGE again. */
516 Lisp_Object Vmessage_stack;
518 /* Nonzero means multibyte characters were enabled when the echo area
519 message was specified. */
521 int message_enable_multibyte;
523 /* Nonzero if we should redraw the mode lines on the next redisplay. */
525 int update_mode_lines;
527 /* Nonzero if window sizes or contents have changed since last
528 redisplay that finished. */
530 int windows_or_buffers_changed;
532 /* Nonzero means a frame's cursor type has been changed. */
534 int cursor_type_changed;
536 /* Nonzero after display_mode_line if %l was used and it displayed a
537 line number. */
539 int line_number_displayed;
541 /* Maximum buffer size for which to display line numbers. */
543 Lisp_Object Vline_number_display_limit;
545 /* Line width to consider when repositioning for line number display. */
547 static EMACS_INT line_number_display_limit_width;
549 /* Number of lines to keep in the message log buffer. t means
550 infinite. nil means don't log at all. */
552 Lisp_Object Vmessage_log_max;
554 /* The name of the *Messages* buffer, a string. */
556 static Lisp_Object Vmessages_buffer_name;
558 /* Current, index 0, and last displayed echo area message. Either
559 buffers from echo_buffers, or nil to indicate no message. */
561 Lisp_Object echo_area_buffer[2];
563 /* The buffers referenced from echo_area_buffer. */
565 static Lisp_Object echo_buffer[2];
567 /* A vector saved used in with_area_buffer to reduce consing. */
569 static Lisp_Object Vwith_echo_area_save_vector;
571 /* Non-zero means display_echo_area should display the last echo area
572 message again. Set by redisplay_preserve_echo_area. */
574 static int display_last_displayed_message_p;
576 /* Nonzero if echo area is being used by print; zero if being used by
577 message. */
579 int message_buf_print;
581 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
583 Lisp_Object Qinhibit_menubar_update;
584 int inhibit_menubar_update;
586 /* Maximum height for resizing mini-windows. Either a float
587 specifying a fraction of the available height, or an integer
588 specifying a number of lines. */
590 Lisp_Object Vmax_mini_window_height;
592 /* Non-zero means messages should be displayed with truncated
593 lines instead of being continued. */
595 int message_truncate_lines;
596 Lisp_Object Qmessage_truncate_lines;
598 /* Set to 1 in clear_message to make redisplay_internal aware
599 of an emptied echo area. */
601 static int message_cleared_p;
603 /* Non-zero means we want a hollow cursor in windows that are not
604 selected. Zero means there's no cursor in such windows. */
606 Lisp_Object Vcursor_in_non_selected_windows;
607 Lisp_Object Qcursor_in_non_selected_windows;
609 /* How to blink the default frame cursor off. */
610 Lisp_Object Vblink_cursor_alist;
612 /* A scratch glyph row with contents used for generating truncation
613 glyphs. Also used in direct_output_for_insert. */
615 #define MAX_SCRATCH_GLYPHS 100
616 struct glyph_row scratch_glyph_row;
617 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
619 /* Ascent and height of the last line processed by move_it_to. */
621 static int last_max_ascent, last_height;
623 /* Non-zero if there's a help-echo in the echo area. */
625 int help_echo_showing_p;
627 /* If >= 0, computed, exact values of mode-line and header-line height
628 to use in the macros CURRENT_MODE_LINE_HEIGHT and
629 CURRENT_HEADER_LINE_HEIGHT. */
631 int current_mode_line_height, current_header_line_height;
633 /* The maximum distance to look ahead for text properties. Values
634 that are too small let us call compute_char_face and similar
635 functions too often which is expensive. Values that are too large
636 let us call compute_char_face and alike too often because we
637 might not be interested in text properties that far away. */
639 #define TEXT_PROP_DISTANCE_LIMIT 100
641 #if GLYPH_DEBUG
643 /* Variables to turn off display optimizations from Lisp. */
645 int inhibit_try_window_id, inhibit_try_window_reusing;
646 int inhibit_try_cursor_movement;
648 /* Non-zero means print traces of redisplay if compiled with
649 GLYPH_DEBUG != 0. */
651 int trace_redisplay_p;
653 #endif /* GLYPH_DEBUG */
655 #ifdef DEBUG_TRACE_MOVE
656 /* Non-zero means trace with TRACE_MOVE to stderr. */
657 int trace_move;
659 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
660 #else
661 #define TRACE_MOVE(x) (void) 0
662 #endif
664 /* Non-zero means automatically scroll windows horizontally to make
665 point visible. */
667 int automatic_hscrolling_p;
669 /* How close to the margin can point get before the window is scrolled
670 horizontally. */
671 EMACS_INT hscroll_margin;
673 /* How much to scroll horizontally when point is inside the above margin. */
674 Lisp_Object Vhscroll_step;
676 /* The variable `resize-mini-windows'. If nil, don't resize
677 mini-windows. If t, always resize them to fit the text they
678 display. If `grow-only', let mini-windows grow only until they
679 become empty. */
681 Lisp_Object Vresize_mini_windows;
683 /* Buffer being redisplayed -- for redisplay_window_error. */
685 struct buffer *displayed_buffer;
687 /* Value returned from text property handlers (see below). */
689 enum prop_handled
691 HANDLED_NORMALLY,
692 HANDLED_RECOMPUTE_PROPS,
693 HANDLED_OVERLAY_STRING_CONSUMED,
694 HANDLED_RETURN
697 /* A description of text properties that redisplay is interested
698 in. */
700 struct props
702 /* The name of the property. */
703 Lisp_Object *name;
705 /* A unique index for the property. */
706 enum prop_idx idx;
708 /* A handler function called to set up iterator IT from the property
709 at IT's current position. Value is used to steer handle_stop. */
710 enum prop_handled (*handler) P_ ((struct it *it));
713 static enum prop_handled handle_face_prop P_ ((struct it *));
714 static enum prop_handled handle_invisible_prop P_ ((struct it *));
715 static enum prop_handled handle_display_prop P_ ((struct it *));
716 static enum prop_handled handle_composition_prop P_ ((struct it *));
717 static enum prop_handled handle_overlay_change P_ ((struct it *));
718 static enum prop_handled handle_fontified_prop P_ ((struct it *));
720 /* Properties handled by iterators. */
722 static struct props it_props[] =
724 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
725 /* Handle `face' before `display' because some sub-properties of
726 `display' need to know the face. */
727 {&Qface, FACE_PROP_IDX, handle_face_prop},
728 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
729 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
730 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
731 {NULL, 0, NULL}
734 /* Value is the position described by X. If X is a marker, value is
735 the marker_position of X. Otherwise, value is X. */
737 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
739 /* Enumeration returned by some move_it_.* functions internally. */
741 enum move_it_result
743 /* Not used. Undefined value. */
744 MOVE_UNDEFINED,
746 /* Move ended at the requested buffer position or ZV. */
747 MOVE_POS_MATCH_OR_ZV,
749 /* Move ended at the requested X pixel position. */
750 MOVE_X_REACHED,
752 /* Move within a line ended at the end of a line that must be
753 continued. */
754 MOVE_LINE_CONTINUED,
756 /* Move within a line ended at the end of a line that would
757 be displayed truncated. */
758 MOVE_LINE_TRUNCATED,
760 /* Move within a line ended at a line end. */
761 MOVE_NEWLINE_OR_CR
764 /* This counter is used to clear the face cache every once in a while
765 in redisplay_internal. It is incremented for each redisplay.
766 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
767 cleared. */
769 #define CLEAR_FACE_CACHE_COUNT 500
770 static int clear_face_cache_count;
772 /* Record the previous terminal frame we displayed. */
774 static struct frame *previous_terminal_frame;
776 /* Non-zero while redisplay_internal is in progress. */
778 int redisplaying_p;
780 /* Non-zero means don't free realized faces. Bound while freeing
781 realized faces is dangerous because glyph matrices might still
782 reference them. */
784 int inhibit_free_realized_faces;
785 Lisp_Object Qinhibit_free_realized_faces;
787 /* If a string, XTread_socket generates an event to display that string.
788 (The display is done in read_char.) */
790 Lisp_Object help_echo_string;
791 Lisp_Object help_echo_window;
792 Lisp_Object help_echo_object;
793 int help_echo_pos;
795 /* Temporary variable for XTread_socket. */
797 Lisp_Object previous_help_echo_string;
799 /* Null glyph slice */
801 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
804 /* Function prototypes. */
806 static void setup_for_ellipsis P_ ((struct it *));
807 static void mark_window_display_accurate_1 P_ ((struct window *, int));
808 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
809 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
810 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
811 static int redisplay_mode_lines P_ ((Lisp_Object, int));
812 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
814 #if 0
815 static int invisible_text_between_p P_ ((struct it *, int, int));
816 #endif
818 static int next_element_from_ellipsis P_ ((struct it *));
819 static void pint2str P_ ((char *, int, int));
820 static void pint2hrstr P_ ((char *, int, int));
821 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
822 struct text_pos));
823 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
824 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
825 static void store_frame_title_char P_ ((char));
826 static int store_frame_title P_ ((const unsigned char *, int, int));
827 static void x_consider_frame_title P_ ((Lisp_Object));
828 static void handle_stop P_ ((struct it *));
829 static int tool_bar_lines_needed P_ ((struct frame *));
830 static int single_display_prop_intangible_p P_ ((Lisp_Object));
831 static void ensure_echo_area_buffers P_ ((void));
832 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
833 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
834 static int with_echo_area_buffer P_ ((struct window *, int,
835 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
836 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static void clear_garbaged_frames P_ ((void));
838 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
839 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
840 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static int display_echo_area P_ ((struct window *));
842 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
843 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
844 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
845 static int string_char_and_length P_ ((const unsigned char *, int, int *));
846 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
847 struct text_pos));
848 static int compute_window_start_on_continuation_line P_ ((struct window *));
849 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
850 static void insert_left_trunc_glyphs P_ ((struct it *));
851 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
852 Lisp_Object));
853 static void extend_face_to_end_of_line P_ ((struct it *));
854 static int append_space_for_newline P_ ((struct it *, int));
855 static int make_cursor_line_fully_visible P_ ((struct window *, int));
856 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
857 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
858 static int trailing_whitespace_p P_ ((int));
859 static int message_log_check_duplicate P_ ((int, int, int, int));
860 static void push_it P_ ((struct it *));
861 static void pop_it P_ ((struct it *));
862 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
863 static void select_frame_for_redisplay P_ ((Lisp_Object));
864 static void redisplay_internal P_ ((int));
865 static int echo_area_display P_ ((int));
866 static void redisplay_windows P_ ((Lisp_Object));
867 static void redisplay_window P_ ((Lisp_Object, int));
868 static Lisp_Object redisplay_window_error ();
869 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
870 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
871 static void update_menu_bar P_ ((struct frame *, int));
872 static int try_window_reusing_current_matrix P_ ((struct window *));
873 static int try_window_id P_ ((struct window *));
874 static int display_line P_ ((struct it *));
875 static int display_mode_lines P_ ((struct window *));
876 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
877 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
878 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
879 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
880 static void display_menu_bar P_ ((struct window *));
881 static int display_count_lines P_ ((int, int, int, int, int *));
882 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
883 int, int, struct it *, int, int, int, int));
884 static void compute_line_metrics P_ ((struct it *));
885 static void run_redisplay_end_trigger_hook P_ ((struct it *));
886 static int get_overlay_strings P_ ((struct it *, int));
887 static void next_overlay_string P_ ((struct it *));
888 static void reseat P_ ((struct it *, struct text_pos, int));
889 static void reseat_1 P_ ((struct it *, struct text_pos, int));
890 static void back_to_previous_visible_line_start P_ ((struct it *));
891 static void reseat_at_previous_visible_line_start P_ ((struct it *));
892 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
893 static int next_element_from_display_vector P_ ((struct it *));
894 static int next_element_from_string P_ ((struct it *));
895 static int next_element_from_c_string P_ ((struct it *));
896 static int next_element_from_buffer P_ ((struct it *));
897 static int next_element_from_composition P_ ((struct it *));
898 static int next_element_from_image P_ ((struct it *));
899 static int next_element_from_stretch P_ ((struct it *));
900 static void load_overlay_strings P_ ((struct it *, int));
901 static int init_from_display_pos P_ ((struct it *, struct window *,
902 struct display_pos *));
903 static void reseat_to_string P_ ((struct it *, unsigned char *,
904 Lisp_Object, int, int, int, int));
905 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
906 int, int, int));
907 void move_it_vertically_backward P_ ((struct it *, int));
908 static void init_to_row_start P_ ((struct it *, struct window *,
909 struct glyph_row *));
910 static int init_to_row_end P_ ((struct it *, struct window *,
911 struct glyph_row *));
912 static void back_to_previous_line_start P_ ((struct it *));
913 static int forward_to_next_line_start P_ ((struct it *, int *));
914 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
915 Lisp_Object, int));
916 static struct text_pos string_pos P_ ((int, Lisp_Object));
917 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
918 static int number_of_chars P_ ((unsigned char *, int));
919 static void compute_stop_pos P_ ((struct it *));
920 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
921 Lisp_Object));
922 static int face_before_or_after_it_pos P_ ((struct it *, int));
923 static int next_overlay_change P_ ((int));
924 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
925 Lisp_Object, struct text_pos *,
926 int));
927 static int underlying_face_id P_ ((struct it *));
928 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
929 struct window *));
931 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
932 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
934 #ifdef HAVE_WINDOW_SYSTEM
936 static void update_tool_bar P_ ((struct frame *, int));
937 static void build_desired_tool_bar_string P_ ((struct frame *f));
938 static int redisplay_tool_bar P_ ((struct frame *));
939 static void display_tool_bar_line P_ ((struct it *));
940 static void notice_overwritten_cursor P_ ((struct window *,
941 enum glyph_row_area,
942 int, int, int, int));
946 #endif /* HAVE_WINDOW_SYSTEM */
949 /***********************************************************************
950 Window display dimensions
951 ***********************************************************************/
953 /* Return the bottom boundary y-position for text lines in window W.
954 This is the first y position at which a line cannot start.
955 It is relative to the top of the window.
957 This is the height of W minus the height of a mode line, if any. */
959 INLINE int
960 window_text_bottom_y (w)
961 struct window *w;
963 int height = WINDOW_TOTAL_HEIGHT (w);
965 if (WINDOW_WANTS_MODELINE_P (w))
966 height -= CURRENT_MODE_LINE_HEIGHT (w);
967 return height;
970 /* Return the pixel width of display area AREA of window W. AREA < 0
971 means return the total width of W, not including fringes to
972 the left and right of the window. */
974 INLINE int
975 window_box_width (w, area)
976 struct window *w;
977 int area;
979 int cols = XFASTINT (w->total_cols);
980 int pixels = 0;
982 if (!w->pseudo_window_p)
984 cols -= WINDOW_SCROLL_BAR_COLS (w);
986 if (area == TEXT_AREA)
988 if (INTEGERP (w->left_margin_cols))
989 cols -= XFASTINT (w->left_margin_cols);
990 if (INTEGERP (w->right_margin_cols))
991 cols -= XFASTINT (w->right_margin_cols);
992 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
994 else if (area == LEFT_MARGIN_AREA)
996 cols = (INTEGERP (w->left_margin_cols)
997 ? XFASTINT (w->left_margin_cols) : 0);
998 pixels = 0;
1000 else if (area == RIGHT_MARGIN_AREA)
1002 cols = (INTEGERP (w->right_margin_cols)
1003 ? XFASTINT (w->right_margin_cols) : 0);
1004 pixels = 0;
1008 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1012 /* Return the pixel height of the display area of window W, not
1013 including mode lines of W, if any. */
1015 INLINE int
1016 window_box_height (w)
1017 struct window *w;
1019 struct frame *f = XFRAME (w->frame);
1020 int height = WINDOW_TOTAL_HEIGHT (w);
1022 xassert (height >= 0);
1024 /* Note: the code below that determines the mode-line/header-line
1025 height is essentially the same as that contained in the macro
1026 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1027 the appropriate glyph row has its `mode_line_p' flag set,
1028 and if it doesn't, uses estimate_mode_line_height instead. */
1030 if (WINDOW_WANTS_MODELINE_P (w))
1032 struct glyph_row *ml_row
1033 = (w->current_matrix && w->current_matrix->rows
1034 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1035 : 0);
1036 if (ml_row && ml_row->mode_line_p)
1037 height -= ml_row->height;
1038 else
1039 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1042 if (WINDOW_WANTS_HEADER_LINE_P (w))
1044 struct glyph_row *hl_row
1045 = (w->current_matrix && w->current_matrix->rows
1046 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1047 : 0);
1048 if (hl_row && hl_row->mode_line_p)
1049 height -= hl_row->height;
1050 else
1051 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1054 /* With a very small font and a mode-line that's taller than
1055 default, we might end up with a negative height. */
1056 return max (0, height);
1059 /* Return the window-relative coordinate of the left edge of display
1060 area AREA of window W. AREA < 0 means return the left edge of the
1061 whole window, to the right of the left fringe of W. */
1063 INLINE int
1064 window_box_left_offset (w, area)
1065 struct window *w;
1066 int area;
1068 int x;
1070 if (w->pseudo_window_p)
1071 return 0;
1073 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1075 if (area == TEXT_AREA)
1076 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1077 + window_box_width (w, LEFT_MARGIN_AREA));
1078 else if (area == RIGHT_MARGIN_AREA)
1079 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1080 + window_box_width (w, LEFT_MARGIN_AREA)
1081 + window_box_width (w, TEXT_AREA)
1082 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1084 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1085 else if (area == LEFT_MARGIN_AREA
1086 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1087 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1089 return x;
1093 /* Return the window-relative coordinate of the right edge of display
1094 area AREA of window W. AREA < 0 means return the left edge of the
1095 whole window, to the left of the right fringe of W. */
1097 INLINE int
1098 window_box_right_offset (w, area)
1099 struct window *w;
1100 int area;
1102 return window_box_left_offset (w, area) + window_box_width (w, area);
1105 /* Return the frame-relative coordinate of the left edge of display
1106 area AREA of window W. AREA < 0 means return the left edge of the
1107 whole window, to the right of the left fringe of W. */
1109 INLINE int
1110 window_box_left (w, area)
1111 struct window *w;
1112 int area;
1114 struct frame *f = XFRAME (w->frame);
1115 int x;
1117 if (w->pseudo_window_p)
1118 return FRAME_INTERNAL_BORDER_WIDTH (f);
1120 x = (WINDOW_LEFT_EDGE_X (w)
1121 + window_box_left_offset (w, area));
1123 return x;
1127 /* Return the frame-relative coordinate of the right edge of display
1128 area AREA of window W. AREA < 0 means return the left edge of the
1129 whole window, to the left of the right fringe of W. */
1131 INLINE int
1132 window_box_right (w, area)
1133 struct window *w;
1134 int area;
1136 return window_box_left (w, area) + window_box_width (w, area);
1139 /* Get the bounding box of the display area AREA of window W, without
1140 mode lines, in frame-relative coordinates. AREA < 0 means the
1141 whole window, not including the left and right fringes of
1142 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1143 coordinates of the upper-left corner of the box. Return in
1144 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1146 INLINE void
1147 window_box (w, area, box_x, box_y, box_width, box_height)
1148 struct window *w;
1149 int area;
1150 int *box_x, *box_y, *box_width, *box_height;
1152 if (box_width)
1153 *box_width = window_box_width (w, area);
1154 if (box_height)
1155 *box_height = window_box_height (w);
1156 if (box_x)
1157 *box_x = window_box_left (w, area);
1158 if (box_y)
1160 *box_y = WINDOW_TOP_EDGE_Y (w);
1161 if (WINDOW_WANTS_HEADER_LINE_P (w))
1162 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1167 /* Get the bounding box of the display area AREA of window W, without
1168 mode lines. AREA < 0 means the whole window, not including the
1169 left and right fringe of the window. Return in *TOP_LEFT_X
1170 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1171 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1172 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1173 box. */
1175 INLINE void
1176 window_box_edges (w, area, top_left_x, top_left_y,
1177 bottom_right_x, bottom_right_y)
1178 struct window *w;
1179 int area;
1180 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1182 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1183 bottom_right_y);
1184 *bottom_right_x += *top_left_x;
1185 *bottom_right_y += *top_left_y;
1190 /***********************************************************************
1191 Utilities
1192 ***********************************************************************/
1194 /* Return the bottom y-position of the line the iterator IT is in.
1195 This can modify IT's settings. */
1198 line_bottom_y (it)
1199 struct it *it;
1201 int line_height = it->max_ascent + it->max_descent;
1202 int line_top_y = it->current_y;
1204 if (line_height == 0)
1206 if (last_height)
1207 line_height = last_height;
1208 else if (IT_CHARPOS (*it) < ZV)
1210 move_it_by_lines (it, 1, 1);
1211 line_height = (it->max_ascent || it->max_descent
1212 ? it->max_ascent + it->max_descent
1213 : last_height);
1215 else
1217 struct glyph_row *row = it->glyph_row;
1219 /* Use the default character height. */
1220 it->glyph_row = NULL;
1221 it->what = IT_CHARACTER;
1222 it->c = ' ';
1223 it->len = 1;
1224 PRODUCE_GLYPHS (it);
1225 line_height = it->ascent + it->descent;
1226 it->glyph_row = row;
1230 return line_top_y + line_height;
1234 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1235 1 if POS is visible and the line containing POS is fully visible.
1236 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1237 and header-lines heights. */
1240 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1241 struct window *w;
1242 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1244 struct it it;
1245 struct text_pos top;
1246 int visible_p;
1247 struct buffer *old_buffer = NULL;
1249 if (XBUFFER (w->buffer) != current_buffer)
1251 old_buffer = current_buffer;
1252 set_buffer_internal_1 (XBUFFER (w->buffer));
1255 *fully = visible_p = 0;
1256 SET_TEXT_POS_FROM_MARKER (top, w->start);
1258 /* Compute exact mode line heights, if requested. */
1259 if (exact_mode_line_heights_p)
1261 if (WINDOW_WANTS_MODELINE_P (w))
1262 current_mode_line_height
1263 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1264 current_buffer->mode_line_format);
1266 if (WINDOW_WANTS_HEADER_LINE_P (w))
1267 current_header_line_height
1268 = display_mode_line (w, HEADER_LINE_FACE_ID,
1269 current_buffer->header_line_format);
1272 start_display (&it, w, top);
1273 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1274 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1276 /* Note that we may overshoot because of invisible text. */
1277 if (IT_CHARPOS (it) >= charpos)
1279 int top_y = it.current_y;
1280 int bottom_y = line_bottom_y (&it);
1281 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1283 if (top_y < window_top_y)
1284 visible_p = bottom_y > window_top_y;
1285 else if (top_y < it.last_visible_y)
1287 visible_p = 1;
1288 *fully = bottom_y <= it.last_visible_y;
1290 if (visible_p && x)
1292 *x = it.current_x;
1293 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1296 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1298 struct it it2;
1300 it2 = it;
1301 move_it_by_lines (&it, 1, 0);
1302 if (charpos < IT_CHARPOS (it))
1304 visible_p = 1;
1305 if (x)
1307 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1308 *x = it2.current_x;
1309 *y = it2.current_y + it2.max_ascent - it2.ascent;
1314 if (old_buffer)
1315 set_buffer_internal_1 (old_buffer);
1317 current_header_line_height = current_mode_line_height = -1;
1319 return visible_p;
1323 /* Return the next character from STR which is MAXLEN bytes long.
1324 Return in *LEN the length of the character. This is like
1325 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1326 we find one, we return a `?', but with the length of the invalid
1327 character. */
1329 static INLINE int
1330 string_char_and_length (str, maxlen, len)
1331 const unsigned char *str;
1332 int maxlen, *len;
1334 int c;
1336 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1337 if (!CHAR_VALID_P (c, 1))
1338 /* We may not change the length here because other places in Emacs
1339 don't use this function, i.e. they silently accept invalid
1340 characters. */
1341 c = '?';
1343 return c;
1348 /* Given a position POS containing a valid character and byte position
1349 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1351 static struct text_pos
1352 string_pos_nchars_ahead (pos, string, nchars)
1353 struct text_pos pos;
1354 Lisp_Object string;
1355 int nchars;
1357 xassert (STRINGP (string) && nchars >= 0);
1359 if (STRING_MULTIBYTE (string))
1361 int rest = SBYTES (string) - BYTEPOS (pos);
1362 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1363 int len;
1365 while (nchars--)
1367 string_char_and_length (p, rest, &len);
1368 p += len, rest -= len;
1369 xassert (rest >= 0);
1370 CHARPOS (pos) += 1;
1371 BYTEPOS (pos) += len;
1374 else
1375 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1377 return pos;
1381 /* Value is the text position, i.e. character and byte position,
1382 for character position CHARPOS in STRING. */
1384 static INLINE struct text_pos
1385 string_pos (charpos, string)
1386 int charpos;
1387 Lisp_Object string;
1389 struct text_pos pos;
1390 xassert (STRINGP (string));
1391 xassert (charpos >= 0);
1392 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1393 return pos;
1397 /* Value is a text position, i.e. character and byte position, for
1398 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1399 means recognize multibyte characters. */
1401 static struct text_pos
1402 c_string_pos (charpos, s, multibyte_p)
1403 int charpos;
1404 unsigned char *s;
1405 int multibyte_p;
1407 struct text_pos pos;
1409 xassert (s != NULL);
1410 xassert (charpos >= 0);
1412 if (multibyte_p)
1414 int rest = strlen (s), len;
1416 SET_TEXT_POS (pos, 0, 0);
1417 while (charpos--)
1419 string_char_and_length (s, rest, &len);
1420 s += len, rest -= len;
1421 xassert (rest >= 0);
1422 CHARPOS (pos) += 1;
1423 BYTEPOS (pos) += len;
1426 else
1427 SET_TEXT_POS (pos, charpos, charpos);
1429 return pos;
1433 /* Value is the number of characters in C string S. MULTIBYTE_P
1434 non-zero means recognize multibyte characters. */
1436 static int
1437 number_of_chars (s, multibyte_p)
1438 unsigned char *s;
1439 int multibyte_p;
1441 int nchars;
1443 if (multibyte_p)
1445 int rest = strlen (s), len;
1446 unsigned char *p = (unsigned char *) s;
1448 for (nchars = 0; rest > 0; ++nchars)
1450 string_char_and_length (p, rest, &len);
1451 rest -= len, p += len;
1454 else
1455 nchars = strlen (s);
1457 return nchars;
1461 /* Compute byte position NEWPOS->bytepos corresponding to
1462 NEWPOS->charpos. POS is a known position in string STRING.
1463 NEWPOS->charpos must be >= POS.charpos. */
1465 static void
1466 compute_string_pos (newpos, pos, string)
1467 struct text_pos *newpos, pos;
1468 Lisp_Object string;
1470 xassert (STRINGP (string));
1471 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1473 if (STRING_MULTIBYTE (string))
1474 *newpos = string_pos_nchars_ahead (pos, string,
1475 CHARPOS (*newpos) - CHARPOS (pos));
1476 else
1477 BYTEPOS (*newpos) = CHARPOS (*newpos);
1480 /* EXPORT:
1481 Return an estimation of the pixel height of mode or top lines on
1482 frame F. FACE_ID specifies what line's height to estimate. */
1485 estimate_mode_line_height (f, face_id)
1486 struct frame *f;
1487 enum face_id face_id;
1489 #ifdef HAVE_WINDOW_SYSTEM
1490 if (FRAME_WINDOW_P (f))
1492 int height = FONT_HEIGHT (FRAME_FONT (f));
1494 /* This function is called so early when Emacs starts that the face
1495 cache and mode line face are not yet initialized. */
1496 if (FRAME_FACE_CACHE (f))
1498 struct face *face = FACE_FROM_ID (f, face_id);
1499 if (face)
1501 if (face->font)
1502 height = FONT_HEIGHT (face->font);
1503 if (face->box_line_width > 0)
1504 height += 2 * face->box_line_width;
1508 return height;
1510 #endif
1512 return 1;
1515 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1516 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1517 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1518 not force the value into range. */
1520 void
1521 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1522 FRAME_PTR f;
1523 register int pix_x, pix_y;
1524 int *x, *y;
1525 NativeRectangle *bounds;
1526 int noclip;
1529 #ifdef HAVE_WINDOW_SYSTEM
1530 if (FRAME_WINDOW_P (f))
1532 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1533 even for negative values. */
1534 if (pix_x < 0)
1535 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1536 if (pix_y < 0)
1537 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1539 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1540 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1542 if (bounds)
1543 STORE_NATIVE_RECT (*bounds,
1544 FRAME_COL_TO_PIXEL_X (f, pix_x),
1545 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1546 FRAME_COLUMN_WIDTH (f) - 1,
1547 FRAME_LINE_HEIGHT (f) - 1);
1549 if (!noclip)
1551 if (pix_x < 0)
1552 pix_x = 0;
1553 else if (pix_x > FRAME_TOTAL_COLS (f))
1554 pix_x = FRAME_TOTAL_COLS (f);
1556 if (pix_y < 0)
1557 pix_y = 0;
1558 else if (pix_y > FRAME_LINES (f))
1559 pix_y = FRAME_LINES (f);
1562 #endif
1564 *x = pix_x;
1565 *y = pix_y;
1569 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1570 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1571 can't tell the positions because W's display is not up to date,
1572 return 0. */
1575 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1576 struct window *w;
1577 int hpos, vpos;
1578 int *frame_x, *frame_y;
1580 #ifdef HAVE_WINDOW_SYSTEM
1581 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1583 int success_p;
1585 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1586 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1588 if (display_completed)
1590 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1591 struct glyph *glyph = row->glyphs[TEXT_AREA];
1592 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1594 hpos = row->x;
1595 vpos = row->y;
1596 while (glyph < end)
1598 hpos += glyph->pixel_width;
1599 ++glyph;
1602 /* If first glyph is partially visible, its first visible position is still 0. */
1603 if (hpos < 0)
1604 hpos = 0;
1606 success_p = 1;
1608 else
1610 hpos = vpos = 0;
1611 success_p = 0;
1614 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1615 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1616 return success_p;
1618 #endif
1620 *frame_x = hpos;
1621 *frame_y = vpos;
1622 return 1;
1626 #ifdef HAVE_WINDOW_SYSTEM
1628 /* Find the glyph under window-relative coordinates X/Y in window W.
1629 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1630 strings. Return in *HPOS and *VPOS the row and column number of
1631 the glyph found. Return in *AREA the glyph area containing X.
1632 Value is a pointer to the glyph found or null if X/Y is not on
1633 text, or we can't tell because W's current matrix is not up to
1634 date. */
1636 static struct glyph *
1637 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1638 struct window *w;
1639 int x, y;
1640 int *hpos, *vpos, *dx, *dy, *area;
1642 struct glyph *glyph, *end;
1643 struct glyph_row *row = NULL;
1644 int x0, i;
1646 /* Find row containing Y. Give up if some row is not enabled. */
1647 for (i = 0; i < w->current_matrix->nrows; ++i)
1649 row = MATRIX_ROW (w->current_matrix, i);
1650 if (!row->enabled_p)
1651 return NULL;
1652 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1653 break;
1656 *vpos = i;
1657 *hpos = 0;
1659 /* Give up if Y is not in the window. */
1660 if (i == w->current_matrix->nrows)
1661 return NULL;
1663 /* Get the glyph area containing X. */
1664 if (w->pseudo_window_p)
1666 *area = TEXT_AREA;
1667 x0 = 0;
1669 else
1671 if (x < window_box_left_offset (w, TEXT_AREA))
1673 *area = LEFT_MARGIN_AREA;
1674 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1676 else if (x < window_box_right_offset (w, TEXT_AREA))
1678 *area = TEXT_AREA;
1679 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1681 else
1683 *area = RIGHT_MARGIN_AREA;
1684 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1688 /* Find glyph containing X. */
1689 glyph = row->glyphs[*area];
1690 end = glyph + row->used[*area];
1691 x -= x0;
1692 while (glyph < end && x >= glyph->pixel_width)
1694 x -= glyph->pixel_width;
1695 ++glyph;
1698 if (glyph == end)
1699 return NULL;
1701 if (dx)
1703 *dx = x;
1704 *dy = y - (row->y + row->ascent - glyph->ascent);
1707 *hpos = glyph - row->glyphs[*area];
1708 return glyph;
1712 /* EXPORT:
1713 Convert frame-relative x/y to coordinates relative to window W.
1714 Takes pseudo-windows into account. */
1716 void
1717 frame_to_window_pixel_xy (w, x, y)
1718 struct window *w;
1719 int *x, *y;
1721 if (w->pseudo_window_p)
1723 /* A pseudo-window is always full-width, and starts at the
1724 left edge of the frame, plus a frame border. */
1725 struct frame *f = XFRAME (w->frame);
1726 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1727 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1729 else
1731 *x -= WINDOW_LEFT_EDGE_X (w);
1732 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1736 /* EXPORT:
1737 Return in *R the clipping rectangle for glyph string S. */
1739 void
1740 get_glyph_string_clip_rect (s, nr)
1741 struct glyph_string *s;
1742 NativeRectangle *nr;
1744 XRectangle r;
1746 if (s->row->full_width_p)
1748 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1749 r.x = WINDOW_LEFT_EDGE_X (s->w);
1750 r.width = WINDOW_TOTAL_WIDTH (s->w);
1752 /* Unless displaying a mode or menu bar line, which are always
1753 fully visible, clip to the visible part of the row. */
1754 if (s->w->pseudo_window_p)
1755 r.height = s->row->visible_height;
1756 else
1757 r.height = s->height;
1759 else
1761 /* This is a text line that may be partially visible. */
1762 r.x = window_box_left (s->w, s->area);
1763 r.width = window_box_width (s->w, s->area);
1764 r.height = s->row->visible_height;
1767 /* If S draws overlapping rows, it's sufficient to use the top and
1768 bottom of the window for clipping because this glyph string
1769 intentionally draws over other lines. */
1770 if (s->for_overlaps_p)
1772 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1773 r.height = window_text_bottom_y (s->w) - r.y;
1775 else
1777 /* Don't use S->y for clipping because it doesn't take partially
1778 visible lines into account. For example, it can be negative for
1779 partially visible lines at the top of a window. */
1780 if (!s->row->full_width_p
1781 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1782 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1783 else
1784 r.y = max (0, s->row->y);
1786 /* If drawing a tool-bar window, draw it over the internal border
1787 at the top of the window. */
1788 if (s->w == XWINDOW (s->f->tool_bar_window))
1789 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1792 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1794 /* If drawing the cursor, don't let glyph draw outside its
1795 advertised boundaries. Cleartype does this under some circumstances. */
1796 if (s->hl == DRAW_CURSOR)
1798 struct glyph *glyph = s->first_glyph;
1799 int height;
1801 if (s->x > r.x)
1803 r.width -= s->x - r.x;
1804 r.x = s->x;
1806 r.width = min (r.width, glyph->pixel_width);
1808 /* Don't draw cursor glyph taller than our actual glyph. */
1809 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1810 if (height < r.height)
1812 int max_y = r.y + r.height;
1813 r.y = min (max_y, s->ybase + glyph->descent - height);
1814 r.height = min (max_y - r.y, height);
1818 #ifdef CONVERT_FROM_XRECT
1819 CONVERT_FROM_XRECT (r, *nr);
1820 #else
1821 *nr = r;
1822 #endif
1825 #endif /* HAVE_WINDOW_SYSTEM */
1828 /***********************************************************************
1829 Lisp form evaluation
1830 ***********************************************************************/
1832 /* Error handler for safe_eval and safe_call. */
1834 static Lisp_Object
1835 safe_eval_handler (arg)
1836 Lisp_Object arg;
1838 add_to_log ("Error during redisplay: %s", arg, Qnil);
1839 return Qnil;
1843 /* Evaluate SEXPR and return the result, or nil if something went
1844 wrong. Prevent redisplay during the evaluation. */
1846 Lisp_Object
1847 safe_eval (sexpr)
1848 Lisp_Object sexpr;
1850 Lisp_Object val;
1852 if (inhibit_eval_during_redisplay)
1853 val = Qnil;
1854 else
1856 int count = SPECPDL_INDEX ();
1857 struct gcpro gcpro1;
1859 GCPRO1 (sexpr);
1860 specbind (Qinhibit_redisplay, Qt);
1861 /* Use Qt to ensure debugger does not run,
1862 so there is no possibility of wanting to redisplay. */
1863 val = internal_condition_case_1 (Feval, sexpr, Qt,
1864 safe_eval_handler);
1865 UNGCPRO;
1866 val = unbind_to (count, val);
1869 return val;
1873 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1874 Return the result, or nil if something went wrong. Prevent
1875 redisplay during the evaluation. */
1877 Lisp_Object
1878 safe_call (nargs, args)
1879 int nargs;
1880 Lisp_Object *args;
1882 Lisp_Object val;
1884 if (inhibit_eval_during_redisplay)
1885 val = Qnil;
1886 else
1888 int count = SPECPDL_INDEX ();
1889 struct gcpro gcpro1;
1891 GCPRO1 (args[0]);
1892 gcpro1.nvars = nargs;
1893 specbind (Qinhibit_redisplay, Qt);
1894 /* Use Qt to ensure debugger does not run,
1895 so there is no possibility of wanting to redisplay. */
1896 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1897 safe_eval_handler);
1898 UNGCPRO;
1899 val = unbind_to (count, val);
1902 return val;
1906 /* Call function FN with one argument ARG.
1907 Return the result, or nil if something went wrong. */
1909 Lisp_Object
1910 safe_call1 (fn, arg)
1911 Lisp_Object fn, arg;
1913 Lisp_Object args[2];
1914 args[0] = fn;
1915 args[1] = arg;
1916 return safe_call (2, args);
1921 /***********************************************************************
1922 Debugging
1923 ***********************************************************************/
1925 #if 0
1927 /* Define CHECK_IT to perform sanity checks on iterators.
1928 This is for debugging. It is too slow to do unconditionally. */
1930 static void
1931 check_it (it)
1932 struct it *it;
1934 if (it->method == next_element_from_string)
1936 xassert (STRINGP (it->string));
1937 xassert (IT_STRING_CHARPOS (*it) >= 0);
1939 else
1941 xassert (IT_STRING_CHARPOS (*it) < 0);
1942 if (it->method == next_element_from_buffer)
1944 /* Check that character and byte positions agree. */
1945 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1949 if (it->dpvec)
1950 xassert (it->current.dpvec_index >= 0);
1951 else
1952 xassert (it->current.dpvec_index < 0);
1955 #define CHECK_IT(IT) check_it ((IT))
1957 #else /* not 0 */
1959 #define CHECK_IT(IT) (void) 0
1961 #endif /* not 0 */
1964 #if GLYPH_DEBUG
1966 /* Check that the window end of window W is what we expect it
1967 to be---the last row in the current matrix displaying text. */
1969 static void
1970 check_window_end (w)
1971 struct window *w;
1973 if (!MINI_WINDOW_P (w)
1974 && !NILP (w->window_end_valid))
1976 struct glyph_row *row;
1977 xassert ((row = MATRIX_ROW (w->current_matrix,
1978 XFASTINT (w->window_end_vpos)),
1979 !row->enabled_p
1980 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1981 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1985 #define CHECK_WINDOW_END(W) check_window_end ((W))
1987 #else /* not GLYPH_DEBUG */
1989 #define CHECK_WINDOW_END(W) (void) 0
1991 #endif /* not GLYPH_DEBUG */
1995 /***********************************************************************
1996 Iterator initialization
1997 ***********************************************************************/
1999 /* Initialize IT for displaying current_buffer in window W, starting
2000 at character position CHARPOS. CHARPOS < 0 means that no buffer
2001 position is specified which is useful when the iterator is assigned
2002 a position later. BYTEPOS is the byte position corresponding to
2003 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2005 If ROW is not null, calls to produce_glyphs with IT as parameter
2006 will produce glyphs in that row.
2008 BASE_FACE_ID is the id of a base face to use. It must be one of
2009 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2010 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2011 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2013 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2014 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2015 will be initialized to use the corresponding mode line glyph row of
2016 the desired matrix of W. */
2018 void
2019 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2020 struct it *it;
2021 struct window *w;
2022 int charpos, bytepos;
2023 struct glyph_row *row;
2024 enum face_id base_face_id;
2026 int highlight_region_p;
2028 /* Some precondition checks. */
2029 xassert (w != NULL && it != NULL);
2030 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2031 && charpos <= ZV));
2033 /* If face attributes have been changed since the last redisplay,
2034 free realized faces now because they depend on face definitions
2035 that might have changed. Don't free faces while there might be
2036 desired matrices pending which reference these faces. */
2037 if (face_change_count && !inhibit_free_realized_faces)
2039 face_change_count = 0;
2040 free_all_realized_faces (Qnil);
2043 /* Use one of the mode line rows of W's desired matrix if
2044 appropriate. */
2045 if (row == NULL)
2047 if (base_face_id == MODE_LINE_FACE_ID
2048 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2049 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2050 else if (base_face_id == HEADER_LINE_FACE_ID)
2051 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2054 /* Clear IT. */
2055 bzero (it, sizeof *it);
2056 it->current.overlay_string_index = -1;
2057 it->current.dpvec_index = -1;
2058 it->base_face_id = base_face_id;
2059 it->string = Qnil;
2060 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2062 /* The window in which we iterate over current_buffer: */
2063 XSETWINDOW (it->window, w);
2064 it->w = w;
2065 it->f = XFRAME (w->frame);
2067 /* Extra space between lines (on window systems only). */
2068 if (base_face_id == DEFAULT_FACE_ID
2069 && FRAME_WINDOW_P (it->f))
2071 if (NATNUMP (current_buffer->extra_line_spacing))
2072 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2073 else if (FLOATP (current_buffer->extra_line_spacing))
2074 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2075 * FRAME_LINE_HEIGHT (it->f));
2076 else if (it->f->extra_line_spacing > 0)
2077 it->extra_line_spacing = it->f->extra_line_spacing;
2080 /* If realized faces have been removed, e.g. because of face
2081 attribute changes of named faces, recompute them. When running
2082 in batch mode, the face cache of Vterminal_frame is null. If
2083 we happen to get called, make a dummy face cache. */
2084 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2085 init_frame_faces (it->f);
2086 if (FRAME_FACE_CACHE (it->f)->used == 0)
2087 recompute_basic_faces (it->f);
2089 /* Current value of the `slice', `space-width', and 'height' properties. */
2090 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2091 it->space_width = Qnil;
2092 it->font_height = Qnil;
2093 it->override_ascent = -1;
2095 /* Are control characters displayed as `^C'? */
2096 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2098 /* -1 means everything between a CR and the following line end
2099 is invisible. >0 means lines indented more than this value are
2100 invisible. */
2101 it->selective = (INTEGERP (current_buffer->selective_display)
2102 ? XFASTINT (current_buffer->selective_display)
2103 : (!NILP (current_buffer->selective_display)
2104 ? -1 : 0));
2105 it->selective_display_ellipsis_p
2106 = !NILP (current_buffer->selective_display_ellipses);
2108 /* Display table to use. */
2109 it->dp = window_display_table (w);
2111 /* Are multibyte characters enabled in current_buffer? */
2112 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2114 /* Non-zero if we should highlight the region. */
2115 highlight_region_p
2116 = (!NILP (Vtransient_mark_mode)
2117 && !NILP (current_buffer->mark_active)
2118 && XMARKER (current_buffer->mark)->buffer != 0);
2120 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2121 start and end of a visible region in window IT->w. Set both to
2122 -1 to indicate no region. */
2123 if (highlight_region_p
2124 /* Maybe highlight only in selected window. */
2125 && (/* Either show region everywhere. */
2126 highlight_nonselected_windows
2127 /* Or show region in the selected window. */
2128 || w == XWINDOW (selected_window)
2129 /* Or show the region if we are in the mini-buffer and W is
2130 the window the mini-buffer refers to. */
2131 || (MINI_WINDOW_P (XWINDOW (selected_window))
2132 && WINDOWP (minibuf_selected_window)
2133 && w == XWINDOW (minibuf_selected_window))))
2135 int charpos = marker_position (current_buffer->mark);
2136 it->region_beg_charpos = min (PT, charpos);
2137 it->region_end_charpos = max (PT, charpos);
2139 else
2140 it->region_beg_charpos = it->region_end_charpos = -1;
2142 /* Get the position at which the redisplay_end_trigger hook should
2143 be run, if it is to be run at all. */
2144 if (MARKERP (w->redisplay_end_trigger)
2145 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2146 it->redisplay_end_trigger_charpos
2147 = marker_position (w->redisplay_end_trigger);
2148 else if (INTEGERP (w->redisplay_end_trigger))
2149 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2151 /* Correct bogus values of tab_width. */
2152 it->tab_width = XINT (current_buffer->tab_width);
2153 if (it->tab_width <= 0 || it->tab_width > 1000)
2154 it->tab_width = 8;
2156 /* Are lines in the display truncated? */
2157 it->truncate_lines_p
2158 = (base_face_id != DEFAULT_FACE_ID
2159 || XINT (it->w->hscroll)
2160 || (truncate_partial_width_windows
2161 && !WINDOW_FULL_WIDTH_P (it->w))
2162 || !NILP (current_buffer->truncate_lines));
2164 /* Get dimensions of truncation and continuation glyphs. These are
2165 displayed as fringe bitmaps under X, so we don't need them for such
2166 frames. */
2167 if (!FRAME_WINDOW_P (it->f))
2169 if (it->truncate_lines_p)
2171 /* We will need the truncation glyph. */
2172 xassert (it->glyph_row == NULL);
2173 produce_special_glyphs (it, IT_TRUNCATION);
2174 it->truncation_pixel_width = it->pixel_width;
2176 else
2178 /* We will need the continuation glyph. */
2179 xassert (it->glyph_row == NULL);
2180 produce_special_glyphs (it, IT_CONTINUATION);
2181 it->continuation_pixel_width = it->pixel_width;
2184 /* Reset these values to zero because the produce_special_glyphs
2185 above has changed them. */
2186 it->pixel_width = it->ascent = it->descent = 0;
2187 it->phys_ascent = it->phys_descent = 0;
2190 /* Set this after getting the dimensions of truncation and
2191 continuation glyphs, so that we don't produce glyphs when calling
2192 produce_special_glyphs, above. */
2193 it->glyph_row = row;
2194 it->area = TEXT_AREA;
2196 /* Get the dimensions of the display area. The display area
2197 consists of the visible window area plus a horizontally scrolled
2198 part to the left of the window. All x-values are relative to the
2199 start of this total display area. */
2200 if (base_face_id != DEFAULT_FACE_ID)
2202 /* Mode lines, menu bar in terminal frames. */
2203 it->first_visible_x = 0;
2204 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2206 else
2208 it->first_visible_x
2209 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2210 it->last_visible_x = (it->first_visible_x
2211 + window_box_width (w, TEXT_AREA));
2213 /* If we truncate lines, leave room for the truncator glyph(s) at
2214 the right margin. Otherwise, leave room for the continuation
2215 glyph(s). Truncation and continuation glyphs are not inserted
2216 for window-based redisplay. */
2217 if (!FRAME_WINDOW_P (it->f))
2219 if (it->truncate_lines_p)
2220 it->last_visible_x -= it->truncation_pixel_width;
2221 else
2222 it->last_visible_x -= it->continuation_pixel_width;
2225 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2226 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2229 /* Leave room for a border glyph. */
2230 if (!FRAME_WINDOW_P (it->f)
2231 && !WINDOW_RIGHTMOST_P (it->w))
2232 it->last_visible_x -= 1;
2234 it->last_visible_y = window_text_bottom_y (w);
2236 /* For mode lines and alike, arrange for the first glyph having a
2237 left box line if the face specifies a box. */
2238 if (base_face_id != DEFAULT_FACE_ID)
2240 struct face *face;
2242 it->face_id = base_face_id;
2244 /* If we have a boxed mode line, make the first character appear
2245 with a left box line. */
2246 face = FACE_FROM_ID (it->f, base_face_id);
2247 if (face->box != FACE_NO_BOX)
2248 it->start_of_box_run_p = 1;
2251 /* If a buffer position was specified, set the iterator there,
2252 getting overlays and face properties from that position. */
2253 if (charpos >= BUF_BEG (current_buffer))
2255 it->end_charpos = ZV;
2256 it->face_id = -1;
2257 IT_CHARPOS (*it) = charpos;
2259 /* Compute byte position if not specified. */
2260 if (bytepos < charpos)
2261 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2262 else
2263 IT_BYTEPOS (*it) = bytepos;
2265 it->start = it->current;
2267 /* Compute faces etc. */
2268 reseat (it, it->current.pos, 1);
2271 CHECK_IT (it);
2275 /* Initialize IT for the display of window W with window start POS. */
2277 void
2278 start_display (it, w, pos)
2279 struct it *it;
2280 struct window *w;
2281 struct text_pos pos;
2283 struct glyph_row *row;
2284 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2286 row = w->desired_matrix->rows + first_vpos;
2287 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2288 it->first_vpos = first_vpos;
2290 if (!it->truncate_lines_p)
2292 int start_at_line_beg_p;
2293 int first_y = it->current_y;
2295 /* If window start is not at a line start, skip forward to POS to
2296 get the correct continuation lines width. */
2297 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2298 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2299 if (!start_at_line_beg_p)
2301 int new_x;
2303 reseat_at_previous_visible_line_start (it);
2304 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2306 new_x = it->current_x + it->pixel_width;
2308 /* If lines are continued, this line may end in the middle
2309 of a multi-glyph character (e.g. a control character
2310 displayed as \003, or in the middle of an overlay
2311 string). In this case move_it_to above will not have
2312 taken us to the start of the continuation line but to the
2313 end of the continued line. */
2314 if (it->current_x > 0
2315 && !it->truncate_lines_p /* Lines are continued. */
2316 && (/* And glyph doesn't fit on the line. */
2317 new_x > it->last_visible_x
2318 /* Or it fits exactly and we're on a window
2319 system frame. */
2320 || (new_x == it->last_visible_x
2321 && FRAME_WINDOW_P (it->f))))
2323 if (it->current.dpvec_index >= 0
2324 || it->current.overlay_string_index >= 0)
2326 set_iterator_to_next (it, 1);
2327 move_it_in_display_line_to (it, -1, -1, 0);
2330 it->continuation_lines_width += it->current_x;
2333 /* We're starting a new display line, not affected by the
2334 height of the continued line, so clear the appropriate
2335 fields in the iterator structure. */
2336 it->max_ascent = it->max_descent = 0;
2337 it->max_phys_ascent = it->max_phys_descent = 0;
2339 it->current_y = first_y;
2340 it->vpos = 0;
2341 it->current_x = it->hpos = 0;
2345 #if 0 /* Don't assert the following because start_display is sometimes
2346 called intentionally with a window start that is not at a
2347 line start. Please leave this code in as a comment. */
2349 /* Window start should be on a line start, now. */
2350 xassert (it->continuation_lines_width
2351 || IT_CHARPOS (it) == BEGV
2352 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2353 #endif /* 0 */
2357 /* Return 1 if POS is a position in ellipses displayed for invisible
2358 text. W is the window we display, for text property lookup. */
2360 static int
2361 in_ellipses_for_invisible_text_p (pos, w)
2362 struct display_pos *pos;
2363 struct window *w;
2365 Lisp_Object prop, window;
2366 int ellipses_p = 0;
2367 int charpos = CHARPOS (pos->pos);
2369 /* If POS specifies a position in a display vector, this might
2370 be for an ellipsis displayed for invisible text. We won't
2371 get the iterator set up for delivering that ellipsis unless
2372 we make sure that it gets aware of the invisible text. */
2373 if (pos->dpvec_index >= 0
2374 && pos->overlay_string_index < 0
2375 && CHARPOS (pos->string_pos) < 0
2376 && charpos > BEGV
2377 && (XSETWINDOW (window, w),
2378 prop = Fget_char_property (make_number (charpos),
2379 Qinvisible, window),
2380 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2382 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2383 window);
2384 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2387 return ellipses_p;
2391 /* Initialize IT for stepping through current_buffer in window W,
2392 starting at position POS that includes overlay string and display
2393 vector/ control character translation position information. Value
2394 is zero if there are overlay strings with newlines at POS. */
2396 static int
2397 init_from_display_pos (it, w, pos)
2398 struct it *it;
2399 struct window *w;
2400 struct display_pos *pos;
2402 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2403 int i, overlay_strings_with_newlines = 0;
2405 /* If POS specifies a position in a display vector, this might
2406 be for an ellipsis displayed for invisible text. We won't
2407 get the iterator set up for delivering that ellipsis unless
2408 we make sure that it gets aware of the invisible text. */
2409 if (in_ellipses_for_invisible_text_p (pos, w))
2411 --charpos;
2412 bytepos = 0;
2415 /* Keep in mind: the call to reseat in init_iterator skips invisible
2416 text, so we might end up at a position different from POS. This
2417 is only a problem when POS is a row start after a newline and an
2418 overlay starts there with an after-string, and the overlay has an
2419 invisible property. Since we don't skip invisible text in
2420 display_line and elsewhere immediately after consuming the
2421 newline before the row start, such a POS will not be in a string,
2422 but the call to init_iterator below will move us to the
2423 after-string. */
2424 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2426 for (i = 0; i < it->n_overlay_strings; ++i)
2428 const char *s = SDATA (it->overlay_strings[i]);
2429 const char *e = s + SBYTES (it->overlay_strings[i]);
2431 while (s < e && *s != '\n')
2432 ++s;
2434 if (s < e)
2436 overlay_strings_with_newlines = 1;
2437 break;
2441 /* If position is within an overlay string, set up IT to the right
2442 overlay string. */
2443 if (pos->overlay_string_index >= 0)
2445 int relative_index;
2447 /* If the first overlay string happens to have a `display'
2448 property for an image, the iterator will be set up for that
2449 image, and we have to undo that setup first before we can
2450 correct the overlay string index. */
2451 if (it->method == next_element_from_image)
2452 pop_it (it);
2454 /* We already have the first chunk of overlay strings in
2455 IT->overlay_strings. Load more until the one for
2456 pos->overlay_string_index is in IT->overlay_strings. */
2457 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2459 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2460 it->current.overlay_string_index = 0;
2461 while (n--)
2463 load_overlay_strings (it, 0);
2464 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2468 it->current.overlay_string_index = pos->overlay_string_index;
2469 relative_index = (it->current.overlay_string_index
2470 % OVERLAY_STRING_CHUNK_SIZE);
2471 it->string = it->overlay_strings[relative_index];
2472 xassert (STRINGP (it->string));
2473 it->current.string_pos = pos->string_pos;
2474 it->method = next_element_from_string;
2477 #if 0 /* This is bogus because POS not having an overlay string
2478 position does not mean it's after the string. Example: A
2479 line starting with a before-string and initialization of IT
2480 to the previous row's end position. */
2481 else if (it->current.overlay_string_index >= 0)
2483 /* If POS says we're already after an overlay string ending at
2484 POS, make sure to pop the iterator because it will be in
2485 front of that overlay string. When POS is ZV, we've thereby
2486 also ``processed'' overlay strings at ZV. */
2487 while (it->sp)
2488 pop_it (it);
2489 it->current.overlay_string_index = -1;
2490 it->method = next_element_from_buffer;
2491 if (CHARPOS (pos->pos) == ZV)
2492 it->overlay_strings_at_end_processed_p = 1;
2494 #endif /* 0 */
2496 if (CHARPOS (pos->string_pos) >= 0)
2498 /* Recorded position is not in an overlay string, but in another
2499 string. This can only be a string from a `display' property.
2500 IT should already be filled with that string. */
2501 it->current.string_pos = pos->string_pos;
2502 xassert (STRINGP (it->string));
2505 /* Restore position in display vector translations, control
2506 character translations or ellipses. */
2507 if (pos->dpvec_index >= 0)
2509 if (it->dpvec == NULL)
2510 get_next_display_element (it);
2511 xassert (it->dpvec && it->current.dpvec_index == 0);
2512 it->current.dpvec_index = pos->dpvec_index;
2515 CHECK_IT (it);
2516 return !overlay_strings_with_newlines;
2520 /* Initialize IT for stepping through current_buffer in window W
2521 starting at ROW->start. */
2523 static void
2524 init_to_row_start (it, w, row)
2525 struct it *it;
2526 struct window *w;
2527 struct glyph_row *row;
2529 init_from_display_pos (it, w, &row->start);
2530 it->start = row->start;
2531 it->continuation_lines_width = row->continuation_lines_width;
2532 CHECK_IT (it);
2536 /* Initialize IT for stepping through current_buffer in window W
2537 starting in the line following ROW, i.e. starting at ROW->end.
2538 Value is zero if there are overlay strings with newlines at ROW's
2539 end position. */
2541 static int
2542 init_to_row_end (it, w, row)
2543 struct it *it;
2544 struct window *w;
2545 struct glyph_row *row;
2547 int success = 0;
2549 if (init_from_display_pos (it, w, &row->end))
2551 if (row->continued_p)
2552 it->continuation_lines_width
2553 = row->continuation_lines_width + row->pixel_width;
2554 CHECK_IT (it);
2555 success = 1;
2558 return success;
2564 /***********************************************************************
2565 Text properties
2566 ***********************************************************************/
2568 /* Called when IT reaches IT->stop_charpos. Handle text property and
2569 overlay changes. Set IT->stop_charpos to the next position where
2570 to stop. */
2572 static void
2573 handle_stop (it)
2574 struct it *it;
2576 enum prop_handled handled;
2577 int handle_overlay_change_p = 1;
2578 struct props *p;
2580 it->dpvec = NULL;
2581 it->current.dpvec_index = -1;
2585 handled = HANDLED_NORMALLY;
2587 /* Call text property handlers. */
2588 for (p = it_props; p->handler; ++p)
2590 handled = p->handler (it);
2592 if (handled == HANDLED_RECOMPUTE_PROPS)
2593 break;
2594 else if (handled == HANDLED_RETURN)
2595 return;
2596 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2597 handle_overlay_change_p = 0;
2600 if (handled != HANDLED_RECOMPUTE_PROPS)
2602 /* Don't check for overlay strings below when set to deliver
2603 characters from a display vector. */
2604 if (it->method == next_element_from_display_vector)
2605 handle_overlay_change_p = 0;
2607 /* Handle overlay changes. */
2608 if (handle_overlay_change_p)
2609 handled = handle_overlay_change (it);
2611 /* Determine where to stop next. */
2612 if (handled == HANDLED_NORMALLY)
2613 compute_stop_pos (it);
2616 while (handled == HANDLED_RECOMPUTE_PROPS);
2620 /* Compute IT->stop_charpos from text property and overlay change
2621 information for IT's current position. */
2623 static void
2624 compute_stop_pos (it)
2625 struct it *it;
2627 register INTERVAL iv, next_iv;
2628 Lisp_Object object, limit, position;
2630 /* If nowhere else, stop at the end. */
2631 it->stop_charpos = it->end_charpos;
2633 if (STRINGP (it->string))
2635 /* Strings are usually short, so don't limit the search for
2636 properties. */
2637 object = it->string;
2638 limit = Qnil;
2639 position = make_number (IT_STRING_CHARPOS (*it));
2641 else
2643 int charpos;
2645 /* If next overlay change is in front of the current stop pos
2646 (which is IT->end_charpos), stop there. Note: value of
2647 next_overlay_change is point-max if no overlay change
2648 follows. */
2649 charpos = next_overlay_change (IT_CHARPOS (*it));
2650 if (charpos < it->stop_charpos)
2651 it->stop_charpos = charpos;
2653 /* If showing the region, we have to stop at the region
2654 start or end because the face might change there. */
2655 if (it->region_beg_charpos > 0)
2657 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2658 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2659 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2660 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2663 /* Set up variables for computing the stop position from text
2664 property changes. */
2665 XSETBUFFER (object, current_buffer);
2666 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2667 position = make_number (IT_CHARPOS (*it));
2671 /* Get the interval containing IT's position. Value is a null
2672 interval if there isn't such an interval. */
2673 iv = validate_interval_range (object, &position, &position, 0);
2674 if (!NULL_INTERVAL_P (iv))
2676 Lisp_Object values_here[LAST_PROP_IDX];
2677 struct props *p;
2679 /* Get properties here. */
2680 for (p = it_props; p->handler; ++p)
2681 values_here[p->idx] = textget (iv->plist, *p->name);
2683 /* Look for an interval following iv that has different
2684 properties. */
2685 for (next_iv = next_interval (iv);
2686 (!NULL_INTERVAL_P (next_iv)
2687 && (NILP (limit)
2688 || XFASTINT (limit) > next_iv->position));
2689 next_iv = next_interval (next_iv))
2691 for (p = it_props; p->handler; ++p)
2693 Lisp_Object new_value;
2695 new_value = textget (next_iv->plist, *p->name);
2696 if (!EQ (values_here[p->idx], new_value))
2697 break;
2700 if (p->handler)
2701 break;
2704 if (!NULL_INTERVAL_P (next_iv))
2706 if (INTEGERP (limit)
2707 && next_iv->position >= XFASTINT (limit))
2708 /* No text property change up to limit. */
2709 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2710 else
2711 /* Text properties change in next_iv. */
2712 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2716 xassert (STRINGP (it->string)
2717 || (it->stop_charpos >= BEGV
2718 && it->stop_charpos >= IT_CHARPOS (*it)));
2722 /* Return the position of the next overlay change after POS in
2723 current_buffer. Value is point-max if no overlay change
2724 follows. This is like `next-overlay-change' but doesn't use
2725 xmalloc. */
2727 static int
2728 next_overlay_change (pos)
2729 int pos;
2731 int noverlays;
2732 int endpos;
2733 Lisp_Object *overlays;
2734 int i;
2736 /* Get all overlays at the given position. */
2737 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2739 /* If any of these overlays ends before endpos,
2740 use its ending point instead. */
2741 for (i = 0; i < noverlays; ++i)
2743 Lisp_Object oend;
2744 int oendpos;
2746 oend = OVERLAY_END (overlays[i]);
2747 oendpos = OVERLAY_POSITION (oend);
2748 endpos = min (endpos, oendpos);
2751 return endpos;
2756 /***********************************************************************
2757 Fontification
2758 ***********************************************************************/
2760 /* Handle changes in the `fontified' property of the current buffer by
2761 calling hook functions from Qfontification_functions to fontify
2762 regions of text. */
2764 static enum prop_handled
2765 handle_fontified_prop (it)
2766 struct it *it;
2768 Lisp_Object prop, pos;
2769 enum prop_handled handled = HANDLED_NORMALLY;
2771 /* Get the value of the `fontified' property at IT's current buffer
2772 position. (The `fontified' property doesn't have a special
2773 meaning in strings.) If the value is nil, call functions from
2774 Qfontification_functions. */
2775 if (!STRINGP (it->string)
2776 && it->s == NULL
2777 && !NILP (Vfontification_functions)
2778 && !NILP (Vrun_hooks)
2779 && (pos = make_number (IT_CHARPOS (*it)),
2780 prop = Fget_char_property (pos, Qfontified, Qnil),
2781 NILP (prop)))
2783 int count = SPECPDL_INDEX ();
2784 Lisp_Object val;
2786 val = Vfontification_functions;
2787 specbind (Qfontification_functions, Qnil);
2789 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2790 safe_call1 (val, pos);
2791 else
2793 Lisp_Object globals, fn;
2794 struct gcpro gcpro1, gcpro2;
2796 globals = Qnil;
2797 GCPRO2 (val, globals);
2799 for (; CONSP (val); val = XCDR (val))
2801 fn = XCAR (val);
2803 if (EQ (fn, Qt))
2805 /* A value of t indicates this hook has a local
2806 binding; it means to run the global binding too.
2807 In a global value, t should not occur. If it
2808 does, we must ignore it to avoid an endless
2809 loop. */
2810 for (globals = Fdefault_value (Qfontification_functions);
2811 CONSP (globals);
2812 globals = XCDR (globals))
2814 fn = XCAR (globals);
2815 if (!EQ (fn, Qt))
2816 safe_call1 (fn, pos);
2819 else
2820 safe_call1 (fn, pos);
2823 UNGCPRO;
2826 unbind_to (count, Qnil);
2828 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2829 something. This avoids an endless loop if they failed to
2830 fontify the text for which reason ever. */
2831 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2832 handled = HANDLED_RECOMPUTE_PROPS;
2835 return handled;
2840 /***********************************************************************
2841 Faces
2842 ***********************************************************************/
2844 /* Set up iterator IT from face properties at its current position.
2845 Called from handle_stop. */
2847 static enum prop_handled
2848 handle_face_prop (it)
2849 struct it *it;
2851 int new_face_id, next_stop;
2853 if (!STRINGP (it->string))
2855 new_face_id
2856 = face_at_buffer_position (it->w,
2857 IT_CHARPOS (*it),
2858 it->region_beg_charpos,
2859 it->region_end_charpos,
2860 &next_stop,
2861 (IT_CHARPOS (*it)
2862 + TEXT_PROP_DISTANCE_LIMIT),
2865 /* Is this a start of a run of characters with box face?
2866 Caveat: this can be called for a freshly initialized
2867 iterator; face_id is -1 in this case. We know that the new
2868 face will not change until limit, i.e. if the new face has a
2869 box, all characters up to limit will have one. But, as
2870 usual, we don't know whether limit is really the end. */
2871 if (new_face_id != it->face_id)
2873 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2875 /* If new face has a box but old face has not, this is
2876 the start of a run of characters with box, i.e. it has
2877 a shadow on the left side. The value of face_id of the
2878 iterator will be -1 if this is the initial call that gets
2879 the face. In this case, we have to look in front of IT's
2880 position and see whether there is a face != new_face_id. */
2881 it->start_of_box_run_p
2882 = (new_face->box != FACE_NO_BOX
2883 && (it->face_id >= 0
2884 || IT_CHARPOS (*it) == BEG
2885 || new_face_id != face_before_it_pos (it)));
2886 it->face_box_p = new_face->box != FACE_NO_BOX;
2889 else
2891 int base_face_id, bufpos;
2893 if (it->current.overlay_string_index >= 0)
2894 bufpos = IT_CHARPOS (*it);
2895 else
2896 bufpos = 0;
2898 /* For strings from a buffer, i.e. overlay strings or strings
2899 from a `display' property, use the face at IT's current
2900 buffer position as the base face to merge with, so that
2901 overlay strings appear in the same face as surrounding
2902 text, unless they specify their own faces. */
2903 base_face_id = underlying_face_id (it);
2905 new_face_id = face_at_string_position (it->w,
2906 it->string,
2907 IT_STRING_CHARPOS (*it),
2908 bufpos,
2909 it->region_beg_charpos,
2910 it->region_end_charpos,
2911 &next_stop,
2912 base_face_id, 0);
2914 #if 0 /* This shouldn't be neccessary. Let's check it. */
2915 /* If IT is used to display a mode line we would really like to
2916 use the mode line face instead of the frame's default face. */
2917 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2918 && new_face_id == DEFAULT_FACE_ID)
2919 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2920 #endif
2922 /* Is this a start of a run of characters with box? Caveat:
2923 this can be called for a freshly allocated iterator; face_id
2924 is -1 is this case. We know that the new face will not
2925 change until the next check pos, i.e. if the new face has a
2926 box, all characters up to that position will have a
2927 box. But, as usual, we don't know whether that position
2928 is really the end. */
2929 if (new_face_id != it->face_id)
2931 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2932 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2934 /* If new face has a box but old face hasn't, this is the
2935 start of a run of characters with box, i.e. it has a
2936 shadow on the left side. */
2937 it->start_of_box_run_p
2938 = new_face->box && (old_face == NULL || !old_face->box);
2939 it->face_box_p = new_face->box != FACE_NO_BOX;
2943 it->face_id = new_face_id;
2944 return HANDLED_NORMALLY;
2948 /* Return the ID of the face ``underlying'' IT's current position,
2949 which is in a string. If the iterator is associated with a
2950 buffer, return the face at IT's current buffer position.
2951 Otherwise, use the iterator's base_face_id. */
2953 static int
2954 underlying_face_id (it)
2955 struct it *it;
2957 int face_id = it->base_face_id, i;
2959 xassert (STRINGP (it->string));
2961 for (i = it->sp - 1; i >= 0; --i)
2962 if (NILP (it->stack[i].string))
2963 face_id = it->stack[i].face_id;
2965 return face_id;
2969 /* Compute the face one character before or after the current position
2970 of IT. BEFORE_P non-zero means get the face in front of IT's
2971 position. Value is the id of the face. */
2973 static int
2974 face_before_or_after_it_pos (it, before_p)
2975 struct it *it;
2976 int before_p;
2978 int face_id, limit;
2979 int next_check_charpos;
2980 struct text_pos pos;
2982 xassert (it->s == NULL);
2984 if (STRINGP (it->string))
2986 int bufpos, base_face_id;
2988 /* No face change past the end of the string (for the case
2989 we are padding with spaces). No face change before the
2990 string start. */
2991 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2992 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2993 return it->face_id;
2995 /* Set pos to the position before or after IT's current position. */
2996 if (before_p)
2997 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2998 else
2999 /* For composition, we must check the character after the
3000 composition. */
3001 pos = (it->what == IT_COMPOSITION
3002 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3003 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3005 if (it->current.overlay_string_index >= 0)
3006 bufpos = IT_CHARPOS (*it);
3007 else
3008 bufpos = 0;
3010 base_face_id = underlying_face_id (it);
3012 /* Get the face for ASCII, or unibyte. */
3013 face_id = face_at_string_position (it->w,
3014 it->string,
3015 CHARPOS (pos),
3016 bufpos,
3017 it->region_beg_charpos,
3018 it->region_end_charpos,
3019 &next_check_charpos,
3020 base_face_id, 0);
3022 /* Correct the face for charsets different from ASCII. Do it
3023 for the multibyte case only. The face returned above is
3024 suitable for unibyte text if IT->string is unibyte. */
3025 if (STRING_MULTIBYTE (it->string))
3027 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3028 int rest = SBYTES (it->string) - BYTEPOS (pos);
3029 int c, len;
3030 struct face *face = FACE_FROM_ID (it->f, face_id);
3032 c = string_char_and_length (p, rest, &len);
3033 face_id = FACE_FOR_CHAR (it->f, face, c);
3036 else
3038 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3039 || (IT_CHARPOS (*it) <= BEGV && before_p))
3040 return it->face_id;
3042 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3043 pos = it->current.pos;
3045 if (before_p)
3046 DEC_TEXT_POS (pos, it->multibyte_p);
3047 else
3049 if (it->what == IT_COMPOSITION)
3050 /* For composition, we must check the position after the
3051 composition. */
3052 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3053 else
3054 INC_TEXT_POS (pos, it->multibyte_p);
3057 /* Determine face for CHARSET_ASCII, or unibyte. */
3058 face_id = face_at_buffer_position (it->w,
3059 CHARPOS (pos),
3060 it->region_beg_charpos,
3061 it->region_end_charpos,
3062 &next_check_charpos,
3063 limit, 0);
3065 /* Correct the face for charsets different from ASCII. Do it
3066 for the multibyte case only. The face returned above is
3067 suitable for unibyte text if current_buffer is unibyte. */
3068 if (it->multibyte_p)
3070 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3071 struct face *face = FACE_FROM_ID (it->f, face_id);
3072 face_id = FACE_FOR_CHAR (it->f, face, c);
3076 return face_id;
3081 /***********************************************************************
3082 Invisible text
3083 ***********************************************************************/
3085 /* Set up iterator IT from invisible properties at its current
3086 position. Called from handle_stop. */
3088 static enum prop_handled
3089 handle_invisible_prop (it)
3090 struct it *it;
3092 enum prop_handled handled = HANDLED_NORMALLY;
3094 if (STRINGP (it->string))
3096 extern Lisp_Object Qinvisible;
3097 Lisp_Object prop, end_charpos, limit, charpos;
3099 /* Get the value of the invisible text property at the
3100 current position. Value will be nil if there is no such
3101 property. */
3102 charpos = make_number (IT_STRING_CHARPOS (*it));
3103 prop = Fget_text_property (charpos, Qinvisible, it->string);
3105 if (!NILP (prop)
3106 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3108 handled = HANDLED_RECOMPUTE_PROPS;
3110 /* Get the position at which the next change of the
3111 invisible text property can be found in IT->string.
3112 Value will be nil if the property value is the same for
3113 all the rest of IT->string. */
3114 XSETINT (limit, SCHARS (it->string));
3115 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3116 it->string, limit);
3118 /* Text at current position is invisible. The next
3119 change in the property is at position end_charpos.
3120 Move IT's current position to that position. */
3121 if (INTEGERP (end_charpos)
3122 && XFASTINT (end_charpos) < XFASTINT (limit))
3124 struct text_pos old;
3125 old = it->current.string_pos;
3126 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3127 compute_string_pos (&it->current.string_pos, old, it->string);
3129 else
3131 /* The rest of the string is invisible. If this is an
3132 overlay string, proceed with the next overlay string
3133 or whatever comes and return a character from there. */
3134 if (it->current.overlay_string_index >= 0)
3136 next_overlay_string (it);
3137 /* Don't check for overlay strings when we just
3138 finished processing them. */
3139 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3141 else
3143 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3144 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3149 else
3151 int invis_p, newpos, next_stop, start_charpos;
3152 Lisp_Object pos, prop, overlay;
3154 /* First of all, is there invisible text at this position? */
3155 start_charpos = IT_CHARPOS (*it);
3156 pos = make_number (IT_CHARPOS (*it));
3157 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3158 &overlay);
3159 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3161 /* If we are on invisible text, skip over it. */
3162 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3164 /* Record whether we have to display an ellipsis for the
3165 invisible text. */
3166 int display_ellipsis_p = invis_p == 2;
3168 handled = HANDLED_RECOMPUTE_PROPS;
3170 /* Loop skipping over invisible text. The loop is left at
3171 ZV or with IT on the first char being visible again. */
3174 /* Try to skip some invisible text. Return value is the
3175 position reached which can be equal to IT's position
3176 if there is nothing invisible here. This skips both
3177 over invisible text properties and overlays with
3178 invisible property. */
3179 newpos = skip_invisible (IT_CHARPOS (*it),
3180 &next_stop, ZV, it->window);
3182 /* If we skipped nothing at all we weren't at invisible
3183 text in the first place. If everything to the end of
3184 the buffer was skipped, end the loop. */
3185 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3186 invis_p = 0;
3187 else
3189 /* We skipped some characters but not necessarily
3190 all there are. Check if we ended up on visible
3191 text. Fget_char_property returns the property of
3192 the char before the given position, i.e. if we
3193 get invis_p = 0, this means that the char at
3194 newpos is visible. */
3195 pos = make_number (newpos);
3196 prop = Fget_char_property (pos, Qinvisible, it->window);
3197 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3200 /* If we ended up on invisible text, proceed to
3201 skip starting with next_stop. */
3202 if (invis_p)
3203 IT_CHARPOS (*it) = next_stop;
3205 while (invis_p);
3207 /* The position newpos is now either ZV or on visible text. */
3208 IT_CHARPOS (*it) = newpos;
3209 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3211 /* If there are before-strings at the start of invisible
3212 text, and the text is invisible because of a text
3213 property, arrange to show before-strings because 20.x did
3214 it that way. (If the text is invisible because of an
3215 overlay property instead of a text property, this is
3216 already handled in the overlay code.) */
3217 if (NILP (overlay)
3218 && get_overlay_strings (it, start_charpos))
3220 handled = HANDLED_RECOMPUTE_PROPS;
3221 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3223 else if (display_ellipsis_p)
3224 setup_for_ellipsis (it);
3228 return handled;
3232 /* Make iterator IT return `...' next. */
3234 static void
3235 setup_for_ellipsis (it)
3236 struct it *it;
3238 if (it->dp
3239 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3241 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3242 it->dpvec = v->contents;
3243 it->dpend = v->contents + v->size;
3245 else
3247 /* Default `...'. */
3248 it->dpvec = default_invis_vector;
3249 it->dpend = default_invis_vector + 3;
3252 /* The ellipsis display does not replace the display of the
3253 character at the new position. Indicate this by setting
3254 IT->dpvec_char_len to zero. */
3255 it->dpvec_char_len = 0;
3257 it->current.dpvec_index = 0;
3258 it->method = next_element_from_display_vector;
3263 /***********************************************************************
3264 'display' property
3265 ***********************************************************************/
3267 /* Set up iterator IT from `display' property at its current position.
3268 Called from handle_stop. */
3270 static enum prop_handled
3271 handle_display_prop (it)
3272 struct it *it;
3274 Lisp_Object prop, object;
3275 struct text_pos *position;
3276 int display_replaced_p = 0;
3278 if (STRINGP (it->string))
3280 object = it->string;
3281 position = &it->current.string_pos;
3283 else
3285 object = it->w->buffer;
3286 position = &it->current.pos;
3289 /* Reset those iterator values set from display property values. */
3290 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3291 it->space_width = Qnil;
3292 it->font_height = Qnil;
3293 it->voffset = 0;
3295 /* We don't support recursive `display' properties, i.e. string
3296 values that have a string `display' property, that have a string
3297 `display' property etc. */
3298 if (!it->string_from_display_prop_p)
3299 it->area = TEXT_AREA;
3301 prop = Fget_char_property (make_number (position->charpos),
3302 Qdisplay, object);
3303 if (NILP (prop))
3304 return HANDLED_NORMALLY;
3306 if (CONSP (prop)
3307 /* Simple properties. */
3308 && !EQ (XCAR (prop), Qimage)
3309 && !EQ (XCAR (prop), Qspace)
3310 && !EQ (XCAR (prop), Qwhen)
3311 && !EQ (XCAR (prop), Qslice)
3312 && !EQ (XCAR (prop), Qspace_width)
3313 && !EQ (XCAR (prop), Qheight)
3314 && !EQ (XCAR (prop), Qraise)
3315 /* Marginal area specifications. */
3316 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3317 && !EQ (XCAR (prop), Qleft_fringe)
3318 && !EQ (XCAR (prop), Qright_fringe)
3319 && !NILP (XCAR (prop)))
3321 for (; CONSP (prop); prop = XCDR (prop))
3323 if (handle_single_display_prop (it, XCAR (prop), object,
3324 position, display_replaced_p))
3325 display_replaced_p = 1;
3328 else if (VECTORP (prop))
3330 int i;
3331 for (i = 0; i < ASIZE (prop); ++i)
3332 if (handle_single_display_prop (it, AREF (prop, i), object,
3333 position, display_replaced_p))
3334 display_replaced_p = 1;
3336 else
3338 if (handle_single_display_prop (it, prop, object, position, 0))
3339 display_replaced_p = 1;
3342 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3346 /* Value is the position of the end of the `display' property starting
3347 at START_POS in OBJECT. */
3349 static struct text_pos
3350 display_prop_end (it, object, start_pos)
3351 struct it *it;
3352 Lisp_Object object;
3353 struct text_pos start_pos;
3355 Lisp_Object end;
3356 struct text_pos end_pos;
3358 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3359 Qdisplay, object, Qnil);
3360 CHARPOS (end_pos) = XFASTINT (end);
3361 if (STRINGP (object))
3362 compute_string_pos (&end_pos, start_pos, it->string);
3363 else
3364 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3366 return end_pos;
3370 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3371 is the object in which the `display' property was found. *POSITION
3372 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3373 means that we previously saw a display sub-property which already
3374 replaced text display with something else, for example an image;
3375 ignore such properties after the first one has been processed.
3377 If PROP is a `space' or `image' sub-property, set *POSITION to the
3378 end position of the `display' property.
3380 Value is non-zero if something was found which replaces the display
3381 of buffer or string text. */
3383 static int
3384 handle_single_display_prop (it, prop, object, position,
3385 display_replaced_before_p)
3386 struct it *it;
3387 Lisp_Object prop;
3388 Lisp_Object object;
3389 struct text_pos *position;
3390 int display_replaced_before_p;
3392 Lisp_Object value;
3393 int replaces_text_display_p = 0;
3394 Lisp_Object form;
3396 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3397 evaluated. If the result is nil, VALUE is ignored. */
3398 form = Qt;
3399 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3401 prop = XCDR (prop);
3402 if (!CONSP (prop))
3403 return 0;
3404 form = XCAR (prop);
3405 prop = XCDR (prop);
3408 if (!NILP (form) && !EQ (form, Qt))
3410 int count = SPECPDL_INDEX ();
3411 struct gcpro gcpro1;
3413 /* Bind `object' to the object having the `display' property, a
3414 buffer or string. Bind `position' to the position in the
3415 object where the property was found, and `buffer-position'
3416 to the current position in the buffer. */
3417 specbind (Qobject, object);
3418 specbind (Qposition, make_number (CHARPOS (*position)));
3419 specbind (Qbuffer_position,
3420 make_number (STRINGP (object)
3421 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3422 GCPRO1 (form);
3423 form = safe_eval (form);
3424 UNGCPRO;
3425 unbind_to (count, Qnil);
3428 if (NILP (form))
3429 return 0;
3431 if (CONSP (prop)
3432 && EQ (XCAR (prop), Qheight)
3433 && CONSP (XCDR (prop)))
3435 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3436 return 0;
3438 /* `(height HEIGHT)'. */
3439 it->font_height = XCAR (XCDR (prop));
3440 if (!NILP (it->font_height))
3442 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3443 int new_height = -1;
3445 if (CONSP (it->font_height)
3446 && (EQ (XCAR (it->font_height), Qplus)
3447 || EQ (XCAR (it->font_height), Qminus))
3448 && CONSP (XCDR (it->font_height))
3449 && INTEGERP (XCAR (XCDR (it->font_height))))
3451 /* `(+ N)' or `(- N)' where N is an integer. */
3452 int steps = XINT (XCAR (XCDR (it->font_height)));
3453 if (EQ (XCAR (it->font_height), Qplus))
3454 steps = - steps;
3455 it->face_id = smaller_face (it->f, it->face_id, steps);
3457 else if (FUNCTIONP (it->font_height))
3459 /* Call function with current height as argument.
3460 Value is the new height. */
3461 Lisp_Object height;
3462 height = safe_call1 (it->font_height,
3463 face->lface[LFACE_HEIGHT_INDEX]);
3464 if (NUMBERP (height))
3465 new_height = XFLOATINT (height);
3467 else if (NUMBERP (it->font_height))
3469 /* Value is a multiple of the canonical char height. */
3470 struct face *face;
3472 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3473 new_height = (XFLOATINT (it->font_height)
3474 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3476 else
3478 /* Evaluate IT->font_height with `height' bound to the
3479 current specified height to get the new height. */
3480 Lisp_Object value;
3481 int count = SPECPDL_INDEX ();
3483 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3484 value = safe_eval (it->font_height);
3485 unbind_to (count, Qnil);
3487 if (NUMBERP (value))
3488 new_height = XFLOATINT (value);
3491 if (new_height > 0)
3492 it->face_id = face_with_height (it->f, it->face_id, new_height);
3495 else if (CONSP (prop)
3496 && EQ (XCAR (prop), Qspace_width)
3497 && CONSP (XCDR (prop)))
3499 /* `(space_width WIDTH)'. */
3500 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3501 return 0;
3503 value = XCAR (XCDR (prop));
3504 if (NUMBERP (value) && XFLOATINT (value) > 0)
3505 it->space_width = value;
3507 else if (CONSP (prop)
3508 && EQ (XCAR (prop), Qslice))
3510 /* `(slice X Y WIDTH HEIGHT)'. */
3511 Lisp_Object tem;
3513 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3514 return 0;
3516 if (tem = XCDR (prop), CONSP (tem))
3518 it->slice.x = XCAR (tem);
3519 if (tem = XCDR (tem), CONSP (tem))
3521 it->slice.y = XCAR (tem);
3522 if (tem = XCDR (tem), CONSP (tem))
3524 it->slice.width = XCAR (tem);
3525 if (tem = XCDR (tem), CONSP (tem))
3526 it->slice.height = XCAR (tem);
3531 else if (CONSP (prop)
3532 && EQ (XCAR (prop), Qraise)
3533 && CONSP (XCDR (prop)))
3535 /* `(raise FACTOR)'. */
3536 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3537 return 0;
3539 #ifdef HAVE_WINDOW_SYSTEM
3540 value = XCAR (XCDR (prop));
3541 if (NUMBERP (value))
3543 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3544 it->voffset = - (XFLOATINT (value)
3545 * (FONT_HEIGHT (face->font)));
3547 #endif /* HAVE_WINDOW_SYSTEM */
3549 else if (!it->string_from_display_prop_p)
3551 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3552 VALUE) or `((margin nil) VALUE)' or VALUE. */
3553 Lisp_Object location, value;
3554 struct text_pos start_pos;
3555 int valid_p;
3557 /* Characters having this form of property are not displayed, so
3558 we have to find the end of the property. */
3559 start_pos = *position;
3560 *position = display_prop_end (it, object, start_pos);
3561 value = Qnil;
3563 /* Let's stop at the new position and assume that all
3564 text properties change there. */
3565 it->stop_charpos = position->charpos;
3567 if (CONSP (prop)
3568 && (EQ (XCAR (prop), Qleft_fringe)
3569 || EQ (XCAR (prop), Qright_fringe))
3570 && CONSP (XCDR (prop)))
3572 unsigned face_id = DEFAULT_FACE_ID;
3573 int fringe_bitmap;
3575 /* Save current settings of IT so that we can restore them
3576 when we are finished with the glyph property value. */
3578 /* `(left-fringe BITMAP FACE)'. */
3579 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3580 return 0;
3582 #ifdef HAVE_WINDOW_SYSTEM
3583 value = XCAR (XCDR (prop));
3584 if (!SYMBOLP (value)
3585 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3586 return 0;
3588 if (CONSP (XCDR (XCDR (prop))))
3590 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3592 face_id = lookup_named_face (it->f, face_name, 'A');
3593 if (face_id < 0)
3594 return 0;
3597 push_it (it);
3599 it->area = TEXT_AREA;
3600 it->what = IT_IMAGE;
3601 it->image_id = -1; /* no image */
3602 it->position = start_pos;
3603 it->object = NILP (object) ? it->w->buffer : object;
3604 it->method = next_element_from_image;
3605 it->face_id = face_id;
3607 /* Say that we haven't consumed the characters with
3608 `display' property yet. The call to pop_it in
3609 set_iterator_to_next will clean this up. */
3610 *position = start_pos;
3612 if (EQ (XCAR (prop), Qleft_fringe))
3614 it->left_user_fringe_bitmap = fringe_bitmap;
3615 it->left_user_fringe_face_id = face_id;
3617 else
3619 it->right_user_fringe_bitmap = fringe_bitmap;
3620 it->right_user_fringe_face_id = face_id;
3622 #endif /* HAVE_WINDOW_SYSTEM */
3623 return 1;
3626 location = Qunbound;
3627 if (CONSP (prop) && CONSP (XCAR (prop)))
3629 Lisp_Object tem;
3631 value = XCDR (prop);
3632 if (CONSP (value))
3633 value = XCAR (value);
3635 tem = XCAR (prop);
3636 if (EQ (XCAR (tem), Qmargin)
3637 && (tem = XCDR (tem),
3638 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3639 (NILP (tem)
3640 || EQ (tem, Qleft_margin)
3641 || EQ (tem, Qright_margin))))
3642 location = tem;
3645 if (EQ (location, Qunbound))
3647 location = Qnil;
3648 value = prop;
3651 valid_p = (STRINGP (value)
3652 #ifdef HAVE_WINDOW_SYSTEM
3653 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3654 #endif /* not HAVE_WINDOW_SYSTEM */
3655 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3657 if ((EQ (location, Qleft_margin)
3658 || EQ (location, Qright_margin)
3659 || NILP (location))
3660 && valid_p
3661 && !display_replaced_before_p)
3663 replaces_text_display_p = 1;
3665 /* Save current settings of IT so that we can restore them
3666 when we are finished with the glyph property value. */
3667 push_it (it);
3669 if (NILP (location))
3670 it->area = TEXT_AREA;
3671 else if (EQ (location, Qleft_margin))
3672 it->area = LEFT_MARGIN_AREA;
3673 else
3674 it->area = RIGHT_MARGIN_AREA;
3676 if (STRINGP (value))
3678 it->string = value;
3679 it->multibyte_p = STRING_MULTIBYTE (it->string);
3680 it->current.overlay_string_index = -1;
3681 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3682 it->end_charpos = it->string_nchars = SCHARS (it->string);
3683 it->method = next_element_from_string;
3684 it->stop_charpos = 0;
3685 it->string_from_display_prop_p = 1;
3686 /* Say that we haven't consumed the characters with
3687 `display' property yet. The call to pop_it in
3688 set_iterator_to_next will clean this up. */
3689 *position = start_pos;
3691 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3693 it->method = next_element_from_stretch;
3694 it->object = value;
3695 it->current.pos = it->position = start_pos;
3697 #ifdef HAVE_WINDOW_SYSTEM
3698 else
3700 it->what = IT_IMAGE;
3701 it->image_id = lookup_image (it->f, value);
3702 it->position = start_pos;
3703 it->object = NILP (object) ? it->w->buffer : object;
3704 it->method = next_element_from_image;
3706 /* Say that we haven't consumed the characters with
3707 `display' property yet. The call to pop_it in
3708 set_iterator_to_next will clean this up. */
3709 *position = start_pos;
3711 #endif /* HAVE_WINDOW_SYSTEM */
3713 else
3714 /* Invalid property or property not supported. Restore
3715 the position to what it was before. */
3716 *position = start_pos;
3719 return replaces_text_display_p;
3723 /* Check if PROP is a display sub-property value whose text should be
3724 treated as intangible. */
3726 static int
3727 single_display_prop_intangible_p (prop)
3728 Lisp_Object prop;
3730 /* Skip over `when FORM'. */
3731 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3733 prop = XCDR (prop);
3734 if (!CONSP (prop))
3735 return 0;
3736 prop = XCDR (prop);
3739 if (STRINGP (prop))
3740 return 1;
3742 if (!CONSP (prop))
3743 return 0;
3745 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3746 we don't need to treat text as intangible. */
3747 if (EQ (XCAR (prop), Qmargin))
3749 prop = XCDR (prop);
3750 if (!CONSP (prop))
3751 return 0;
3753 prop = XCDR (prop);
3754 if (!CONSP (prop)
3755 || EQ (XCAR (prop), Qleft_margin)
3756 || EQ (XCAR (prop), Qright_margin))
3757 return 0;
3760 return (CONSP (prop)
3761 && (EQ (XCAR (prop), Qimage)
3762 || EQ (XCAR (prop), Qspace)));
3766 /* Check if PROP is a display property value whose text should be
3767 treated as intangible. */
3770 display_prop_intangible_p (prop)
3771 Lisp_Object prop;
3773 if (CONSP (prop)
3774 && CONSP (XCAR (prop))
3775 && !EQ (Qmargin, XCAR (XCAR (prop))))
3777 /* A list of sub-properties. */
3778 while (CONSP (prop))
3780 if (single_display_prop_intangible_p (XCAR (prop)))
3781 return 1;
3782 prop = XCDR (prop);
3785 else if (VECTORP (prop))
3787 /* A vector of sub-properties. */
3788 int i;
3789 for (i = 0; i < ASIZE (prop); ++i)
3790 if (single_display_prop_intangible_p (AREF (prop, i)))
3791 return 1;
3793 else
3794 return single_display_prop_intangible_p (prop);
3796 return 0;
3800 /* Return 1 if PROP is a display sub-property value containing STRING. */
3802 static int
3803 single_display_prop_string_p (prop, string)
3804 Lisp_Object prop, string;
3806 if (EQ (string, prop))
3807 return 1;
3809 /* Skip over `when FORM'. */
3810 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3812 prop = XCDR (prop);
3813 if (!CONSP (prop))
3814 return 0;
3815 prop = XCDR (prop);
3818 if (CONSP (prop))
3819 /* Skip over `margin LOCATION'. */
3820 if (EQ (XCAR (prop), Qmargin))
3822 prop = XCDR (prop);
3823 if (!CONSP (prop))
3824 return 0;
3826 prop = XCDR (prop);
3827 if (!CONSP (prop))
3828 return 0;
3831 return CONSP (prop) && EQ (XCAR (prop), string);
3835 /* Return 1 if STRING appears in the `display' property PROP. */
3837 static int
3838 display_prop_string_p (prop, string)
3839 Lisp_Object prop, string;
3841 if (CONSP (prop)
3842 && CONSP (XCAR (prop))
3843 && !EQ (Qmargin, XCAR (XCAR (prop))))
3845 /* A list of sub-properties. */
3846 while (CONSP (prop))
3848 if (single_display_prop_string_p (XCAR (prop), string))
3849 return 1;
3850 prop = XCDR (prop);
3853 else if (VECTORP (prop))
3855 /* A vector of sub-properties. */
3856 int i;
3857 for (i = 0; i < ASIZE (prop); ++i)
3858 if (single_display_prop_string_p (AREF (prop, i), string))
3859 return 1;
3861 else
3862 return single_display_prop_string_p (prop, string);
3864 return 0;
3868 /* Determine from which buffer position in W's buffer STRING comes
3869 from. AROUND_CHARPOS is an approximate position where it could
3870 be from. Value is the buffer position or 0 if it couldn't be
3871 determined.
3873 W's buffer must be current.
3875 This function is necessary because we don't record buffer positions
3876 in glyphs generated from strings (to keep struct glyph small).
3877 This function may only use code that doesn't eval because it is
3878 called asynchronously from note_mouse_highlight. */
3881 string_buffer_position (w, string, around_charpos)
3882 struct window *w;
3883 Lisp_Object string;
3884 int around_charpos;
3886 Lisp_Object limit, prop, pos;
3887 const int MAX_DISTANCE = 1000;
3888 int found = 0;
3890 pos = make_number (around_charpos);
3891 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3892 while (!found && !EQ (pos, limit))
3894 prop = Fget_char_property (pos, Qdisplay, Qnil);
3895 if (!NILP (prop) && display_prop_string_p (prop, string))
3896 found = 1;
3897 else
3898 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3901 if (!found)
3903 pos = make_number (around_charpos);
3904 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3905 while (!found && !EQ (pos, limit))
3907 prop = Fget_char_property (pos, Qdisplay, Qnil);
3908 if (!NILP (prop) && display_prop_string_p (prop, string))
3909 found = 1;
3910 else
3911 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3912 limit);
3916 return found ? XINT (pos) : 0;
3921 /***********************************************************************
3922 `composition' property
3923 ***********************************************************************/
3925 /* Set up iterator IT from `composition' property at its current
3926 position. Called from handle_stop. */
3928 static enum prop_handled
3929 handle_composition_prop (it)
3930 struct it *it;
3932 Lisp_Object prop, string;
3933 int pos, pos_byte, end;
3934 enum prop_handled handled = HANDLED_NORMALLY;
3936 if (STRINGP (it->string))
3938 pos = IT_STRING_CHARPOS (*it);
3939 pos_byte = IT_STRING_BYTEPOS (*it);
3940 string = it->string;
3942 else
3944 pos = IT_CHARPOS (*it);
3945 pos_byte = IT_BYTEPOS (*it);
3946 string = Qnil;
3949 /* If there's a valid composition and point is not inside of the
3950 composition (in the case that the composition is from the current
3951 buffer), draw a glyph composed from the composition components. */
3952 if (find_composition (pos, -1, &pos, &end, &prop, string)
3953 && COMPOSITION_VALID_P (pos, end, prop)
3954 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3956 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3958 if (id >= 0)
3960 it->method = next_element_from_composition;
3961 it->cmp_id = id;
3962 it->cmp_len = COMPOSITION_LENGTH (prop);
3963 /* For a terminal, draw only the first character of the
3964 components. */
3965 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3966 it->len = (STRINGP (it->string)
3967 ? string_char_to_byte (it->string, end)
3968 : CHAR_TO_BYTE (end)) - pos_byte;
3969 it->stop_charpos = end;
3970 handled = HANDLED_RETURN;
3974 return handled;
3979 /***********************************************************************
3980 Overlay strings
3981 ***********************************************************************/
3983 /* The following structure is used to record overlay strings for
3984 later sorting in load_overlay_strings. */
3986 struct overlay_entry
3988 Lisp_Object overlay;
3989 Lisp_Object string;
3990 int priority;
3991 int after_string_p;
3995 /* Set up iterator IT from overlay strings at its current position.
3996 Called from handle_stop. */
3998 static enum prop_handled
3999 handle_overlay_change (it)
4000 struct it *it;
4002 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4003 return HANDLED_RECOMPUTE_PROPS;
4004 else
4005 return HANDLED_NORMALLY;
4009 /* Set up the next overlay string for delivery by IT, if there is an
4010 overlay string to deliver. Called by set_iterator_to_next when the
4011 end of the current overlay string is reached. If there are more
4012 overlay strings to display, IT->string and
4013 IT->current.overlay_string_index are set appropriately here.
4014 Otherwise IT->string is set to nil. */
4016 static void
4017 next_overlay_string (it)
4018 struct it *it;
4020 ++it->current.overlay_string_index;
4021 if (it->current.overlay_string_index == it->n_overlay_strings)
4023 /* No more overlay strings. Restore IT's settings to what
4024 they were before overlay strings were processed, and
4025 continue to deliver from current_buffer. */
4026 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4028 pop_it (it);
4029 xassert (it->stop_charpos >= BEGV
4030 && it->stop_charpos <= it->end_charpos);
4031 it->string = Qnil;
4032 it->current.overlay_string_index = -1;
4033 SET_TEXT_POS (it->current.string_pos, -1, -1);
4034 it->n_overlay_strings = 0;
4035 it->method = next_element_from_buffer;
4037 /* If we're at the end of the buffer, record that we have
4038 processed the overlay strings there already, so that
4039 next_element_from_buffer doesn't try it again. */
4040 if (IT_CHARPOS (*it) >= it->end_charpos)
4041 it->overlay_strings_at_end_processed_p = 1;
4043 /* If we have to display `...' for invisible text, set
4044 the iterator up for that. */
4045 if (display_ellipsis_p)
4046 setup_for_ellipsis (it);
4048 else
4050 /* There are more overlay strings to process. If
4051 IT->current.overlay_string_index has advanced to a position
4052 where we must load IT->overlay_strings with more strings, do
4053 it. */
4054 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4056 if (it->current.overlay_string_index && i == 0)
4057 load_overlay_strings (it, 0);
4059 /* Initialize IT to deliver display elements from the overlay
4060 string. */
4061 it->string = it->overlay_strings[i];
4062 it->multibyte_p = STRING_MULTIBYTE (it->string);
4063 SET_TEXT_POS (it->current.string_pos, 0, 0);
4064 it->method = next_element_from_string;
4065 it->stop_charpos = 0;
4068 CHECK_IT (it);
4072 /* Compare two overlay_entry structures E1 and E2. Used as a
4073 comparison function for qsort in load_overlay_strings. Overlay
4074 strings for the same position are sorted so that
4076 1. All after-strings come in front of before-strings, except
4077 when they come from the same overlay.
4079 2. Within after-strings, strings are sorted so that overlay strings
4080 from overlays with higher priorities come first.
4082 2. Within before-strings, strings are sorted so that overlay
4083 strings from overlays with higher priorities come last.
4085 Value is analogous to strcmp. */
4088 static int
4089 compare_overlay_entries (e1, e2)
4090 void *e1, *e2;
4092 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4093 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4094 int result;
4096 if (entry1->after_string_p != entry2->after_string_p)
4098 /* Let after-strings appear in front of before-strings if
4099 they come from different overlays. */
4100 if (EQ (entry1->overlay, entry2->overlay))
4101 result = entry1->after_string_p ? 1 : -1;
4102 else
4103 result = entry1->after_string_p ? -1 : 1;
4105 else if (entry1->after_string_p)
4106 /* After-strings sorted in order of decreasing priority. */
4107 result = entry2->priority - entry1->priority;
4108 else
4109 /* Before-strings sorted in order of increasing priority. */
4110 result = entry1->priority - entry2->priority;
4112 return result;
4116 /* Load the vector IT->overlay_strings with overlay strings from IT's
4117 current buffer position, or from CHARPOS if that is > 0. Set
4118 IT->n_overlays to the total number of overlay strings found.
4120 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4121 a time. On entry into load_overlay_strings,
4122 IT->current.overlay_string_index gives the number of overlay
4123 strings that have already been loaded by previous calls to this
4124 function.
4126 IT->add_overlay_start contains an additional overlay start
4127 position to consider for taking overlay strings from, if non-zero.
4128 This position comes into play when the overlay has an `invisible'
4129 property, and both before and after-strings. When we've skipped to
4130 the end of the overlay, because of its `invisible' property, we
4131 nevertheless want its before-string to appear.
4132 IT->add_overlay_start will contain the overlay start position
4133 in this case.
4135 Overlay strings are sorted so that after-string strings come in
4136 front of before-string strings. Within before and after-strings,
4137 strings are sorted by overlay priority. See also function
4138 compare_overlay_entries. */
4140 static void
4141 load_overlay_strings (it, charpos)
4142 struct it *it;
4143 int charpos;
4145 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4146 Lisp_Object overlay, window, str, invisible;
4147 struct Lisp_Overlay *ov;
4148 int start, end;
4149 int size = 20;
4150 int n = 0, i, j, invis_p;
4151 struct overlay_entry *entries
4152 = (struct overlay_entry *) alloca (size * sizeof *entries);
4154 if (charpos <= 0)
4155 charpos = IT_CHARPOS (*it);
4157 /* Append the overlay string STRING of overlay OVERLAY to vector
4158 `entries' which has size `size' and currently contains `n'
4159 elements. AFTER_P non-zero means STRING is an after-string of
4160 OVERLAY. */
4161 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4162 do \
4164 Lisp_Object priority; \
4166 if (n == size) \
4168 int new_size = 2 * size; \
4169 struct overlay_entry *old = entries; \
4170 entries = \
4171 (struct overlay_entry *) alloca (new_size \
4172 * sizeof *entries); \
4173 bcopy (old, entries, size * sizeof *entries); \
4174 size = new_size; \
4177 entries[n].string = (STRING); \
4178 entries[n].overlay = (OVERLAY); \
4179 priority = Foverlay_get ((OVERLAY), Qpriority); \
4180 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4181 entries[n].after_string_p = (AFTER_P); \
4182 ++n; \
4184 while (0)
4186 /* Process overlay before the overlay center. */
4187 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4189 XSETMISC (overlay, ov);
4190 xassert (OVERLAYP (overlay));
4191 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4192 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4194 if (end < charpos)
4195 break;
4197 /* Skip this overlay if it doesn't start or end at IT's current
4198 position. */
4199 if (end != charpos && start != charpos)
4200 continue;
4202 /* Skip this overlay if it doesn't apply to IT->w. */
4203 window = Foverlay_get (overlay, Qwindow);
4204 if (WINDOWP (window) && XWINDOW (window) != it->w)
4205 continue;
4207 /* If the text ``under'' the overlay is invisible, both before-
4208 and after-strings from this overlay are visible; start and
4209 end position are indistinguishable. */
4210 invisible = Foverlay_get (overlay, Qinvisible);
4211 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4213 /* If overlay has a non-empty before-string, record it. */
4214 if ((start == charpos || (end == charpos && invis_p))
4215 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4216 && SCHARS (str))
4217 RECORD_OVERLAY_STRING (overlay, str, 0);
4219 /* If overlay has a non-empty after-string, record it. */
4220 if ((end == charpos || (start == charpos && invis_p))
4221 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4222 && SCHARS (str))
4223 RECORD_OVERLAY_STRING (overlay, str, 1);
4226 /* Process overlays after the overlay center. */
4227 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4229 XSETMISC (overlay, ov);
4230 xassert (OVERLAYP (overlay));
4231 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4232 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4234 if (start > charpos)
4235 break;
4237 /* Skip this overlay if it doesn't start or end at IT's current
4238 position. */
4239 if (end != charpos && start != charpos)
4240 continue;
4242 /* Skip this overlay if it doesn't apply to IT->w. */
4243 window = Foverlay_get (overlay, Qwindow);
4244 if (WINDOWP (window) && XWINDOW (window) != it->w)
4245 continue;
4247 /* If the text ``under'' the overlay is invisible, it has a zero
4248 dimension, and both before- and after-strings apply. */
4249 invisible = Foverlay_get (overlay, Qinvisible);
4250 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4252 /* If overlay has a non-empty before-string, record it. */
4253 if ((start == charpos || (end == charpos && invis_p))
4254 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4255 && SCHARS (str))
4256 RECORD_OVERLAY_STRING (overlay, str, 0);
4258 /* If overlay has a non-empty after-string, record it. */
4259 if ((end == charpos || (start == charpos && invis_p))
4260 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4261 && SCHARS (str))
4262 RECORD_OVERLAY_STRING (overlay, str, 1);
4265 #undef RECORD_OVERLAY_STRING
4267 /* Sort entries. */
4268 if (n > 1)
4269 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4271 /* Record the total number of strings to process. */
4272 it->n_overlay_strings = n;
4274 /* IT->current.overlay_string_index is the number of overlay strings
4275 that have already been consumed by IT. Copy some of the
4276 remaining overlay strings to IT->overlay_strings. */
4277 i = 0;
4278 j = it->current.overlay_string_index;
4279 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4280 it->overlay_strings[i++] = entries[j++].string;
4282 CHECK_IT (it);
4286 /* Get the first chunk of overlay strings at IT's current buffer
4287 position, or at CHARPOS if that is > 0. Value is non-zero if at
4288 least one overlay string was found. */
4290 static int
4291 get_overlay_strings (it, charpos)
4292 struct it *it;
4293 int charpos;
4295 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4296 process. This fills IT->overlay_strings with strings, and sets
4297 IT->n_overlay_strings to the total number of strings to process.
4298 IT->pos.overlay_string_index has to be set temporarily to zero
4299 because load_overlay_strings needs this; it must be set to -1
4300 when no overlay strings are found because a zero value would
4301 indicate a position in the first overlay string. */
4302 it->current.overlay_string_index = 0;
4303 load_overlay_strings (it, charpos);
4305 /* If we found overlay strings, set up IT to deliver display
4306 elements from the first one. Otherwise set up IT to deliver
4307 from current_buffer. */
4308 if (it->n_overlay_strings)
4310 /* Make sure we know settings in current_buffer, so that we can
4311 restore meaningful values when we're done with the overlay
4312 strings. */
4313 compute_stop_pos (it);
4314 xassert (it->face_id >= 0);
4316 /* Save IT's settings. They are restored after all overlay
4317 strings have been processed. */
4318 xassert (it->sp == 0);
4319 push_it (it);
4321 /* Set up IT to deliver display elements from the first overlay
4322 string. */
4323 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4324 it->string = it->overlay_strings[0];
4325 it->stop_charpos = 0;
4326 xassert (STRINGP (it->string));
4327 it->end_charpos = SCHARS (it->string);
4328 it->multibyte_p = STRING_MULTIBYTE (it->string);
4329 it->method = next_element_from_string;
4331 else
4333 it->string = Qnil;
4334 it->current.overlay_string_index = -1;
4335 it->method = next_element_from_buffer;
4338 CHECK_IT (it);
4340 /* Value is non-zero if we found at least one overlay string. */
4341 return STRINGP (it->string);
4346 /***********************************************************************
4347 Saving and restoring state
4348 ***********************************************************************/
4350 /* Save current settings of IT on IT->stack. Called, for example,
4351 before setting up IT for an overlay string, to be able to restore
4352 IT's settings to what they were after the overlay string has been
4353 processed. */
4355 static void
4356 push_it (it)
4357 struct it *it;
4359 struct iterator_stack_entry *p;
4361 xassert (it->sp < 2);
4362 p = it->stack + it->sp;
4364 p->stop_charpos = it->stop_charpos;
4365 xassert (it->face_id >= 0);
4366 p->face_id = it->face_id;
4367 p->string = it->string;
4368 p->pos = it->current;
4369 p->end_charpos = it->end_charpos;
4370 p->string_nchars = it->string_nchars;
4371 p->area = it->area;
4372 p->multibyte_p = it->multibyte_p;
4373 p->slice = it->slice;
4374 p->space_width = it->space_width;
4375 p->font_height = it->font_height;
4376 p->voffset = it->voffset;
4377 p->string_from_display_prop_p = it->string_from_display_prop_p;
4378 p->display_ellipsis_p = 0;
4379 ++it->sp;
4383 /* Restore IT's settings from IT->stack. Called, for example, when no
4384 more overlay strings must be processed, and we return to delivering
4385 display elements from a buffer, or when the end of a string from a
4386 `display' property is reached and we return to delivering display
4387 elements from an overlay string, or from a buffer. */
4389 static void
4390 pop_it (it)
4391 struct it *it;
4393 struct iterator_stack_entry *p;
4395 xassert (it->sp > 0);
4396 --it->sp;
4397 p = it->stack + it->sp;
4398 it->stop_charpos = p->stop_charpos;
4399 it->face_id = p->face_id;
4400 it->string = p->string;
4401 it->current = p->pos;
4402 it->end_charpos = p->end_charpos;
4403 it->string_nchars = p->string_nchars;
4404 it->area = p->area;
4405 it->multibyte_p = p->multibyte_p;
4406 it->slice = p->slice;
4407 it->space_width = p->space_width;
4408 it->font_height = p->font_height;
4409 it->voffset = p->voffset;
4410 it->string_from_display_prop_p = p->string_from_display_prop_p;
4415 /***********************************************************************
4416 Moving over lines
4417 ***********************************************************************/
4419 /* Set IT's current position to the previous line start. */
4421 static void
4422 back_to_previous_line_start (it)
4423 struct it *it;
4425 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4426 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4430 /* Move IT to the next line start.
4432 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4433 we skipped over part of the text (as opposed to moving the iterator
4434 continuously over the text). Otherwise, don't change the value
4435 of *SKIPPED_P.
4437 Newlines may come from buffer text, overlay strings, or strings
4438 displayed via the `display' property. That's the reason we can't
4439 simply use find_next_newline_no_quit.
4441 Note that this function may not skip over invisible text that is so
4442 because of text properties and immediately follows a newline. If
4443 it would, function reseat_at_next_visible_line_start, when called
4444 from set_iterator_to_next, would effectively make invisible
4445 characters following a newline part of the wrong glyph row, which
4446 leads to wrong cursor motion. */
4448 static int
4449 forward_to_next_line_start (it, skipped_p)
4450 struct it *it;
4451 int *skipped_p;
4453 int old_selective, newline_found_p, n;
4454 const int MAX_NEWLINE_DISTANCE = 500;
4456 /* If already on a newline, just consume it to avoid unintended
4457 skipping over invisible text below. */
4458 if (it->what == IT_CHARACTER
4459 && it->c == '\n'
4460 && CHARPOS (it->position) == IT_CHARPOS (*it))
4462 set_iterator_to_next (it, 0);
4463 it->c = 0;
4464 return 1;
4467 /* Don't handle selective display in the following. It's (a)
4468 unnecessary because it's done by the caller, and (b) leads to an
4469 infinite recursion because next_element_from_ellipsis indirectly
4470 calls this function. */
4471 old_selective = it->selective;
4472 it->selective = 0;
4474 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4475 from buffer text. */
4476 for (n = newline_found_p = 0;
4477 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4478 n += STRINGP (it->string) ? 0 : 1)
4480 if (!get_next_display_element (it))
4481 return 0;
4482 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4483 set_iterator_to_next (it, 0);
4486 /* If we didn't find a newline near enough, see if we can use a
4487 short-cut. */
4488 if (!newline_found_p)
4490 int start = IT_CHARPOS (*it);
4491 int limit = find_next_newline_no_quit (start, 1);
4492 Lisp_Object pos;
4494 xassert (!STRINGP (it->string));
4496 /* If there isn't any `display' property in sight, and no
4497 overlays, we can just use the position of the newline in
4498 buffer text. */
4499 if (it->stop_charpos >= limit
4500 || ((pos = Fnext_single_property_change (make_number (start),
4501 Qdisplay,
4502 Qnil, make_number (limit)),
4503 NILP (pos))
4504 && next_overlay_change (start) == ZV))
4506 IT_CHARPOS (*it) = limit;
4507 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4508 *skipped_p = newline_found_p = 1;
4510 else
4512 while (get_next_display_element (it)
4513 && !newline_found_p)
4515 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4516 set_iterator_to_next (it, 0);
4521 it->selective = old_selective;
4522 return newline_found_p;
4526 /* Set IT's current position to the previous visible line start. Skip
4527 invisible text that is so either due to text properties or due to
4528 selective display. Caution: this does not change IT->current_x and
4529 IT->hpos. */
4531 static void
4532 back_to_previous_visible_line_start (it)
4533 struct it *it;
4535 int visible_p = 0;
4537 /* Go back one newline if not on BEGV already. */
4538 if (IT_CHARPOS (*it) > BEGV)
4539 back_to_previous_line_start (it);
4541 /* Move over lines that are invisible because of selective display
4542 or text properties. */
4543 while (IT_CHARPOS (*it) > BEGV
4544 && !visible_p)
4546 visible_p = 1;
4548 /* If selective > 0, then lines indented more than that values
4549 are invisible. */
4550 if (it->selective > 0
4551 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4552 (double) it->selective)) /* iftc */
4553 visible_p = 0;
4554 else
4556 Lisp_Object prop;
4558 /* Check the newline before point for invisibility. */
4559 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4560 Qinvisible, it->window);
4561 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4562 visible_p = 0;
4565 if (visible_p)
4567 struct it it2 = *it;
4569 if (handle_display_prop (&it2) == HANDLED_RETURN)
4570 visible_p = 0;
4573 /* Back one more newline if the current one is invisible. */
4574 if (!visible_p)
4575 back_to_previous_line_start (it);
4578 xassert (IT_CHARPOS (*it) >= BEGV);
4579 xassert (IT_CHARPOS (*it) == BEGV
4580 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4581 CHECK_IT (it);
4585 /* Reseat iterator IT at the previous visible line start. Skip
4586 invisible text that is so either due to text properties or due to
4587 selective display. At the end, update IT's overlay information,
4588 face information etc. */
4590 static void
4591 reseat_at_previous_visible_line_start (it)
4592 struct it *it;
4594 back_to_previous_visible_line_start (it);
4595 reseat (it, it->current.pos, 1);
4596 CHECK_IT (it);
4600 /* Reseat iterator IT on the next visible line start in the current
4601 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4602 preceding the line start. Skip over invisible text that is so
4603 because of selective display. Compute faces, overlays etc at the
4604 new position. Note that this function does not skip over text that
4605 is invisible because of text properties. */
4607 static void
4608 reseat_at_next_visible_line_start (it, on_newline_p)
4609 struct it *it;
4610 int on_newline_p;
4612 int newline_found_p, skipped_p = 0;
4614 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4616 /* Skip over lines that are invisible because they are indented
4617 more than the value of IT->selective. */
4618 if (it->selective > 0)
4619 while (IT_CHARPOS (*it) < ZV
4620 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4621 (double) it->selective)) /* iftc */
4623 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4624 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4627 /* Position on the newline if that's what's requested. */
4628 if (on_newline_p && newline_found_p)
4630 if (STRINGP (it->string))
4632 if (IT_STRING_CHARPOS (*it) > 0)
4634 --IT_STRING_CHARPOS (*it);
4635 --IT_STRING_BYTEPOS (*it);
4638 else if (IT_CHARPOS (*it) > BEGV)
4640 --IT_CHARPOS (*it);
4641 --IT_BYTEPOS (*it);
4642 reseat (it, it->current.pos, 0);
4645 else if (skipped_p)
4646 reseat (it, it->current.pos, 0);
4648 CHECK_IT (it);
4653 /***********************************************************************
4654 Changing an iterator's position
4655 ***********************************************************************/
4657 /* Change IT's current position to POS in current_buffer. If FORCE_P
4658 is non-zero, always check for text properties at the new position.
4659 Otherwise, text properties are only looked up if POS >=
4660 IT->check_charpos of a property. */
4662 static void
4663 reseat (it, pos, force_p)
4664 struct it *it;
4665 struct text_pos pos;
4666 int force_p;
4668 int original_pos = IT_CHARPOS (*it);
4670 reseat_1 (it, pos, 0);
4672 /* Determine where to check text properties. Avoid doing it
4673 where possible because text property lookup is very expensive. */
4674 if (force_p
4675 || CHARPOS (pos) > it->stop_charpos
4676 || CHARPOS (pos) < original_pos)
4677 handle_stop (it);
4679 CHECK_IT (it);
4683 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4684 IT->stop_pos to POS, also. */
4686 static void
4687 reseat_1 (it, pos, set_stop_p)
4688 struct it *it;
4689 struct text_pos pos;
4690 int set_stop_p;
4692 /* Don't call this function when scanning a C string. */
4693 xassert (it->s == NULL);
4695 /* POS must be a reasonable value. */
4696 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4698 it->current.pos = it->position = pos;
4699 XSETBUFFER (it->object, current_buffer);
4700 it->end_charpos = ZV;
4701 it->dpvec = NULL;
4702 it->current.dpvec_index = -1;
4703 it->current.overlay_string_index = -1;
4704 IT_STRING_CHARPOS (*it) = -1;
4705 IT_STRING_BYTEPOS (*it) = -1;
4706 it->string = Qnil;
4707 it->method = next_element_from_buffer;
4708 /* RMS: I added this to fix a bug in move_it_vertically_backward
4709 where it->area continued to relate to the starting point
4710 for the backward motion. Bug report from
4711 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4712 However, I am not sure whether reseat still does the right thing
4713 in general after this change. */
4714 it->area = TEXT_AREA;
4715 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4716 it->sp = 0;
4717 it->face_before_selective_p = 0;
4719 if (set_stop_p)
4720 it->stop_charpos = CHARPOS (pos);
4724 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4725 If S is non-null, it is a C string to iterate over. Otherwise,
4726 STRING gives a Lisp string to iterate over.
4728 If PRECISION > 0, don't return more then PRECISION number of
4729 characters from the string.
4731 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4732 characters have been returned. FIELD_WIDTH < 0 means an infinite
4733 field width.
4735 MULTIBYTE = 0 means disable processing of multibyte characters,
4736 MULTIBYTE > 0 means enable it,
4737 MULTIBYTE < 0 means use IT->multibyte_p.
4739 IT must be initialized via a prior call to init_iterator before
4740 calling this function. */
4742 static void
4743 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4744 struct it *it;
4745 unsigned char *s;
4746 Lisp_Object string;
4747 int charpos;
4748 int precision, field_width, multibyte;
4750 /* No region in strings. */
4751 it->region_beg_charpos = it->region_end_charpos = -1;
4753 /* No text property checks performed by default, but see below. */
4754 it->stop_charpos = -1;
4756 /* Set iterator position and end position. */
4757 bzero (&it->current, sizeof it->current);
4758 it->current.overlay_string_index = -1;
4759 it->current.dpvec_index = -1;
4760 xassert (charpos >= 0);
4762 /* If STRING is specified, use its multibyteness, otherwise use the
4763 setting of MULTIBYTE, if specified. */
4764 if (multibyte >= 0)
4765 it->multibyte_p = multibyte > 0;
4767 if (s == NULL)
4769 xassert (STRINGP (string));
4770 it->string = string;
4771 it->s = NULL;
4772 it->end_charpos = it->string_nchars = SCHARS (string);
4773 it->method = next_element_from_string;
4774 it->current.string_pos = string_pos (charpos, string);
4776 else
4778 it->s = s;
4779 it->string = Qnil;
4781 /* Note that we use IT->current.pos, not it->current.string_pos,
4782 for displaying C strings. */
4783 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4784 if (it->multibyte_p)
4786 it->current.pos = c_string_pos (charpos, s, 1);
4787 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4789 else
4791 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4792 it->end_charpos = it->string_nchars = strlen (s);
4795 it->method = next_element_from_c_string;
4798 /* PRECISION > 0 means don't return more than PRECISION characters
4799 from the string. */
4800 if (precision > 0 && it->end_charpos - charpos > precision)
4801 it->end_charpos = it->string_nchars = charpos + precision;
4803 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4804 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4805 FIELD_WIDTH < 0 means infinite field width. This is useful for
4806 padding with `-' at the end of a mode line. */
4807 if (field_width < 0)
4808 field_width = INFINITY;
4809 if (field_width > it->end_charpos - charpos)
4810 it->end_charpos = charpos + field_width;
4812 /* Use the standard display table for displaying strings. */
4813 if (DISP_TABLE_P (Vstandard_display_table))
4814 it->dp = XCHAR_TABLE (Vstandard_display_table);
4816 it->stop_charpos = charpos;
4817 CHECK_IT (it);
4822 /***********************************************************************
4823 Iteration
4824 ***********************************************************************/
4826 /* Load IT's display element fields with information about the next
4827 display element from the current position of IT. Value is zero if
4828 end of buffer (or C string) is reached. */
4831 get_next_display_element (it)
4832 struct it *it;
4834 /* Non-zero means that we found a display element. Zero means that
4835 we hit the end of what we iterate over. Performance note: the
4836 function pointer `method' used here turns out to be faster than
4837 using a sequence of if-statements. */
4838 int success_p = (*it->method) (it);
4840 if (it->what == IT_CHARACTER)
4842 /* Map via display table or translate control characters.
4843 IT->c, IT->len etc. have been set to the next character by
4844 the function call above. If we have a display table, and it
4845 contains an entry for IT->c, translate it. Don't do this if
4846 IT->c itself comes from a display table, otherwise we could
4847 end up in an infinite recursion. (An alternative could be to
4848 count the recursion depth of this function and signal an
4849 error when a certain maximum depth is reached.) Is it worth
4850 it? */
4851 if (success_p && it->dpvec == NULL)
4853 Lisp_Object dv;
4855 if (it->dp
4856 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4857 VECTORP (dv)))
4859 struct Lisp_Vector *v = XVECTOR (dv);
4861 /* Return the first character from the display table
4862 entry, if not empty. If empty, don't display the
4863 current character. */
4864 if (v->size)
4866 it->dpvec_char_len = it->len;
4867 it->dpvec = v->contents;
4868 it->dpend = v->contents + v->size;
4869 it->current.dpvec_index = 0;
4870 it->method = next_element_from_display_vector;
4871 success_p = get_next_display_element (it);
4873 else
4875 set_iterator_to_next (it, 0);
4876 success_p = get_next_display_element (it);
4880 /* Translate control characters into `\003' or `^C' form.
4881 Control characters coming from a display table entry are
4882 currently not translated because we use IT->dpvec to hold
4883 the translation. This could easily be changed but I
4884 don't believe that it is worth doing.
4886 If it->multibyte_p is nonzero, eight-bit characters and
4887 non-printable multibyte characters are also translated to
4888 octal form.
4890 If it->multibyte_p is zero, eight-bit characters that
4891 don't have corresponding multibyte char code are also
4892 translated to octal form. */
4893 else if ((it->c < ' '
4894 && (it->area != TEXT_AREA
4895 /* In mode line, treat \n, \t like other crl chars. */
4896 || (it->glyph_row && it->glyph_row->mode_line_p)
4897 || (it->c != '\n' && it->c != '\t')))
4898 || (it->multibyte_p
4899 ? ((it->c >= 127
4900 && it->len == 1)
4901 || !CHAR_PRINTABLE_P (it->c))
4902 : (it->c >= 127
4903 && (!unibyte_display_via_language_environment
4904 || it->c == unibyte_char_to_multibyte (it->c)))))
4906 /* IT->c is a control character which must be displayed
4907 either as '\003' or as `^C' where the '\\' and '^'
4908 can be defined in the display table. Fill
4909 IT->ctl_chars with glyphs for what we have to
4910 display. Then, set IT->dpvec to these glyphs. */
4911 GLYPH g;
4913 if (it->c < 128 && it->ctl_arrow_p)
4915 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4916 if (it->dp
4917 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4918 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4919 g = XINT (DISP_CTRL_GLYPH (it->dp));
4920 else
4921 g = FAST_MAKE_GLYPH ('^', 0);
4922 XSETINT (it->ctl_chars[0], g);
4924 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4925 XSETINT (it->ctl_chars[1], g);
4927 /* Set up IT->dpvec and return first character from it. */
4928 it->dpvec_char_len = it->len;
4929 it->dpvec = it->ctl_chars;
4930 it->dpend = it->dpvec + 2;
4931 it->current.dpvec_index = 0;
4932 it->method = next_element_from_display_vector;
4933 get_next_display_element (it);
4935 else
4937 unsigned char str[MAX_MULTIBYTE_LENGTH];
4938 int len;
4939 int i;
4940 GLYPH escape_glyph;
4942 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4943 if (it->dp
4944 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4945 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4946 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4947 else
4948 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4950 if (SINGLE_BYTE_CHAR_P (it->c))
4951 str[0] = it->c, len = 1;
4952 else
4954 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4955 if (len < 0)
4957 /* It's an invalid character, which
4958 shouldn't happen actually, but due to
4959 bugs it may happen. Let's print the char
4960 as is, there's not much meaningful we can
4961 do with it. */
4962 str[0] = it->c;
4963 str[1] = it->c >> 8;
4964 str[2] = it->c >> 16;
4965 str[3] = it->c >> 24;
4966 len = 4;
4970 for (i = 0; i < len; i++)
4972 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4973 /* Insert three more glyphs into IT->ctl_chars for
4974 the octal display of the character. */
4975 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4976 XSETINT (it->ctl_chars[i * 4 + 1], g);
4977 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4978 XSETINT (it->ctl_chars[i * 4 + 2], g);
4979 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4980 XSETINT (it->ctl_chars[i * 4 + 3], g);
4983 /* Set up IT->dpvec and return the first character
4984 from it. */
4985 it->dpvec_char_len = it->len;
4986 it->dpvec = it->ctl_chars;
4987 it->dpend = it->dpvec + len * 4;
4988 it->current.dpvec_index = 0;
4989 it->method = next_element_from_display_vector;
4990 get_next_display_element (it);
4995 /* Adjust face id for a multibyte character. There are no
4996 multibyte character in unibyte text. */
4997 if (it->multibyte_p
4998 && success_p
4999 && FRAME_WINDOW_P (it->f))
5001 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5002 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5006 /* Is this character the last one of a run of characters with
5007 box? If yes, set IT->end_of_box_run_p to 1. */
5008 if (it->face_box_p
5009 && it->s == NULL)
5011 int face_id;
5012 struct face *face;
5014 it->end_of_box_run_p
5015 = ((face_id = face_after_it_pos (it),
5016 face_id != it->face_id)
5017 && (face = FACE_FROM_ID (it->f, face_id),
5018 face->box == FACE_NO_BOX));
5021 /* Value is 0 if end of buffer or string reached. */
5022 return success_p;
5026 /* Move IT to the next display element.
5028 RESEAT_P non-zero means if called on a newline in buffer text,
5029 skip to the next visible line start.
5031 Functions get_next_display_element and set_iterator_to_next are
5032 separate because I find this arrangement easier to handle than a
5033 get_next_display_element function that also increments IT's
5034 position. The way it is we can first look at an iterator's current
5035 display element, decide whether it fits on a line, and if it does,
5036 increment the iterator position. The other way around we probably
5037 would either need a flag indicating whether the iterator has to be
5038 incremented the next time, or we would have to implement a
5039 decrement position function which would not be easy to write. */
5041 void
5042 set_iterator_to_next (it, reseat_p)
5043 struct it *it;
5044 int reseat_p;
5046 /* Reset flags indicating start and end of a sequence of characters
5047 with box. Reset them at the start of this function because
5048 moving the iterator to a new position might set them. */
5049 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5051 if (it->method == next_element_from_buffer)
5053 /* The current display element of IT is a character from
5054 current_buffer. Advance in the buffer, and maybe skip over
5055 invisible lines that are so because of selective display. */
5056 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5057 reseat_at_next_visible_line_start (it, 0);
5058 else
5060 xassert (it->len != 0);
5061 IT_BYTEPOS (*it) += it->len;
5062 IT_CHARPOS (*it) += 1;
5063 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5066 else if (it->method == next_element_from_composition)
5068 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5069 if (STRINGP (it->string))
5071 IT_STRING_BYTEPOS (*it) += it->len;
5072 IT_STRING_CHARPOS (*it) += it->cmp_len;
5073 it->method = next_element_from_string;
5074 goto consider_string_end;
5076 else
5078 IT_BYTEPOS (*it) += it->len;
5079 IT_CHARPOS (*it) += it->cmp_len;
5080 it->method = next_element_from_buffer;
5083 else if (it->method == next_element_from_c_string)
5085 /* Current display element of IT is from a C string. */
5086 IT_BYTEPOS (*it) += it->len;
5087 IT_CHARPOS (*it) += 1;
5089 else if (it->method == next_element_from_display_vector)
5091 /* Current display element of IT is from a display table entry.
5092 Advance in the display table definition. Reset it to null if
5093 end reached, and continue with characters from buffers/
5094 strings. */
5095 ++it->current.dpvec_index;
5097 /* Restore face of the iterator to what they were before the
5098 display vector entry (these entries may contain faces). */
5099 it->face_id = it->saved_face_id;
5101 if (it->dpvec + it->current.dpvec_index == it->dpend)
5103 if (it->s)
5104 it->method = next_element_from_c_string;
5105 else if (STRINGP (it->string))
5106 it->method = next_element_from_string;
5107 else
5108 it->method = next_element_from_buffer;
5110 it->dpvec = NULL;
5111 it->current.dpvec_index = -1;
5113 /* Skip over characters which were displayed via IT->dpvec. */
5114 if (it->dpvec_char_len < 0)
5115 reseat_at_next_visible_line_start (it, 1);
5116 else if (it->dpvec_char_len > 0)
5118 it->len = it->dpvec_char_len;
5119 set_iterator_to_next (it, reseat_p);
5123 else if (it->method == next_element_from_string)
5125 /* Current display element is a character from a Lisp string. */
5126 xassert (it->s == NULL && STRINGP (it->string));
5127 IT_STRING_BYTEPOS (*it) += it->len;
5128 IT_STRING_CHARPOS (*it) += 1;
5130 consider_string_end:
5132 if (it->current.overlay_string_index >= 0)
5134 /* IT->string is an overlay string. Advance to the
5135 next, if there is one. */
5136 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5137 next_overlay_string (it);
5139 else
5141 /* IT->string is not an overlay string. If we reached
5142 its end, and there is something on IT->stack, proceed
5143 with what is on the stack. This can be either another
5144 string, this time an overlay string, or a buffer. */
5145 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5146 && it->sp > 0)
5148 pop_it (it);
5149 if (!STRINGP (it->string))
5150 it->method = next_element_from_buffer;
5151 else
5152 goto consider_string_end;
5156 else if (it->method == next_element_from_image
5157 || it->method == next_element_from_stretch)
5159 /* The position etc with which we have to proceed are on
5160 the stack. The position may be at the end of a string,
5161 if the `display' property takes up the whole string. */
5162 pop_it (it);
5163 it->image_id = 0;
5164 if (STRINGP (it->string))
5166 it->method = next_element_from_string;
5167 goto consider_string_end;
5169 else
5170 it->method = next_element_from_buffer;
5172 else
5173 /* There are no other methods defined, so this should be a bug. */
5174 abort ();
5176 xassert (it->method != next_element_from_string
5177 || (STRINGP (it->string)
5178 && IT_STRING_CHARPOS (*it) >= 0));
5182 /* Load IT's display element fields with information about the next
5183 display element which comes from a display table entry or from the
5184 result of translating a control character to one of the forms `^C'
5185 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5187 static int
5188 next_element_from_display_vector (it)
5189 struct it *it;
5191 /* Precondition. */
5192 xassert (it->dpvec && it->current.dpvec_index >= 0);
5194 /* Remember the current face id in case glyphs specify faces.
5195 IT's face is restored in set_iterator_to_next. */
5196 it->saved_face_id = it->face_id;
5198 if (INTEGERP (*it->dpvec)
5199 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5201 int lface_id;
5202 GLYPH g;
5204 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5205 it->c = FAST_GLYPH_CHAR (g);
5206 it->len = CHAR_BYTES (it->c);
5208 /* The entry may contain a face id to use. Such a face id is
5209 the id of a Lisp face, not a realized face. A face id of
5210 zero means no face is specified. */
5211 lface_id = FAST_GLYPH_FACE (g);
5212 if (lface_id)
5214 /* The function returns -1 if lface_id is invalid. */
5215 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5216 if (face_id >= 0)
5217 it->face_id = face_id;
5220 else
5221 /* Display table entry is invalid. Return a space. */
5222 it->c = ' ', it->len = 1;
5224 /* Don't change position and object of the iterator here. They are
5225 still the values of the character that had this display table
5226 entry or was translated, and that's what we want. */
5227 it->what = IT_CHARACTER;
5228 return 1;
5232 /* Load IT with the next display element from Lisp string IT->string.
5233 IT->current.string_pos is the current position within the string.
5234 If IT->current.overlay_string_index >= 0, the Lisp string is an
5235 overlay string. */
5237 static int
5238 next_element_from_string (it)
5239 struct it *it;
5241 struct text_pos position;
5243 xassert (STRINGP (it->string));
5244 xassert (IT_STRING_CHARPOS (*it) >= 0);
5245 position = it->current.string_pos;
5247 /* Time to check for invisible text? */
5248 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5249 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5251 handle_stop (it);
5253 /* Since a handler may have changed IT->method, we must
5254 recurse here. */
5255 return get_next_display_element (it);
5258 if (it->current.overlay_string_index >= 0)
5260 /* Get the next character from an overlay string. In overlay
5261 strings, There is no field width or padding with spaces to
5262 do. */
5263 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5265 it->what = IT_EOB;
5266 return 0;
5268 else if (STRING_MULTIBYTE (it->string))
5270 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5271 const unsigned char *s = (SDATA (it->string)
5272 + IT_STRING_BYTEPOS (*it));
5273 it->c = string_char_and_length (s, remaining, &it->len);
5275 else
5277 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5278 it->len = 1;
5281 else
5283 /* Get the next character from a Lisp string that is not an
5284 overlay string. Such strings come from the mode line, for
5285 example. We may have to pad with spaces, or truncate the
5286 string. See also next_element_from_c_string. */
5287 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5289 it->what = IT_EOB;
5290 return 0;
5292 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5294 /* Pad with spaces. */
5295 it->c = ' ', it->len = 1;
5296 CHARPOS (position) = BYTEPOS (position) = -1;
5298 else if (STRING_MULTIBYTE (it->string))
5300 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5301 const unsigned char *s = (SDATA (it->string)
5302 + IT_STRING_BYTEPOS (*it));
5303 it->c = string_char_and_length (s, maxlen, &it->len);
5305 else
5307 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5308 it->len = 1;
5312 /* Record what we have and where it came from. Note that we store a
5313 buffer position in IT->position although it could arguably be a
5314 string position. */
5315 it->what = IT_CHARACTER;
5316 it->object = it->string;
5317 it->position = position;
5318 return 1;
5322 /* Load IT with next display element from C string IT->s.
5323 IT->string_nchars is the maximum number of characters to return
5324 from the string. IT->end_charpos may be greater than
5325 IT->string_nchars when this function is called, in which case we
5326 may have to return padding spaces. Value is zero if end of string
5327 reached, including padding spaces. */
5329 static int
5330 next_element_from_c_string (it)
5331 struct it *it;
5333 int success_p = 1;
5335 xassert (it->s);
5336 it->what = IT_CHARACTER;
5337 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5338 it->object = Qnil;
5340 /* IT's position can be greater IT->string_nchars in case a field
5341 width or precision has been specified when the iterator was
5342 initialized. */
5343 if (IT_CHARPOS (*it) >= it->end_charpos)
5345 /* End of the game. */
5346 it->what = IT_EOB;
5347 success_p = 0;
5349 else if (IT_CHARPOS (*it) >= it->string_nchars)
5351 /* Pad with spaces. */
5352 it->c = ' ', it->len = 1;
5353 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5355 else if (it->multibyte_p)
5357 /* Implementation note: The calls to strlen apparently aren't a
5358 performance problem because there is no noticeable performance
5359 difference between Emacs running in unibyte or multibyte mode. */
5360 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5361 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5362 maxlen, &it->len);
5364 else
5365 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5367 return success_p;
5371 /* Set up IT to return characters from an ellipsis, if appropriate.
5372 The definition of the ellipsis glyphs may come from a display table
5373 entry. This function Fills IT with the first glyph from the
5374 ellipsis if an ellipsis is to be displayed. */
5376 static int
5377 next_element_from_ellipsis (it)
5378 struct it *it;
5380 if (it->selective_display_ellipsis_p)
5382 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5384 /* Use the display table definition for `...'. Invalid glyphs
5385 will be handled by the method returning elements from dpvec. */
5386 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5387 it->dpvec_char_len = it->len;
5388 it->dpvec = v->contents;
5389 it->dpend = v->contents + v->size;
5390 it->current.dpvec_index = 0;
5391 it->method = next_element_from_display_vector;
5393 else
5395 /* Use default `...' which is stored in default_invis_vector. */
5396 it->dpvec_char_len = it->len;
5397 it->dpvec = default_invis_vector;
5398 it->dpend = default_invis_vector + 3;
5399 it->current.dpvec_index = 0;
5400 it->method = next_element_from_display_vector;
5403 else
5405 /* The face at the current position may be different from the
5406 face we find after the invisible text. Remember what it
5407 was in IT->saved_face_id, and signal that it's there by
5408 setting face_before_selective_p. */
5409 it->saved_face_id = it->face_id;
5410 it->method = next_element_from_buffer;
5411 reseat_at_next_visible_line_start (it, 1);
5412 it->face_before_selective_p = 1;
5415 return get_next_display_element (it);
5419 /* Deliver an image display element. The iterator IT is already
5420 filled with image information (done in handle_display_prop). Value
5421 is always 1. */
5424 static int
5425 next_element_from_image (it)
5426 struct it *it;
5428 it->what = IT_IMAGE;
5429 return 1;
5433 /* Fill iterator IT with next display element from a stretch glyph
5434 property. IT->object is the value of the text property. Value is
5435 always 1. */
5437 static int
5438 next_element_from_stretch (it)
5439 struct it *it;
5441 it->what = IT_STRETCH;
5442 return 1;
5446 /* Load IT with the next display element from current_buffer. Value
5447 is zero if end of buffer reached. IT->stop_charpos is the next
5448 position at which to stop and check for text properties or buffer
5449 end. */
5451 static int
5452 next_element_from_buffer (it)
5453 struct it *it;
5455 int success_p = 1;
5457 /* Check this assumption, otherwise, we would never enter the
5458 if-statement, below. */
5459 xassert (IT_CHARPOS (*it) >= BEGV
5460 && IT_CHARPOS (*it) <= it->stop_charpos);
5462 if (IT_CHARPOS (*it) >= it->stop_charpos)
5464 if (IT_CHARPOS (*it) >= it->end_charpos)
5466 int overlay_strings_follow_p;
5468 /* End of the game, except when overlay strings follow that
5469 haven't been returned yet. */
5470 if (it->overlay_strings_at_end_processed_p)
5471 overlay_strings_follow_p = 0;
5472 else
5474 it->overlay_strings_at_end_processed_p = 1;
5475 overlay_strings_follow_p = get_overlay_strings (it, 0);
5478 if (overlay_strings_follow_p)
5479 success_p = get_next_display_element (it);
5480 else
5482 it->what = IT_EOB;
5483 it->position = it->current.pos;
5484 success_p = 0;
5487 else
5489 handle_stop (it);
5490 return get_next_display_element (it);
5493 else
5495 /* No face changes, overlays etc. in sight, so just return a
5496 character from current_buffer. */
5497 unsigned char *p;
5499 /* Maybe run the redisplay end trigger hook. Performance note:
5500 This doesn't seem to cost measurable time. */
5501 if (it->redisplay_end_trigger_charpos
5502 && it->glyph_row
5503 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5504 run_redisplay_end_trigger_hook (it);
5506 /* Get the next character, maybe multibyte. */
5507 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5508 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5510 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5511 - IT_BYTEPOS (*it));
5512 it->c = string_char_and_length (p, maxlen, &it->len);
5514 else
5515 it->c = *p, it->len = 1;
5517 /* Record what we have and where it came from. */
5518 it->what = IT_CHARACTER;;
5519 it->object = it->w->buffer;
5520 it->position = it->current.pos;
5522 /* Normally we return the character found above, except when we
5523 really want to return an ellipsis for selective display. */
5524 if (it->selective)
5526 if (it->c == '\n')
5528 /* A value of selective > 0 means hide lines indented more
5529 than that number of columns. */
5530 if (it->selective > 0
5531 && IT_CHARPOS (*it) + 1 < ZV
5532 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5533 IT_BYTEPOS (*it) + 1,
5534 (double) it->selective)) /* iftc */
5536 success_p = next_element_from_ellipsis (it);
5537 it->dpvec_char_len = -1;
5540 else if (it->c == '\r' && it->selective == -1)
5542 /* A value of selective == -1 means that everything from the
5543 CR to the end of the line is invisible, with maybe an
5544 ellipsis displayed for it. */
5545 success_p = next_element_from_ellipsis (it);
5546 it->dpvec_char_len = -1;
5551 /* Value is zero if end of buffer reached. */
5552 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5553 return success_p;
5557 /* Run the redisplay end trigger hook for IT. */
5559 static void
5560 run_redisplay_end_trigger_hook (it)
5561 struct it *it;
5563 Lisp_Object args[3];
5565 /* IT->glyph_row should be non-null, i.e. we should be actually
5566 displaying something, or otherwise we should not run the hook. */
5567 xassert (it->glyph_row);
5569 /* Set up hook arguments. */
5570 args[0] = Qredisplay_end_trigger_functions;
5571 args[1] = it->window;
5572 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5573 it->redisplay_end_trigger_charpos = 0;
5575 /* Since we are *trying* to run these functions, don't try to run
5576 them again, even if they get an error. */
5577 it->w->redisplay_end_trigger = Qnil;
5578 Frun_hook_with_args (3, args);
5580 /* Notice if it changed the face of the character we are on. */
5581 handle_face_prop (it);
5585 /* Deliver a composition display element. The iterator IT is already
5586 filled with composition information (done in
5587 handle_composition_prop). Value is always 1. */
5589 static int
5590 next_element_from_composition (it)
5591 struct it *it;
5593 it->what = IT_COMPOSITION;
5594 it->position = (STRINGP (it->string)
5595 ? it->current.string_pos
5596 : it->current.pos);
5597 return 1;
5602 /***********************************************************************
5603 Moving an iterator without producing glyphs
5604 ***********************************************************************/
5606 /* Move iterator IT to a specified buffer or X position within one
5607 line on the display without producing glyphs.
5609 OP should be a bit mask including some or all of these bits:
5610 MOVE_TO_X: Stop on reaching x-position TO_X.
5611 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5612 Regardless of OP's value, stop in reaching the end of the display line.
5614 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5615 This means, in particular, that TO_X includes window's horizontal
5616 scroll amount.
5618 The return value has several possible values that
5619 say what condition caused the scan to stop:
5621 MOVE_POS_MATCH_OR_ZV
5622 - when TO_POS or ZV was reached.
5624 MOVE_X_REACHED
5625 -when TO_X was reached before TO_POS or ZV were reached.
5627 MOVE_LINE_CONTINUED
5628 - when we reached the end of the display area and the line must
5629 be continued.
5631 MOVE_LINE_TRUNCATED
5632 - when we reached the end of the display area and the line is
5633 truncated.
5635 MOVE_NEWLINE_OR_CR
5636 - when we stopped at a line end, i.e. a newline or a CR and selective
5637 display is on. */
5639 static enum move_it_result
5640 move_it_in_display_line_to (it, to_charpos, to_x, op)
5641 struct it *it;
5642 int to_charpos, to_x, op;
5644 enum move_it_result result = MOVE_UNDEFINED;
5645 struct glyph_row *saved_glyph_row;
5647 /* Don't produce glyphs in produce_glyphs. */
5648 saved_glyph_row = it->glyph_row;
5649 it->glyph_row = NULL;
5651 #define BUFFER_POS_REACHED_P() \
5652 ((op & MOVE_TO_POS) != 0 \
5653 && BUFFERP (it->object) \
5654 && IT_CHARPOS (*it) >= to_charpos)
5656 while (1)
5658 int x, i, ascent = 0, descent = 0;
5660 /* Stop when ZV reached.
5661 We used to stop here when TO_CHARPOS reached as well, but that is
5662 too soon if this glyph does not fit on this line. So we handle it
5663 explicitly below. */
5664 if (!get_next_display_element (it)
5665 || (it->truncate_lines_p
5666 && BUFFER_POS_REACHED_P ()))
5668 result = MOVE_POS_MATCH_OR_ZV;
5669 break;
5672 /* The call to produce_glyphs will get the metrics of the
5673 display element IT is loaded with. We record in x the
5674 x-position before this display element in case it does not
5675 fit on the line. */
5676 x = it->current_x;
5678 /* Remember the line height so far in case the next element doesn't
5679 fit on the line. */
5680 if (!it->truncate_lines_p)
5682 ascent = it->max_ascent;
5683 descent = it->max_descent;
5686 PRODUCE_GLYPHS (it);
5688 if (it->area != TEXT_AREA)
5690 set_iterator_to_next (it, 1);
5691 continue;
5694 /* The number of glyphs we get back in IT->nglyphs will normally
5695 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5696 character on a terminal frame, or (iii) a line end. For the
5697 second case, IT->nglyphs - 1 padding glyphs will be present
5698 (on X frames, there is only one glyph produced for a
5699 composite character.
5701 The behavior implemented below means, for continuation lines,
5702 that as many spaces of a TAB as fit on the current line are
5703 displayed there. For terminal frames, as many glyphs of a
5704 multi-glyph character are displayed in the current line, too.
5705 This is what the old redisplay code did, and we keep it that
5706 way. Under X, the whole shape of a complex character must
5707 fit on the line or it will be completely displayed in the
5708 next line.
5710 Note that both for tabs and padding glyphs, all glyphs have
5711 the same width. */
5712 if (it->nglyphs)
5714 /* More than one glyph or glyph doesn't fit on line. All
5715 glyphs have the same width. */
5716 int single_glyph_width = it->pixel_width / it->nglyphs;
5717 int new_x;
5719 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5721 new_x = x + single_glyph_width;
5723 /* We want to leave anything reaching TO_X to the caller. */
5724 if ((op & MOVE_TO_X) && new_x > to_x)
5726 if (BUFFER_POS_REACHED_P ())
5727 goto buffer_pos_reached;
5728 it->current_x = x;
5729 result = MOVE_X_REACHED;
5730 break;
5732 else if (/* Lines are continued. */
5733 !it->truncate_lines_p
5734 && (/* And glyph doesn't fit on the line. */
5735 new_x > it->last_visible_x
5736 /* Or it fits exactly and we're on a window
5737 system frame. */
5738 || (new_x == it->last_visible_x
5739 && FRAME_WINDOW_P (it->f))))
5741 if (/* IT->hpos == 0 means the very first glyph
5742 doesn't fit on the line, e.g. a wide image. */
5743 it->hpos == 0
5744 || (new_x == it->last_visible_x
5745 && FRAME_WINDOW_P (it->f)))
5747 ++it->hpos;
5748 it->current_x = new_x;
5749 if (i == it->nglyphs - 1)
5751 set_iterator_to_next (it, 1);
5752 #ifdef HAVE_WINDOW_SYSTEM
5753 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5755 if (!get_next_display_element (it))
5757 result = MOVE_POS_MATCH_OR_ZV;
5758 break;
5760 if (BUFFER_POS_REACHED_P ())
5762 if (ITERATOR_AT_END_OF_LINE_P (it))
5763 result = MOVE_POS_MATCH_OR_ZV;
5764 else
5765 result = MOVE_LINE_CONTINUED;
5766 break;
5768 if (ITERATOR_AT_END_OF_LINE_P (it))
5770 result = MOVE_NEWLINE_OR_CR;
5771 break;
5774 #endif /* HAVE_WINDOW_SYSTEM */
5777 else
5779 it->current_x = x;
5780 it->max_ascent = ascent;
5781 it->max_descent = descent;
5784 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5785 IT_CHARPOS (*it)));
5786 result = MOVE_LINE_CONTINUED;
5787 break;
5789 else if (BUFFER_POS_REACHED_P ())
5790 goto buffer_pos_reached;
5791 else if (new_x > it->first_visible_x)
5793 /* Glyph is visible. Increment number of glyphs that
5794 would be displayed. */
5795 ++it->hpos;
5797 else
5799 /* Glyph is completely off the left margin of the display
5800 area. Nothing to do. */
5804 if (result != MOVE_UNDEFINED)
5805 break;
5807 else if (BUFFER_POS_REACHED_P ())
5809 buffer_pos_reached:
5810 it->current_x = x;
5811 it->max_ascent = ascent;
5812 it->max_descent = descent;
5813 result = MOVE_POS_MATCH_OR_ZV;
5814 break;
5816 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5818 /* Stop when TO_X specified and reached. This check is
5819 necessary here because of lines consisting of a line end,
5820 only. The line end will not produce any glyphs and we
5821 would never get MOVE_X_REACHED. */
5822 xassert (it->nglyphs == 0);
5823 result = MOVE_X_REACHED;
5824 break;
5827 /* Is this a line end? If yes, we're done. */
5828 if (ITERATOR_AT_END_OF_LINE_P (it))
5830 result = MOVE_NEWLINE_OR_CR;
5831 break;
5834 /* The current display element has been consumed. Advance
5835 to the next. */
5836 set_iterator_to_next (it, 1);
5838 /* Stop if lines are truncated and IT's current x-position is
5839 past the right edge of the window now. */
5840 if (it->truncate_lines_p
5841 && it->current_x >= it->last_visible_x)
5843 #ifdef HAVE_WINDOW_SYSTEM
5844 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5846 if (!get_next_display_element (it)
5847 || BUFFER_POS_REACHED_P ())
5849 result = MOVE_POS_MATCH_OR_ZV;
5850 break;
5852 if (ITERATOR_AT_END_OF_LINE_P (it))
5854 result = MOVE_NEWLINE_OR_CR;
5855 break;
5858 #endif /* HAVE_WINDOW_SYSTEM */
5859 result = MOVE_LINE_TRUNCATED;
5860 break;
5864 #undef BUFFER_POS_REACHED_P
5866 /* Restore the iterator settings altered at the beginning of this
5867 function. */
5868 it->glyph_row = saved_glyph_row;
5869 return result;
5873 /* Move IT forward until it satisfies one or more of the criteria in
5874 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5876 OP is a bit-mask that specifies where to stop, and in particular,
5877 which of those four position arguments makes a difference. See the
5878 description of enum move_operation_enum.
5880 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5881 screen line, this function will set IT to the next position >
5882 TO_CHARPOS. */
5884 void
5885 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5886 struct it *it;
5887 int to_charpos, to_x, to_y, to_vpos;
5888 int op;
5890 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5891 int line_height;
5892 int reached = 0;
5894 for (;;)
5896 if (op & MOVE_TO_VPOS)
5898 /* If no TO_CHARPOS and no TO_X specified, stop at the
5899 start of the line TO_VPOS. */
5900 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5902 if (it->vpos == to_vpos)
5904 reached = 1;
5905 break;
5907 else
5908 skip = move_it_in_display_line_to (it, -1, -1, 0);
5910 else
5912 /* TO_VPOS >= 0 means stop at TO_X in the line at
5913 TO_VPOS, or at TO_POS, whichever comes first. */
5914 if (it->vpos == to_vpos)
5916 reached = 2;
5917 break;
5920 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5922 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5924 reached = 3;
5925 break;
5927 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5929 /* We have reached TO_X but not in the line we want. */
5930 skip = move_it_in_display_line_to (it, to_charpos,
5931 -1, MOVE_TO_POS);
5932 if (skip == MOVE_POS_MATCH_OR_ZV)
5934 reached = 4;
5935 break;
5940 else if (op & MOVE_TO_Y)
5942 struct it it_backup;
5944 /* TO_Y specified means stop at TO_X in the line containing
5945 TO_Y---or at TO_CHARPOS if this is reached first. The
5946 problem is that we can't really tell whether the line
5947 contains TO_Y before we have completely scanned it, and
5948 this may skip past TO_X. What we do is to first scan to
5949 TO_X.
5951 If TO_X is not specified, use a TO_X of zero. The reason
5952 is to make the outcome of this function more predictable.
5953 If we didn't use TO_X == 0, we would stop at the end of
5954 the line which is probably not what a caller would expect
5955 to happen. */
5956 skip = move_it_in_display_line_to (it, to_charpos,
5957 ((op & MOVE_TO_X)
5958 ? to_x : 0),
5959 (MOVE_TO_X
5960 | (op & MOVE_TO_POS)));
5962 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5963 if (skip == MOVE_POS_MATCH_OR_ZV)
5965 reached = 5;
5966 break;
5969 /* If TO_X was reached, we would like to know whether TO_Y
5970 is in the line. This can only be said if we know the
5971 total line height which requires us to scan the rest of
5972 the line. */
5973 if (skip == MOVE_X_REACHED)
5975 it_backup = *it;
5976 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5977 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5978 op & MOVE_TO_POS);
5979 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5982 /* Now, decide whether TO_Y is in this line. */
5983 line_height = it->max_ascent + it->max_descent;
5984 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5986 if (to_y >= it->current_y
5987 && to_y < it->current_y + line_height)
5989 if (skip == MOVE_X_REACHED)
5990 /* If TO_Y is in this line and TO_X was reached above,
5991 we scanned too far. We have to restore IT's settings
5992 to the ones before skipping. */
5993 *it = it_backup;
5994 reached = 6;
5996 else if (skip == MOVE_X_REACHED)
5998 skip = skip2;
5999 if (skip == MOVE_POS_MATCH_OR_ZV)
6000 reached = 7;
6003 if (reached)
6004 break;
6006 else
6007 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6009 switch (skip)
6011 case MOVE_POS_MATCH_OR_ZV:
6012 reached = 8;
6013 goto out;
6015 case MOVE_NEWLINE_OR_CR:
6016 set_iterator_to_next (it, 1);
6017 it->continuation_lines_width = 0;
6018 break;
6020 case MOVE_LINE_TRUNCATED:
6021 it->continuation_lines_width = 0;
6022 reseat_at_next_visible_line_start (it, 0);
6023 if ((op & MOVE_TO_POS) != 0
6024 && IT_CHARPOS (*it) > to_charpos)
6026 reached = 9;
6027 goto out;
6029 break;
6031 case MOVE_LINE_CONTINUED:
6032 it->continuation_lines_width += it->current_x;
6033 break;
6035 default:
6036 abort ();
6039 /* Reset/increment for the next run. */
6040 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6041 it->current_x = it->hpos = 0;
6042 it->current_y += it->max_ascent + it->max_descent;
6043 ++it->vpos;
6044 last_height = it->max_ascent + it->max_descent;
6045 last_max_ascent = it->max_ascent;
6046 it->max_ascent = it->max_descent = 0;
6049 out:
6051 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6055 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6057 If DY > 0, move IT backward at least that many pixels. DY = 0
6058 means move IT backward to the preceding line start or BEGV. This
6059 function may move over more than DY pixels if IT->current_y - DY
6060 ends up in the middle of a line; in this case IT->current_y will be
6061 set to the top of the line moved to. */
6063 void
6064 move_it_vertically_backward (it, dy)
6065 struct it *it;
6066 int dy;
6068 int nlines, h;
6069 struct it it2, it3;
6070 int start_pos = IT_CHARPOS (*it);
6072 xassert (dy >= 0);
6074 /* Estimate how many newlines we must move back. */
6075 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6077 /* Set the iterator's position that many lines back. */
6078 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6079 back_to_previous_visible_line_start (it);
6081 /* Reseat the iterator here. When moving backward, we don't want
6082 reseat to skip forward over invisible text, set up the iterator
6083 to deliver from overlay strings at the new position etc. So,
6084 use reseat_1 here. */
6085 reseat_1 (it, it->current.pos, 1);
6087 /* We are now surely at a line start. */
6088 it->current_x = it->hpos = 0;
6089 it->continuation_lines_width = 0;
6091 /* Move forward and see what y-distance we moved. First move to the
6092 start of the next line so that we get its height. We need this
6093 height to be able to tell whether we reached the specified
6094 y-distance. */
6095 it2 = *it;
6096 it2.max_ascent = it2.max_descent = 0;
6097 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6098 MOVE_TO_POS | MOVE_TO_VPOS);
6099 xassert (IT_CHARPOS (*it) >= BEGV);
6100 it3 = it2;
6102 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6103 xassert (IT_CHARPOS (*it) >= BEGV);
6104 /* H is the actual vertical distance from the position in *IT
6105 and the starting position. */
6106 h = it2.current_y - it->current_y;
6107 /* NLINES is the distance in number of lines. */
6108 nlines = it2.vpos - it->vpos;
6110 /* Correct IT's y and vpos position
6111 so that they are relative to the starting point. */
6112 it->vpos -= nlines;
6113 it->current_y -= h;
6115 if (dy == 0)
6117 /* DY == 0 means move to the start of the screen line. The
6118 value of nlines is > 0 if continuation lines were involved. */
6119 if (nlines > 0)
6120 move_it_by_lines (it, nlines, 1);
6121 xassert (IT_CHARPOS (*it) <= start_pos);
6123 else
6125 /* The y-position we try to reach, relative to *IT.
6126 Note that H has been subtracted in front of the if-statement. */
6127 int target_y = it->current_y + h - dy;
6128 int y0 = it3.current_y;
6129 int y1 = line_bottom_y (&it3);
6130 int line_height = y1 - y0;
6132 /* If we did not reach target_y, try to move further backward if
6133 we can. If we moved too far backward, try to move forward. */
6134 if (target_y < it->current_y
6135 /* This is heuristic. In a window that's 3 lines high, with
6136 a line height of 13 pixels each, recentering with point
6137 on the bottom line will try to move -39/2 = 19 pixels
6138 backward. Try to avoid moving into the first line. */
6139 && it->current_y - target_y > line_height / 3 * 2
6140 && IT_CHARPOS (*it) > BEGV)
6142 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6143 target_y - it->current_y));
6144 move_it_vertically (it, target_y - it->current_y);
6145 xassert (IT_CHARPOS (*it) >= BEGV);
6147 else if (target_y >= it->current_y + line_height
6148 && IT_CHARPOS (*it) < ZV)
6150 /* Should move forward by at least one line, maybe more.
6152 Note: Calling move_it_by_lines can be expensive on
6153 terminal frames, where compute_motion is used (via
6154 vmotion) to do the job, when there are very long lines
6155 and truncate-lines is nil. That's the reason for
6156 treating terminal frames specially here. */
6158 if (!FRAME_WINDOW_P (it->f))
6159 move_it_vertically (it, target_y - (it->current_y + line_height));
6160 else
6164 move_it_by_lines (it, 1, 1);
6166 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6169 xassert (IT_CHARPOS (*it) >= BEGV);
6175 /* Move IT by a specified amount of pixel lines DY. DY negative means
6176 move backwards. DY = 0 means move to start of screen line. At the
6177 end, IT will be on the start of a screen line. */
6179 void
6180 move_it_vertically (it, dy)
6181 struct it *it;
6182 int dy;
6184 if (dy <= 0)
6185 move_it_vertically_backward (it, -dy);
6186 else if (dy > 0)
6188 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6189 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6190 MOVE_TO_POS | MOVE_TO_Y);
6191 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6193 /* If buffer ends in ZV without a newline, move to the start of
6194 the line to satisfy the post-condition. */
6195 if (IT_CHARPOS (*it) == ZV
6196 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6197 move_it_by_lines (it, 0, 0);
6202 /* Move iterator IT past the end of the text line it is in. */
6204 void
6205 move_it_past_eol (it)
6206 struct it *it;
6208 enum move_it_result rc;
6210 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6211 if (rc == MOVE_NEWLINE_OR_CR)
6212 set_iterator_to_next (it, 0);
6216 #if 0 /* Currently not used. */
6218 /* Return non-zero if some text between buffer positions START_CHARPOS
6219 and END_CHARPOS is invisible. IT->window is the window for text
6220 property lookup. */
6222 static int
6223 invisible_text_between_p (it, start_charpos, end_charpos)
6224 struct it *it;
6225 int start_charpos, end_charpos;
6227 Lisp_Object prop, limit;
6228 int invisible_found_p;
6230 xassert (it != NULL && start_charpos <= end_charpos);
6232 /* Is text at START invisible? */
6233 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6234 it->window);
6235 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6236 invisible_found_p = 1;
6237 else
6239 limit = Fnext_single_char_property_change (make_number (start_charpos),
6240 Qinvisible, Qnil,
6241 make_number (end_charpos));
6242 invisible_found_p = XFASTINT (limit) < end_charpos;
6245 return invisible_found_p;
6248 #endif /* 0 */
6251 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6252 negative means move up. DVPOS == 0 means move to the start of the
6253 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6254 NEED_Y_P is zero, IT->current_y will be left unchanged.
6256 Further optimization ideas: If we would know that IT->f doesn't use
6257 a face with proportional font, we could be faster for
6258 truncate-lines nil. */
6260 void
6261 move_it_by_lines (it, dvpos, need_y_p)
6262 struct it *it;
6263 int dvpos, need_y_p;
6265 struct position pos;
6267 if (!FRAME_WINDOW_P (it->f))
6269 struct text_pos textpos;
6271 /* We can use vmotion on frames without proportional fonts. */
6272 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6273 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6274 reseat (it, textpos, 1);
6275 it->vpos += pos.vpos;
6276 it->current_y += pos.vpos;
6278 else if (dvpos == 0)
6280 /* DVPOS == 0 means move to the start of the screen line. */
6281 move_it_vertically_backward (it, 0);
6282 xassert (it->current_x == 0 && it->hpos == 0);
6284 else if (dvpos > 0)
6285 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6286 else
6288 struct it it2;
6289 int start_charpos, i;
6291 /* Start at the beginning of the screen line containing IT's
6292 position. */
6293 move_it_vertically_backward (it, 0);
6295 /* Go back -DVPOS visible lines and reseat the iterator there. */
6296 start_charpos = IT_CHARPOS (*it);
6297 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6298 back_to_previous_visible_line_start (it);
6299 reseat (it, it->current.pos, 1);
6300 it->current_x = it->hpos = 0;
6302 /* Above call may have moved too far if continuation lines
6303 are involved. Scan forward and see if it did. */
6304 it2 = *it;
6305 it2.vpos = it2.current_y = 0;
6306 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6307 it->vpos -= it2.vpos;
6308 it->current_y -= it2.current_y;
6309 it->current_x = it->hpos = 0;
6311 /* If we moved too far, move IT some lines forward. */
6312 if (it2.vpos > -dvpos)
6314 int delta = it2.vpos + dvpos;
6315 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6320 /* Return 1 if IT points into the middle of a display vector. */
6323 in_display_vector_p (it)
6324 struct it *it;
6326 return (it->method == next_element_from_display_vector
6327 && it->current.dpvec_index > 0
6328 && it->dpvec + it->current.dpvec_index != it->dpend);
6332 /***********************************************************************
6333 Messages
6334 ***********************************************************************/
6337 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6338 to *Messages*. */
6340 void
6341 add_to_log (format, arg1, arg2)
6342 char *format;
6343 Lisp_Object arg1, arg2;
6345 Lisp_Object args[3];
6346 Lisp_Object msg, fmt;
6347 char *buffer;
6348 int len;
6349 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6350 USE_SAFE_ALLOCA;
6352 /* Do nothing if called asynchronously. Inserting text into
6353 a buffer may call after-change-functions and alike and
6354 that would means running Lisp asynchronously. */
6355 if (handling_signal)
6356 return;
6358 fmt = msg = Qnil;
6359 GCPRO4 (fmt, msg, arg1, arg2);
6361 args[0] = fmt = build_string (format);
6362 args[1] = arg1;
6363 args[2] = arg2;
6364 msg = Fformat (3, args);
6366 len = SBYTES (msg) + 1;
6367 SAFE_ALLOCA (buffer, char *, len);
6368 bcopy (SDATA (msg), buffer, len);
6370 message_dolog (buffer, len - 1, 1, 0);
6371 SAFE_FREE ();
6373 UNGCPRO;
6377 /* Output a newline in the *Messages* buffer if "needs" one. */
6379 void
6380 message_log_maybe_newline ()
6382 if (message_log_need_newline)
6383 message_dolog ("", 0, 1, 0);
6387 /* Add a string M of length NBYTES to the message log, optionally
6388 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6389 nonzero, means interpret the contents of M as multibyte. This
6390 function calls low-level routines in order to bypass text property
6391 hooks, etc. which might not be safe to run. */
6393 void
6394 message_dolog (m, nbytes, nlflag, multibyte)
6395 const char *m;
6396 int nbytes, nlflag, multibyte;
6398 if (!NILP (Vmemory_full))
6399 return;
6401 if (!NILP (Vmessage_log_max))
6403 struct buffer *oldbuf;
6404 Lisp_Object oldpoint, oldbegv, oldzv;
6405 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6406 int point_at_end = 0;
6407 int zv_at_end = 0;
6408 Lisp_Object old_deactivate_mark, tem;
6409 struct gcpro gcpro1;
6411 old_deactivate_mark = Vdeactivate_mark;
6412 oldbuf = current_buffer;
6413 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6414 current_buffer->undo_list = Qt;
6416 oldpoint = message_dolog_marker1;
6417 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6418 oldbegv = message_dolog_marker2;
6419 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6420 oldzv = message_dolog_marker3;
6421 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6422 GCPRO1 (old_deactivate_mark);
6424 if (PT == Z)
6425 point_at_end = 1;
6426 if (ZV == Z)
6427 zv_at_end = 1;
6429 BEGV = BEG;
6430 BEGV_BYTE = BEG_BYTE;
6431 ZV = Z;
6432 ZV_BYTE = Z_BYTE;
6433 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6435 /* Insert the string--maybe converting multibyte to single byte
6436 or vice versa, so that all the text fits the buffer. */
6437 if (multibyte
6438 && NILP (current_buffer->enable_multibyte_characters))
6440 int i, c, char_bytes;
6441 unsigned char work[1];
6443 /* Convert a multibyte string to single-byte
6444 for the *Message* buffer. */
6445 for (i = 0; i < nbytes; i += char_bytes)
6447 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6448 work[0] = (SINGLE_BYTE_CHAR_P (c)
6450 : multibyte_char_to_unibyte (c, Qnil));
6451 insert_1_both (work, 1, 1, 1, 0, 0);
6454 else if (! multibyte
6455 && ! NILP (current_buffer->enable_multibyte_characters))
6457 int i, c, char_bytes;
6458 unsigned char *msg = (unsigned char *) m;
6459 unsigned char str[MAX_MULTIBYTE_LENGTH];
6460 /* Convert a single-byte string to multibyte
6461 for the *Message* buffer. */
6462 for (i = 0; i < nbytes; i++)
6464 c = unibyte_char_to_multibyte (msg[i]);
6465 char_bytes = CHAR_STRING (c, str);
6466 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6469 else if (nbytes)
6470 insert_1 (m, nbytes, 1, 0, 0);
6472 if (nlflag)
6474 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6475 insert_1 ("\n", 1, 1, 0, 0);
6477 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6478 this_bol = PT;
6479 this_bol_byte = PT_BYTE;
6481 /* See if this line duplicates the previous one.
6482 If so, combine duplicates. */
6483 if (this_bol > BEG)
6485 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6486 prev_bol = PT;
6487 prev_bol_byte = PT_BYTE;
6489 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6490 this_bol, this_bol_byte);
6491 if (dup)
6493 del_range_both (prev_bol, prev_bol_byte,
6494 this_bol, this_bol_byte, 0);
6495 if (dup > 1)
6497 char dupstr[40];
6498 int duplen;
6500 /* If you change this format, don't forget to also
6501 change message_log_check_duplicate. */
6502 sprintf (dupstr, " [%d times]", dup);
6503 duplen = strlen (dupstr);
6504 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6505 insert_1 (dupstr, duplen, 1, 0, 1);
6510 /* If we have more than the desired maximum number of lines
6511 in the *Messages* buffer now, delete the oldest ones.
6512 This is safe because we don't have undo in this buffer. */
6514 if (NATNUMP (Vmessage_log_max))
6516 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6517 -XFASTINT (Vmessage_log_max) - 1, 0);
6518 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6521 BEGV = XMARKER (oldbegv)->charpos;
6522 BEGV_BYTE = marker_byte_position (oldbegv);
6524 if (zv_at_end)
6526 ZV = Z;
6527 ZV_BYTE = Z_BYTE;
6529 else
6531 ZV = XMARKER (oldzv)->charpos;
6532 ZV_BYTE = marker_byte_position (oldzv);
6535 if (point_at_end)
6536 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6537 else
6538 /* We can't do Fgoto_char (oldpoint) because it will run some
6539 Lisp code. */
6540 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6541 XMARKER (oldpoint)->bytepos);
6543 UNGCPRO;
6544 unchain_marker (XMARKER (oldpoint));
6545 unchain_marker (XMARKER (oldbegv));
6546 unchain_marker (XMARKER (oldzv));
6548 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6549 set_buffer_internal (oldbuf);
6550 if (NILP (tem))
6551 windows_or_buffers_changed = old_windows_or_buffers_changed;
6552 message_log_need_newline = !nlflag;
6553 Vdeactivate_mark = old_deactivate_mark;
6558 /* We are at the end of the buffer after just having inserted a newline.
6559 (Note: We depend on the fact we won't be crossing the gap.)
6560 Check to see if the most recent message looks a lot like the previous one.
6561 Return 0 if different, 1 if the new one should just replace it, or a
6562 value N > 1 if we should also append " [N times]". */
6564 static int
6565 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6566 int prev_bol, this_bol;
6567 int prev_bol_byte, this_bol_byte;
6569 int i;
6570 int len = Z_BYTE - 1 - this_bol_byte;
6571 int seen_dots = 0;
6572 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6573 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6575 for (i = 0; i < len; i++)
6577 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6578 seen_dots = 1;
6579 if (p1[i] != p2[i])
6580 return seen_dots;
6582 p1 += len;
6583 if (*p1 == '\n')
6584 return 2;
6585 if (*p1++ == ' ' && *p1++ == '[')
6587 int n = 0;
6588 while (*p1 >= '0' && *p1 <= '9')
6589 n = n * 10 + *p1++ - '0';
6590 if (strncmp (p1, " times]\n", 8) == 0)
6591 return n+1;
6593 return 0;
6597 /* Display an echo area message M with a specified length of NBYTES
6598 bytes. The string may include null characters. If M is 0, clear
6599 out any existing message, and let the mini-buffer text show
6600 through.
6602 The buffer M must continue to exist until after the echo area gets
6603 cleared or some other message gets displayed there. This means do
6604 not pass text that is stored in a Lisp string; do not pass text in
6605 a buffer that was alloca'd. */
6607 void
6608 message2 (m, nbytes, multibyte)
6609 const char *m;
6610 int nbytes;
6611 int multibyte;
6613 /* First flush out any partial line written with print. */
6614 message_log_maybe_newline ();
6615 if (m)
6616 message_dolog (m, nbytes, 1, multibyte);
6617 message2_nolog (m, nbytes, multibyte);
6621 /* The non-logging counterpart of message2. */
6623 void
6624 message2_nolog (m, nbytes, multibyte)
6625 const char *m;
6626 int nbytes, multibyte;
6628 struct frame *sf = SELECTED_FRAME ();
6629 message_enable_multibyte = multibyte;
6631 if (noninteractive)
6633 if (noninteractive_need_newline)
6634 putc ('\n', stderr);
6635 noninteractive_need_newline = 0;
6636 if (m)
6637 fwrite (m, nbytes, 1, stderr);
6638 if (cursor_in_echo_area == 0)
6639 fprintf (stderr, "\n");
6640 fflush (stderr);
6642 /* A null message buffer means that the frame hasn't really been
6643 initialized yet. Error messages get reported properly by
6644 cmd_error, so this must be just an informative message; toss it. */
6645 else if (INTERACTIVE
6646 && sf->glyphs_initialized_p
6647 && FRAME_MESSAGE_BUF (sf))
6649 Lisp_Object mini_window;
6650 struct frame *f;
6652 /* Get the frame containing the mini-buffer
6653 that the selected frame is using. */
6654 mini_window = FRAME_MINIBUF_WINDOW (sf);
6655 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6657 FRAME_SAMPLE_VISIBILITY (f);
6658 if (FRAME_VISIBLE_P (sf)
6659 && ! FRAME_VISIBLE_P (f))
6660 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6662 if (m)
6664 set_message (m, Qnil, nbytes, multibyte);
6665 if (minibuffer_auto_raise)
6666 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6668 else
6669 clear_message (1, 1);
6671 do_pending_window_change (0);
6672 echo_area_display (1);
6673 do_pending_window_change (0);
6674 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6675 (*frame_up_to_date_hook) (f);
6680 /* Display an echo area message M with a specified length of NBYTES
6681 bytes. The string may include null characters. If M is not a
6682 string, clear out any existing message, and let the mini-buffer
6683 text show through. */
6685 void
6686 message3 (m, nbytes, multibyte)
6687 Lisp_Object m;
6688 int nbytes;
6689 int multibyte;
6691 struct gcpro gcpro1;
6693 GCPRO1 (m);
6695 /* First flush out any partial line written with print. */
6696 message_log_maybe_newline ();
6697 if (STRINGP (m))
6698 message_dolog (SDATA (m), nbytes, 1, multibyte);
6699 message3_nolog (m, nbytes, multibyte);
6701 UNGCPRO;
6705 /* The non-logging version of message3. */
6707 void
6708 message3_nolog (m, nbytes, multibyte)
6709 Lisp_Object m;
6710 int nbytes, multibyte;
6712 struct frame *sf = SELECTED_FRAME ();
6713 message_enable_multibyte = multibyte;
6715 if (noninteractive)
6717 if (noninteractive_need_newline)
6718 putc ('\n', stderr);
6719 noninteractive_need_newline = 0;
6720 if (STRINGP (m))
6721 fwrite (SDATA (m), nbytes, 1, stderr);
6722 if (cursor_in_echo_area == 0)
6723 fprintf (stderr, "\n");
6724 fflush (stderr);
6726 /* A null message buffer means that the frame hasn't really been
6727 initialized yet. Error messages get reported properly by
6728 cmd_error, so this must be just an informative message; toss it. */
6729 else if (INTERACTIVE
6730 && sf->glyphs_initialized_p
6731 && FRAME_MESSAGE_BUF (sf))
6733 Lisp_Object mini_window;
6734 Lisp_Object frame;
6735 struct frame *f;
6737 /* Get the frame containing the mini-buffer
6738 that the selected frame is using. */
6739 mini_window = FRAME_MINIBUF_WINDOW (sf);
6740 frame = XWINDOW (mini_window)->frame;
6741 f = XFRAME (frame);
6743 FRAME_SAMPLE_VISIBILITY (f);
6744 if (FRAME_VISIBLE_P (sf)
6745 && !FRAME_VISIBLE_P (f))
6746 Fmake_frame_visible (frame);
6748 if (STRINGP (m) && SCHARS (m) > 0)
6750 set_message (NULL, m, nbytes, multibyte);
6751 if (minibuffer_auto_raise)
6752 Fraise_frame (frame);
6754 else
6755 clear_message (1, 1);
6757 do_pending_window_change (0);
6758 echo_area_display (1);
6759 do_pending_window_change (0);
6760 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6761 (*frame_up_to_date_hook) (f);
6766 /* Display a null-terminated echo area message M. If M is 0, clear
6767 out any existing message, and let the mini-buffer text show through.
6769 The buffer M must continue to exist until after the echo area gets
6770 cleared or some other message gets displayed there. Do not pass
6771 text that is stored in a Lisp string. Do not pass text in a buffer
6772 that was alloca'd. */
6774 void
6775 message1 (m)
6776 char *m;
6778 message2 (m, (m ? strlen (m) : 0), 0);
6782 /* The non-logging counterpart of message1. */
6784 void
6785 message1_nolog (m)
6786 char *m;
6788 message2_nolog (m, (m ? strlen (m) : 0), 0);
6791 /* Display a message M which contains a single %s
6792 which gets replaced with STRING. */
6794 void
6795 message_with_string (m, string, log)
6796 char *m;
6797 Lisp_Object string;
6798 int log;
6800 CHECK_STRING (string);
6802 if (noninteractive)
6804 if (m)
6806 if (noninteractive_need_newline)
6807 putc ('\n', stderr);
6808 noninteractive_need_newline = 0;
6809 fprintf (stderr, m, SDATA (string));
6810 if (cursor_in_echo_area == 0)
6811 fprintf (stderr, "\n");
6812 fflush (stderr);
6815 else if (INTERACTIVE)
6817 /* The frame whose minibuffer we're going to display the message on.
6818 It may be larger than the selected frame, so we need
6819 to use its buffer, not the selected frame's buffer. */
6820 Lisp_Object mini_window;
6821 struct frame *f, *sf = SELECTED_FRAME ();
6823 /* Get the frame containing the minibuffer
6824 that the selected frame is using. */
6825 mini_window = FRAME_MINIBUF_WINDOW (sf);
6826 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6828 /* A null message buffer means that the frame hasn't really been
6829 initialized yet. Error messages get reported properly by
6830 cmd_error, so this must be just an informative message; toss it. */
6831 if (FRAME_MESSAGE_BUF (f))
6833 Lisp_Object args[2], message;
6834 struct gcpro gcpro1, gcpro2;
6836 args[0] = build_string (m);
6837 args[1] = message = string;
6838 GCPRO2 (args[0], message);
6839 gcpro1.nvars = 2;
6841 message = Fformat (2, args);
6843 if (log)
6844 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6845 else
6846 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6848 UNGCPRO;
6850 /* Print should start at the beginning of the message
6851 buffer next time. */
6852 message_buf_print = 0;
6858 /* Dump an informative message to the minibuf. If M is 0, clear out
6859 any existing message, and let the mini-buffer text show through. */
6861 /* VARARGS 1 */
6862 void
6863 message (m, a1, a2, a3)
6864 char *m;
6865 EMACS_INT a1, a2, a3;
6867 if (noninteractive)
6869 if (m)
6871 if (noninteractive_need_newline)
6872 putc ('\n', stderr);
6873 noninteractive_need_newline = 0;
6874 fprintf (stderr, m, a1, a2, a3);
6875 if (cursor_in_echo_area == 0)
6876 fprintf (stderr, "\n");
6877 fflush (stderr);
6880 else if (INTERACTIVE)
6882 /* The frame whose mini-buffer we're going to display the message
6883 on. It may be larger than the selected frame, so we need to
6884 use its buffer, not the selected frame's buffer. */
6885 Lisp_Object mini_window;
6886 struct frame *f, *sf = SELECTED_FRAME ();
6888 /* Get the frame containing the mini-buffer
6889 that the selected frame is using. */
6890 mini_window = FRAME_MINIBUF_WINDOW (sf);
6891 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6893 /* A null message buffer means that the frame hasn't really been
6894 initialized yet. Error messages get reported properly by
6895 cmd_error, so this must be just an informative message; toss
6896 it. */
6897 if (FRAME_MESSAGE_BUF (f))
6899 if (m)
6901 int len;
6902 #ifdef NO_ARG_ARRAY
6903 char *a[3];
6904 a[0] = (char *) a1;
6905 a[1] = (char *) a2;
6906 a[2] = (char *) a3;
6908 len = doprnt (FRAME_MESSAGE_BUF (f),
6909 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6910 #else
6911 len = doprnt (FRAME_MESSAGE_BUF (f),
6912 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6913 (char **) &a1);
6914 #endif /* NO_ARG_ARRAY */
6916 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6918 else
6919 message1 (0);
6921 /* Print should start at the beginning of the message
6922 buffer next time. */
6923 message_buf_print = 0;
6929 /* The non-logging version of message. */
6931 void
6932 message_nolog (m, a1, a2, a3)
6933 char *m;
6934 EMACS_INT a1, a2, a3;
6936 Lisp_Object old_log_max;
6937 old_log_max = Vmessage_log_max;
6938 Vmessage_log_max = Qnil;
6939 message (m, a1, a2, a3);
6940 Vmessage_log_max = old_log_max;
6944 /* Display the current message in the current mini-buffer. This is
6945 only called from error handlers in process.c, and is not time
6946 critical. */
6948 void
6949 update_echo_area ()
6951 if (!NILP (echo_area_buffer[0]))
6953 Lisp_Object string;
6954 string = Fcurrent_message ();
6955 message3 (string, SBYTES (string),
6956 !NILP (current_buffer->enable_multibyte_characters));
6961 /* Make sure echo area buffers in `echo_buffers' are live.
6962 If they aren't, make new ones. */
6964 static void
6965 ensure_echo_area_buffers ()
6967 int i;
6969 for (i = 0; i < 2; ++i)
6970 if (!BUFFERP (echo_buffer[i])
6971 || NILP (XBUFFER (echo_buffer[i])->name))
6973 char name[30];
6974 Lisp_Object old_buffer;
6975 int j;
6977 old_buffer = echo_buffer[i];
6978 sprintf (name, " *Echo Area %d*", i);
6979 echo_buffer[i] = Fget_buffer_create (build_string (name));
6980 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6982 for (j = 0; j < 2; ++j)
6983 if (EQ (old_buffer, echo_area_buffer[j]))
6984 echo_area_buffer[j] = echo_buffer[i];
6989 /* Call FN with args A1..A4 with either the current or last displayed
6990 echo_area_buffer as current buffer.
6992 WHICH zero means use the current message buffer
6993 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6994 from echo_buffer[] and clear it.
6996 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6997 suitable buffer from echo_buffer[] and clear it.
6999 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7000 that the current message becomes the last displayed one, make
7001 choose a suitable buffer for echo_area_buffer[0], and clear it.
7003 Value is what FN returns. */
7005 static int
7006 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7007 struct window *w;
7008 int which;
7009 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7010 EMACS_INT a1;
7011 Lisp_Object a2;
7012 EMACS_INT a3, a4;
7014 Lisp_Object buffer;
7015 int this_one, the_other, clear_buffer_p, rc;
7016 int count = SPECPDL_INDEX ();
7018 /* If buffers aren't live, make new ones. */
7019 ensure_echo_area_buffers ();
7021 clear_buffer_p = 0;
7023 if (which == 0)
7024 this_one = 0, the_other = 1;
7025 else if (which > 0)
7026 this_one = 1, the_other = 0;
7027 else
7029 this_one = 0, the_other = 1;
7030 clear_buffer_p = 1;
7032 /* We need a fresh one in case the current echo buffer equals
7033 the one containing the last displayed echo area message. */
7034 if (!NILP (echo_area_buffer[this_one])
7035 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7036 echo_area_buffer[this_one] = Qnil;
7039 /* Choose a suitable buffer from echo_buffer[] is we don't
7040 have one. */
7041 if (NILP (echo_area_buffer[this_one]))
7043 echo_area_buffer[this_one]
7044 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7045 ? echo_buffer[the_other]
7046 : echo_buffer[this_one]);
7047 clear_buffer_p = 1;
7050 buffer = echo_area_buffer[this_one];
7052 /* Don't get confused by reusing the buffer used for echoing
7053 for a different purpose. */
7054 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7055 cancel_echoing ();
7057 record_unwind_protect (unwind_with_echo_area_buffer,
7058 with_echo_area_buffer_unwind_data (w));
7060 /* Make the echo area buffer current. Note that for display
7061 purposes, it is not necessary that the displayed window's buffer
7062 == current_buffer, except for text property lookup. So, let's
7063 only set that buffer temporarily here without doing a full
7064 Fset_window_buffer. We must also change w->pointm, though,
7065 because otherwise an assertions in unshow_buffer fails, and Emacs
7066 aborts. */
7067 set_buffer_internal_1 (XBUFFER (buffer));
7068 if (w)
7070 w->buffer = buffer;
7071 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7074 current_buffer->undo_list = Qt;
7075 current_buffer->read_only = Qnil;
7076 specbind (Qinhibit_read_only, Qt);
7077 specbind (Qinhibit_modification_hooks, Qt);
7079 if (clear_buffer_p && Z > BEG)
7080 del_range (BEG, Z);
7082 xassert (BEGV >= BEG);
7083 xassert (ZV <= Z && ZV >= BEGV);
7085 rc = fn (a1, a2, a3, a4);
7087 xassert (BEGV >= BEG);
7088 xassert (ZV <= Z && ZV >= BEGV);
7090 unbind_to (count, Qnil);
7091 return rc;
7095 /* Save state that should be preserved around the call to the function
7096 FN called in with_echo_area_buffer. */
7098 static Lisp_Object
7099 with_echo_area_buffer_unwind_data (w)
7100 struct window *w;
7102 int i = 0;
7103 Lisp_Object vector;
7105 /* Reduce consing by keeping one vector in
7106 Vwith_echo_area_save_vector. */
7107 vector = Vwith_echo_area_save_vector;
7108 Vwith_echo_area_save_vector = Qnil;
7110 if (NILP (vector))
7111 vector = Fmake_vector (make_number (7), Qnil);
7113 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7114 AREF (vector, i) = Vdeactivate_mark, ++i;
7115 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7117 if (w)
7119 XSETWINDOW (AREF (vector, i), w); ++i;
7120 AREF (vector, i) = w->buffer; ++i;
7121 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7122 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7124 else
7126 int end = i + 4;
7127 for (; i < end; ++i)
7128 AREF (vector, i) = Qnil;
7131 xassert (i == ASIZE (vector));
7132 return vector;
7136 /* Restore global state from VECTOR which was created by
7137 with_echo_area_buffer_unwind_data. */
7139 static Lisp_Object
7140 unwind_with_echo_area_buffer (vector)
7141 Lisp_Object vector;
7143 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7144 Vdeactivate_mark = AREF (vector, 1);
7145 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7147 if (WINDOWP (AREF (vector, 3)))
7149 struct window *w;
7150 Lisp_Object buffer, charpos, bytepos;
7152 w = XWINDOW (AREF (vector, 3));
7153 buffer = AREF (vector, 4);
7154 charpos = AREF (vector, 5);
7155 bytepos = AREF (vector, 6);
7157 w->buffer = buffer;
7158 set_marker_both (w->pointm, buffer,
7159 XFASTINT (charpos), XFASTINT (bytepos));
7162 Vwith_echo_area_save_vector = vector;
7163 return Qnil;
7167 /* Set up the echo area for use by print functions. MULTIBYTE_P
7168 non-zero means we will print multibyte. */
7170 void
7171 setup_echo_area_for_printing (multibyte_p)
7172 int multibyte_p;
7174 /* If we can't find an echo area any more, exit. */
7175 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7176 Fkill_emacs (Qnil);
7178 ensure_echo_area_buffers ();
7180 if (!message_buf_print)
7182 /* A message has been output since the last time we printed.
7183 Choose a fresh echo area buffer. */
7184 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7185 echo_area_buffer[0] = echo_buffer[1];
7186 else
7187 echo_area_buffer[0] = echo_buffer[0];
7189 /* Switch to that buffer and clear it. */
7190 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7191 current_buffer->truncate_lines = Qnil;
7193 if (Z > BEG)
7195 int count = SPECPDL_INDEX ();
7196 specbind (Qinhibit_read_only, Qt);
7197 /* Note that undo recording is always disabled. */
7198 del_range (BEG, Z);
7199 unbind_to (count, Qnil);
7201 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7203 /* Set up the buffer for the multibyteness we need. */
7204 if (multibyte_p
7205 != !NILP (current_buffer->enable_multibyte_characters))
7206 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7208 /* Raise the frame containing the echo area. */
7209 if (minibuffer_auto_raise)
7211 struct frame *sf = SELECTED_FRAME ();
7212 Lisp_Object mini_window;
7213 mini_window = FRAME_MINIBUF_WINDOW (sf);
7214 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7217 message_log_maybe_newline ();
7218 message_buf_print = 1;
7220 else
7222 if (NILP (echo_area_buffer[0]))
7224 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7225 echo_area_buffer[0] = echo_buffer[1];
7226 else
7227 echo_area_buffer[0] = echo_buffer[0];
7230 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7232 /* Someone switched buffers between print requests. */
7233 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7234 current_buffer->truncate_lines = Qnil;
7240 /* Display an echo area message in window W. Value is non-zero if W's
7241 height is changed. If display_last_displayed_message_p is
7242 non-zero, display the message that was last displayed, otherwise
7243 display the current message. */
7245 static int
7246 display_echo_area (w)
7247 struct window *w;
7249 int i, no_message_p, window_height_changed_p, count;
7251 /* Temporarily disable garbage collections while displaying the echo
7252 area. This is done because a GC can print a message itself.
7253 That message would modify the echo area buffer's contents while a
7254 redisplay of the buffer is going on, and seriously confuse
7255 redisplay. */
7256 count = inhibit_garbage_collection ();
7258 /* If there is no message, we must call display_echo_area_1
7259 nevertheless because it resizes the window. But we will have to
7260 reset the echo_area_buffer in question to nil at the end because
7261 with_echo_area_buffer will sets it to an empty buffer. */
7262 i = display_last_displayed_message_p ? 1 : 0;
7263 no_message_p = NILP (echo_area_buffer[i]);
7265 window_height_changed_p
7266 = with_echo_area_buffer (w, display_last_displayed_message_p,
7267 display_echo_area_1,
7268 (EMACS_INT) w, Qnil, 0, 0);
7270 if (no_message_p)
7271 echo_area_buffer[i] = Qnil;
7273 unbind_to (count, Qnil);
7274 return window_height_changed_p;
7278 /* Helper for display_echo_area. Display the current buffer which
7279 contains the current echo area message in window W, a mini-window,
7280 a pointer to which is passed in A1. A2..A4 are currently not used.
7281 Change the height of W so that all of the message is displayed.
7282 Value is non-zero if height of W was changed. */
7284 static int
7285 display_echo_area_1 (a1, a2, a3, a4)
7286 EMACS_INT a1;
7287 Lisp_Object a2;
7288 EMACS_INT a3, a4;
7290 struct window *w = (struct window *) a1;
7291 Lisp_Object window;
7292 struct text_pos start;
7293 int window_height_changed_p = 0;
7295 /* Do this before displaying, so that we have a large enough glyph
7296 matrix for the display. */
7297 window_height_changed_p = resize_mini_window (w, 0);
7299 /* Display. */
7300 clear_glyph_matrix (w->desired_matrix);
7301 XSETWINDOW (window, w);
7302 SET_TEXT_POS (start, BEG, BEG_BYTE);
7303 try_window (window, start);
7305 return window_height_changed_p;
7309 /* Resize the echo area window to exactly the size needed for the
7310 currently displayed message, if there is one. If a mini-buffer
7311 is active, don't shrink it. */
7313 void
7314 resize_echo_area_exactly ()
7316 if (BUFFERP (echo_area_buffer[0])
7317 && WINDOWP (echo_area_window))
7319 struct window *w = XWINDOW (echo_area_window);
7320 int resized_p;
7321 Lisp_Object resize_exactly;
7323 if (minibuf_level == 0)
7324 resize_exactly = Qt;
7325 else
7326 resize_exactly = Qnil;
7328 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7329 (EMACS_INT) w, resize_exactly, 0, 0);
7330 if (resized_p)
7332 ++windows_or_buffers_changed;
7333 ++update_mode_lines;
7334 redisplay_internal (0);
7340 /* Callback function for with_echo_area_buffer, when used from
7341 resize_echo_area_exactly. A1 contains a pointer to the window to
7342 resize, EXACTLY non-nil means resize the mini-window exactly to the
7343 size of the text displayed. A3 and A4 are not used. Value is what
7344 resize_mini_window returns. */
7346 static int
7347 resize_mini_window_1 (a1, exactly, a3, a4)
7348 EMACS_INT a1;
7349 Lisp_Object exactly;
7350 EMACS_INT a3, a4;
7352 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7356 /* Resize mini-window W to fit the size of its contents. EXACT:P
7357 means size the window exactly to the size needed. Otherwise, it's
7358 only enlarged until W's buffer is empty. Value is non-zero if
7359 the window height has been changed. */
7362 resize_mini_window (w, exact_p)
7363 struct window *w;
7364 int exact_p;
7366 struct frame *f = XFRAME (w->frame);
7367 int window_height_changed_p = 0;
7369 xassert (MINI_WINDOW_P (w));
7371 /* Don't resize windows while redisplaying a window; it would
7372 confuse redisplay functions when the size of the window they are
7373 displaying changes from under them. Such a resizing can happen,
7374 for instance, when which-func prints a long message while
7375 we are running fontification-functions. We're running these
7376 functions with safe_call which binds inhibit-redisplay to t. */
7377 if (!NILP (Vinhibit_redisplay))
7378 return 0;
7380 /* Nil means don't try to resize. */
7381 if (NILP (Vresize_mini_windows)
7382 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7383 return 0;
7385 if (!FRAME_MINIBUF_ONLY_P (f))
7387 struct it it;
7388 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7389 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7390 int height, max_height;
7391 int unit = FRAME_LINE_HEIGHT (f);
7392 struct text_pos start;
7393 struct buffer *old_current_buffer = NULL;
7395 if (current_buffer != XBUFFER (w->buffer))
7397 old_current_buffer = current_buffer;
7398 set_buffer_internal (XBUFFER (w->buffer));
7401 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7403 /* Compute the max. number of lines specified by the user. */
7404 if (FLOATP (Vmax_mini_window_height))
7405 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7406 else if (INTEGERP (Vmax_mini_window_height))
7407 max_height = XINT (Vmax_mini_window_height);
7408 else
7409 max_height = total_height / 4;
7411 /* Correct that max. height if it's bogus. */
7412 max_height = max (1, max_height);
7413 max_height = min (total_height, max_height);
7415 /* Find out the height of the text in the window. */
7416 if (it.truncate_lines_p)
7417 height = 1;
7418 else
7420 last_height = 0;
7421 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7422 if (it.max_ascent == 0 && it.max_descent == 0)
7423 height = it.current_y + last_height;
7424 else
7425 height = it.current_y + it.max_ascent + it.max_descent;
7426 height -= it.extra_line_spacing;
7427 height = (height + unit - 1) / unit;
7430 /* Compute a suitable window start. */
7431 if (height > max_height)
7433 height = max_height;
7434 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7435 move_it_vertically_backward (&it, (height - 1) * unit);
7436 start = it.current.pos;
7438 else
7439 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7440 SET_MARKER_FROM_TEXT_POS (w->start, start);
7442 if (EQ (Vresize_mini_windows, Qgrow_only))
7444 /* Let it grow only, until we display an empty message, in which
7445 case the window shrinks again. */
7446 if (height > WINDOW_TOTAL_LINES (w))
7448 int old_height = WINDOW_TOTAL_LINES (w);
7449 freeze_window_starts (f, 1);
7450 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7451 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7453 else if (height < WINDOW_TOTAL_LINES (w)
7454 && (exact_p || BEGV == ZV))
7456 int old_height = WINDOW_TOTAL_LINES (w);
7457 freeze_window_starts (f, 0);
7458 shrink_mini_window (w);
7459 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7462 else
7464 /* Always resize to exact size needed. */
7465 if (height > WINDOW_TOTAL_LINES (w))
7467 int old_height = WINDOW_TOTAL_LINES (w);
7468 freeze_window_starts (f, 1);
7469 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7470 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7472 else if (height < WINDOW_TOTAL_LINES (w))
7474 int old_height = WINDOW_TOTAL_LINES (w);
7475 freeze_window_starts (f, 0);
7476 shrink_mini_window (w);
7478 if (height)
7480 freeze_window_starts (f, 1);
7481 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7484 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7488 if (old_current_buffer)
7489 set_buffer_internal (old_current_buffer);
7492 return window_height_changed_p;
7496 /* Value is the current message, a string, or nil if there is no
7497 current message. */
7499 Lisp_Object
7500 current_message ()
7502 Lisp_Object msg;
7504 if (NILP (echo_area_buffer[0]))
7505 msg = Qnil;
7506 else
7508 with_echo_area_buffer (0, 0, current_message_1,
7509 (EMACS_INT) &msg, Qnil, 0, 0);
7510 if (NILP (msg))
7511 echo_area_buffer[0] = Qnil;
7514 return msg;
7518 static int
7519 current_message_1 (a1, a2, a3, a4)
7520 EMACS_INT a1;
7521 Lisp_Object a2;
7522 EMACS_INT a3, a4;
7524 Lisp_Object *msg = (Lisp_Object *) a1;
7526 if (Z > BEG)
7527 *msg = make_buffer_string (BEG, Z, 1);
7528 else
7529 *msg = Qnil;
7530 return 0;
7534 /* Push the current message on Vmessage_stack for later restauration
7535 by restore_message. Value is non-zero if the current message isn't
7536 empty. This is a relatively infrequent operation, so it's not
7537 worth optimizing. */
7540 push_message ()
7542 Lisp_Object msg;
7543 msg = current_message ();
7544 Vmessage_stack = Fcons (msg, Vmessage_stack);
7545 return STRINGP (msg);
7549 /* Restore message display from the top of Vmessage_stack. */
7551 void
7552 restore_message ()
7554 Lisp_Object msg;
7556 xassert (CONSP (Vmessage_stack));
7557 msg = XCAR (Vmessage_stack);
7558 if (STRINGP (msg))
7559 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7560 else
7561 message3_nolog (msg, 0, 0);
7565 /* Handler for record_unwind_protect calling pop_message. */
7567 Lisp_Object
7568 pop_message_unwind (dummy)
7569 Lisp_Object dummy;
7571 pop_message ();
7572 return Qnil;
7575 /* Pop the top-most entry off Vmessage_stack. */
7577 void
7578 pop_message ()
7580 xassert (CONSP (Vmessage_stack));
7581 Vmessage_stack = XCDR (Vmessage_stack);
7585 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7586 exits. If the stack is not empty, we have a missing pop_message
7587 somewhere. */
7589 void
7590 check_message_stack ()
7592 if (!NILP (Vmessage_stack))
7593 abort ();
7597 /* Truncate to NCHARS what will be displayed in the echo area the next
7598 time we display it---but don't redisplay it now. */
7600 void
7601 truncate_echo_area (nchars)
7602 int nchars;
7604 if (nchars == 0)
7605 echo_area_buffer[0] = Qnil;
7606 /* A null message buffer means that the frame hasn't really been
7607 initialized yet. Error messages get reported properly by
7608 cmd_error, so this must be just an informative message; toss it. */
7609 else if (!noninteractive
7610 && INTERACTIVE
7611 && !NILP (echo_area_buffer[0]))
7613 struct frame *sf = SELECTED_FRAME ();
7614 if (FRAME_MESSAGE_BUF (sf))
7615 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7620 /* Helper function for truncate_echo_area. Truncate the current
7621 message to at most NCHARS characters. */
7623 static int
7624 truncate_message_1 (nchars, a2, a3, a4)
7625 EMACS_INT nchars;
7626 Lisp_Object a2;
7627 EMACS_INT a3, a4;
7629 if (BEG + nchars < Z)
7630 del_range (BEG + nchars, Z);
7631 if (Z == BEG)
7632 echo_area_buffer[0] = Qnil;
7633 return 0;
7637 /* Set the current message to a substring of S or STRING.
7639 If STRING is a Lisp string, set the message to the first NBYTES
7640 bytes from STRING. NBYTES zero means use the whole string. If
7641 STRING is multibyte, the message will be displayed multibyte.
7643 If S is not null, set the message to the first LEN bytes of S. LEN
7644 zero means use the whole string. MULTIBYTE_P non-zero means S is
7645 multibyte. Display the message multibyte in that case. */
7647 void
7648 set_message (s, string, nbytes, multibyte_p)
7649 const char *s;
7650 Lisp_Object string;
7651 int nbytes, multibyte_p;
7653 message_enable_multibyte
7654 = ((s && multibyte_p)
7655 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7657 with_echo_area_buffer (0, -1, set_message_1,
7658 (EMACS_INT) s, string, nbytes, multibyte_p);
7659 message_buf_print = 0;
7660 help_echo_showing_p = 0;
7664 /* Helper function for set_message. Arguments have the same meaning
7665 as there, with A1 corresponding to S and A2 corresponding to STRING
7666 This function is called with the echo area buffer being
7667 current. */
7669 static int
7670 set_message_1 (a1, a2, nbytes, multibyte_p)
7671 EMACS_INT a1;
7672 Lisp_Object a2;
7673 EMACS_INT nbytes, multibyte_p;
7675 const char *s = (const char *) a1;
7676 Lisp_Object string = a2;
7678 xassert (BEG == Z);
7680 /* Change multibyteness of the echo buffer appropriately. */
7681 if (message_enable_multibyte
7682 != !NILP (current_buffer->enable_multibyte_characters))
7683 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7685 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7687 /* Insert new message at BEG. */
7688 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7690 if (STRINGP (string))
7692 int nchars;
7694 if (nbytes == 0)
7695 nbytes = SBYTES (string);
7696 nchars = string_byte_to_char (string, nbytes);
7698 /* This function takes care of single/multibyte conversion. We
7699 just have to ensure that the echo area buffer has the right
7700 setting of enable_multibyte_characters. */
7701 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7703 else if (s)
7705 if (nbytes == 0)
7706 nbytes = strlen (s);
7708 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7710 /* Convert from multi-byte to single-byte. */
7711 int i, c, n;
7712 unsigned char work[1];
7714 /* Convert a multibyte string to single-byte. */
7715 for (i = 0; i < nbytes; i += n)
7717 c = string_char_and_length (s + i, nbytes - i, &n);
7718 work[0] = (SINGLE_BYTE_CHAR_P (c)
7720 : multibyte_char_to_unibyte (c, Qnil));
7721 insert_1_both (work, 1, 1, 1, 0, 0);
7724 else if (!multibyte_p
7725 && !NILP (current_buffer->enable_multibyte_characters))
7727 /* Convert from single-byte to multi-byte. */
7728 int i, c, n;
7729 const unsigned char *msg = (const unsigned char *) s;
7730 unsigned char str[MAX_MULTIBYTE_LENGTH];
7732 /* Convert a single-byte string to multibyte. */
7733 for (i = 0; i < nbytes; i++)
7735 c = unibyte_char_to_multibyte (msg[i]);
7736 n = CHAR_STRING (c, str);
7737 insert_1_both (str, 1, n, 1, 0, 0);
7740 else
7741 insert_1 (s, nbytes, 1, 0, 0);
7744 return 0;
7748 /* Clear messages. CURRENT_P non-zero means clear the current
7749 message. LAST_DISPLAYED_P non-zero means clear the message
7750 last displayed. */
7752 void
7753 clear_message (current_p, last_displayed_p)
7754 int current_p, last_displayed_p;
7756 if (current_p)
7758 echo_area_buffer[0] = Qnil;
7759 message_cleared_p = 1;
7762 if (last_displayed_p)
7763 echo_area_buffer[1] = Qnil;
7765 message_buf_print = 0;
7768 /* Clear garbaged frames.
7770 This function is used where the old redisplay called
7771 redraw_garbaged_frames which in turn called redraw_frame which in
7772 turn called clear_frame. The call to clear_frame was a source of
7773 flickering. I believe a clear_frame is not necessary. It should
7774 suffice in the new redisplay to invalidate all current matrices,
7775 and ensure a complete redisplay of all windows. */
7777 static void
7778 clear_garbaged_frames ()
7780 if (frame_garbaged)
7782 Lisp_Object tail, frame;
7783 int changed_count = 0;
7785 FOR_EACH_FRAME (tail, frame)
7787 struct frame *f = XFRAME (frame);
7789 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7791 if (f->resized_p)
7793 Fredraw_frame (frame);
7794 f->force_flush_display_p = 1;
7796 clear_current_matrices (f);
7797 changed_count++;
7798 f->garbaged = 0;
7799 f->resized_p = 0;
7803 frame_garbaged = 0;
7804 if (changed_count)
7805 ++windows_or_buffers_changed;
7810 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7811 is non-zero update selected_frame. Value is non-zero if the
7812 mini-windows height has been changed. */
7814 static int
7815 echo_area_display (update_frame_p)
7816 int update_frame_p;
7818 Lisp_Object mini_window;
7819 struct window *w;
7820 struct frame *f;
7821 int window_height_changed_p = 0;
7822 struct frame *sf = SELECTED_FRAME ();
7824 mini_window = FRAME_MINIBUF_WINDOW (sf);
7825 w = XWINDOW (mini_window);
7826 f = XFRAME (WINDOW_FRAME (w));
7828 /* Don't display if frame is invisible or not yet initialized. */
7829 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7830 return 0;
7832 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7833 #ifndef MAC_OS8
7834 #ifdef HAVE_WINDOW_SYSTEM
7835 /* When Emacs starts, selected_frame may be a visible terminal
7836 frame, even if we run under a window system. If we let this
7837 through, a message would be displayed on the terminal. */
7838 if (EQ (selected_frame, Vterminal_frame)
7839 && !NILP (Vwindow_system))
7840 return 0;
7841 #endif /* HAVE_WINDOW_SYSTEM */
7842 #endif
7844 /* Redraw garbaged frames. */
7845 if (frame_garbaged)
7846 clear_garbaged_frames ();
7848 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7850 echo_area_window = mini_window;
7851 window_height_changed_p = display_echo_area (w);
7852 w->must_be_updated_p = 1;
7854 /* Update the display, unless called from redisplay_internal.
7855 Also don't update the screen during redisplay itself. The
7856 update will happen at the end of redisplay, and an update
7857 here could cause confusion. */
7858 if (update_frame_p && !redisplaying_p)
7860 int n = 0;
7862 /* If the display update has been interrupted by pending
7863 input, update mode lines in the frame. Due to the
7864 pending input, it might have been that redisplay hasn't
7865 been called, so that mode lines above the echo area are
7866 garbaged. This looks odd, so we prevent it here. */
7867 if (!display_completed)
7868 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7870 if (window_height_changed_p
7871 /* Don't do this if Emacs is shutting down. Redisplay
7872 needs to run hooks. */
7873 && !NILP (Vrun_hooks))
7875 /* Must update other windows. Likewise as in other
7876 cases, don't let this update be interrupted by
7877 pending input. */
7878 int count = SPECPDL_INDEX ();
7879 specbind (Qredisplay_dont_pause, Qt);
7880 windows_or_buffers_changed = 1;
7881 redisplay_internal (0);
7882 unbind_to (count, Qnil);
7884 else if (FRAME_WINDOW_P (f) && n == 0)
7886 /* Window configuration is the same as before.
7887 Can do with a display update of the echo area,
7888 unless we displayed some mode lines. */
7889 update_single_window (w, 1);
7890 rif->flush_display (f);
7892 else
7893 update_frame (f, 1, 1);
7895 /* If cursor is in the echo area, make sure that the next
7896 redisplay displays the minibuffer, so that the cursor will
7897 be replaced with what the minibuffer wants. */
7898 if (cursor_in_echo_area)
7899 ++windows_or_buffers_changed;
7902 else if (!EQ (mini_window, selected_window))
7903 windows_or_buffers_changed++;
7905 /* Last displayed message is now the current message. */
7906 echo_area_buffer[1] = echo_area_buffer[0];
7908 /* Prevent redisplay optimization in redisplay_internal by resetting
7909 this_line_start_pos. This is done because the mini-buffer now
7910 displays the message instead of its buffer text. */
7911 if (EQ (mini_window, selected_window))
7912 CHARPOS (this_line_start_pos) = 0;
7914 return window_height_changed_p;
7919 /***********************************************************************
7920 Frame Titles
7921 ***********************************************************************/
7924 /* The frame title buffering code is also used by Fformat_mode_line.
7925 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7927 /* A buffer for constructing frame titles in it; allocated from the
7928 heap in init_xdisp and resized as needed in store_frame_title_char. */
7930 static char *frame_title_buf;
7932 /* The buffer's end, and a current output position in it. */
7934 static char *frame_title_buf_end;
7935 static char *frame_title_ptr;
7938 /* Store a single character C for the frame title in frame_title_buf.
7939 Re-allocate frame_title_buf if necessary. */
7941 static void
7942 #ifdef PROTOTYPES
7943 store_frame_title_char (char c)
7944 #else
7945 store_frame_title_char (c)
7946 char c;
7947 #endif
7949 /* If output position has reached the end of the allocated buffer,
7950 double the buffer's size. */
7951 if (frame_title_ptr == frame_title_buf_end)
7953 int len = frame_title_ptr - frame_title_buf;
7954 int new_size = 2 * len * sizeof *frame_title_buf;
7955 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7956 frame_title_buf_end = frame_title_buf + new_size;
7957 frame_title_ptr = frame_title_buf + len;
7960 *frame_title_ptr++ = c;
7964 /* Store part of a frame title in frame_title_buf, beginning at
7965 frame_title_ptr. STR is the string to store. Do not copy
7966 characters that yield more columns than PRECISION; PRECISION <= 0
7967 means copy the whole string. Pad with spaces until FIELD_WIDTH
7968 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7969 pad. Called from display_mode_element when it is used to build a
7970 frame title. */
7972 static int
7973 store_frame_title (str, field_width, precision)
7974 const unsigned char *str;
7975 int field_width, precision;
7977 int n = 0;
7978 int dummy, nbytes;
7980 /* Copy at most PRECISION chars from STR. */
7981 nbytes = strlen (str);
7982 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
7983 while (nbytes--)
7984 store_frame_title_char (*str++);
7986 /* Fill up with spaces until FIELD_WIDTH reached. */
7987 while (field_width > 0
7988 && n < field_width)
7990 store_frame_title_char (' ');
7991 ++n;
7994 return n;
7997 #ifdef HAVE_WINDOW_SYSTEM
7999 /* Set the title of FRAME, if it has changed. The title format is
8000 Vicon_title_format if FRAME is iconified, otherwise it is
8001 frame_title_format. */
8003 static void
8004 x_consider_frame_title (frame)
8005 Lisp_Object frame;
8007 struct frame *f = XFRAME (frame);
8009 if (FRAME_WINDOW_P (f)
8010 || FRAME_MINIBUF_ONLY_P (f)
8011 || f->explicit_name)
8013 /* Do we have more than one visible frame on this X display? */
8014 Lisp_Object tail;
8015 Lisp_Object fmt;
8016 struct buffer *obuf;
8017 int len;
8018 struct it it;
8020 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8022 Lisp_Object other_frame = XCAR (tail);
8023 struct frame *tf = XFRAME (other_frame);
8025 if (tf != f
8026 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8027 && !FRAME_MINIBUF_ONLY_P (tf)
8028 && !EQ (other_frame, tip_frame)
8029 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8030 break;
8033 /* Set global variable indicating that multiple frames exist. */
8034 multiple_frames = CONSP (tail);
8036 /* Switch to the buffer of selected window of the frame. Set up
8037 frame_title_ptr so that display_mode_element will output into it;
8038 then display the title. */
8039 obuf = current_buffer;
8040 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8041 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8042 frame_title_ptr = frame_title_buf;
8043 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8044 NULL, DEFAULT_FACE_ID);
8045 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8046 len = frame_title_ptr - frame_title_buf;
8047 frame_title_ptr = NULL;
8048 set_buffer_internal_1 (obuf);
8050 /* Set the title only if it's changed. This avoids consing in
8051 the common case where it hasn't. (If it turns out that we've
8052 already wasted too much time by walking through the list with
8053 display_mode_element, then we might need to optimize at a
8054 higher level than this.) */
8055 if (! STRINGP (f->name)
8056 || SBYTES (f->name) != len
8057 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8058 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8062 #endif /* not HAVE_WINDOW_SYSTEM */
8067 /***********************************************************************
8068 Menu Bars
8069 ***********************************************************************/
8072 /* Prepare for redisplay by updating menu-bar item lists when
8073 appropriate. This can call eval. */
8075 void
8076 prepare_menu_bars ()
8078 int all_windows;
8079 struct gcpro gcpro1, gcpro2;
8080 struct frame *f;
8081 Lisp_Object tooltip_frame;
8083 #ifdef HAVE_WINDOW_SYSTEM
8084 tooltip_frame = tip_frame;
8085 #else
8086 tooltip_frame = Qnil;
8087 #endif
8089 /* Update all frame titles based on their buffer names, etc. We do
8090 this before the menu bars so that the buffer-menu will show the
8091 up-to-date frame titles. */
8092 #ifdef HAVE_WINDOW_SYSTEM
8093 if (windows_or_buffers_changed || update_mode_lines)
8095 Lisp_Object tail, frame;
8097 FOR_EACH_FRAME (tail, frame)
8099 f = XFRAME (frame);
8100 if (!EQ (frame, tooltip_frame)
8101 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8102 x_consider_frame_title (frame);
8105 #endif /* HAVE_WINDOW_SYSTEM */
8107 /* Update the menu bar item lists, if appropriate. This has to be
8108 done before any actual redisplay or generation of display lines. */
8109 all_windows = (update_mode_lines
8110 || buffer_shared > 1
8111 || windows_or_buffers_changed);
8112 if (all_windows)
8114 Lisp_Object tail, frame;
8115 int count = SPECPDL_INDEX ();
8117 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8119 FOR_EACH_FRAME (tail, frame)
8121 f = XFRAME (frame);
8123 /* Ignore tooltip frame. */
8124 if (EQ (frame, tooltip_frame))
8125 continue;
8127 /* If a window on this frame changed size, report that to
8128 the user and clear the size-change flag. */
8129 if (FRAME_WINDOW_SIZES_CHANGED (f))
8131 Lisp_Object functions;
8133 /* Clear flag first in case we get an error below. */
8134 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8135 functions = Vwindow_size_change_functions;
8136 GCPRO2 (tail, functions);
8138 while (CONSP (functions))
8140 call1 (XCAR (functions), frame);
8141 functions = XCDR (functions);
8143 UNGCPRO;
8146 GCPRO1 (tail);
8147 update_menu_bar (f, 0);
8148 #ifdef HAVE_WINDOW_SYSTEM
8149 update_tool_bar (f, 0);
8150 #endif
8151 UNGCPRO;
8154 unbind_to (count, Qnil);
8156 else
8158 struct frame *sf = SELECTED_FRAME ();
8159 update_menu_bar (sf, 1);
8160 #ifdef HAVE_WINDOW_SYSTEM
8161 update_tool_bar (sf, 1);
8162 #endif
8165 /* Motif needs this. See comment in xmenu.c. Turn it off when
8166 pending_menu_activation is not defined. */
8167 #ifdef USE_X_TOOLKIT
8168 pending_menu_activation = 0;
8169 #endif
8173 /* Update the menu bar item list for frame F. This has to be done
8174 before we start to fill in any display lines, because it can call
8175 eval.
8177 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8179 static void
8180 update_menu_bar (f, save_match_data)
8181 struct frame *f;
8182 int save_match_data;
8184 Lisp_Object window;
8185 register struct window *w;
8187 /* If called recursively during a menu update, do nothing. This can
8188 happen when, for instance, an activate-menubar-hook causes a
8189 redisplay. */
8190 if (inhibit_menubar_update)
8191 return;
8193 window = FRAME_SELECTED_WINDOW (f);
8194 w = XWINDOW (window);
8196 #if 0 /* The if statement below this if statement used to include the
8197 condition !NILP (w->update_mode_line), rather than using
8198 update_mode_lines directly, and this if statement may have
8199 been added to make that condition work. Now the if
8200 statement below matches its comment, this isn't needed. */
8201 if (update_mode_lines)
8202 w->update_mode_line = Qt;
8203 #endif
8205 if (FRAME_WINDOW_P (f)
8207 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8208 || defined (USE_GTK)
8209 FRAME_EXTERNAL_MENU_BAR (f)
8210 #else
8211 FRAME_MENU_BAR_LINES (f) > 0
8212 #endif
8213 : FRAME_MENU_BAR_LINES (f) > 0)
8215 /* If the user has switched buffers or windows, we need to
8216 recompute to reflect the new bindings. But we'll
8217 recompute when update_mode_lines is set too; that means
8218 that people can use force-mode-line-update to request
8219 that the menu bar be recomputed. The adverse effect on
8220 the rest of the redisplay algorithm is about the same as
8221 windows_or_buffers_changed anyway. */
8222 if (windows_or_buffers_changed
8223 /* This used to test w->update_mode_line, but we believe
8224 there is no need to recompute the menu in that case. */
8225 || update_mode_lines
8226 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8227 < BUF_MODIFF (XBUFFER (w->buffer)))
8228 != !NILP (w->last_had_star))
8229 || ((!NILP (Vtransient_mark_mode)
8230 && !NILP (XBUFFER (w->buffer)->mark_active))
8231 != !NILP (w->region_showing)))
8233 struct buffer *prev = current_buffer;
8234 int count = SPECPDL_INDEX ();
8236 specbind (Qinhibit_menubar_update, Qt);
8238 set_buffer_internal_1 (XBUFFER (w->buffer));
8239 if (save_match_data)
8240 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8241 if (NILP (Voverriding_local_map_menu_flag))
8243 specbind (Qoverriding_terminal_local_map, Qnil);
8244 specbind (Qoverriding_local_map, Qnil);
8247 /* Run the Lucid hook. */
8248 safe_run_hooks (Qactivate_menubar_hook);
8250 /* If it has changed current-menubar from previous value,
8251 really recompute the menu-bar from the value. */
8252 if (! NILP (Vlucid_menu_bar_dirty_flag))
8253 call0 (Qrecompute_lucid_menubar);
8255 safe_run_hooks (Qmenu_bar_update_hook);
8256 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8258 /* Redisplay the menu bar in case we changed it. */
8259 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8260 || defined (USE_GTK)
8261 if (FRAME_WINDOW_P (f)
8262 #if defined (MAC_OS)
8263 /* All frames on Mac OS share the same menubar. So only the
8264 selected frame should be allowed to set it. */
8265 && f == SELECTED_FRAME ()
8266 #endif
8268 set_frame_menubar (f, 0, 0);
8269 else
8270 /* On a terminal screen, the menu bar is an ordinary screen
8271 line, and this makes it get updated. */
8272 w->update_mode_line = Qt;
8273 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8274 /* In the non-toolkit version, the menu bar is an ordinary screen
8275 line, and this makes it get updated. */
8276 w->update_mode_line = Qt;
8277 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8279 unbind_to (count, Qnil);
8280 set_buffer_internal_1 (prev);
8287 /***********************************************************************
8288 Output Cursor
8289 ***********************************************************************/
8291 #ifdef HAVE_WINDOW_SYSTEM
8293 /* EXPORT:
8294 Nominal cursor position -- where to draw output.
8295 HPOS and VPOS are window relative glyph matrix coordinates.
8296 X and Y are window relative pixel coordinates. */
8298 struct cursor_pos output_cursor;
8301 /* EXPORT:
8302 Set the global variable output_cursor to CURSOR. All cursor
8303 positions are relative to updated_window. */
8305 void
8306 set_output_cursor (cursor)
8307 struct cursor_pos *cursor;
8309 output_cursor.hpos = cursor->hpos;
8310 output_cursor.vpos = cursor->vpos;
8311 output_cursor.x = cursor->x;
8312 output_cursor.y = cursor->y;
8316 /* EXPORT for RIF:
8317 Set a nominal cursor position.
8319 HPOS and VPOS are column/row positions in a window glyph matrix. X
8320 and Y are window text area relative pixel positions.
8322 If this is done during an update, updated_window will contain the
8323 window that is being updated and the position is the future output
8324 cursor position for that window. If updated_window is null, use
8325 selected_window and display the cursor at the given position. */
8327 void
8328 x_cursor_to (vpos, hpos, y, x)
8329 int vpos, hpos, y, x;
8331 struct window *w;
8333 /* If updated_window is not set, work on selected_window. */
8334 if (updated_window)
8335 w = updated_window;
8336 else
8337 w = XWINDOW (selected_window);
8339 /* Set the output cursor. */
8340 output_cursor.hpos = hpos;
8341 output_cursor.vpos = vpos;
8342 output_cursor.x = x;
8343 output_cursor.y = y;
8345 /* If not called as part of an update, really display the cursor.
8346 This will also set the cursor position of W. */
8347 if (updated_window == NULL)
8349 BLOCK_INPUT;
8350 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8351 if (rif->flush_display_optional)
8352 rif->flush_display_optional (SELECTED_FRAME ());
8353 UNBLOCK_INPUT;
8357 #endif /* HAVE_WINDOW_SYSTEM */
8360 /***********************************************************************
8361 Tool-bars
8362 ***********************************************************************/
8364 #ifdef HAVE_WINDOW_SYSTEM
8366 /* Where the mouse was last time we reported a mouse event. */
8368 FRAME_PTR last_mouse_frame;
8370 /* Tool-bar item index of the item on which a mouse button was pressed
8371 or -1. */
8373 int last_tool_bar_item;
8376 /* Update the tool-bar item list for frame F. This has to be done
8377 before we start to fill in any display lines. Called from
8378 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8379 and restore it here. */
8381 static void
8382 update_tool_bar (f, save_match_data)
8383 struct frame *f;
8384 int save_match_data;
8386 #ifdef USE_GTK
8387 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8388 #else
8389 int do_update = WINDOWP (f->tool_bar_window)
8390 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8391 #endif
8393 if (do_update)
8395 Lisp_Object window;
8396 struct window *w;
8398 window = FRAME_SELECTED_WINDOW (f);
8399 w = XWINDOW (window);
8401 /* If the user has switched buffers or windows, we need to
8402 recompute to reflect the new bindings. But we'll
8403 recompute when update_mode_lines is set too; that means
8404 that people can use force-mode-line-update to request
8405 that the menu bar be recomputed. The adverse effect on
8406 the rest of the redisplay algorithm is about the same as
8407 windows_or_buffers_changed anyway. */
8408 if (windows_or_buffers_changed
8409 || !NILP (w->update_mode_line)
8410 || update_mode_lines
8411 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8412 < BUF_MODIFF (XBUFFER (w->buffer)))
8413 != !NILP (w->last_had_star))
8414 || ((!NILP (Vtransient_mark_mode)
8415 && !NILP (XBUFFER (w->buffer)->mark_active))
8416 != !NILP (w->region_showing)))
8418 struct buffer *prev = current_buffer;
8419 int count = SPECPDL_INDEX ();
8420 Lisp_Object new_tool_bar;
8421 int new_n_tool_bar;
8422 struct gcpro gcpro1;
8424 /* Set current_buffer to the buffer of the selected
8425 window of the frame, so that we get the right local
8426 keymaps. */
8427 set_buffer_internal_1 (XBUFFER (w->buffer));
8429 /* Save match data, if we must. */
8430 if (save_match_data)
8431 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8433 /* Make sure that we don't accidentally use bogus keymaps. */
8434 if (NILP (Voverriding_local_map_menu_flag))
8436 specbind (Qoverriding_terminal_local_map, Qnil);
8437 specbind (Qoverriding_local_map, Qnil);
8440 GCPRO1 (new_tool_bar);
8442 /* Build desired tool-bar items from keymaps. */
8443 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8444 &new_n_tool_bar);
8446 /* Redisplay the tool-bar if we changed it. */
8447 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8449 /* Redisplay that happens asynchronously due to an expose event
8450 may access f->tool_bar_items. Make sure we update both
8451 variables within BLOCK_INPUT so no such event interrupts. */
8452 BLOCK_INPUT;
8453 f->tool_bar_items = new_tool_bar;
8454 f->n_tool_bar_items = new_n_tool_bar;
8455 w->update_mode_line = Qt;
8456 UNBLOCK_INPUT;
8459 UNGCPRO;
8461 unbind_to (count, Qnil);
8462 set_buffer_internal_1 (prev);
8468 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8469 F's desired tool-bar contents. F->tool_bar_items must have
8470 been set up previously by calling prepare_menu_bars. */
8472 static void
8473 build_desired_tool_bar_string (f)
8474 struct frame *f;
8476 int i, size, size_needed;
8477 struct gcpro gcpro1, gcpro2, gcpro3;
8478 Lisp_Object image, plist, props;
8480 image = plist = props = Qnil;
8481 GCPRO3 (image, plist, props);
8483 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8484 Otherwise, make a new string. */
8486 /* The size of the string we might be able to reuse. */
8487 size = (STRINGP (f->desired_tool_bar_string)
8488 ? SCHARS (f->desired_tool_bar_string)
8489 : 0);
8491 /* We need one space in the string for each image. */
8492 size_needed = f->n_tool_bar_items;
8494 /* Reuse f->desired_tool_bar_string, if possible. */
8495 if (size < size_needed || NILP (f->desired_tool_bar_string))
8496 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8497 make_number (' '));
8498 else
8500 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8501 Fremove_text_properties (make_number (0), make_number (size),
8502 props, f->desired_tool_bar_string);
8505 /* Put a `display' property on the string for the images to display,
8506 put a `menu_item' property on tool-bar items with a value that
8507 is the index of the item in F's tool-bar item vector. */
8508 for (i = 0; i < f->n_tool_bar_items; ++i)
8510 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8512 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8513 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8514 int hmargin, vmargin, relief, idx, end;
8515 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8517 /* If image is a vector, choose the image according to the
8518 button state. */
8519 image = PROP (TOOL_BAR_ITEM_IMAGES);
8520 if (VECTORP (image))
8522 if (enabled_p)
8523 idx = (selected_p
8524 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8525 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8526 else
8527 idx = (selected_p
8528 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8529 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8531 xassert (ASIZE (image) >= idx);
8532 image = AREF (image, idx);
8534 else
8535 idx = -1;
8537 /* Ignore invalid image specifications. */
8538 if (!valid_image_p (image))
8539 continue;
8541 /* Display the tool-bar button pressed, or depressed. */
8542 plist = Fcopy_sequence (XCDR (image));
8544 /* Compute margin and relief to draw. */
8545 relief = (tool_bar_button_relief >= 0
8546 ? tool_bar_button_relief
8547 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8548 hmargin = vmargin = relief;
8550 if (INTEGERP (Vtool_bar_button_margin)
8551 && XINT (Vtool_bar_button_margin) > 0)
8553 hmargin += XFASTINT (Vtool_bar_button_margin);
8554 vmargin += XFASTINT (Vtool_bar_button_margin);
8556 else if (CONSP (Vtool_bar_button_margin))
8558 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8559 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8560 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8562 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8563 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8564 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8567 if (auto_raise_tool_bar_buttons_p)
8569 /* Add a `:relief' property to the image spec if the item is
8570 selected. */
8571 if (selected_p)
8573 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8574 hmargin -= relief;
8575 vmargin -= relief;
8578 else
8580 /* If image is selected, display it pressed, i.e. with a
8581 negative relief. If it's not selected, display it with a
8582 raised relief. */
8583 plist = Fplist_put (plist, QCrelief,
8584 (selected_p
8585 ? make_number (-relief)
8586 : make_number (relief)));
8587 hmargin -= relief;
8588 vmargin -= relief;
8591 /* Put a margin around the image. */
8592 if (hmargin || vmargin)
8594 if (hmargin == vmargin)
8595 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8596 else
8597 plist = Fplist_put (plist, QCmargin,
8598 Fcons (make_number (hmargin),
8599 make_number (vmargin)));
8602 /* If button is not enabled, and we don't have special images
8603 for the disabled state, make the image appear disabled by
8604 applying an appropriate algorithm to it. */
8605 if (!enabled_p && idx < 0)
8606 plist = Fplist_put (plist, QCconversion, Qdisabled);
8608 /* Put a `display' text property on the string for the image to
8609 display. Put a `menu-item' property on the string that gives
8610 the start of this item's properties in the tool-bar items
8611 vector. */
8612 image = Fcons (Qimage, plist);
8613 props = list4 (Qdisplay, image,
8614 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8616 /* Let the last image hide all remaining spaces in the tool bar
8617 string. The string can be longer than needed when we reuse a
8618 previous string. */
8619 if (i + 1 == f->n_tool_bar_items)
8620 end = SCHARS (f->desired_tool_bar_string);
8621 else
8622 end = i + 1;
8623 Fadd_text_properties (make_number (i), make_number (end),
8624 props, f->desired_tool_bar_string);
8625 #undef PROP
8628 UNGCPRO;
8632 /* Display one line of the tool-bar of frame IT->f. */
8634 static void
8635 display_tool_bar_line (it)
8636 struct it *it;
8638 struct glyph_row *row = it->glyph_row;
8639 int max_x = it->last_visible_x;
8640 struct glyph *last;
8642 prepare_desired_row (row);
8643 row->y = it->current_y;
8645 /* Note that this isn't made use of if the face hasn't a box,
8646 so there's no need to check the face here. */
8647 it->start_of_box_run_p = 1;
8649 while (it->current_x < max_x)
8651 int x_before, x, n_glyphs_before, i, nglyphs;
8653 /* Get the next display element. */
8654 if (!get_next_display_element (it))
8655 break;
8657 /* Produce glyphs. */
8658 x_before = it->current_x;
8659 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8660 PRODUCE_GLYPHS (it);
8662 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8663 i = 0;
8664 x = x_before;
8665 while (i < nglyphs)
8667 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8669 if (x + glyph->pixel_width > max_x)
8671 /* Glyph doesn't fit on line. */
8672 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8673 it->current_x = x;
8674 goto out;
8677 ++it->hpos;
8678 x += glyph->pixel_width;
8679 ++i;
8682 /* Stop at line ends. */
8683 if (ITERATOR_AT_END_OF_LINE_P (it))
8684 break;
8686 set_iterator_to_next (it, 1);
8689 out:;
8691 row->displays_text_p = row->used[TEXT_AREA] != 0;
8692 extend_face_to_end_of_line (it);
8693 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8694 last->right_box_line_p = 1;
8695 if (last == row->glyphs[TEXT_AREA])
8696 last->left_box_line_p = 1;
8697 compute_line_metrics (it);
8699 /* If line is empty, make it occupy the rest of the tool-bar. */
8700 if (!row->displays_text_p)
8702 row->height = row->phys_height = it->last_visible_y - row->y;
8703 row->ascent = row->phys_ascent = 0;
8706 row->full_width_p = 1;
8707 row->continued_p = 0;
8708 row->truncated_on_left_p = 0;
8709 row->truncated_on_right_p = 0;
8711 it->current_x = it->hpos = 0;
8712 it->current_y += row->height;
8713 ++it->vpos;
8714 ++it->glyph_row;
8718 /* Value is the number of screen lines needed to make all tool-bar
8719 items of frame F visible. */
8721 static int
8722 tool_bar_lines_needed (f)
8723 struct frame *f;
8725 struct window *w = XWINDOW (f->tool_bar_window);
8726 struct it it;
8728 /* Initialize an iterator for iteration over
8729 F->desired_tool_bar_string in the tool-bar window of frame F. */
8730 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8731 it.first_visible_x = 0;
8732 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8733 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8735 while (!ITERATOR_AT_END_P (&it))
8737 it.glyph_row = w->desired_matrix->rows;
8738 clear_glyph_row (it.glyph_row);
8739 display_tool_bar_line (&it);
8742 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8746 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8747 0, 1, 0,
8748 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8749 (frame)
8750 Lisp_Object frame;
8752 struct frame *f;
8753 struct window *w;
8754 int nlines = 0;
8756 if (NILP (frame))
8757 frame = selected_frame;
8758 else
8759 CHECK_FRAME (frame);
8760 f = XFRAME (frame);
8762 if (WINDOWP (f->tool_bar_window)
8763 || (w = XWINDOW (f->tool_bar_window),
8764 WINDOW_TOTAL_LINES (w) > 0))
8766 update_tool_bar (f, 1);
8767 if (f->n_tool_bar_items)
8769 build_desired_tool_bar_string (f);
8770 nlines = tool_bar_lines_needed (f);
8774 return make_number (nlines);
8778 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8779 height should be changed. */
8781 static int
8782 redisplay_tool_bar (f)
8783 struct frame *f;
8785 struct window *w;
8786 struct it it;
8787 struct glyph_row *row;
8788 int change_height_p = 0;
8790 #ifdef USE_GTK
8791 if (FRAME_EXTERNAL_TOOL_BAR (f))
8792 update_frame_tool_bar (f);
8793 return 0;
8794 #endif
8796 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8797 do anything. This means you must start with tool-bar-lines
8798 non-zero to get the auto-sizing effect. Or in other words, you
8799 can turn off tool-bars by specifying tool-bar-lines zero. */
8800 if (!WINDOWP (f->tool_bar_window)
8801 || (w = XWINDOW (f->tool_bar_window),
8802 WINDOW_TOTAL_LINES (w) == 0))
8803 return 0;
8805 /* Set up an iterator for the tool-bar window. */
8806 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8807 it.first_visible_x = 0;
8808 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8809 row = it.glyph_row;
8811 /* Build a string that represents the contents of the tool-bar. */
8812 build_desired_tool_bar_string (f);
8813 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8815 /* Display as many lines as needed to display all tool-bar items. */
8816 while (it.current_y < it.last_visible_y)
8817 display_tool_bar_line (&it);
8819 /* It doesn't make much sense to try scrolling in the tool-bar
8820 window, so don't do it. */
8821 w->desired_matrix->no_scrolling_p = 1;
8822 w->must_be_updated_p = 1;
8824 if (auto_resize_tool_bars_p)
8826 int nlines;
8828 /* If we couldn't display everything, change the tool-bar's
8829 height. */
8830 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8831 change_height_p = 1;
8833 /* If there are blank lines at the end, except for a partially
8834 visible blank line at the end that is smaller than
8835 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8836 row = it.glyph_row - 1;
8837 if (!row->displays_text_p
8838 && row->height >= FRAME_LINE_HEIGHT (f))
8839 change_height_p = 1;
8841 /* If row displays tool-bar items, but is partially visible,
8842 change the tool-bar's height. */
8843 if (row->displays_text_p
8844 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8845 change_height_p = 1;
8847 /* Resize windows as needed by changing the `tool-bar-lines'
8848 frame parameter. */
8849 if (change_height_p
8850 && (nlines = tool_bar_lines_needed (f),
8851 nlines != WINDOW_TOTAL_LINES (w)))
8853 extern Lisp_Object Qtool_bar_lines;
8854 Lisp_Object frame;
8855 int old_height = WINDOW_TOTAL_LINES (w);
8857 XSETFRAME (frame, f);
8858 clear_glyph_matrix (w->desired_matrix);
8859 Fmodify_frame_parameters (frame,
8860 Fcons (Fcons (Qtool_bar_lines,
8861 make_number (nlines)),
8862 Qnil));
8863 if (WINDOW_TOTAL_LINES (w) != old_height)
8864 fonts_changed_p = 1;
8868 return change_height_p;
8872 /* Get information about the tool-bar item which is displayed in GLYPH
8873 on frame F. Return in *PROP_IDX the index where tool-bar item
8874 properties start in F->tool_bar_items. Value is zero if
8875 GLYPH doesn't display a tool-bar item. */
8877 static int
8878 tool_bar_item_info (f, glyph, prop_idx)
8879 struct frame *f;
8880 struct glyph *glyph;
8881 int *prop_idx;
8883 Lisp_Object prop;
8884 int success_p;
8885 int charpos;
8887 /* This function can be called asynchronously, which means we must
8888 exclude any possibility that Fget_text_property signals an
8889 error. */
8890 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8891 charpos = max (0, charpos);
8893 /* Get the text property `menu-item' at pos. The value of that
8894 property is the start index of this item's properties in
8895 F->tool_bar_items. */
8896 prop = Fget_text_property (make_number (charpos),
8897 Qmenu_item, f->current_tool_bar_string);
8898 if (INTEGERP (prop))
8900 *prop_idx = XINT (prop);
8901 success_p = 1;
8903 else
8904 success_p = 0;
8906 return success_p;
8910 /* Get information about the tool-bar item at position X/Y on frame F.
8911 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8912 the current matrix of the tool-bar window of F, or NULL if not
8913 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8914 item in F->tool_bar_items. Value is
8916 -1 if X/Y is not on a tool-bar item
8917 0 if X/Y is on the same item that was highlighted before.
8918 1 otherwise. */
8920 static int
8921 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8922 struct frame *f;
8923 int x, y;
8924 struct glyph **glyph;
8925 int *hpos, *vpos, *prop_idx;
8927 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8928 struct window *w = XWINDOW (f->tool_bar_window);
8929 int area;
8931 /* Find the glyph under X/Y. */
8932 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8933 if (*glyph == NULL)
8934 return -1;
8936 /* Get the start of this tool-bar item's properties in
8937 f->tool_bar_items. */
8938 if (!tool_bar_item_info (f, *glyph, prop_idx))
8939 return -1;
8941 /* Is mouse on the highlighted item? */
8942 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8943 && *vpos >= dpyinfo->mouse_face_beg_row
8944 && *vpos <= dpyinfo->mouse_face_end_row
8945 && (*vpos > dpyinfo->mouse_face_beg_row
8946 || *hpos >= dpyinfo->mouse_face_beg_col)
8947 && (*vpos < dpyinfo->mouse_face_end_row
8948 || *hpos < dpyinfo->mouse_face_end_col
8949 || dpyinfo->mouse_face_past_end))
8950 return 0;
8952 return 1;
8956 /* EXPORT:
8957 Handle mouse button event on the tool-bar of frame F, at
8958 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8959 0 for button release. MODIFIERS is event modifiers for button
8960 release. */
8962 void
8963 handle_tool_bar_click (f, x, y, down_p, modifiers)
8964 struct frame *f;
8965 int x, y, down_p;
8966 unsigned int modifiers;
8968 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8969 struct window *w = XWINDOW (f->tool_bar_window);
8970 int hpos, vpos, prop_idx;
8971 struct glyph *glyph;
8972 Lisp_Object enabled_p;
8974 /* If not on the highlighted tool-bar item, return. */
8975 frame_to_window_pixel_xy (w, &x, &y);
8976 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8977 return;
8979 /* If item is disabled, do nothing. */
8980 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8981 if (NILP (enabled_p))
8982 return;
8984 if (down_p)
8986 /* Show item in pressed state. */
8987 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8988 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8989 last_tool_bar_item = prop_idx;
8991 else
8993 Lisp_Object key, frame;
8994 struct input_event event;
8995 EVENT_INIT (event);
8997 /* Show item in released state. */
8998 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8999 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9001 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9003 XSETFRAME (frame, f);
9004 event.kind = TOOL_BAR_EVENT;
9005 event.frame_or_window = frame;
9006 event.arg = frame;
9007 kbd_buffer_store_event (&event);
9009 event.kind = TOOL_BAR_EVENT;
9010 event.frame_or_window = frame;
9011 event.arg = key;
9012 event.modifiers = modifiers;
9013 kbd_buffer_store_event (&event);
9014 last_tool_bar_item = -1;
9019 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9020 tool-bar window-relative coordinates X/Y. Called from
9021 note_mouse_highlight. */
9023 static void
9024 note_tool_bar_highlight (f, x, y)
9025 struct frame *f;
9026 int x, y;
9028 Lisp_Object window = f->tool_bar_window;
9029 struct window *w = XWINDOW (window);
9030 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9031 int hpos, vpos;
9032 struct glyph *glyph;
9033 struct glyph_row *row;
9034 int i;
9035 Lisp_Object enabled_p;
9036 int prop_idx;
9037 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9038 int mouse_down_p, rc;
9040 /* Function note_mouse_highlight is called with negative x(y
9041 values when mouse moves outside of the frame. */
9042 if (x <= 0 || y <= 0)
9044 clear_mouse_face (dpyinfo);
9045 return;
9048 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9049 if (rc < 0)
9051 /* Not on tool-bar item. */
9052 clear_mouse_face (dpyinfo);
9053 return;
9055 else if (rc == 0)
9056 /* On same tool-bar item as before. */
9057 goto set_help_echo;
9059 clear_mouse_face (dpyinfo);
9061 /* Mouse is down, but on different tool-bar item? */
9062 mouse_down_p = (dpyinfo->grabbed
9063 && f == last_mouse_frame
9064 && FRAME_LIVE_P (f));
9065 if (mouse_down_p
9066 && last_tool_bar_item != prop_idx)
9067 return;
9069 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9070 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9072 /* If tool-bar item is not enabled, don't highlight it. */
9073 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9074 if (!NILP (enabled_p))
9076 /* Compute the x-position of the glyph. In front and past the
9077 image is a space. We include this in the highlighted area. */
9078 row = MATRIX_ROW (w->current_matrix, vpos);
9079 for (i = x = 0; i < hpos; ++i)
9080 x += row->glyphs[TEXT_AREA][i].pixel_width;
9082 /* Record this as the current active region. */
9083 dpyinfo->mouse_face_beg_col = hpos;
9084 dpyinfo->mouse_face_beg_row = vpos;
9085 dpyinfo->mouse_face_beg_x = x;
9086 dpyinfo->mouse_face_beg_y = row->y;
9087 dpyinfo->mouse_face_past_end = 0;
9089 dpyinfo->mouse_face_end_col = hpos + 1;
9090 dpyinfo->mouse_face_end_row = vpos;
9091 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9092 dpyinfo->mouse_face_end_y = row->y;
9093 dpyinfo->mouse_face_window = window;
9094 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9096 /* Display it as active. */
9097 show_mouse_face (dpyinfo, draw);
9098 dpyinfo->mouse_face_image_state = draw;
9101 set_help_echo:
9103 /* Set help_echo_string to a help string to display for this tool-bar item.
9104 XTread_socket does the rest. */
9105 help_echo_object = help_echo_window = Qnil;
9106 help_echo_pos = -1;
9107 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9108 if (NILP (help_echo_string))
9109 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9112 #endif /* HAVE_WINDOW_SYSTEM */
9116 /************************************************************************
9117 Horizontal scrolling
9118 ************************************************************************/
9120 static int hscroll_window_tree P_ ((Lisp_Object));
9121 static int hscroll_windows P_ ((Lisp_Object));
9123 /* For all leaf windows in the window tree rooted at WINDOW, set their
9124 hscroll value so that PT is (i) visible in the window, and (ii) so
9125 that it is not within a certain margin at the window's left and
9126 right border. Value is non-zero if any window's hscroll has been
9127 changed. */
9129 static int
9130 hscroll_window_tree (window)
9131 Lisp_Object window;
9133 int hscrolled_p = 0;
9134 int hscroll_relative_p = FLOATP (Vhscroll_step);
9135 int hscroll_step_abs = 0;
9136 double hscroll_step_rel = 0;
9138 if (hscroll_relative_p)
9140 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9141 if (hscroll_step_rel < 0)
9143 hscroll_relative_p = 0;
9144 hscroll_step_abs = 0;
9147 else if (INTEGERP (Vhscroll_step))
9149 hscroll_step_abs = XINT (Vhscroll_step);
9150 if (hscroll_step_abs < 0)
9151 hscroll_step_abs = 0;
9153 else
9154 hscroll_step_abs = 0;
9156 while (WINDOWP (window))
9158 struct window *w = XWINDOW (window);
9160 if (WINDOWP (w->hchild))
9161 hscrolled_p |= hscroll_window_tree (w->hchild);
9162 else if (WINDOWP (w->vchild))
9163 hscrolled_p |= hscroll_window_tree (w->vchild);
9164 else if (w->cursor.vpos >= 0)
9166 int h_margin;
9167 int text_area_width;
9168 struct glyph_row *current_cursor_row
9169 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9170 struct glyph_row *desired_cursor_row
9171 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9172 struct glyph_row *cursor_row
9173 = (desired_cursor_row->enabled_p
9174 ? desired_cursor_row
9175 : current_cursor_row);
9177 text_area_width = window_box_width (w, TEXT_AREA);
9179 /* Scroll when cursor is inside this scroll margin. */
9180 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9182 if ((XFASTINT (w->hscroll)
9183 && w->cursor.x <= h_margin)
9184 || (cursor_row->enabled_p
9185 && cursor_row->truncated_on_right_p
9186 && (w->cursor.x >= text_area_width - h_margin)))
9188 struct it it;
9189 int hscroll;
9190 struct buffer *saved_current_buffer;
9191 int pt;
9192 int wanted_x;
9194 /* Find point in a display of infinite width. */
9195 saved_current_buffer = current_buffer;
9196 current_buffer = XBUFFER (w->buffer);
9198 if (w == XWINDOW (selected_window))
9199 pt = BUF_PT (current_buffer);
9200 else
9202 pt = marker_position (w->pointm);
9203 pt = max (BEGV, pt);
9204 pt = min (ZV, pt);
9207 /* Move iterator to pt starting at cursor_row->start in
9208 a line with infinite width. */
9209 init_to_row_start (&it, w, cursor_row);
9210 it.last_visible_x = INFINITY;
9211 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9212 current_buffer = saved_current_buffer;
9214 /* Position cursor in window. */
9215 if (!hscroll_relative_p && hscroll_step_abs == 0)
9216 hscroll = max (0, (it.current_x
9217 - (ITERATOR_AT_END_OF_LINE_P (&it)
9218 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9219 : (text_area_width / 2))))
9220 / FRAME_COLUMN_WIDTH (it.f);
9221 else if (w->cursor.x >= text_area_width - h_margin)
9223 if (hscroll_relative_p)
9224 wanted_x = text_area_width * (1 - hscroll_step_rel)
9225 - h_margin;
9226 else
9227 wanted_x = text_area_width
9228 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9229 - h_margin;
9230 hscroll
9231 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9233 else
9235 if (hscroll_relative_p)
9236 wanted_x = text_area_width * hscroll_step_rel
9237 + h_margin;
9238 else
9239 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9240 + h_margin;
9241 hscroll
9242 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9244 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9246 /* Don't call Fset_window_hscroll if value hasn't
9247 changed because it will prevent redisplay
9248 optimizations. */
9249 if (XFASTINT (w->hscroll) != hscroll)
9251 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9252 w->hscroll = make_number (hscroll);
9253 hscrolled_p = 1;
9258 window = w->next;
9261 /* Value is non-zero if hscroll of any leaf window has been changed. */
9262 return hscrolled_p;
9266 /* Set hscroll so that cursor is visible and not inside horizontal
9267 scroll margins for all windows in the tree rooted at WINDOW. See
9268 also hscroll_window_tree above. Value is non-zero if any window's
9269 hscroll has been changed. If it has, desired matrices on the frame
9270 of WINDOW are cleared. */
9272 static int
9273 hscroll_windows (window)
9274 Lisp_Object window;
9276 int hscrolled_p;
9278 if (automatic_hscrolling_p)
9280 hscrolled_p = hscroll_window_tree (window);
9281 if (hscrolled_p)
9282 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9284 else
9285 hscrolled_p = 0;
9286 return hscrolled_p;
9291 /************************************************************************
9292 Redisplay
9293 ************************************************************************/
9295 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9296 to a non-zero value. This is sometimes handy to have in a debugger
9297 session. */
9299 #if GLYPH_DEBUG
9301 /* First and last unchanged row for try_window_id. */
9303 int debug_first_unchanged_at_end_vpos;
9304 int debug_last_unchanged_at_beg_vpos;
9306 /* Delta vpos and y. */
9308 int debug_dvpos, debug_dy;
9310 /* Delta in characters and bytes for try_window_id. */
9312 int debug_delta, debug_delta_bytes;
9314 /* Values of window_end_pos and window_end_vpos at the end of
9315 try_window_id. */
9317 EMACS_INT debug_end_pos, debug_end_vpos;
9319 /* Append a string to W->desired_matrix->method. FMT is a printf
9320 format string. A1...A9 are a supplement for a variable-length
9321 argument list. If trace_redisplay_p is non-zero also printf the
9322 resulting string to stderr. */
9324 static void
9325 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9326 struct window *w;
9327 char *fmt;
9328 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9330 char buffer[512];
9331 char *method = w->desired_matrix->method;
9332 int len = strlen (method);
9333 int size = sizeof w->desired_matrix->method;
9334 int remaining = size - len - 1;
9336 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9337 if (len && remaining)
9339 method[len] = '|';
9340 --remaining, ++len;
9343 strncpy (method + len, buffer, remaining);
9345 if (trace_redisplay_p)
9346 fprintf (stderr, "%p (%s): %s\n",
9348 ((BUFFERP (w->buffer)
9349 && STRINGP (XBUFFER (w->buffer)->name))
9350 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9351 : "no buffer"),
9352 buffer);
9355 #endif /* GLYPH_DEBUG */
9358 /* Value is non-zero if all changes in window W, which displays
9359 current_buffer, are in the text between START and END. START is a
9360 buffer position, END is given as a distance from Z. Used in
9361 redisplay_internal for display optimization. */
9363 static INLINE int
9364 text_outside_line_unchanged_p (w, start, end)
9365 struct window *w;
9366 int start, end;
9368 int unchanged_p = 1;
9370 /* If text or overlays have changed, see where. */
9371 if (XFASTINT (w->last_modified) < MODIFF
9372 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9374 /* Gap in the line? */
9375 if (GPT < start || Z - GPT < end)
9376 unchanged_p = 0;
9378 /* Changes start in front of the line, or end after it? */
9379 if (unchanged_p
9380 && (BEG_UNCHANGED < start - 1
9381 || END_UNCHANGED < end))
9382 unchanged_p = 0;
9384 /* If selective display, can't optimize if changes start at the
9385 beginning of the line. */
9386 if (unchanged_p
9387 && INTEGERP (current_buffer->selective_display)
9388 && XINT (current_buffer->selective_display) > 0
9389 && (BEG_UNCHANGED < start || GPT <= start))
9390 unchanged_p = 0;
9392 /* If there are overlays at the start or end of the line, these
9393 may have overlay strings with newlines in them. A change at
9394 START, for instance, may actually concern the display of such
9395 overlay strings as well, and they are displayed on different
9396 lines. So, quickly rule out this case. (For the future, it
9397 might be desirable to implement something more telling than
9398 just BEG/END_UNCHANGED.) */
9399 if (unchanged_p)
9401 if (BEG + BEG_UNCHANGED == start
9402 && overlay_touches_p (start))
9403 unchanged_p = 0;
9404 if (END_UNCHANGED == end
9405 && overlay_touches_p (Z - end))
9406 unchanged_p = 0;
9410 return unchanged_p;
9414 /* Do a frame update, taking possible shortcuts into account. This is
9415 the main external entry point for redisplay.
9417 If the last redisplay displayed an echo area message and that message
9418 is no longer requested, we clear the echo area or bring back the
9419 mini-buffer if that is in use. */
9421 void
9422 redisplay ()
9424 redisplay_internal (0);
9428 static Lisp_Object
9429 overlay_arrow_string_or_property (var, pbitmap)
9430 Lisp_Object var;
9431 int *pbitmap;
9433 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9434 Lisp_Object bitmap;
9436 if (pbitmap)
9438 *pbitmap = 0;
9439 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9440 *pbitmap = XINT (bitmap);
9443 if (!NILP (pstr))
9444 return pstr;
9445 return Voverlay_arrow_string;
9448 /* Return 1 if there are any overlay-arrows in current_buffer. */
9449 static int
9450 overlay_arrow_in_current_buffer_p ()
9452 Lisp_Object vlist;
9454 for (vlist = Voverlay_arrow_variable_list;
9455 CONSP (vlist);
9456 vlist = XCDR (vlist))
9458 Lisp_Object var = XCAR (vlist);
9459 Lisp_Object val;
9461 if (!SYMBOLP (var))
9462 continue;
9463 val = find_symbol_value (var);
9464 if (MARKERP (val)
9465 && current_buffer == XMARKER (val)->buffer)
9466 return 1;
9468 return 0;
9472 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9473 has changed. */
9475 static int
9476 overlay_arrows_changed_p ()
9478 Lisp_Object vlist;
9480 for (vlist = Voverlay_arrow_variable_list;
9481 CONSP (vlist);
9482 vlist = XCDR (vlist))
9484 Lisp_Object var = XCAR (vlist);
9485 Lisp_Object val, pstr;
9487 if (!SYMBOLP (var))
9488 continue;
9489 val = find_symbol_value (var);
9490 if (!MARKERP (val))
9491 continue;
9492 if (! EQ (COERCE_MARKER (val),
9493 Fget (var, Qlast_arrow_position))
9494 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9495 EQ (pstr, Fget (var, Qlast_arrow_string))))
9496 return 1;
9498 return 0;
9501 /* Mark overlay arrows to be updated on next redisplay. */
9503 static void
9504 update_overlay_arrows (up_to_date)
9505 int up_to_date;
9507 Lisp_Object vlist;
9509 for (vlist = Voverlay_arrow_variable_list;
9510 CONSP (vlist);
9511 vlist = XCDR (vlist))
9513 Lisp_Object var = XCAR (vlist);
9515 if (!SYMBOLP (var))
9516 continue;
9518 if (up_to_date > 0)
9520 Lisp_Object val = find_symbol_value (var);
9521 Fput (var, Qlast_arrow_position,
9522 COERCE_MARKER (val));
9523 Fput (var, Qlast_arrow_string,
9524 overlay_arrow_string_or_property (var, 0));
9526 else if (up_to_date < 0
9527 || !NILP (Fget (var, Qlast_arrow_position)))
9529 Fput (var, Qlast_arrow_position, Qt);
9530 Fput (var, Qlast_arrow_string, Qt);
9536 /* Return overlay arrow string to display at row.
9537 Return t if display as bitmap in left fringe.
9538 Return nil if no overlay arrow. */
9540 static Lisp_Object
9541 overlay_arrow_at_row (it, row, pbitmap)
9542 struct it *it;
9543 struct glyph_row *row;
9544 int *pbitmap;
9546 Lisp_Object vlist;
9548 for (vlist = Voverlay_arrow_variable_list;
9549 CONSP (vlist);
9550 vlist = XCDR (vlist))
9552 Lisp_Object var = XCAR (vlist);
9553 Lisp_Object val;
9555 if (!SYMBOLP (var))
9556 continue;
9558 val = find_symbol_value (var);
9560 if (MARKERP (val)
9561 && current_buffer == XMARKER (val)->buffer
9562 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9564 val = overlay_arrow_string_or_property (var, pbitmap);
9565 if (FRAME_WINDOW_P (it->f)
9566 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9567 return Qt;
9568 if (STRINGP (val))
9569 return val;
9570 break;
9574 *pbitmap = 0;
9575 return Qnil;
9578 /* Return 1 if point moved out of or into a composition. Otherwise
9579 return 0. PREV_BUF and PREV_PT are the last point buffer and
9580 position. BUF and PT are the current point buffer and position. */
9583 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9584 struct buffer *prev_buf, *buf;
9585 int prev_pt, pt;
9587 int start, end;
9588 Lisp_Object prop;
9589 Lisp_Object buffer;
9591 XSETBUFFER (buffer, buf);
9592 /* Check a composition at the last point if point moved within the
9593 same buffer. */
9594 if (prev_buf == buf)
9596 if (prev_pt == pt)
9597 /* Point didn't move. */
9598 return 0;
9600 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9601 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9602 && COMPOSITION_VALID_P (start, end, prop)
9603 && start < prev_pt && end > prev_pt)
9604 /* The last point was within the composition. Return 1 iff
9605 point moved out of the composition. */
9606 return (pt <= start || pt >= end);
9609 /* Check a composition at the current point. */
9610 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9611 && find_composition (pt, -1, &start, &end, &prop, buffer)
9612 && COMPOSITION_VALID_P (start, end, prop)
9613 && start < pt && end > pt);
9617 /* Reconsider the setting of B->clip_changed which is displayed
9618 in window W. */
9620 static INLINE void
9621 reconsider_clip_changes (w, b)
9622 struct window *w;
9623 struct buffer *b;
9625 if (b->clip_changed
9626 && !NILP (w->window_end_valid)
9627 && w->current_matrix->buffer == b
9628 && w->current_matrix->zv == BUF_ZV (b)
9629 && w->current_matrix->begv == BUF_BEGV (b))
9630 b->clip_changed = 0;
9632 /* If display wasn't paused, and W is not a tool bar window, see if
9633 point has been moved into or out of a composition. In that case,
9634 we set b->clip_changed to 1 to force updating the screen. If
9635 b->clip_changed has already been set to 1, we can skip this
9636 check. */
9637 if (!b->clip_changed
9638 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9640 int pt;
9642 if (w == XWINDOW (selected_window))
9643 pt = BUF_PT (current_buffer);
9644 else
9645 pt = marker_position (w->pointm);
9647 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9648 || pt != XINT (w->last_point))
9649 && check_point_in_composition (w->current_matrix->buffer,
9650 XINT (w->last_point),
9651 XBUFFER (w->buffer), pt))
9652 b->clip_changed = 1;
9657 /* Select FRAME to forward the values of frame-local variables into C
9658 variables so that the redisplay routines can access those values
9659 directly. */
9661 static void
9662 select_frame_for_redisplay (frame)
9663 Lisp_Object frame;
9665 Lisp_Object tail, sym, val;
9666 Lisp_Object old = selected_frame;
9668 selected_frame = frame;
9670 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9671 if (CONSP (XCAR (tail))
9672 && (sym = XCAR (XCAR (tail)),
9673 SYMBOLP (sym))
9674 && (sym = indirect_variable (sym),
9675 val = SYMBOL_VALUE (sym),
9676 (BUFFER_LOCAL_VALUEP (val)
9677 || SOME_BUFFER_LOCAL_VALUEP (val)))
9678 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9679 Fsymbol_value (sym);
9681 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9682 if (CONSP (XCAR (tail))
9683 && (sym = XCAR (XCAR (tail)),
9684 SYMBOLP (sym))
9685 && (sym = indirect_variable (sym),
9686 val = SYMBOL_VALUE (sym),
9687 (BUFFER_LOCAL_VALUEP (val)
9688 || SOME_BUFFER_LOCAL_VALUEP (val)))
9689 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9690 Fsymbol_value (sym);
9694 #define STOP_POLLING \
9695 do { if (! polling_stopped_here) stop_polling (); \
9696 polling_stopped_here = 1; } while (0)
9698 #define RESUME_POLLING \
9699 do { if (polling_stopped_here) start_polling (); \
9700 polling_stopped_here = 0; } while (0)
9703 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9704 response to any user action; therefore, we should preserve the echo
9705 area. (Actually, our caller does that job.) Perhaps in the future
9706 avoid recentering windows if it is not necessary; currently that
9707 causes some problems. */
9709 static void
9710 redisplay_internal (preserve_echo_area)
9711 int preserve_echo_area;
9713 struct window *w = XWINDOW (selected_window);
9714 struct frame *f = XFRAME (w->frame);
9715 int pause;
9716 int must_finish = 0;
9717 struct text_pos tlbufpos, tlendpos;
9718 int number_of_visible_frames;
9719 int count;
9720 struct frame *sf = SELECTED_FRAME ();
9721 int polling_stopped_here = 0;
9723 /* Non-zero means redisplay has to consider all windows on all
9724 frames. Zero means, only selected_window is considered. */
9725 int consider_all_windows_p;
9727 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9729 /* No redisplay if running in batch mode or frame is not yet fully
9730 initialized, or redisplay is explicitly turned off by setting
9731 Vinhibit_redisplay. */
9732 if (noninteractive
9733 || !NILP (Vinhibit_redisplay)
9734 || !f->glyphs_initialized_p)
9735 return;
9737 /* The flag redisplay_performed_directly_p is set by
9738 direct_output_for_insert when it already did the whole screen
9739 update necessary. */
9740 if (redisplay_performed_directly_p)
9742 redisplay_performed_directly_p = 0;
9743 if (!hscroll_windows (selected_window))
9744 return;
9747 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9748 if (popup_activated ())
9749 return;
9750 #endif
9752 /* I don't think this happens but let's be paranoid. */
9753 if (redisplaying_p)
9754 return;
9756 /* Record a function that resets redisplaying_p to its old value
9757 when we leave this function. */
9758 count = SPECPDL_INDEX ();
9759 record_unwind_protect (unwind_redisplay,
9760 Fcons (make_number (redisplaying_p), selected_frame));
9761 ++redisplaying_p;
9762 specbind (Qinhibit_free_realized_faces, Qnil);
9764 retry:
9765 pause = 0;
9766 reconsider_clip_changes (w, current_buffer);
9768 /* If new fonts have been loaded that make a glyph matrix adjustment
9769 necessary, do it. */
9770 if (fonts_changed_p)
9772 adjust_glyphs (NULL);
9773 ++windows_or_buffers_changed;
9774 fonts_changed_p = 0;
9777 /* If face_change_count is non-zero, init_iterator will free all
9778 realized faces, which includes the faces referenced from current
9779 matrices. So, we can't reuse current matrices in this case. */
9780 if (face_change_count)
9781 ++windows_or_buffers_changed;
9783 if (! FRAME_WINDOW_P (sf)
9784 && previous_terminal_frame != sf)
9786 /* Since frames on an ASCII terminal share the same display
9787 area, displaying a different frame means redisplay the whole
9788 thing. */
9789 windows_or_buffers_changed++;
9790 SET_FRAME_GARBAGED (sf);
9791 XSETFRAME (Vterminal_frame, sf);
9793 previous_terminal_frame = sf;
9795 /* Set the visible flags for all frames. Do this before checking
9796 for resized or garbaged frames; they want to know if their frames
9797 are visible. See the comment in frame.h for
9798 FRAME_SAMPLE_VISIBILITY. */
9800 Lisp_Object tail, frame;
9802 number_of_visible_frames = 0;
9804 FOR_EACH_FRAME (tail, frame)
9806 struct frame *f = XFRAME (frame);
9808 FRAME_SAMPLE_VISIBILITY (f);
9809 if (FRAME_VISIBLE_P (f))
9810 ++number_of_visible_frames;
9811 clear_desired_matrices (f);
9815 /* Notice any pending interrupt request to change frame size. */
9816 do_pending_window_change (1);
9818 /* Clear frames marked as garbaged. */
9819 if (frame_garbaged)
9820 clear_garbaged_frames ();
9822 /* Build menubar and tool-bar items. */
9823 prepare_menu_bars ();
9825 if (windows_or_buffers_changed)
9826 update_mode_lines++;
9828 /* Detect case that we need to write or remove a star in the mode line. */
9829 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9831 w->update_mode_line = Qt;
9832 if (buffer_shared > 1)
9833 update_mode_lines++;
9836 /* If %c is in the mode line, update it if needed. */
9837 if (!NILP (w->column_number_displayed)
9838 /* This alternative quickly identifies a common case
9839 where no change is needed. */
9840 && !(PT == XFASTINT (w->last_point)
9841 && XFASTINT (w->last_modified) >= MODIFF
9842 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9843 && (XFASTINT (w->column_number_displayed)
9844 != (int) current_column ())) /* iftc */
9845 w->update_mode_line = Qt;
9847 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9849 /* The variable buffer_shared is set in redisplay_window and
9850 indicates that we redisplay a buffer in different windows. See
9851 there. */
9852 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9853 || cursor_type_changed);
9855 /* If specs for an arrow have changed, do thorough redisplay
9856 to ensure we remove any arrow that should no longer exist. */
9857 if (overlay_arrows_changed_p ())
9858 consider_all_windows_p = windows_or_buffers_changed = 1;
9860 /* Normally the message* functions will have already displayed and
9861 updated the echo area, but the frame may have been trashed, or
9862 the update may have been preempted, so display the echo area
9863 again here. Checking message_cleared_p captures the case that
9864 the echo area should be cleared. */
9865 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9866 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9867 || (message_cleared_p
9868 && minibuf_level == 0
9869 /* If the mini-window is currently selected, this means the
9870 echo-area doesn't show through. */
9871 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9873 int window_height_changed_p = echo_area_display (0);
9874 must_finish = 1;
9876 /* If we don't display the current message, don't clear the
9877 message_cleared_p flag, because, if we did, we wouldn't clear
9878 the echo area in the next redisplay which doesn't preserve
9879 the echo area. */
9880 if (!display_last_displayed_message_p)
9881 message_cleared_p = 0;
9883 if (fonts_changed_p)
9884 goto retry;
9885 else if (window_height_changed_p)
9887 consider_all_windows_p = 1;
9888 ++update_mode_lines;
9889 ++windows_or_buffers_changed;
9891 /* If window configuration was changed, frames may have been
9892 marked garbaged. Clear them or we will experience
9893 surprises wrt scrolling. */
9894 if (frame_garbaged)
9895 clear_garbaged_frames ();
9898 else if (EQ (selected_window, minibuf_window)
9899 && (current_buffer->clip_changed
9900 || XFASTINT (w->last_modified) < MODIFF
9901 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9902 && resize_mini_window (w, 0))
9904 /* Resized active mini-window to fit the size of what it is
9905 showing if its contents might have changed. */
9906 must_finish = 1;
9907 consider_all_windows_p = 1;
9908 ++windows_or_buffers_changed;
9909 ++update_mode_lines;
9911 /* If window configuration was changed, frames may have been
9912 marked garbaged. Clear them or we will experience
9913 surprises wrt scrolling. */
9914 if (frame_garbaged)
9915 clear_garbaged_frames ();
9919 /* If showing the region, and mark has changed, we must redisplay
9920 the whole window. The assignment to this_line_start_pos prevents
9921 the optimization directly below this if-statement. */
9922 if (((!NILP (Vtransient_mark_mode)
9923 && !NILP (XBUFFER (w->buffer)->mark_active))
9924 != !NILP (w->region_showing))
9925 || (!NILP (w->region_showing)
9926 && !EQ (w->region_showing,
9927 Fmarker_position (XBUFFER (w->buffer)->mark))))
9928 CHARPOS (this_line_start_pos) = 0;
9930 /* Optimize the case that only the line containing the cursor in the
9931 selected window has changed. Variables starting with this_ are
9932 set in display_line and record information about the line
9933 containing the cursor. */
9934 tlbufpos = this_line_start_pos;
9935 tlendpos = this_line_end_pos;
9936 if (!consider_all_windows_p
9937 && CHARPOS (tlbufpos) > 0
9938 && NILP (w->update_mode_line)
9939 && !current_buffer->clip_changed
9940 && !current_buffer->prevent_redisplay_optimizations_p
9941 && FRAME_VISIBLE_P (XFRAME (w->frame))
9942 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9943 /* Make sure recorded data applies to current buffer, etc. */
9944 && this_line_buffer == current_buffer
9945 && current_buffer == XBUFFER (w->buffer)
9946 && NILP (w->force_start)
9947 && NILP (w->optional_new_start)
9948 /* Point must be on the line that we have info recorded about. */
9949 && PT >= CHARPOS (tlbufpos)
9950 && PT <= Z - CHARPOS (tlendpos)
9951 /* All text outside that line, including its final newline,
9952 must be unchanged */
9953 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9954 CHARPOS (tlendpos)))
9956 if (CHARPOS (tlbufpos) > BEGV
9957 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9958 && (CHARPOS (tlbufpos) == ZV
9959 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9960 /* Former continuation line has disappeared by becoming empty */
9961 goto cancel;
9962 else if (XFASTINT (w->last_modified) < MODIFF
9963 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9964 || MINI_WINDOW_P (w))
9966 /* We have to handle the case of continuation around a
9967 wide-column character (See the comment in indent.c around
9968 line 885).
9970 For instance, in the following case:
9972 -------- Insert --------
9973 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9974 J_I_ ==> J_I_ `^^' are cursors.
9975 ^^ ^^
9976 -------- --------
9978 As we have to redraw the line above, we should goto cancel. */
9980 struct it it;
9981 int line_height_before = this_line_pixel_height;
9983 /* Note that start_display will handle the case that the
9984 line starting at tlbufpos is a continuation lines. */
9985 start_display (&it, w, tlbufpos);
9987 /* Implementation note: It this still necessary? */
9988 if (it.current_x != this_line_start_x)
9989 goto cancel;
9991 TRACE ((stderr, "trying display optimization 1\n"));
9992 w->cursor.vpos = -1;
9993 overlay_arrow_seen = 0;
9994 it.vpos = this_line_vpos;
9995 it.current_y = this_line_y;
9996 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9997 display_line (&it);
9999 /* If line contains point, is not continued,
10000 and ends at same distance from eob as before, we win */
10001 if (w->cursor.vpos >= 0
10002 /* Line is not continued, otherwise this_line_start_pos
10003 would have been set to 0 in display_line. */
10004 && CHARPOS (this_line_start_pos)
10005 /* Line ends as before. */
10006 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10007 /* Line has same height as before. Otherwise other lines
10008 would have to be shifted up or down. */
10009 && this_line_pixel_height == line_height_before)
10011 /* If this is not the window's last line, we must adjust
10012 the charstarts of the lines below. */
10013 if (it.current_y < it.last_visible_y)
10015 struct glyph_row *row
10016 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10017 int delta, delta_bytes;
10019 if (Z - CHARPOS (tlendpos) == ZV)
10021 /* This line ends at end of (accessible part of)
10022 buffer. There is no newline to count. */
10023 delta = (Z
10024 - CHARPOS (tlendpos)
10025 - MATRIX_ROW_START_CHARPOS (row));
10026 delta_bytes = (Z_BYTE
10027 - BYTEPOS (tlendpos)
10028 - MATRIX_ROW_START_BYTEPOS (row));
10030 else
10032 /* This line ends in a newline. Must take
10033 account of the newline and the rest of the
10034 text that follows. */
10035 delta = (Z
10036 - CHARPOS (tlendpos)
10037 - MATRIX_ROW_START_CHARPOS (row));
10038 delta_bytes = (Z_BYTE
10039 - BYTEPOS (tlendpos)
10040 - MATRIX_ROW_START_BYTEPOS (row));
10043 increment_matrix_positions (w->current_matrix,
10044 this_line_vpos + 1,
10045 w->current_matrix->nrows,
10046 delta, delta_bytes);
10049 /* If this row displays text now but previously didn't,
10050 or vice versa, w->window_end_vpos may have to be
10051 adjusted. */
10052 if ((it.glyph_row - 1)->displays_text_p)
10054 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10055 XSETINT (w->window_end_vpos, this_line_vpos);
10057 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10058 && this_line_vpos > 0)
10059 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10060 w->window_end_valid = Qnil;
10062 /* Update hint: No need to try to scroll in update_window. */
10063 w->desired_matrix->no_scrolling_p = 1;
10065 #if GLYPH_DEBUG
10066 *w->desired_matrix->method = 0;
10067 debug_method_add (w, "optimization 1");
10068 #endif
10069 #ifdef HAVE_WINDOW_SYSTEM
10070 update_window_fringes (w, 0);
10071 #endif
10072 goto update;
10074 else
10075 goto cancel;
10077 else if (/* Cursor position hasn't changed. */
10078 PT == XFASTINT (w->last_point)
10079 /* Make sure the cursor was last displayed
10080 in this window. Otherwise we have to reposition it. */
10081 && 0 <= w->cursor.vpos
10082 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10084 if (!must_finish)
10086 do_pending_window_change (1);
10088 /* We used to always goto end_of_redisplay here, but this
10089 isn't enough if we have a blinking cursor. */
10090 if (w->cursor_off_p == w->last_cursor_off_p)
10091 goto end_of_redisplay;
10093 goto update;
10095 /* If highlighting the region, or if the cursor is in the echo area,
10096 then we can't just move the cursor. */
10097 else if (! (!NILP (Vtransient_mark_mode)
10098 && !NILP (current_buffer->mark_active))
10099 && (EQ (selected_window, current_buffer->last_selected_window)
10100 || highlight_nonselected_windows)
10101 && NILP (w->region_showing)
10102 && NILP (Vshow_trailing_whitespace)
10103 && !cursor_in_echo_area)
10105 struct it it;
10106 struct glyph_row *row;
10108 /* Skip from tlbufpos to PT and see where it is. Note that
10109 PT may be in invisible text. If so, we will end at the
10110 next visible position. */
10111 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10112 NULL, DEFAULT_FACE_ID);
10113 it.current_x = this_line_start_x;
10114 it.current_y = this_line_y;
10115 it.vpos = this_line_vpos;
10117 /* The call to move_it_to stops in front of PT, but
10118 moves over before-strings. */
10119 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10121 if (it.vpos == this_line_vpos
10122 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10123 row->enabled_p))
10125 xassert (this_line_vpos == it.vpos);
10126 xassert (this_line_y == it.current_y);
10127 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10128 #if GLYPH_DEBUG
10129 *w->desired_matrix->method = 0;
10130 debug_method_add (w, "optimization 3");
10131 #endif
10132 goto update;
10134 else
10135 goto cancel;
10138 cancel:
10139 /* Text changed drastically or point moved off of line. */
10140 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10143 CHARPOS (this_line_start_pos) = 0;
10144 consider_all_windows_p |= buffer_shared > 1;
10145 ++clear_face_cache_count;
10148 /* Build desired matrices, and update the display. If
10149 consider_all_windows_p is non-zero, do it for all windows on all
10150 frames. Otherwise do it for selected_window, only. */
10152 if (consider_all_windows_p)
10154 Lisp_Object tail, frame;
10155 int i, n = 0, size = 50;
10156 struct frame **updated
10157 = (struct frame **) alloca (size * sizeof *updated);
10159 /* Clear the face cache eventually. */
10160 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10162 clear_face_cache (0);
10163 clear_face_cache_count = 0;
10166 /* Recompute # windows showing selected buffer. This will be
10167 incremented each time such a window is displayed. */
10168 buffer_shared = 0;
10170 FOR_EACH_FRAME (tail, frame)
10172 struct frame *f = XFRAME (frame);
10174 if (FRAME_WINDOW_P (f) || f == sf)
10176 if (! EQ (frame, selected_frame))
10177 /* Select the frame, for the sake of frame-local
10178 variables. */
10179 select_frame_for_redisplay (frame);
10181 #ifdef HAVE_WINDOW_SYSTEM
10182 if (clear_face_cache_count % 50 == 0
10183 && FRAME_WINDOW_P (f))
10184 clear_image_cache (f, 0);
10185 #endif /* HAVE_WINDOW_SYSTEM */
10187 /* Mark all the scroll bars to be removed; we'll redeem
10188 the ones we want when we redisplay their windows. */
10189 if (condemn_scroll_bars_hook)
10190 condemn_scroll_bars_hook (f);
10192 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10193 redisplay_windows (FRAME_ROOT_WINDOW (f));
10195 /* Any scroll bars which redisplay_windows should have
10196 nuked should now go away. */
10197 if (judge_scroll_bars_hook)
10198 judge_scroll_bars_hook (f);
10200 /* If fonts changed, display again. */
10201 /* ??? rms: I suspect it is a mistake to jump all the way
10202 back to retry here. It should just retry this frame. */
10203 if (fonts_changed_p)
10204 goto retry;
10206 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10208 /* See if we have to hscroll. */
10209 if (hscroll_windows (f->root_window))
10210 goto retry;
10212 /* Prevent various kinds of signals during display
10213 update. stdio is not robust about handling
10214 signals, which can cause an apparent I/O
10215 error. */
10216 if (interrupt_input)
10217 unrequest_sigio ();
10218 STOP_POLLING;
10220 /* Update the display. */
10221 set_window_update_flags (XWINDOW (f->root_window), 1);
10222 pause |= update_frame (f, 0, 0);
10223 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10224 if (pause)
10225 break;
10226 #endif
10228 if (n == size)
10230 int nbytes = size * sizeof *updated;
10231 struct frame **p = (struct frame **) alloca (2 * nbytes);
10232 bcopy (updated, p, nbytes);
10233 size *= 2;
10236 updated[n++] = f;
10241 if (!pause)
10243 /* Do the mark_window_display_accurate after all windows have
10244 been redisplayed because this call resets flags in buffers
10245 which are needed for proper redisplay. */
10246 for (i = 0; i < n; ++i)
10248 struct frame *f = updated[i];
10249 mark_window_display_accurate (f->root_window, 1);
10250 if (frame_up_to_date_hook)
10251 frame_up_to_date_hook (f);
10255 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10257 Lisp_Object mini_window;
10258 struct frame *mini_frame;
10260 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10261 /* Use list_of_error, not Qerror, so that
10262 we catch only errors and don't run the debugger. */
10263 internal_condition_case_1 (redisplay_window_1, selected_window,
10264 list_of_error,
10265 redisplay_window_error);
10267 /* Compare desired and current matrices, perform output. */
10269 update:
10270 /* If fonts changed, display again. */
10271 if (fonts_changed_p)
10272 goto retry;
10274 /* Prevent various kinds of signals during display update.
10275 stdio is not robust about handling signals,
10276 which can cause an apparent I/O error. */
10277 if (interrupt_input)
10278 unrequest_sigio ();
10279 STOP_POLLING;
10281 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10283 if (hscroll_windows (selected_window))
10284 goto retry;
10286 XWINDOW (selected_window)->must_be_updated_p = 1;
10287 pause = update_frame (sf, 0, 0);
10290 /* We may have called echo_area_display at the top of this
10291 function. If the echo area is on another frame, that may
10292 have put text on a frame other than the selected one, so the
10293 above call to update_frame would not have caught it. Catch
10294 it here. */
10295 mini_window = FRAME_MINIBUF_WINDOW (sf);
10296 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10298 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10300 XWINDOW (mini_window)->must_be_updated_p = 1;
10301 pause |= update_frame (mini_frame, 0, 0);
10302 if (!pause && hscroll_windows (mini_window))
10303 goto retry;
10307 /* If display was paused because of pending input, make sure we do a
10308 thorough update the next time. */
10309 if (pause)
10311 /* Prevent the optimization at the beginning of
10312 redisplay_internal that tries a single-line update of the
10313 line containing the cursor in the selected window. */
10314 CHARPOS (this_line_start_pos) = 0;
10316 /* Let the overlay arrow be updated the next time. */
10317 update_overlay_arrows (0);
10319 /* If we pause after scrolling, some rows in the current
10320 matrices of some windows are not valid. */
10321 if (!WINDOW_FULL_WIDTH_P (w)
10322 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10323 update_mode_lines = 1;
10325 else
10327 if (!consider_all_windows_p)
10329 /* This has already been done above if
10330 consider_all_windows_p is set. */
10331 mark_window_display_accurate_1 (w, 1);
10333 /* Say overlay arrows are up to date. */
10334 update_overlay_arrows (1);
10336 if (frame_up_to_date_hook != 0)
10337 frame_up_to_date_hook (sf);
10340 update_mode_lines = 0;
10341 windows_or_buffers_changed = 0;
10342 cursor_type_changed = 0;
10345 /* Start SIGIO interrupts coming again. Having them off during the
10346 code above makes it less likely one will discard output, but not
10347 impossible, since there might be stuff in the system buffer here.
10348 But it is much hairier to try to do anything about that. */
10349 if (interrupt_input)
10350 request_sigio ();
10351 RESUME_POLLING;
10353 /* If a frame has become visible which was not before, redisplay
10354 again, so that we display it. Expose events for such a frame
10355 (which it gets when becoming visible) don't call the parts of
10356 redisplay constructing glyphs, so simply exposing a frame won't
10357 display anything in this case. So, we have to display these
10358 frames here explicitly. */
10359 if (!pause)
10361 Lisp_Object tail, frame;
10362 int new_count = 0;
10364 FOR_EACH_FRAME (tail, frame)
10366 int this_is_visible = 0;
10368 if (XFRAME (frame)->visible)
10369 this_is_visible = 1;
10370 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10371 if (XFRAME (frame)->visible)
10372 this_is_visible = 1;
10374 if (this_is_visible)
10375 new_count++;
10378 if (new_count != number_of_visible_frames)
10379 windows_or_buffers_changed++;
10382 /* Change frame size now if a change is pending. */
10383 do_pending_window_change (1);
10385 /* If we just did a pending size change, or have additional
10386 visible frames, redisplay again. */
10387 if (windows_or_buffers_changed && !pause)
10388 goto retry;
10390 end_of_redisplay:
10391 unbind_to (count, Qnil);
10392 RESUME_POLLING;
10396 /* Redisplay, but leave alone any recent echo area message unless
10397 another message has been requested in its place.
10399 This is useful in situations where you need to redisplay but no
10400 user action has occurred, making it inappropriate for the message
10401 area to be cleared. See tracking_off and
10402 wait_reading_process_output for examples of these situations.
10404 FROM_WHERE is an integer saying from where this function was
10405 called. This is useful for debugging. */
10407 void
10408 redisplay_preserve_echo_area (from_where)
10409 int from_where;
10411 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10413 if (!NILP (echo_area_buffer[1]))
10415 /* We have a previously displayed message, but no current
10416 message. Redisplay the previous message. */
10417 display_last_displayed_message_p = 1;
10418 redisplay_internal (1);
10419 display_last_displayed_message_p = 0;
10421 else
10422 redisplay_internal (1);
10424 if (rif != NULL && rif->flush_display_optional)
10425 rif->flush_display_optional (NULL);
10429 /* Function registered with record_unwind_protect in
10430 redisplay_internal. Reset redisplaying_p to the value it had
10431 before redisplay_internal was called, and clear
10432 prevent_freeing_realized_faces_p. It also selects the previously
10433 selected frame. */
10435 static Lisp_Object
10436 unwind_redisplay (val)
10437 Lisp_Object val;
10439 Lisp_Object old_redisplaying_p, old_frame;
10441 old_redisplaying_p = XCAR (val);
10442 redisplaying_p = XFASTINT (old_redisplaying_p);
10443 old_frame = XCDR (val);
10444 if (! EQ (old_frame, selected_frame))
10445 select_frame_for_redisplay (old_frame);
10446 return Qnil;
10450 /* Mark the display of window W as accurate or inaccurate. If
10451 ACCURATE_P is non-zero mark display of W as accurate. If
10452 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10453 redisplay_internal is called. */
10455 static void
10456 mark_window_display_accurate_1 (w, accurate_p)
10457 struct window *w;
10458 int accurate_p;
10460 if (BUFFERP (w->buffer))
10462 struct buffer *b = XBUFFER (w->buffer);
10464 w->last_modified
10465 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10466 w->last_overlay_modified
10467 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10468 w->last_had_star
10469 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10471 if (accurate_p)
10473 b->clip_changed = 0;
10474 b->prevent_redisplay_optimizations_p = 0;
10476 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10477 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10478 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10479 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10481 w->current_matrix->buffer = b;
10482 w->current_matrix->begv = BUF_BEGV (b);
10483 w->current_matrix->zv = BUF_ZV (b);
10485 w->last_cursor = w->cursor;
10486 w->last_cursor_off_p = w->cursor_off_p;
10488 if (w == XWINDOW (selected_window))
10489 w->last_point = make_number (BUF_PT (b));
10490 else
10491 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10495 if (accurate_p)
10497 w->window_end_valid = w->buffer;
10498 #if 0 /* This is incorrect with variable-height lines. */
10499 xassert (XINT (w->window_end_vpos)
10500 < (WINDOW_TOTAL_LINES (w)
10501 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10502 #endif
10503 w->update_mode_line = Qnil;
10508 /* Mark the display of windows in the window tree rooted at WINDOW as
10509 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10510 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10511 be redisplayed the next time redisplay_internal is called. */
10513 void
10514 mark_window_display_accurate (window, accurate_p)
10515 Lisp_Object window;
10516 int accurate_p;
10518 struct window *w;
10520 for (; !NILP (window); window = w->next)
10522 w = XWINDOW (window);
10523 mark_window_display_accurate_1 (w, accurate_p);
10525 if (!NILP (w->vchild))
10526 mark_window_display_accurate (w->vchild, accurate_p);
10527 if (!NILP (w->hchild))
10528 mark_window_display_accurate (w->hchild, accurate_p);
10531 if (accurate_p)
10533 update_overlay_arrows (1);
10535 else
10537 /* Force a thorough redisplay the next time by setting
10538 last_arrow_position and last_arrow_string to t, which is
10539 unequal to any useful value of Voverlay_arrow_... */
10540 update_overlay_arrows (-1);
10545 /* Return value in display table DP (Lisp_Char_Table *) for character
10546 C. Since a display table doesn't have any parent, we don't have to
10547 follow parent. Do not call this function directly but use the
10548 macro DISP_CHAR_VECTOR. */
10550 Lisp_Object
10551 disp_char_vector (dp, c)
10552 struct Lisp_Char_Table *dp;
10553 int c;
10555 int code[4], i;
10556 Lisp_Object val;
10558 if (SINGLE_BYTE_CHAR_P (c))
10559 return (dp->contents[c]);
10561 SPLIT_CHAR (c, code[0], code[1], code[2]);
10562 if (code[1] < 32)
10563 code[1] = -1;
10564 else if (code[2] < 32)
10565 code[2] = -1;
10567 /* Here, the possible range of code[0] (== charset ID) is
10568 128..max_charset. Since the top level char table contains data
10569 for multibyte characters after 256th element, we must increment
10570 code[0] by 128 to get a correct index. */
10571 code[0] += 128;
10572 code[3] = -1; /* anchor */
10574 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10576 val = dp->contents[code[i]];
10577 if (!SUB_CHAR_TABLE_P (val))
10578 return (NILP (val) ? dp->defalt : val);
10581 /* Here, val is a sub char table. We return the default value of
10582 it. */
10583 return (dp->defalt);
10588 /***********************************************************************
10589 Window Redisplay
10590 ***********************************************************************/
10592 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10594 static void
10595 redisplay_windows (window)
10596 Lisp_Object window;
10598 while (!NILP (window))
10600 struct window *w = XWINDOW (window);
10602 if (!NILP (w->hchild))
10603 redisplay_windows (w->hchild);
10604 else if (!NILP (w->vchild))
10605 redisplay_windows (w->vchild);
10606 else
10608 displayed_buffer = XBUFFER (w->buffer);
10609 /* Use list_of_error, not Qerror, so that
10610 we catch only errors and don't run the debugger. */
10611 internal_condition_case_1 (redisplay_window_0, window,
10612 list_of_error,
10613 redisplay_window_error);
10616 window = w->next;
10620 static Lisp_Object
10621 redisplay_window_error ()
10623 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10624 return Qnil;
10627 static Lisp_Object
10628 redisplay_window_0 (window)
10629 Lisp_Object window;
10631 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10632 redisplay_window (window, 0);
10633 return Qnil;
10636 static Lisp_Object
10637 redisplay_window_1 (window)
10638 Lisp_Object window;
10640 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10641 redisplay_window (window, 1);
10642 return Qnil;
10646 /* Increment GLYPH until it reaches END or CONDITION fails while
10647 adding (GLYPH)->pixel_width to X. */
10649 #define SKIP_GLYPHS(glyph, end, x, condition) \
10650 do \
10652 (x) += (glyph)->pixel_width; \
10653 ++(glyph); \
10655 while ((glyph) < (end) && (condition))
10658 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10659 DELTA is the number of bytes by which positions recorded in ROW
10660 differ from current buffer positions. */
10662 void
10663 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10664 struct window *w;
10665 struct glyph_row *row;
10666 struct glyph_matrix *matrix;
10667 int delta, delta_bytes, dy, dvpos;
10669 struct glyph *glyph = row->glyphs[TEXT_AREA];
10670 struct glyph *end = glyph + row->used[TEXT_AREA];
10671 struct glyph *cursor = NULL;
10672 /* The first glyph that starts a sequence of glyphs from string. */
10673 struct glyph *string_start;
10674 /* The X coordinate of string_start. */
10675 int string_start_x;
10676 /* The last known character position. */
10677 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10678 /* The last known character position before string_start. */
10679 int string_before_pos;
10680 int x = row->x;
10681 int cursor_x = x;
10682 int cursor_from_overlay_pos = 0;
10683 int pt_old = PT - delta;
10685 /* Skip over glyphs not having an object at the start of the row.
10686 These are special glyphs like truncation marks on terminal
10687 frames. */
10688 if (row->displays_text_p)
10689 while (glyph < end
10690 && INTEGERP (glyph->object)
10691 && glyph->charpos < 0)
10693 x += glyph->pixel_width;
10694 ++glyph;
10697 string_start = NULL;
10698 while (glyph < end
10699 && !INTEGERP (glyph->object)
10700 && (!BUFFERP (glyph->object)
10701 || (last_pos = glyph->charpos) < pt_old))
10703 if (! STRINGP (glyph->object))
10705 string_start = NULL;
10706 x += glyph->pixel_width;
10707 ++glyph;
10708 if (cursor_from_overlay_pos
10709 && last_pos > cursor_from_overlay_pos)
10711 cursor_from_overlay_pos = 0;
10712 cursor = 0;
10715 else
10717 string_before_pos = last_pos;
10718 string_start = glyph;
10719 string_start_x = x;
10720 /* Skip all glyphs from string. */
10723 int pos;
10724 if ((cursor == NULL || glyph > cursor)
10725 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10726 Qcursor, (glyph)->object))
10727 && (pos = string_buffer_position (w, glyph->object,
10728 string_before_pos),
10729 (pos == 0 /* From overlay */
10730 || pos == pt_old)))
10732 /* Estimate overlay buffer position from the buffer
10733 positions of the glyphs before and after the overlay.
10734 Add 1 to last_pos so that if point corresponds to the
10735 glyph right after the overlay, we still use a 'cursor'
10736 property found in that overlay. */
10737 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10738 cursor = glyph;
10739 cursor_x = x;
10741 x += glyph->pixel_width;
10742 ++glyph;
10744 while (glyph < end && STRINGP (glyph->object));
10748 if (cursor != NULL)
10750 glyph = cursor;
10751 x = cursor_x;
10753 else if (string_start
10754 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10756 /* We may have skipped over point because the previous glyphs
10757 are from string. As there's no easy way to know the
10758 character position of the current glyph, find the correct
10759 glyph on point by scanning from string_start again. */
10760 Lisp_Object limit;
10761 Lisp_Object string;
10762 int pos;
10764 limit = make_number (pt_old + 1);
10765 end = glyph;
10766 glyph = string_start;
10767 x = string_start_x;
10768 string = glyph->object;
10769 pos = string_buffer_position (w, string, string_before_pos);
10770 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10771 because we always put cursor after overlay strings. */
10772 while (pos == 0 && glyph < end)
10774 string = glyph->object;
10775 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10776 if (glyph < end)
10777 pos = string_buffer_position (w, glyph->object, string_before_pos);
10780 while (glyph < end)
10782 pos = XINT (Fnext_single_char_property_change
10783 (make_number (pos), Qdisplay, Qnil, limit));
10784 if (pos > pt_old)
10785 break;
10786 /* Skip glyphs from the same string. */
10787 string = glyph->object;
10788 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10789 /* Skip glyphs from an overlay. */
10790 while (glyph < end
10791 && ! string_buffer_position (w, glyph->object, pos))
10793 string = glyph->object;
10794 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10799 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10800 w->cursor.x = x;
10801 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10802 w->cursor.y = row->y + dy;
10804 if (w == XWINDOW (selected_window))
10806 if (!row->continued_p
10807 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10808 && row->x == 0)
10810 this_line_buffer = XBUFFER (w->buffer);
10812 CHARPOS (this_line_start_pos)
10813 = MATRIX_ROW_START_CHARPOS (row) + delta;
10814 BYTEPOS (this_line_start_pos)
10815 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10817 CHARPOS (this_line_end_pos)
10818 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10819 BYTEPOS (this_line_end_pos)
10820 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10822 this_line_y = w->cursor.y;
10823 this_line_pixel_height = row->height;
10824 this_line_vpos = w->cursor.vpos;
10825 this_line_start_x = row->x;
10827 else
10828 CHARPOS (this_line_start_pos) = 0;
10833 /* Run window scroll functions, if any, for WINDOW with new window
10834 start STARTP. Sets the window start of WINDOW to that position.
10836 We assume that the window's buffer is really current. */
10838 static INLINE struct text_pos
10839 run_window_scroll_functions (window, startp)
10840 Lisp_Object window;
10841 struct text_pos startp;
10843 struct window *w = XWINDOW (window);
10844 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10846 if (current_buffer != XBUFFER (w->buffer))
10847 abort ();
10849 if (!NILP (Vwindow_scroll_functions))
10851 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10852 make_number (CHARPOS (startp)));
10853 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10854 /* In case the hook functions switch buffers. */
10855 if (current_buffer != XBUFFER (w->buffer))
10856 set_buffer_internal_1 (XBUFFER (w->buffer));
10859 return startp;
10863 /* Make sure the line containing the cursor is fully visible.
10864 A value of 1 means there is nothing to be done.
10865 (Either the line is fully visible, or it cannot be made so,
10866 or we cannot tell.)
10868 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10869 is higher than window.
10871 A value of 0 means the caller should do scrolling
10872 as if point had gone off the screen. */
10874 static int
10875 make_cursor_line_fully_visible (w, force_p)
10876 struct window *w;
10877 int force_p;
10879 struct glyph_matrix *matrix;
10880 struct glyph_row *row;
10881 int window_height;
10883 /* It's not always possible to find the cursor, e.g, when a window
10884 is full of overlay strings. Don't do anything in that case. */
10885 if (w->cursor.vpos < 0)
10886 return 1;
10888 matrix = w->desired_matrix;
10889 row = MATRIX_ROW (matrix, w->cursor.vpos);
10891 /* If the cursor row is not partially visible, there's nothing to do. */
10892 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10893 return 1;
10895 /* If the row the cursor is in is taller than the window's height,
10896 it's not clear what to do, so do nothing. */
10897 window_height = window_box_height (w);
10898 if (row->height >= window_height)
10900 if (!force_p || w->vscroll)
10901 return 1;
10903 return 0;
10905 #if 0
10906 /* This code used to try to scroll the window just enough to make
10907 the line visible. It returned 0 to say that the caller should
10908 allocate larger glyph matrices. */
10910 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10912 int dy = row->height - row->visible_height;
10913 w->vscroll = 0;
10914 w->cursor.y += dy;
10915 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10917 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10919 int dy = - (row->height - row->visible_height);
10920 w->vscroll = dy;
10921 w->cursor.y += dy;
10922 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10925 /* When we change the cursor y-position of the selected window,
10926 change this_line_y as well so that the display optimization for
10927 the cursor line of the selected window in redisplay_internal uses
10928 the correct y-position. */
10929 if (w == XWINDOW (selected_window))
10930 this_line_y = w->cursor.y;
10932 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10933 redisplay with larger matrices. */
10934 if (matrix->nrows < required_matrix_height (w))
10936 fonts_changed_p = 1;
10937 return 0;
10940 return 1;
10941 #endif /* 0 */
10945 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10946 non-zero means only WINDOW is redisplayed in redisplay_internal.
10947 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10948 in redisplay_window to bring a partially visible line into view in
10949 the case that only the cursor has moved.
10951 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10952 last screen line's vertical height extends past the end of the screen.
10954 Value is
10956 1 if scrolling succeeded
10958 0 if scrolling didn't find point.
10960 -1 if new fonts have been loaded so that we must interrupt
10961 redisplay, adjust glyph matrices, and try again. */
10963 enum
10965 SCROLLING_SUCCESS,
10966 SCROLLING_FAILED,
10967 SCROLLING_NEED_LARGER_MATRICES
10970 static int
10971 try_scrolling (window, just_this_one_p, scroll_conservatively,
10972 scroll_step, temp_scroll_step, last_line_misfit)
10973 Lisp_Object window;
10974 int just_this_one_p;
10975 EMACS_INT scroll_conservatively, scroll_step;
10976 int temp_scroll_step;
10977 int last_line_misfit;
10979 struct window *w = XWINDOW (window);
10980 struct frame *f = XFRAME (w->frame);
10981 struct text_pos scroll_margin_pos;
10982 struct text_pos pos;
10983 struct text_pos startp;
10984 struct it it;
10985 Lisp_Object window_end;
10986 int this_scroll_margin;
10987 int dy = 0;
10988 int scroll_max;
10989 int rc;
10990 int amount_to_scroll = 0;
10991 Lisp_Object aggressive;
10992 int height;
10993 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10995 #if GLYPH_DEBUG
10996 debug_method_add (w, "try_scrolling");
10997 #endif
10999 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11001 /* Compute scroll margin height in pixels. We scroll when point is
11002 within this distance from the top or bottom of the window. */
11003 if (scroll_margin > 0)
11005 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11006 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11008 else
11009 this_scroll_margin = 0;
11011 /* Force scroll_conservatively to have a reasonable value so it doesn't
11012 cause an overflow while computing how much to scroll. */
11013 if (scroll_conservatively)
11014 scroll_conservatively = min (scroll_conservatively,
11015 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11017 /* Compute how much we should try to scroll maximally to bring point
11018 into view. */
11019 if (scroll_step || scroll_conservatively || temp_scroll_step)
11020 scroll_max = max (scroll_step,
11021 max (scroll_conservatively, temp_scroll_step));
11022 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11023 || NUMBERP (current_buffer->scroll_up_aggressively))
11024 /* We're trying to scroll because of aggressive scrolling
11025 but no scroll_step is set. Choose an arbitrary one. Maybe
11026 there should be a variable for this. */
11027 scroll_max = 10;
11028 else
11029 scroll_max = 0;
11030 scroll_max *= FRAME_LINE_HEIGHT (f);
11032 /* Decide whether we have to scroll down. Start at the window end
11033 and move this_scroll_margin up to find the position of the scroll
11034 margin. */
11035 window_end = Fwindow_end (window, Qt);
11037 too_near_end:
11039 CHARPOS (scroll_margin_pos) = XINT (window_end);
11040 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11042 if (this_scroll_margin || extra_scroll_margin_lines)
11044 start_display (&it, w, scroll_margin_pos);
11045 if (this_scroll_margin)
11046 move_it_vertically (&it, - this_scroll_margin);
11047 if (extra_scroll_margin_lines)
11048 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11049 scroll_margin_pos = it.current.pos;
11052 if (PT >= CHARPOS (scroll_margin_pos))
11054 int y0;
11056 /* Point is in the scroll margin at the bottom of the window, or
11057 below. Compute a new window start that makes point visible. */
11059 /* Compute the distance from the scroll margin to PT.
11060 Give up if the distance is greater than scroll_max. */
11061 start_display (&it, w, scroll_margin_pos);
11062 y0 = it.current_y;
11063 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11064 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11066 /* To make point visible, we have to move the window start
11067 down so that the line the cursor is in is visible, which
11068 means we have to add in the height of the cursor line. */
11069 dy = line_bottom_y (&it) - y0;
11071 if (dy > scroll_max)
11072 return SCROLLING_FAILED;
11074 /* Move the window start down. If scrolling conservatively,
11075 move it just enough down to make point visible. If
11076 scroll_step is set, move it down by scroll_step. */
11077 start_display (&it, w, startp);
11079 if (scroll_conservatively)
11080 /* Set AMOUNT_TO_SCROLL to at least one line,
11081 and at most scroll_conservatively lines. */
11082 amount_to_scroll
11083 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11084 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11085 else if (scroll_step || temp_scroll_step)
11086 amount_to_scroll = scroll_max;
11087 else
11089 aggressive = current_buffer->scroll_up_aggressively;
11090 height = WINDOW_BOX_TEXT_HEIGHT (w);
11091 if (NUMBERP (aggressive))
11093 double float_amount = XFLOATINT (aggressive) * height;
11094 amount_to_scroll = float_amount;
11095 if (amount_to_scroll == 0 && float_amount > 0)
11096 amount_to_scroll = 1;
11100 if (amount_to_scroll <= 0)
11101 return SCROLLING_FAILED;
11103 /* If moving by amount_to_scroll leaves STARTP unchanged,
11104 move it down one screen line. */
11106 move_it_vertically (&it, amount_to_scroll);
11107 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11108 move_it_by_lines (&it, 1, 1);
11109 startp = it.current.pos;
11111 else
11113 /* See if point is inside the scroll margin at the top of the
11114 window. */
11115 scroll_margin_pos = startp;
11116 if (this_scroll_margin)
11118 start_display (&it, w, startp);
11119 move_it_vertically (&it, this_scroll_margin);
11120 scroll_margin_pos = it.current.pos;
11123 if (PT < CHARPOS (scroll_margin_pos))
11125 /* Point is in the scroll margin at the top of the window or
11126 above what is displayed in the window. */
11127 int y0;
11129 /* Compute the vertical distance from PT to the scroll
11130 margin position. Give up if distance is greater than
11131 scroll_max. */
11132 SET_TEXT_POS (pos, PT, PT_BYTE);
11133 start_display (&it, w, pos);
11134 y0 = it.current_y;
11135 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11136 it.last_visible_y, -1,
11137 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11138 dy = it.current_y - y0;
11139 if (dy > scroll_max)
11140 return SCROLLING_FAILED;
11142 /* Compute new window start. */
11143 start_display (&it, w, startp);
11145 if (scroll_conservatively)
11146 amount_to_scroll
11147 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11148 else if (scroll_step || temp_scroll_step)
11149 amount_to_scroll = scroll_max;
11150 else
11152 aggressive = current_buffer->scroll_down_aggressively;
11153 height = WINDOW_BOX_TEXT_HEIGHT (w);
11154 if (NUMBERP (aggressive))
11156 double float_amount = XFLOATINT (aggressive) * height;
11157 amount_to_scroll = float_amount;
11158 if (amount_to_scroll == 0 && float_amount > 0)
11159 amount_to_scroll = 1;
11163 if (amount_to_scroll <= 0)
11164 return SCROLLING_FAILED;
11166 move_it_vertically (&it, - amount_to_scroll);
11167 startp = it.current.pos;
11171 /* Run window scroll functions. */
11172 startp = run_window_scroll_functions (window, startp);
11174 /* Display the window. Give up if new fonts are loaded, or if point
11175 doesn't appear. */
11176 if (!try_window (window, startp))
11177 rc = SCROLLING_NEED_LARGER_MATRICES;
11178 else if (w->cursor.vpos < 0)
11180 clear_glyph_matrix (w->desired_matrix);
11181 rc = SCROLLING_FAILED;
11183 else
11185 /* Maybe forget recorded base line for line number display. */
11186 if (!just_this_one_p
11187 || current_buffer->clip_changed
11188 || BEG_UNCHANGED < CHARPOS (startp))
11189 w->base_line_number = Qnil;
11191 /* If cursor ends up on a partially visible line,
11192 treat that as being off the bottom of the screen. */
11193 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11195 clear_glyph_matrix (w->desired_matrix);
11196 ++extra_scroll_margin_lines;
11197 goto too_near_end;
11199 rc = SCROLLING_SUCCESS;
11202 return rc;
11206 /* Compute a suitable window start for window W if display of W starts
11207 on a continuation line. Value is non-zero if a new window start
11208 was computed.
11210 The new window start will be computed, based on W's width, starting
11211 from the start of the continued line. It is the start of the
11212 screen line with the minimum distance from the old start W->start. */
11214 static int
11215 compute_window_start_on_continuation_line (w)
11216 struct window *w;
11218 struct text_pos pos, start_pos;
11219 int window_start_changed_p = 0;
11221 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11223 /* If window start is on a continuation line... Window start may be
11224 < BEGV in case there's invisible text at the start of the
11225 buffer (M-x rmail, for example). */
11226 if (CHARPOS (start_pos) > BEGV
11227 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11229 struct it it;
11230 struct glyph_row *row;
11232 /* Handle the case that the window start is out of range. */
11233 if (CHARPOS (start_pos) < BEGV)
11234 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11235 else if (CHARPOS (start_pos) > ZV)
11236 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11238 /* Find the start of the continued line. This should be fast
11239 because scan_buffer is fast (newline cache). */
11240 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11241 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11242 row, DEFAULT_FACE_ID);
11243 reseat_at_previous_visible_line_start (&it);
11245 /* If the line start is "too far" away from the window start,
11246 say it takes too much time to compute a new window start. */
11247 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11248 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11250 int min_distance, distance;
11252 /* Move forward by display lines to find the new window
11253 start. If window width was enlarged, the new start can
11254 be expected to be > the old start. If window width was
11255 decreased, the new window start will be < the old start.
11256 So, we're looking for the display line start with the
11257 minimum distance from the old window start. */
11258 pos = it.current.pos;
11259 min_distance = INFINITY;
11260 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11261 distance < min_distance)
11263 min_distance = distance;
11264 pos = it.current.pos;
11265 move_it_by_lines (&it, 1, 0);
11268 /* Set the window start there. */
11269 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11270 window_start_changed_p = 1;
11274 return window_start_changed_p;
11278 /* Try cursor movement in case text has not changed in window WINDOW,
11279 with window start STARTP. Value is
11281 CURSOR_MOVEMENT_SUCCESS if successful
11283 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11285 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11286 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11287 we want to scroll as if scroll-step were set to 1. See the code.
11289 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11290 which case we have to abort this redisplay, and adjust matrices
11291 first. */
11293 enum
11295 CURSOR_MOVEMENT_SUCCESS,
11296 CURSOR_MOVEMENT_CANNOT_BE_USED,
11297 CURSOR_MOVEMENT_MUST_SCROLL,
11298 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11301 static int
11302 try_cursor_movement (window, startp, scroll_step)
11303 Lisp_Object window;
11304 struct text_pos startp;
11305 int *scroll_step;
11307 struct window *w = XWINDOW (window);
11308 struct frame *f = XFRAME (w->frame);
11309 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11311 #if GLYPH_DEBUG
11312 if (inhibit_try_cursor_movement)
11313 return rc;
11314 #endif
11316 /* Handle case where text has not changed, only point, and it has
11317 not moved off the frame. */
11318 if (/* Point may be in this window. */
11319 PT >= CHARPOS (startp)
11320 /* Selective display hasn't changed. */
11321 && !current_buffer->clip_changed
11322 /* Function force-mode-line-update is used to force a thorough
11323 redisplay. It sets either windows_or_buffers_changed or
11324 update_mode_lines. So don't take a shortcut here for these
11325 cases. */
11326 && !update_mode_lines
11327 && !windows_or_buffers_changed
11328 && !cursor_type_changed
11329 /* Can't use this case if highlighting a region. When a
11330 region exists, cursor movement has to do more than just
11331 set the cursor. */
11332 && !(!NILP (Vtransient_mark_mode)
11333 && !NILP (current_buffer->mark_active))
11334 && NILP (w->region_showing)
11335 && NILP (Vshow_trailing_whitespace)
11336 /* Right after splitting windows, last_point may be nil. */
11337 && INTEGERP (w->last_point)
11338 /* This code is not used for mini-buffer for the sake of the case
11339 of redisplaying to replace an echo area message; since in
11340 that case the mini-buffer contents per se are usually
11341 unchanged. This code is of no real use in the mini-buffer
11342 since the handling of this_line_start_pos, etc., in redisplay
11343 handles the same cases. */
11344 && !EQ (window, minibuf_window)
11345 /* When splitting windows or for new windows, it happens that
11346 redisplay is called with a nil window_end_vpos or one being
11347 larger than the window. This should really be fixed in
11348 window.c. I don't have this on my list, now, so we do
11349 approximately the same as the old redisplay code. --gerd. */
11350 && INTEGERP (w->window_end_vpos)
11351 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11352 && (FRAME_WINDOW_P (f)
11353 || !overlay_arrow_in_current_buffer_p ()))
11355 int this_scroll_margin, top_scroll_margin;
11356 struct glyph_row *row = NULL;
11358 #if GLYPH_DEBUG
11359 debug_method_add (w, "cursor movement");
11360 #endif
11362 /* Scroll if point within this distance from the top or bottom
11363 of the window. This is a pixel value. */
11364 this_scroll_margin = max (0, scroll_margin);
11365 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11366 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11368 top_scroll_margin = this_scroll_margin;
11369 if (WINDOW_WANTS_HEADER_LINE_P (w))
11370 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11372 /* Start with the row the cursor was displayed during the last
11373 not paused redisplay. Give up if that row is not valid. */
11374 if (w->last_cursor.vpos < 0
11375 || w->last_cursor.vpos >= w->current_matrix->nrows)
11376 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11377 else
11379 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11380 if (row->mode_line_p)
11381 ++row;
11382 if (!row->enabled_p)
11383 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11386 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11388 int scroll_p = 0;
11389 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11391 if (PT > XFASTINT (w->last_point))
11393 /* Point has moved forward. */
11394 while (MATRIX_ROW_END_CHARPOS (row) < PT
11395 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11397 xassert (row->enabled_p);
11398 ++row;
11401 /* The end position of a row equals the start position
11402 of the next row. If PT is there, we would rather
11403 display it in the next line. */
11404 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11405 && MATRIX_ROW_END_CHARPOS (row) == PT
11406 && !cursor_row_p (w, row))
11407 ++row;
11409 /* If within the scroll margin, scroll. Note that
11410 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11411 the next line would be drawn, and that
11412 this_scroll_margin can be zero. */
11413 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11414 || PT > MATRIX_ROW_END_CHARPOS (row)
11415 /* Line is completely visible last line in window
11416 and PT is to be set in the next line. */
11417 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11418 && PT == MATRIX_ROW_END_CHARPOS (row)
11419 && !row->ends_at_zv_p
11420 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11421 scroll_p = 1;
11423 else if (PT < XFASTINT (w->last_point))
11425 /* Cursor has to be moved backward. Note that PT >=
11426 CHARPOS (startp) because of the outer if-statement. */
11427 while (!row->mode_line_p
11428 && (MATRIX_ROW_START_CHARPOS (row) > PT
11429 || (MATRIX_ROW_START_CHARPOS (row) == PT
11430 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11431 && (row->y > top_scroll_margin
11432 || CHARPOS (startp) == BEGV))
11434 xassert (row->enabled_p);
11435 --row;
11438 /* Consider the following case: Window starts at BEGV,
11439 there is invisible, intangible text at BEGV, so that
11440 display starts at some point START > BEGV. It can
11441 happen that we are called with PT somewhere between
11442 BEGV and START. Try to handle that case. */
11443 if (row < w->current_matrix->rows
11444 || row->mode_line_p)
11446 row = w->current_matrix->rows;
11447 if (row->mode_line_p)
11448 ++row;
11451 /* Due to newlines in overlay strings, we may have to
11452 skip forward over overlay strings. */
11453 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11454 && MATRIX_ROW_END_CHARPOS (row) == PT
11455 && !cursor_row_p (w, row))
11456 ++row;
11458 /* If within the scroll margin, scroll. */
11459 if (row->y < top_scroll_margin
11460 && CHARPOS (startp) != BEGV)
11461 scroll_p = 1;
11464 if (PT < MATRIX_ROW_START_CHARPOS (row)
11465 || PT > MATRIX_ROW_END_CHARPOS (row))
11467 /* if PT is not in the glyph row, give up. */
11468 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11470 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11472 if (PT == MATRIX_ROW_END_CHARPOS (row)
11473 && !row->ends_at_zv_p
11474 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11475 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11476 else if (row->height > window_box_height (w))
11478 /* If we end up in a partially visible line, let's
11479 make it fully visible, except when it's taller
11480 than the window, in which case we can't do much
11481 about it. */
11482 *scroll_step = 1;
11483 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11485 else
11487 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11488 if (!make_cursor_line_fully_visible (w, 0))
11489 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11490 else
11491 rc = CURSOR_MOVEMENT_SUCCESS;
11494 else if (scroll_p)
11495 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11496 else
11498 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11499 rc = CURSOR_MOVEMENT_SUCCESS;
11504 return rc;
11507 void
11508 set_vertical_scroll_bar (w)
11509 struct window *w;
11511 int start, end, whole;
11513 /* Calculate the start and end positions for the current window.
11514 At some point, it would be nice to choose between scrollbars
11515 which reflect the whole buffer size, with special markers
11516 indicating narrowing, and scrollbars which reflect only the
11517 visible region.
11519 Note that mini-buffers sometimes aren't displaying any text. */
11520 if (!MINI_WINDOW_P (w)
11521 || (w == XWINDOW (minibuf_window)
11522 && NILP (echo_area_buffer[0])))
11524 struct buffer *buf = XBUFFER (w->buffer);
11525 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11526 start = marker_position (w->start) - BUF_BEGV (buf);
11527 /* I don't think this is guaranteed to be right. For the
11528 moment, we'll pretend it is. */
11529 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11531 if (end < start)
11532 end = start;
11533 if (whole < (end - start))
11534 whole = end - start;
11536 else
11537 start = end = whole = 0;
11539 /* Indicate what this scroll bar ought to be displaying now. */
11540 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11544 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11545 selected_window is redisplayed.
11547 We can return without actually redisplaying the window if
11548 fonts_changed_p is nonzero. In that case, redisplay_internal will
11549 retry. */
11551 static void
11552 redisplay_window (window, just_this_one_p)
11553 Lisp_Object window;
11554 int just_this_one_p;
11556 struct window *w = XWINDOW (window);
11557 struct frame *f = XFRAME (w->frame);
11558 struct buffer *buffer = XBUFFER (w->buffer);
11559 struct buffer *old = current_buffer;
11560 struct text_pos lpoint, opoint, startp;
11561 int update_mode_line;
11562 int tem;
11563 struct it it;
11564 /* Record it now because it's overwritten. */
11565 int current_matrix_up_to_date_p = 0;
11566 int used_current_matrix_p = 0;
11567 /* This is less strict than current_matrix_up_to_date_p.
11568 It indictes that the buffer contents and narrowing are unchanged. */
11569 int buffer_unchanged_p = 0;
11570 int temp_scroll_step = 0;
11571 int count = SPECPDL_INDEX ();
11572 int rc;
11573 int centering_position;
11574 int last_line_misfit = 0;
11576 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11577 opoint = lpoint;
11579 /* W must be a leaf window here. */
11580 xassert (!NILP (w->buffer));
11581 #if GLYPH_DEBUG
11582 *w->desired_matrix->method = 0;
11583 #endif
11585 specbind (Qinhibit_point_motion_hooks, Qt);
11587 reconsider_clip_changes (w, buffer);
11589 /* Has the mode line to be updated? */
11590 update_mode_line = (!NILP (w->update_mode_line)
11591 || update_mode_lines
11592 || buffer->clip_changed
11593 || buffer->prevent_redisplay_optimizations_p);
11595 if (MINI_WINDOW_P (w))
11597 if (w == XWINDOW (echo_area_window)
11598 && !NILP (echo_area_buffer[0]))
11600 if (update_mode_line)
11601 /* We may have to update a tty frame's menu bar or a
11602 tool-bar. Example `M-x C-h C-h C-g'. */
11603 goto finish_menu_bars;
11604 else
11605 /* We've already displayed the echo area glyphs in this window. */
11606 goto finish_scroll_bars;
11608 else if ((w != XWINDOW (minibuf_window)
11609 || minibuf_level == 0)
11610 /* When buffer is nonempty, redisplay window normally. */
11611 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11612 /* Quail displays non-mini buffers in minibuffer window.
11613 In that case, redisplay the window normally. */
11614 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11616 /* W is a mini-buffer window, but it's not active, so clear
11617 it. */
11618 int yb = window_text_bottom_y (w);
11619 struct glyph_row *row;
11620 int y;
11622 for (y = 0, row = w->desired_matrix->rows;
11623 y < yb;
11624 y += row->height, ++row)
11625 blank_row (w, row, y);
11626 goto finish_scroll_bars;
11629 clear_glyph_matrix (w->desired_matrix);
11632 /* Otherwise set up data on this window; select its buffer and point
11633 value. */
11634 /* Really select the buffer, for the sake of buffer-local
11635 variables. */
11636 set_buffer_internal_1 (XBUFFER (w->buffer));
11637 SET_TEXT_POS (opoint, PT, PT_BYTE);
11639 current_matrix_up_to_date_p
11640 = (!NILP (w->window_end_valid)
11641 && !current_buffer->clip_changed
11642 && !current_buffer->prevent_redisplay_optimizations_p
11643 && XFASTINT (w->last_modified) >= MODIFF
11644 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11646 buffer_unchanged_p
11647 = (!NILP (w->window_end_valid)
11648 && !current_buffer->clip_changed
11649 && XFASTINT (w->last_modified) >= MODIFF
11650 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11652 /* When windows_or_buffers_changed is non-zero, we can't rely on
11653 the window end being valid, so set it to nil there. */
11654 if (windows_or_buffers_changed)
11656 /* If window starts on a continuation line, maybe adjust the
11657 window start in case the window's width changed. */
11658 if (XMARKER (w->start)->buffer == current_buffer)
11659 compute_window_start_on_continuation_line (w);
11661 w->window_end_valid = Qnil;
11664 /* Some sanity checks. */
11665 CHECK_WINDOW_END (w);
11666 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11667 abort ();
11668 if (BYTEPOS (opoint) < CHARPOS (opoint))
11669 abort ();
11671 /* If %c is in mode line, update it if needed. */
11672 if (!NILP (w->column_number_displayed)
11673 /* This alternative quickly identifies a common case
11674 where no change is needed. */
11675 && !(PT == XFASTINT (w->last_point)
11676 && XFASTINT (w->last_modified) >= MODIFF
11677 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11678 && (XFASTINT (w->column_number_displayed)
11679 != (int) current_column ())) /* iftc */
11680 update_mode_line = 1;
11682 /* Count number of windows showing the selected buffer. An indirect
11683 buffer counts as its base buffer. */
11684 if (!just_this_one_p)
11686 struct buffer *current_base, *window_base;
11687 current_base = current_buffer;
11688 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11689 if (current_base->base_buffer)
11690 current_base = current_base->base_buffer;
11691 if (window_base->base_buffer)
11692 window_base = window_base->base_buffer;
11693 if (current_base == window_base)
11694 buffer_shared++;
11697 /* Point refers normally to the selected window. For any other
11698 window, set up appropriate value. */
11699 if (!EQ (window, selected_window))
11701 int new_pt = XMARKER (w->pointm)->charpos;
11702 int new_pt_byte = marker_byte_position (w->pointm);
11703 if (new_pt < BEGV)
11705 new_pt = BEGV;
11706 new_pt_byte = BEGV_BYTE;
11707 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11709 else if (new_pt > (ZV - 1))
11711 new_pt = ZV;
11712 new_pt_byte = ZV_BYTE;
11713 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11716 /* We don't use SET_PT so that the point-motion hooks don't run. */
11717 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11720 /* If any of the character widths specified in the display table
11721 have changed, invalidate the width run cache. It's true that
11722 this may be a bit late to catch such changes, but the rest of
11723 redisplay goes (non-fatally) haywire when the display table is
11724 changed, so why should we worry about doing any better? */
11725 if (current_buffer->width_run_cache)
11727 struct Lisp_Char_Table *disptab = buffer_display_table ();
11729 if (! disptab_matches_widthtab (disptab,
11730 XVECTOR (current_buffer->width_table)))
11732 invalidate_region_cache (current_buffer,
11733 current_buffer->width_run_cache,
11734 BEG, Z);
11735 recompute_width_table (current_buffer, disptab);
11739 /* If window-start is screwed up, choose a new one. */
11740 if (XMARKER (w->start)->buffer != current_buffer)
11741 goto recenter;
11743 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11745 /* If someone specified a new starting point but did not insist,
11746 check whether it can be used. */
11747 if (!NILP (w->optional_new_start)
11748 && CHARPOS (startp) >= BEGV
11749 && CHARPOS (startp) <= ZV)
11751 w->optional_new_start = Qnil;
11752 start_display (&it, w, startp);
11753 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11754 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11755 if (IT_CHARPOS (it) == PT)
11756 w->force_start = Qt;
11757 /* IT may overshoot PT if text at PT is invisible. */
11758 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11759 w->force_start = Qt;
11764 /* Handle case where place to start displaying has been specified,
11765 unless the specified location is outside the accessible range. */
11766 if (!NILP (w->force_start)
11767 || w->frozen_window_start_p)
11769 /* We set this later on if we have to adjust point. */
11770 int new_vpos = -1;
11772 w->force_start = Qnil;
11773 w->vscroll = 0;
11774 w->window_end_valid = Qnil;
11776 /* Forget any recorded base line for line number display. */
11777 if (!buffer_unchanged_p)
11778 w->base_line_number = Qnil;
11780 /* Redisplay the mode line. Select the buffer properly for that.
11781 Also, run the hook window-scroll-functions
11782 because we have scrolled. */
11783 /* Note, we do this after clearing force_start because
11784 if there's an error, it is better to forget about force_start
11785 than to get into an infinite loop calling the hook functions
11786 and having them get more errors. */
11787 if (!update_mode_line
11788 || ! NILP (Vwindow_scroll_functions))
11790 update_mode_line = 1;
11791 w->update_mode_line = Qt;
11792 startp = run_window_scroll_functions (window, startp);
11795 w->last_modified = make_number (0);
11796 w->last_overlay_modified = make_number (0);
11797 if (CHARPOS (startp) < BEGV)
11798 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11799 else if (CHARPOS (startp) > ZV)
11800 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11802 /* Redisplay, then check if cursor has been set during the
11803 redisplay. Give up if new fonts were loaded. */
11804 if (!try_window (window, startp))
11806 w->force_start = Qt;
11807 clear_glyph_matrix (w->desired_matrix);
11808 goto need_larger_matrices;
11811 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11813 /* If point does not appear, try to move point so it does
11814 appear. The desired matrix has been built above, so we
11815 can use it here. */
11816 new_vpos = window_box_height (w) / 2;
11819 if (!make_cursor_line_fully_visible (w, 0))
11821 /* Point does appear, but on a line partly visible at end of window.
11822 Move it back to a fully-visible line. */
11823 new_vpos = window_box_height (w);
11826 /* If we need to move point for either of the above reasons,
11827 now actually do it. */
11828 if (new_vpos >= 0)
11830 struct glyph_row *row;
11832 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11833 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11834 ++row;
11836 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11837 MATRIX_ROW_START_BYTEPOS (row));
11839 if (w != XWINDOW (selected_window))
11840 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11841 else if (current_buffer == old)
11842 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11844 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11846 /* If we are highlighting the region, then we just changed
11847 the region, so redisplay to show it. */
11848 if (!NILP (Vtransient_mark_mode)
11849 && !NILP (current_buffer->mark_active))
11851 clear_glyph_matrix (w->desired_matrix);
11852 if (!try_window (window, startp))
11853 goto need_larger_matrices;
11857 #if GLYPH_DEBUG
11858 debug_method_add (w, "forced window start");
11859 #endif
11860 goto done;
11863 /* Handle case where text has not changed, only point, and it has
11864 not moved off the frame, and we are not retrying after hscroll.
11865 (current_matrix_up_to_date_p is nonzero when retrying.) */
11866 if (current_matrix_up_to_date_p
11867 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11868 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11870 switch (rc)
11872 case CURSOR_MOVEMENT_SUCCESS:
11873 used_current_matrix_p = 1;
11874 goto done;
11876 #if 0 /* try_cursor_movement never returns this value. */
11877 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11878 goto need_larger_matrices;
11879 #endif
11881 case CURSOR_MOVEMENT_MUST_SCROLL:
11882 goto try_to_scroll;
11884 default:
11885 abort ();
11888 /* If current starting point was originally the beginning of a line
11889 but no longer is, find a new starting point. */
11890 else if (!NILP (w->start_at_line_beg)
11891 && !(CHARPOS (startp) <= BEGV
11892 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11894 #if GLYPH_DEBUG
11895 debug_method_add (w, "recenter 1");
11896 #endif
11897 goto recenter;
11900 /* Try scrolling with try_window_id. Value is > 0 if update has
11901 been done, it is -1 if we know that the same window start will
11902 not work. It is 0 if unsuccessful for some other reason. */
11903 else if ((tem = try_window_id (w)) != 0)
11905 #if GLYPH_DEBUG
11906 debug_method_add (w, "try_window_id %d", tem);
11907 #endif
11909 if (fonts_changed_p)
11910 goto need_larger_matrices;
11911 if (tem > 0)
11912 goto done;
11914 /* Otherwise try_window_id has returned -1 which means that we
11915 don't want the alternative below this comment to execute. */
11917 else if (CHARPOS (startp) >= BEGV
11918 && CHARPOS (startp) <= ZV
11919 && PT >= CHARPOS (startp)
11920 && (CHARPOS (startp) < ZV
11921 /* Avoid starting at end of buffer. */
11922 || CHARPOS (startp) == BEGV
11923 || (XFASTINT (w->last_modified) >= MODIFF
11924 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11926 #if GLYPH_DEBUG
11927 debug_method_add (w, "same window start");
11928 #endif
11930 /* Try to redisplay starting at same place as before.
11931 If point has not moved off frame, accept the results. */
11932 if (!current_matrix_up_to_date_p
11933 /* Don't use try_window_reusing_current_matrix in this case
11934 because a window scroll function can have changed the
11935 buffer. */
11936 || !NILP (Vwindow_scroll_functions)
11937 || MINI_WINDOW_P (w)
11938 || !(used_current_matrix_p
11939 = try_window_reusing_current_matrix (w)))
11941 IF_DEBUG (debug_method_add (w, "1"));
11942 try_window (window, startp);
11945 if (fonts_changed_p)
11946 goto need_larger_matrices;
11948 if (w->cursor.vpos >= 0)
11950 if (!just_this_one_p
11951 || current_buffer->clip_changed
11952 || BEG_UNCHANGED < CHARPOS (startp))
11953 /* Forget any recorded base line for line number display. */
11954 w->base_line_number = Qnil;
11956 if (!make_cursor_line_fully_visible (w, 1))
11958 clear_glyph_matrix (w->desired_matrix);
11959 last_line_misfit = 1;
11961 /* Drop through and scroll. */
11962 else
11963 goto done;
11965 else
11966 clear_glyph_matrix (w->desired_matrix);
11969 try_to_scroll:
11971 w->last_modified = make_number (0);
11972 w->last_overlay_modified = make_number (0);
11974 /* Redisplay the mode line. Select the buffer properly for that. */
11975 if (!update_mode_line)
11977 update_mode_line = 1;
11978 w->update_mode_line = Qt;
11981 /* Try to scroll by specified few lines. */
11982 if ((scroll_conservatively
11983 || scroll_step
11984 || temp_scroll_step
11985 || NUMBERP (current_buffer->scroll_up_aggressively)
11986 || NUMBERP (current_buffer->scroll_down_aggressively))
11987 && !current_buffer->clip_changed
11988 && CHARPOS (startp) >= BEGV
11989 && CHARPOS (startp) <= ZV)
11991 /* The function returns -1 if new fonts were loaded, 1 if
11992 successful, 0 if not successful. */
11993 int rc = try_scrolling (window, just_this_one_p,
11994 scroll_conservatively,
11995 scroll_step,
11996 temp_scroll_step, last_line_misfit);
11997 switch (rc)
11999 case SCROLLING_SUCCESS:
12000 goto done;
12002 case SCROLLING_NEED_LARGER_MATRICES:
12003 goto need_larger_matrices;
12005 case SCROLLING_FAILED:
12006 break;
12008 default:
12009 abort ();
12013 /* Finally, just choose place to start which centers point */
12015 recenter:
12016 centering_position = window_box_height (w) / 2;
12018 point_at_top:
12019 /* Jump here with centering_position already set to 0. */
12021 #if GLYPH_DEBUG
12022 debug_method_add (w, "recenter");
12023 #endif
12025 /* w->vscroll = 0; */
12027 /* Forget any previously recorded base line for line number display. */
12028 if (!buffer_unchanged_p)
12029 w->base_line_number = Qnil;
12031 /* Move backward half the height of the window. */
12032 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12033 it.current_y = it.last_visible_y;
12034 move_it_vertically_backward (&it, centering_position);
12035 xassert (IT_CHARPOS (it) >= BEGV);
12037 /* The function move_it_vertically_backward may move over more
12038 than the specified y-distance. If it->w is small, e.g. a
12039 mini-buffer window, we may end up in front of the window's
12040 display area. Start displaying at the start of the line
12041 containing PT in this case. */
12042 if (it.current_y <= 0)
12044 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12045 move_it_vertically (&it, 0);
12046 xassert (IT_CHARPOS (it) <= PT);
12047 it.current_y = 0;
12050 it.current_x = it.hpos = 0;
12052 /* Set startp here explicitly in case that helps avoid an infinite loop
12053 in case the window-scroll-functions functions get errors. */
12054 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12056 /* Run scroll hooks. */
12057 startp = run_window_scroll_functions (window, it.current.pos);
12059 /* Redisplay the window. */
12060 if (!current_matrix_up_to_date_p
12061 || windows_or_buffers_changed
12062 || cursor_type_changed
12063 /* Don't use try_window_reusing_current_matrix in this case
12064 because it can have changed the buffer. */
12065 || !NILP (Vwindow_scroll_functions)
12066 || !just_this_one_p
12067 || MINI_WINDOW_P (w)
12068 || !(used_current_matrix_p
12069 = try_window_reusing_current_matrix (w)))
12070 try_window (window, startp);
12072 /* If new fonts have been loaded (due to fontsets), give up. We
12073 have to start a new redisplay since we need to re-adjust glyph
12074 matrices. */
12075 if (fonts_changed_p)
12076 goto need_larger_matrices;
12078 /* If cursor did not appear assume that the middle of the window is
12079 in the first line of the window. Do it again with the next line.
12080 (Imagine a window of height 100, displaying two lines of height
12081 60. Moving back 50 from it->last_visible_y will end in the first
12082 line.) */
12083 if (w->cursor.vpos < 0)
12085 if (!NILP (w->window_end_valid)
12086 && PT >= Z - XFASTINT (w->window_end_pos))
12088 clear_glyph_matrix (w->desired_matrix);
12089 move_it_by_lines (&it, 1, 0);
12090 try_window (window, it.current.pos);
12092 else if (PT < IT_CHARPOS (it))
12094 clear_glyph_matrix (w->desired_matrix);
12095 move_it_by_lines (&it, -1, 0);
12096 try_window (window, it.current.pos);
12098 else
12100 /* Not much we can do about it. */
12104 /* Consider the following case: Window starts at BEGV, there is
12105 invisible, intangible text at BEGV, so that display starts at
12106 some point START > BEGV. It can happen that we are called with
12107 PT somewhere between BEGV and START. Try to handle that case. */
12108 if (w->cursor.vpos < 0)
12110 struct glyph_row *row = w->current_matrix->rows;
12111 if (row->mode_line_p)
12112 ++row;
12113 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12116 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12118 /* If vscroll is enabled, disable it and try again. */
12119 if (w->vscroll)
12121 w->vscroll = 0;
12122 clear_glyph_matrix (w->desired_matrix);
12123 goto recenter;
12126 /* If centering point failed to make the whole line visible,
12127 put point at the top instead. That has to make the whole line
12128 visible, if it can be done. */
12129 clear_glyph_matrix (w->desired_matrix);
12130 centering_position = 0;
12131 goto point_at_top;
12134 done:
12136 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12137 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12138 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12139 ? Qt : Qnil);
12141 /* Display the mode line, if we must. */
12142 if ((update_mode_line
12143 /* If window not full width, must redo its mode line
12144 if (a) the window to its side is being redone and
12145 (b) we do a frame-based redisplay. This is a consequence
12146 of how inverted lines are drawn in frame-based redisplay. */
12147 || (!just_this_one_p
12148 && !FRAME_WINDOW_P (f)
12149 && !WINDOW_FULL_WIDTH_P (w))
12150 /* Line number to display. */
12151 || INTEGERP (w->base_line_pos)
12152 /* Column number is displayed and different from the one displayed. */
12153 || (!NILP (w->column_number_displayed)
12154 && (XFASTINT (w->column_number_displayed)
12155 != (int) current_column ()))) /* iftc */
12156 /* This means that the window has a mode line. */
12157 && (WINDOW_WANTS_MODELINE_P (w)
12158 || WINDOW_WANTS_HEADER_LINE_P (w)))
12160 display_mode_lines (w);
12162 /* If mode line height has changed, arrange for a thorough
12163 immediate redisplay using the correct mode line height. */
12164 if (WINDOW_WANTS_MODELINE_P (w)
12165 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12167 fonts_changed_p = 1;
12168 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12169 = DESIRED_MODE_LINE_HEIGHT (w);
12172 /* If top line height has changed, arrange for a thorough
12173 immediate redisplay using the correct mode line height. */
12174 if (WINDOW_WANTS_HEADER_LINE_P (w)
12175 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12177 fonts_changed_p = 1;
12178 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12179 = DESIRED_HEADER_LINE_HEIGHT (w);
12182 if (fonts_changed_p)
12183 goto need_larger_matrices;
12186 if (!line_number_displayed
12187 && !BUFFERP (w->base_line_pos))
12189 w->base_line_pos = Qnil;
12190 w->base_line_number = Qnil;
12193 finish_menu_bars:
12195 /* When we reach a frame's selected window, redo the frame's menu bar. */
12196 if (update_mode_line
12197 && EQ (FRAME_SELECTED_WINDOW (f), window))
12199 int redisplay_menu_p = 0;
12200 int redisplay_tool_bar_p = 0;
12202 if (FRAME_WINDOW_P (f))
12204 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12205 || defined (USE_GTK)
12206 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12207 #else
12208 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12209 #endif
12211 else
12212 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12214 if (redisplay_menu_p)
12215 display_menu_bar (w);
12217 #ifdef HAVE_WINDOW_SYSTEM
12218 #ifdef USE_GTK
12219 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12220 #else
12221 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12222 && (FRAME_TOOL_BAR_LINES (f) > 0
12223 || auto_resize_tool_bars_p);
12225 #endif
12227 if (redisplay_tool_bar_p)
12228 redisplay_tool_bar (f);
12229 #endif
12232 #ifdef HAVE_WINDOW_SYSTEM
12233 if (FRAME_WINDOW_P (f)
12234 && update_window_fringes (w, 0)
12235 && !just_this_one_p
12236 && (used_current_matrix_p || overlay_arrow_seen)
12237 && !w->pseudo_window_p)
12239 update_begin (f);
12240 BLOCK_INPUT;
12241 if (draw_window_fringes (w, 1))
12242 x_draw_vertical_border (w);
12243 UNBLOCK_INPUT;
12244 update_end (f);
12246 #endif /* HAVE_WINDOW_SYSTEM */
12248 /* We go to this label, with fonts_changed_p nonzero,
12249 if it is necessary to try again using larger glyph matrices.
12250 We have to redeem the scroll bar even in this case,
12251 because the loop in redisplay_internal expects that. */
12252 need_larger_matrices:
12254 finish_scroll_bars:
12256 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12258 /* Set the thumb's position and size. */
12259 set_vertical_scroll_bar (w);
12261 /* Note that we actually used the scroll bar attached to this
12262 window, so it shouldn't be deleted at the end of redisplay. */
12263 redeem_scroll_bar_hook (w);
12266 /* Restore current_buffer and value of point in it. */
12267 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12268 set_buffer_internal_1 (old);
12269 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12271 unbind_to (count, Qnil);
12275 /* Build the complete desired matrix of WINDOW with a window start
12276 buffer position POS. Value is non-zero if successful. It is zero
12277 if fonts were loaded during redisplay which makes re-adjusting
12278 glyph matrices necessary. */
12281 try_window (window, pos)
12282 Lisp_Object window;
12283 struct text_pos pos;
12285 struct window *w = XWINDOW (window);
12286 struct it it;
12287 struct glyph_row *last_text_row = NULL;
12289 /* Make POS the new window start. */
12290 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12292 /* Mark cursor position as unknown. No overlay arrow seen. */
12293 w->cursor.vpos = -1;
12294 overlay_arrow_seen = 0;
12296 /* Initialize iterator and info to start at POS. */
12297 start_display (&it, w, pos);
12299 /* Display all lines of W. */
12300 while (it.current_y < it.last_visible_y)
12302 if (display_line (&it))
12303 last_text_row = it.glyph_row - 1;
12304 if (fonts_changed_p)
12305 return 0;
12308 /* If bottom moved off end of frame, change mode line percentage. */
12309 if (XFASTINT (w->window_end_pos) <= 0
12310 && Z != IT_CHARPOS (it))
12311 w->update_mode_line = Qt;
12313 /* Set window_end_pos to the offset of the last character displayed
12314 on the window from the end of current_buffer. Set
12315 window_end_vpos to its row number. */
12316 if (last_text_row)
12318 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12319 w->window_end_bytepos
12320 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12321 w->window_end_pos
12322 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12323 w->window_end_vpos
12324 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12325 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12326 ->displays_text_p);
12328 else
12330 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12331 w->window_end_pos = make_number (Z - ZV);
12332 w->window_end_vpos = make_number (0);
12335 /* But that is not valid info until redisplay finishes. */
12336 w->window_end_valid = Qnil;
12337 return 1;
12342 /************************************************************************
12343 Window redisplay reusing current matrix when buffer has not changed
12344 ************************************************************************/
12346 /* Try redisplay of window W showing an unchanged buffer with a
12347 different window start than the last time it was displayed by
12348 reusing its current matrix. Value is non-zero if successful.
12349 W->start is the new window start. */
12351 static int
12352 try_window_reusing_current_matrix (w)
12353 struct window *w;
12355 struct frame *f = XFRAME (w->frame);
12356 struct glyph_row *row, *bottom_row;
12357 struct it it;
12358 struct run run;
12359 struct text_pos start, new_start;
12360 int nrows_scrolled, i;
12361 struct glyph_row *last_text_row;
12362 struct glyph_row *last_reused_text_row;
12363 struct glyph_row *start_row;
12364 int start_vpos, min_y, max_y;
12366 #if GLYPH_DEBUG
12367 if (inhibit_try_window_reusing)
12368 return 0;
12369 #endif
12371 if (/* This function doesn't handle terminal frames. */
12372 !FRAME_WINDOW_P (f)
12373 /* Don't try to reuse the display if windows have been split
12374 or such. */
12375 || windows_or_buffers_changed
12376 || cursor_type_changed)
12377 return 0;
12379 /* Can't do this if region may have changed. */
12380 if ((!NILP (Vtransient_mark_mode)
12381 && !NILP (current_buffer->mark_active))
12382 || !NILP (w->region_showing)
12383 || !NILP (Vshow_trailing_whitespace))
12384 return 0;
12386 /* If top-line visibility has changed, give up. */
12387 if (WINDOW_WANTS_HEADER_LINE_P (w)
12388 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12389 return 0;
12391 /* Give up if old or new display is scrolled vertically. We could
12392 make this function handle this, but right now it doesn't. */
12393 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12394 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12395 return 0;
12397 /* The variable new_start now holds the new window start. The old
12398 start `start' can be determined from the current matrix. */
12399 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12400 start = start_row->start.pos;
12401 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12403 /* Clear the desired matrix for the display below. */
12404 clear_glyph_matrix (w->desired_matrix);
12406 if (CHARPOS (new_start) <= CHARPOS (start))
12408 int first_row_y;
12410 /* Don't use this method if the display starts with an ellipsis
12411 displayed for invisible text. It's not easy to handle that case
12412 below, and it's certainly not worth the effort since this is
12413 not a frequent case. */
12414 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12415 return 0;
12417 IF_DEBUG (debug_method_add (w, "twu1"));
12419 /* Display up to a row that can be reused. The variable
12420 last_text_row is set to the last row displayed that displays
12421 text. Note that it.vpos == 0 if or if not there is a
12422 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12423 start_display (&it, w, new_start);
12424 first_row_y = it.current_y;
12425 w->cursor.vpos = -1;
12426 last_text_row = last_reused_text_row = NULL;
12428 while (it.current_y < it.last_visible_y
12429 && !fonts_changed_p)
12431 /* If we have reached into the characters in the START row,
12432 that means the line boundaries have changed. So we
12433 can't start copying with the row START. Maybe it will
12434 work to start copying with the following row. */
12435 while (IT_CHARPOS (it) > CHARPOS (start))
12437 /* Advance to the next row as the "start". */
12438 start_row++;
12439 start = start_row->start.pos;
12440 /* If there are no more rows to try, or just one, give up. */
12441 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12442 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row)
12443 || CHARPOS (start) == ZV)
12445 clear_glyph_matrix (w->desired_matrix);
12446 return 0;
12449 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12451 /* If we have reached alignment,
12452 we can copy the rest of the rows. */
12453 if (IT_CHARPOS (it) == CHARPOS (start))
12454 break;
12456 if (display_line (&it))
12457 last_text_row = it.glyph_row - 1;
12460 /* A value of current_y < last_visible_y means that we stopped
12461 at the previous window start, which in turn means that we
12462 have at least one reusable row. */
12463 if (it.current_y < it.last_visible_y)
12465 /* IT.vpos always starts from 0; it counts text lines. */
12466 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12468 /* Find PT if not already found in the lines displayed. */
12469 if (w->cursor.vpos < 0)
12471 int dy = it.current_y - start_row->y;
12473 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12474 row = row_containing_pos (w, PT, row, NULL, dy);
12475 if (row)
12476 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12477 dy, nrows_scrolled);
12478 else
12480 clear_glyph_matrix (w->desired_matrix);
12481 return 0;
12485 /* Scroll the display. Do it before the current matrix is
12486 changed. The problem here is that update has not yet
12487 run, i.e. part of the current matrix is not up to date.
12488 scroll_run_hook will clear the cursor, and use the
12489 current matrix to get the height of the row the cursor is
12490 in. */
12491 run.current_y = start_row->y;
12492 run.desired_y = it.current_y;
12493 run.height = it.last_visible_y - it.current_y;
12495 if (run.height > 0 && run.current_y != run.desired_y)
12497 update_begin (f);
12498 rif->update_window_begin_hook (w);
12499 rif->clear_window_mouse_face (w);
12500 rif->scroll_run_hook (w, &run);
12501 rif->update_window_end_hook (w, 0, 0);
12502 update_end (f);
12505 /* Shift current matrix down by nrows_scrolled lines. */
12506 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12507 rotate_matrix (w->current_matrix,
12508 start_vpos,
12509 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12510 nrows_scrolled);
12512 /* Disable lines that must be updated. */
12513 for (i = 0; i < it.vpos; ++i)
12514 (start_row + i)->enabled_p = 0;
12516 /* Re-compute Y positions. */
12517 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12518 max_y = it.last_visible_y;
12519 for (row = start_row + nrows_scrolled;
12520 row < bottom_row;
12521 ++row)
12523 row->y = it.current_y;
12524 row->visible_height = row->height;
12526 if (row->y < min_y)
12527 row->visible_height -= min_y - row->y;
12528 if (row->y + row->height > max_y)
12529 row->visible_height -= row->y + row->height - max_y;
12530 row->redraw_fringe_bitmaps_p = 1;
12532 it.current_y += row->height;
12534 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12535 last_reused_text_row = row;
12536 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12537 break;
12540 /* Disable lines in the current matrix which are now
12541 below the window. */
12542 for (++row; row < bottom_row; ++row)
12543 row->enabled_p = 0;
12546 /* Update window_end_pos etc.; last_reused_text_row is the last
12547 reused row from the current matrix containing text, if any.
12548 The value of last_text_row is the last displayed line
12549 containing text. */
12550 if (last_reused_text_row)
12552 w->window_end_bytepos
12553 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12554 w->window_end_pos
12555 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12556 w->window_end_vpos
12557 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12558 w->current_matrix));
12560 else if (last_text_row)
12562 w->window_end_bytepos
12563 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12564 w->window_end_pos
12565 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12566 w->window_end_vpos
12567 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12569 else
12571 /* This window must be completely empty. */
12572 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12573 w->window_end_pos = make_number (Z - ZV);
12574 w->window_end_vpos = make_number (0);
12576 w->window_end_valid = Qnil;
12578 /* Update hint: don't try scrolling again in update_window. */
12579 w->desired_matrix->no_scrolling_p = 1;
12581 #if GLYPH_DEBUG
12582 debug_method_add (w, "try_window_reusing_current_matrix 1");
12583 #endif
12584 return 1;
12586 else if (CHARPOS (new_start) > CHARPOS (start))
12588 struct glyph_row *pt_row, *row;
12589 struct glyph_row *first_reusable_row;
12590 struct glyph_row *first_row_to_display;
12591 int dy;
12592 int yb = window_text_bottom_y (w);
12594 /* Find the row starting at new_start, if there is one. Don't
12595 reuse a partially visible line at the end. */
12596 first_reusable_row = start_row;
12597 while (first_reusable_row->enabled_p
12598 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12599 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12600 < CHARPOS (new_start)))
12601 ++first_reusable_row;
12603 /* Give up if there is no row to reuse. */
12604 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12605 || !first_reusable_row->enabled_p
12606 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12607 != CHARPOS (new_start)))
12608 return 0;
12610 /* We can reuse fully visible rows beginning with
12611 first_reusable_row to the end of the window. Set
12612 first_row_to_display to the first row that cannot be reused.
12613 Set pt_row to the row containing point, if there is any. */
12614 pt_row = NULL;
12615 for (first_row_to_display = first_reusable_row;
12616 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12617 ++first_row_to_display)
12619 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12620 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12621 pt_row = first_row_to_display;
12624 /* Start displaying at the start of first_row_to_display. */
12625 xassert (first_row_to_display->y < yb);
12626 init_to_row_start (&it, w, first_row_to_display);
12628 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12629 - start_vpos);
12630 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12631 - nrows_scrolled);
12632 it.current_y = (first_row_to_display->y - first_reusable_row->y
12633 + WINDOW_HEADER_LINE_HEIGHT (w));
12635 /* Display lines beginning with first_row_to_display in the
12636 desired matrix. Set last_text_row to the last row displayed
12637 that displays text. */
12638 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12639 if (pt_row == NULL)
12640 w->cursor.vpos = -1;
12641 last_text_row = NULL;
12642 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12643 if (display_line (&it))
12644 last_text_row = it.glyph_row - 1;
12646 /* Give up If point isn't in a row displayed or reused. */
12647 if (w->cursor.vpos < 0)
12649 clear_glyph_matrix (w->desired_matrix);
12650 return 0;
12653 /* If point is in a reused row, adjust y and vpos of the cursor
12654 position. */
12655 if (pt_row)
12657 w->cursor.vpos -= nrows_scrolled;
12658 w->cursor.y -= first_reusable_row->y - start_row->y;
12661 /* Scroll the display. */
12662 run.current_y = first_reusable_row->y;
12663 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12664 run.height = it.last_visible_y - run.current_y;
12665 dy = run.current_y - run.desired_y;
12667 if (run.height)
12669 update_begin (f);
12670 rif->update_window_begin_hook (w);
12671 rif->clear_window_mouse_face (w);
12672 rif->scroll_run_hook (w, &run);
12673 rif->update_window_end_hook (w, 0, 0);
12674 update_end (f);
12677 /* Adjust Y positions of reused rows. */
12678 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12679 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12680 max_y = it.last_visible_y;
12681 for (row = first_reusable_row; row < first_row_to_display; ++row)
12683 row->y -= dy;
12684 row->visible_height = row->height;
12685 if (row->y < min_y)
12686 row->visible_height -= min_y - row->y;
12687 if (row->y + row->height > max_y)
12688 row->visible_height -= row->y + row->height - max_y;
12689 row->redraw_fringe_bitmaps_p = 1;
12692 /* Scroll the current matrix. */
12693 xassert (nrows_scrolled > 0);
12694 rotate_matrix (w->current_matrix,
12695 start_vpos,
12696 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12697 -nrows_scrolled);
12699 /* Disable rows not reused. */
12700 for (row -= nrows_scrolled; row < bottom_row; ++row)
12701 row->enabled_p = 0;
12703 /* Point may have moved to a different line, so we cannot assume that
12704 the previous cursor position is valid; locate the correct row. */
12705 if (pt_row)
12707 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12708 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12709 row++)
12711 w->cursor.vpos++;
12712 w->cursor.y = row->y;
12714 if (row < bottom_row)
12716 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12717 while (glyph->charpos < PT)
12719 w->cursor.hpos++;
12720 w->cursor.x += glyph->pixel_width;
12721 glyph++;
12726 /* Adjust window end. A null value of last_text_row means that
12727 the window end is in reused rows which in turn means that
12728 only its vpos can have changed. */
12729 if (last_text_row)
12731 w->window_end_bytepos
12732 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12733 w->window_end_pos
12734 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12735 w->window_end_vpos
12736 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12738 else
12740 w->window_end_vpos
12741 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12744 w->window_end_valid = Qnil;
12745 w->desired_matrix->no_scrolling_p = 1;
12747 #if GLYPH_DEBUG
12748 debug_method_add (w, "try_window_reusing_current_matrix 2");
12749 #endif
12750 return 1;
12753 return 0;
12758 /************************************************************************
12759 Window redisplay reusing current matrix when buffer has changed
12760 ************************************************************************/
12762 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12763 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12764 int *, int *));
12765 static struct glyph_row *
12766 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12767 struct glyph_row *));
12770 /* Return the last row in MATRIX displaying text. If row START is
12771 non-null, start searching with that row. IT gives the dimensions
12772 of the display. Value is null if matrix is empty; otherwise it is
12773 a pointer to the row found. */
12775 static struct glyph_row *
12776 find_last_row_displaying_text (matrix, it, start)
12777 struct glyph_matrix *matrix;
12778 struct it *it;
12779 struct glyph_row *start;
12781 struct glyph_row *row, *row_found;
12783 /* Set row_found to the last row in IT->w's current matrix
12784 displaying text. The loop looks funny but think of partially
12785 visible lines. */
12786 row_found = NULL;
12787 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12788 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12790 xassert (row->enabled_p);
12791 row_found = row;
12792 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12793 break;
12794 ++row;
12797 return row_found;
12801 /* Return the last row in the current matrix of W that is not affected
12802 by changes at the start of current_buffer that occurred since W's
12803 current matrix was built. Value is null if no such row exists.
12805 BEG_UNCHANGED us the number of characters unchanged at the start of
12806 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12807 first changed character in current_buffer. Characters at positions <
12808 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12809 when the current matrix was built. */
12811 static struct glyph_row *
12812 find_last_unchanged_at_beg_row (w)
12813 struct window *w;
12815 int first_changed_pos = BEG + BEG_UNCHANGED;
12816 struct glyph_row *row;
12817 struct glyph_row *row_found = NULL;
12818 int yb = window_text_bottom_y (w);
12820 /* Find the last row displaying unchanged text. */
12821 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12822 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12823 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12825 if (/* If row ends before first_changed_pos, it is unchanged,
12826 except in some case. */
12827 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12828 /* When row ends in ZV and we write at ZV it is not
12829 unchanged. */
12830 && !row->ends_at_zv_p
12831 /* When first_changed_pos is the end of a continued line,
12832 row is not unchanged because it may be no longer
12833 continued. */
12834 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12835 && (row->continued_p
12836 || row->exact_window_width_line_p)))
12837 row_found = row;
12839 /* Stop if last visible row. */
12840 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12841 break;
12843 ++row;
12846 return row_found;
12850 /* Find the first glyph row in the current matrix of W that is not
12851 affected by changes at the end of current_buffer since the
12852 time W's current matrix was built.
12854 Return in *DELTA the number of chars by which buffer positions in
12855 unchanged text at the end of current_buffer must be adjusted.
12857 Return in *DELTA_BYTES the corresponding number of bytes.
12859 Value is null if no such row exists, i.e. all rows are affected by
12860 changes. */
12862 static struct glyph_row *
12863 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12864 struct window *w;
12865 int *delta, *delta_bytes;
12867 struct glyph_row *row;
12868 struct glyph_row *row_found = NULL;
12870 *delta = *delta_bytes = 0;
12872 /* Display must not have been paused, otherwise the current matrix
12873 is not up to date. */
12874 if (NILP (w->window_end_valid))
12875 abort ();
12877 /* A value of window_end_pos >= END_UNCHANGED means that the window
12878 end is in the range of changed text. If so, there is no
12879 unchanged row at the end of W's current matrix. */
12880 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12881 return NULL;
12883 /* Set row to the last row in W's current matrix displaying text. */
12884 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12886 /* If matrix is entirely empty, no unchanged row exists. */
12887 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12889 /* The value of row is the last glyph row in the matrix having a
12890 meaningful buffer position in it. The end position of row
12891 corresponds to window_end_pos. This allows us to translate
12892 buffer positions in the current matrix to current buffer
12893 positions for characters not in changed text. */
12894 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12895 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12896 int last_unchanged_pos, last_unchanged_pos_old;
12897 struct glyph_row *first_text_row
12898 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12900 *delta = Z - Z_old;
12901 *delta_bytes = Z_BYTE - Z_BYTE_old;
12903 /* Set last_unchanged_pos to the buffer position of the last
12904 character in the buffer that has not been changed. Z is the
12905 index + 1 of the last character in current_buffer, i.e. by
12906 subtracting END_UNCHANGED we get the index of the last
12907 unchanged character, and we have to add BEG to get its buffer
12908 position. */
12909 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12910 last_unchanged_pos_old = last_unchanged_pos - *delta;
12912 /* Search backward from ROW for a row displaying a line that
12913 starts at a minimum position >= last_unchanged_pos_old. */
12914 for (; row > first_text_row; --row)
12916 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12917 abort ();
12919 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12920 row_found = row;
12924 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12925 abort ();
12927 return row_found;
12931 /* Make sure that glyph rows in the current matrix of window W
12932 reference the same glyph memory as corresponding rows in the
12933 frame's frame matrix. This function is called after scrolling W's
12934 current matrix on a terminal frame in try_window_id and
12935 try_window_reusing_current_matrix. */
12937 static void
12938 sync_frame_with_window_matrix_rows (w)
12939 struct window *w;
12941 struct frame *f = XFRAME (w->frame);
12942 struct glyph_row *window_row, *window_row_end, *frame_row;
12944 /* Preconditions: W must be a leaf window and full-width. Its frame
12945 must have a frame matrix. */
12946 xassert (NILP (w->hchild) && NILP (w->vchild));
12947 xassert (WINDOW_FULL_WIDTH_P (w));
12948 xassert (!FRAME_WINDOW_P (f));
12950 /* If W is a full-width window, glyph pointers in W's current matrix
12951 have, by definition, to be the same as glyph pointers in the
12952 corresponding frame matrix. Note that frame matrices have no
12953 marginal areas (see build_frame_matrix). */
12954 window_row = w->current_matrix->rows;
12955 window_row_end = window_row + w->current_matrix->nrows;
12956 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12957 while (window_row < window_row_end)
12959 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12960 struct glyph *end = window_row->glyphs[LAST_AREA];
12962 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12963 frame_row->glyphs[TEXT_AREA] = start;
12964 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12965 frame_row->glyphs[LAST_AREA] = end;
12967 /* Disable frame rows whose corresponding window rows have
12968 been disabled in try_window_id. */
12969 if (!window_row->enabled_p)
12970 frame_row->enabled_p = 0;
12972 ++window_row, ++frame_row;
12977 /* Find the glyph row in window W containing CHARPOS. Consider all
12978 rows between START and END (not inclusive). END null means search
12979 all rows to the end of the display area of W. Value is the row
12980 containing CHARPOS or null. */
12982 struct glyph_row *
12983 row_containing_pos (w, charpos, start, end, dy)
12984 struct window *w;
12985 int charpos;
12986 struct glyph_row *start, *end;
12987 int dy;
12989 struct glyph_row *row = start;
12990 int last_y;
12992 /* If we happen to start on a header-line, skip that. */
12993 if (row->mode_line_p)
12994 ++row;
12996 if ((end && row >= end) || !row->enabled_p)
12997 return NULL;
12999 last_y = window_text_bottom_y (w) - dy;
13001 while (1)
13003 /* Give up if we have gone too far. */
13004 if (end && row >= end)
13005 return NULL;
13006 /* This formerly returned if they were equal.
13007 I think that both quantities are of a "last plus one" type;
13008 if so, when they are equal, the row is within the screen. -- rms. */
13009 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13010 return NULL;
13012 /* If it is in this row, return this row. */
13013 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13014 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13015 /* The end position of a row equals the start
13016 position of the next row. If CHARPOS is there, we
13017 would rather display it in the next line, except
13018 when this line ends in ZV. */
13019 && !row->ends_at_zv_p
13020 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13021 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13022 return row;
13023 ++row;
13028 /* Try to redisplay window W by reusing its existing display. W's
13029 current matrix must be up to date when this function is called,
13030 i.e. window_end_valid must not be nil.
13032 Value is
13034 1 if display has been updated
13035 0 if otherwise unsuccessful
13036 -1 if redisplay with same window start is known not to succeed
13038 The following steps are performed:
13040 1. Find the last row in the current matrix of W that is not
13041 affected by changes at the start of current_buffer. If no such row
13042 is found, give up.
13044 2. Find the first row in W's current matrix that is not affected by
13045 changes at the end of current_buffer. Maybe there is no such row.
13047 3. Display lines beginning with the row + 1 found in step 1 to the
13048 row found in step 2 or, if step 2 didn't find a row, to the end of
13049 the window.
13051 4. If cursor is not known to appear on the window, give up.
13053 5. If display stopped at the row found in step 2, scroll the
13054 display and current matrix as needed.
13056 6. Maybe display some lines at the end of W, if we must. This can
13057 happen under various circumstances, like a partially visible line
13058 becoming fully visible, or because newly displayed lines are displayed
13059 in smaller font sizes.
13061 7. Update W's window end information. */
13063 static int
13064 try_window_id (w)
13065 struct window *w;
13067 struct frame *f = XFRAME (w->frame);
13068 struct glyph_matrix *current_matrix = w->current_matrix;
13069 struct glyph_matrix *desired_matrix = w->desired_matrix;
13070 struct glyph_row *last_unchanged_at_beg_row;
13071 struct glyph_row *first_unchanged_at_end_row;
13072 struct glyph_row *row;
13073 struct glyph_row *bottom_row;
13074 int bottom_vpos;
13075 struct it it;
13076 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13077 struct text_pos start_pos;
13078 struct run run;
13079 int first_unchanged_at_end_vpos = 0;
13080 struct glyph_row *last_text_row, *last_text_row_at_end;
13081 struct text_pos start;
13082 int first_changed_charpos, last_changed_charpos;
13084 #if GLYPH_DEBUG
13085 if (inhibit_try_window_id)
13086 return 0;
13087 #endif
13089 /* This is handy for debugging. */
13090 #if 0
13091 #define GIVE_UP(X) \
13092 do { \
13093 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13094 return 0; \
13095 } while (0)
13096 #else
13097 #define GIVE_UP(X) return 0
13098 #endif
13100 SET_TEXT_POS_FROM_MARKER (start, w->start);
13102 /* Don't use this for mini-windows because these can show
13103 messages and mini-buffers, and we don't handle that here. */
13104 if (MINI_WINDOW_P (w))
13105 GIVE_UP (1);
13107 /* This flag is used to prevent redisplay optimizations. */
13108 if (windows_or_buffers_changed || cursor_type_changed)
13109 GIVE_UP (2);
13111 /* Verify that narrowing has not changed.
13112 Also verify that we were not told to prevent redisplay optimizations.
13113 It would be nice to further
13114 reduce the number of cases where this prevents try_window_id. */
13115 if (current_buffer->clip_changed
13116 || current_buffer->prevent_redisplay_optimizations_p)
13117 GIVE_UP (3);
13119 /* Window must either use window-based redisplay or be full width. */
13120 if (!FRAME_WINDOW_P (f)
13121 && (!line_ins_del_ok
13122 || !WINDOW_FULL_WIDTH_P (w)))
13123 GIVE_UP (4);
13125 /* Give up if point is not known NOT to appear in W. */
13126 if (PT < CHARPOS (start))
13127 GIVE_UP (5);
13129 /* Another way to prevent redisplay optimizations. */
13130 if (XFASTINT (w->last_modified) == 0)
13131 GIVE_UP (6);
13133 /* Verify that window is not hscrolled. */
13134 if (XFASTINT (w->hscroll) != 0)
13135 GIVE_UP (7);
13137 /* Verify that display wasn't paused. */
13138 if (NILP (w->window_end_valid))
13139 GIVE_UP (8);
13141 /* Can't use this if highlighting a region because a cursor movement
13142 will do more than just set the cursor. */
13143 if (!NILP (Vtransient_mark_mode)
13144 && !NILP (current_buffer->mark_active))
13145 GIVE_UP (9);
13147 /* Likewise if highlighting trailing whitespace. */
13148 if (!NILP (Vshow_trailing_whitespace))
13149 GIVE_UP (11);
13151 /* Likewise if showing a region. */
13152 if (!NILP (w->region_showing))
13153 GIVE_UP (10);
13155 /* Can use this if overlay arrow position and or string have changed. */
13156 if (overlay_arrows_changed_p ())
13157 GIVE_UP (12);
13160 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13161 only if buffer has really changed. The reason is that the gap is
13162 initially at Z for freshly visited files. The code below would
13163 set end_unchanged to 0 in that case. */
13164 if (MODIFF > SAVE_MODIFF
13165 /* This seems to happen sometimes after saving a buffer. */
13166 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13168 if (GPT - BEG < BEG_UNCHANGED)
13169 BEG_UNCHANGED = GPT - BEG;
13170 if (Z - GPT < END_UNCHANGED)
13171 END_UNCHANGED = Z - GPT;
13174 /* The position of the first and last character that has been changed. */
13175 first_changed_charpos = BEG + BEG_UNCHANGED;
13176 last_changed_charpos = Z - END_UNCHANGED;
13178 /* If window starts after a line end, and the last change is in
13179 front of that newline, then changes don't affect the display.
13180 This case happens with stealth-fontification. Note that although
13181 the display is unchanged, glyph positions in the matrix have to
13182 be adjusted, of course. */
13183 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13184 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13185 && ((last_changed_charpos < CHARPOS (start)
13186 && CHARPOS (start) == BEGV)
13187 || (last_changed_charpos < CHARPOS (start) - 1
13188 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13190 int Z_old, delta, Z_BYTE_old, delta_bytes;
13191 struct glyph_row *r0;
13193 /* Compute how many chars/bytes have been added to or removed
13194 from the buffer. */
13195 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13196 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13197 delta = Z - Z_old;
13198 delta_bytes = Z_BYTE - Z_BYTE_old;
13200 /* Give up if PT is not in the window. Note that it already has
13201 been checked at the start of try_window_id that PT is not in
13202 front of the window start. */
13203 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13204 GIVE_UP (13);
13206 /* If window start is unchanged, we can reuse the whole matrix
13207 as is, after adjusting glyph positions. No need to compute
13208 the window end again, since its offset from Z hasn't changed. */
13209 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13210 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13211 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13212 /* PT must not be in a partially visible line. */
13213 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13214 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13216 /* Adjust positions in the glyph matrix. */
13217 if (delta || delta_bytes)
13219 struct glyph_row *r1
13220 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13221 increment_matrix_positions (w->current_matrix,
13222 MATRIX_ROW_VPOS (r0, current_matrix),
13223 MATRIX_ROW_VPOS (r1, current_matrix),
13224 delta, delta_bytes);
13227 /* Set the cursor. */
13228 row = row_containing_pos (w, PT, r0, NULL, 0);
13229 if (row)
13230 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13231 else
13232 abort ();
13233 return 1;
13237 /* Handle the case that changes are all below what is displayed in
13238 the window, and that PT is in the window. This shortcut cannot
13239 be taken if ZV is visible in the window, and text has been added
13240 there that is visible in the window. */
13241 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13242 /* ZV is not visible in the window, or there are no
13243 changes at ZV, actually. */
13244 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13245 || first_changed_charpos == last_changed_charpos))
13247 struct glyph_row *r0;
13249 /* Give up if PT is not in the window. Note that it already has
13250 been checked at the start of try_window_id that PT is not in
13251 front of the window start. */
13252 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13253 GIVE_UP (14);
13255 /* If window start is unchanged, we can reuse the whole matrix
13256 as is, without changing glyph positions since no text has
13257 been added/removed in front of the window end. */
13258 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13259 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13260 /* PT must not be in a partially visible line. */
13261 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13262 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13264 /* We have to compute the window end anew since text
13265 can have been added/removed after it. */
13266 w->window_end_pos
13267 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13268 w->window_end_bytepos
13269 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13271 /* Set the cursor. */
13272 row = row_containing_pos (w, PT, r0, NULL, 0);
13273 if (row)
13274 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13275 else
13276 abort ();
13277 return 2;
13281 /* Give up if window start is in the changed area.
13283 The condition used to read
13285 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13287 but why that was tested escapes me at the moment. */
13288 if (CHARPOS (start) >= first_changed_charpos
13289 && CHARPOS (start) <= last_changed_charpos)
13290 GIVE_UP (15);
13292 /* Check that window start agrees with the start of the first glyph
13293 row in its current matrix. Check this after we know the window
13294 start is not in changed text, otherwise positions would not be
13295 comparable. */
13296 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13297 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13298 GIVE_UP (16);
13300 /* Give up if the window ends in strings. Overlay strings
13301 at the end are difficult to handle, so don't try. */
13302 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13303 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13304 GIVE_UP (20);
13306 /* Compute the position at which we have to start displaying new
13307 lines. Some of the lines at the top of the window might be
13308 reusable because they are not displaying changed text. Find the
13309 last row in W's current matrix not affected by changes at the
13310 start of current_buffer. Value is null if changes start in the
13311 first line of window. */
13312 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13313 if (last_unchanged_at_beg_row)
13315 /* Avoid starting to display in the moddle of a character, a TAB
13316 for instance. This is easier than to set up the iterator
13317 exactly, and it's not a frequent case, so the additional
13318 effort wouldn't really pay off. */
13319 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13320 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13321 && last_unchanged_at_beg_row > w->current_matrix->rows)
13322 --last_unchanged_at_beg_row;
13324 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13325 GIVE_UP (17);
13327 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13328 GIVE_UP (18);
13329 start_pos = it.current.pos;
13331 /* Start displaying new lines in the desired matrix at the same
13332 vpos we would use in the current matrix, i.e. below
13333 last_unchanged_at_beg_row. */
13334 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13335 current_matrix);
13336 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13337 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13339 xassert (it.hpos == 0 && it.current_x == 0);
13341 else
13343 /* There are no reusable lines at the start of the window.
13344 Start displaying in the first text line. */
13345 start_display (&it, w, start);
13346 it.vpos = it.first_vpos;
13347 start_pos = it.current.pos;
13350 /* Find the first row that is not affected by changes at the end of
13351 the buffer. Value will be null if there is no unchanged row, in
13352 which case we must redisplay to the end of the window. delta
13353 will be set to the value by which buffer positions beginning with
13354 first_unchanged_at_end_row have to be adjusted due to text
13355 changes. */
13356 first_unchanged_at_end_row
13357 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13358 IF_DEBUG (debug_delta = delta);
13359 IF_DEBUG (debug_delta_bytes = delta_bytes);
13361 /* Set stop_pos to the buffer position up to which we will have to
13362 display new lines. If first_unchanged_at_end_row != NULL, this
13363 is the buffer position of the start of the line displayed in that
13364 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13365 that we don't stop at a buffer position. */
13366 stop_pos = 0;
13367 if (first_unchanged_at_end_row)
13369 xassert (last_unchanged_at_beg_row == NULL
13370 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13372 /* If this is a continuation line, move forward to the next one
13373 that isn't. Changes in lines above affect this line.
13374 Caution: this may move first_unchanged_at_end_row to a row
13375 not displaying text. */
13376 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13377 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13378 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13379 < it.last_visible_y))
13380 ++first_unchanged_at_end_row;
13382 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13383 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13384 >= it.last_visible_y))
13385 first_unchanged_at_end_row = NULL;
13386 else
13388 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13389 + delta);
13390 first_unchanged_at_end_vpos
13391 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13392 xassert (stop_pos >= Z - END_UNCHANGED);
13395 else if (last_unchanged_at_beg_row == NULL)
13396 GIVE_UP (19);
13399 #if GLYPH_DEBUG
13401 /* Either there is no unchanged row at the end, or the one we have
13402 now displays text. This is a necessary condition for the window
13403 end pos calculation at the end of this function. */
13404 xassert (first_unchanged_at_end_row == NULL
13405 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13407 debug_last_unchanged_at_beg_vpos
13408 = (last_unchanged_at_beg_row
13409 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13410 : -1);
13411 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13413 #endif /* GLYPH_DEBUG != 0 */
13416 /* Display new lines. Set last_text_row to the last new line
13417 displayed which has text on it, i.e. might end up as being the
13418 line where the window_end_vpos is. */
13419 w->cursor.vpos = -1;
13420 last_text_row = NULL;
13421 overlay_arrow_seen = 0;
13422 while (it.current_y < it.last_visible_y
13423 && !fonts_changed_p
13424 && (first_unchanged_at_end_row == NULL
13425 || IT_CHARPOS (it) < stop_pos))
13427 if (display_line (&it))
13428 last_text_row = it.glyph_row - 1;
13431 if (fonts_changed_p)
13432 return -1;
13435 /* Compute differences in buffer positions, y-positions etc. for
13436 lines reused at the bottom of the window. Compute what we can
13437 scroll. */
13438 if (first_unchanged_at_end_row
13439 /* No lines reused because we displayed everything up to the
13440 bottom of the window. */
13441 && it.current_y < it.last_visible_y)
13443 dvpos = (it.vpos
13444 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13445 current_matrix));
13446 dy = it.current_y - first_unchanged_at_end_row->y;
13447 run.current_y = first_unchanged_at_end_row->y;
13448 run.desired_y = run.current_y + dy;
13449 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13451 else
13453 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13454 first_unchanged_at_end_row = NULL;
13456 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13459 /* Find the cursor if not already found. We have to decide whether
13460 PT will appear on this window (it sometimes doesn't, but this is
13461 not a very frequent case.) This decision has to be made before
13462 the current matrix is altered. A value of cursor.vpos < 0 means
13463 that PT is either in one of the lines beginning at
13464 first_unchanged_at_end_row or below the window. Don't care for
13465 lines that might be displayed later at the window end; as
13466 mentioned, this is not a frequent case. */
13467 if (w->cursor.vpos < 0)
13469 /* Cursor in unchanged rows at the top? */
13470 if (PT < CHARPOS (start_pos)
13471 && last_unchanged_at_beg_row)
13473 row = row_containing_pos (w, PT,
13474 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13475 last_unchanged_at_beg_row + 1, 0);
13476 if (row)
13477 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13480 /* Start from first_unchanged_at_end_row looking for PT. */
13481 else if (first_unchanged_at_end_row)
13483 row = row_containing_pos (w, PT - delta,
13484 first_unchanged_at_end_row, NULL, 0);
13485 if (row)
13486 set_cursor_from_row (w, row, w->current_matrix, delta,
13487 delta_bytes, dy, dvpos);
13490 /* Give up if cursor was not found. */
13491 if (w->cursor.vpos < 0)
13493 clear_glyph_matrix (w->desired_matrix);
13494 return -1;
13498 /* Don't let the cursor end in the scroll margins. */
13500 int this_scroll_margin, cursor_height;
13502 this_scroll_margin = max (0, scroll_margin);
13503 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13504 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13505 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13507 if ((w->cursor.y < this_scroll_margin
13508 && CHARPOS (start) > BEGV)
13509 /* Old redisplay didn't take scroll margin into account at the bottom,
13510 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13511 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13513 w->cursor.vpos = -1;
13514 clear_glyph_matrix (w->desired_matrix);
13515 return -1;
13519 /* Scroll the display. Do it before changing the current matrix so
13520 that xterm.c doesn't get confused about where the cursor glyph is
13521 found. */
13522 if (dy && run.height)
13524 update_begin (f);
13526 if (FRAME_WINDOW_P (f))
13528 rif->update_window_begin_hook (w);
13529 rif->clear_window_mouse_face (w);
13530 rif->scroll_run_hook (w, &run);
13531 rif->update_window_end_hook (w, 0, 0);
13533 else
13535 /* Terminal frame. In this case, dvpos gives the number of
13536 lines to scroll by; dvpos < 0 means scroll up. */
13537 int first_unchanged_at_end_vpos
13538 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13539 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13540 int end = (WINDOW_TOP_EDGE_LINE (w)
13541 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13542 + window_internal_height (w));
13544 /* Perform the operation on the screen. */
13545 if (dvpos > 0)
13547 /* Scroll last_unchanged_at_beg_row to the end of the
13548 window down dvpos lines. */
13549 set_terminal_window (end);
13551 /* On dumb terminals delete dvpos lines at the end
13552 before inserting dvpos empty lines. */
13553 if (!scroll_region_ok)
13554 ins_del_lines (end - dvpos, -dvpos);
13556 /* Insert dvpos empty lines in front of
13557 last_unchanged_at_beg_row. */
13558 ins_del_lines (from, dvpos);
13560 else if (dvpos < 0)
13562 /* Scroll up last_unchanged_at_beg_vpos to the end of
13563 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13564 set_terminal_window (end);
13566 /* Delete dvpos lines in front of
13567 last_unchanged_at_beg_vpos. ins_del_lines will set
13568 the cursor to the given vpos and emit |dvpos| delete
13569 line sequences. */
13570 ins_del_lines (from + dvpos, dvpos);
13572 /* On a dumb terminal insert dvpos empty lines at the
13573 end. */
13574 if (!scroll_region_ok)
13575 ins_del_lines (end + dvpos, -dvpos);
13578 set_terminal_window (0);
13581 update_end (f);
13584 /* Shift reused rows of the current matrix to the right position.
13585 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13586 text. */
13587 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13588 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13589 if (dvpos < 0)
13591 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13592 bottom_vpos, dvpos);
13593 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13594 bottom_vpos, 0);
13596 else if (dvpos > 0)
13598 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13599 bottom_vpos, dvpos);
13600 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13601 first_unchanged_at_end_vpos + dvpos, 0);
13604 /* For frame-based redisplay, make sure that current frame and window
13605 matrix are in sync with respect to glyph memory. */
13606 if (!FRAME_WINDOW_P (f))
13607 sync_frame_with_window_matrix_rows (w);
13609 /* Adjust buffer positions in reused rows. */
13610 if (delta)
13611 increment_matrix_positions (current_matrix,
13612 first_unchanged_at_end_vpos + dvpos,
13613 bottom_vpos, delta, delta_bytes);
13615 /* Adjust Y positions. */
13616 if (dy)
13617 shift_glyph_matrix (w, current_matrix,
13618 first_unchanged_at_end_vpos + dvpos,
13619 bottom_vpos, dy);
13621 if (first_unchanged_at_end_row)
13622 first_unchanged_at_end_row += dvpos;
13624 /* If scrolling up, there may be some lines to display at the end of
13625 the window. */
13626 last_text_row_at_end = NULL;
13627 if (dy < 0)
13629 /* Scrolling up can leave for example a partially visible line
13630 at the end of the window to be redisplayed. */
13631 /* Set last_row to the glyph row in the current matrix where the
13632 window end line is found. It has been moved up or down in
13633 the matrix by dvpos. */
13634 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13635 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13637 /* If last_row is the window end line, it should display text. */
13638 xassert (last_row->displays_text_p);
13640 /* If window end line was partially visible before, begin
13641 displaying at that line. Otherwise begin displaying with the
13642 line following it. */
13643 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13645 init_to_row_start (&it, w, last_row);
13646 it.vpos = last_vpos;
13647 it.current_y = last_row->y;
13649 else
13651 init_to_row_end (&it, w, last_row);
13652 it.vpos = 1 + last_vpos;
13653 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13654 ++last_row;
13657 /* We may start in a continuation line. If so, we have to
13658 get the right continuation_lines_width and current_x. */
13659 it.continuation_lines_width = last_row->continuation_lines_width;
13660 it.hpos = it.current_x = 0;
13662 /* Display the rest of the lines at the window end. */
13663 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13664 while (it.current_y < it.last_visible_y
13665 && !fonts_changed_p)
13667 /* Is it always sure that the display agrees with lines in
13668 the current matrix? I don't think so, so we mark rows
13669 displayed invalid in the current matrix by setting their
13670 enabled_p flag to zero. */
13671 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13672 if (display_line (&it))
13673 last_text_row_at_end = it.glyph_row - 1;
13677 /* Update window_end_pos and window_end_vpos. */
13678 if (first_unchanged_at_end_row
13679 && first_unchanged_at_end_row->y < it.last_visible_y
13680 && !last_text_row_at_end)
13682 /* Window end line if one of the preserved rows from the current
13683 matrix. Set row to the last row displaying text in current
13684 matrix starting at first_unchanged_at_end_row, after
13685 scrolling. */
13686 xassert (first_unchanged_at_end_row->displays_text_p);
13687 row = find_last_row_displaying_text (w->current_matrix, &it,
13688 first_unchanged_at_end_row);
13689 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13691 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13692 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13693 w->window_end_vpos
13694 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13695 xassert (w->window_end_bytepos >= 0);
13696 IF_DEBUG (debug_method_add (w, "A"));
13698 else if (last_text_row_at_end)
13700 w->window_end_pos
13701 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13702 w->window_end_bytepos
13703 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13704 w->window_end_vpos
13705 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13706 xassert (w->window_end_bytepos >= 0);
13707 IF_DEBUG (debug_method_add (w, "B"));
13709 else if (last_text_row)
13711 /* We have displayed either to the end of the window or at the
13712 end of the window, i.e. the last row with text is to be found
13713 in the desired matrix. */
13714 w->window_end_pos
13715 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13716 w->window_end_bytepos
13717 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13718 w->window_end_vpos
13719 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13720 xassert (w->window_end_bytepos >= 0);
13722 else if (first_unchanged_at_end_row == NULL
13723 && last_text_row == NULL
13724 && last_text_row_at_end == NULL)
13726 /* Displayed to end of window, but no line containing text was
13727 displayed. Lines were deleted at the end of the window. */
13728 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13729 int vpos = XFASTINT (w->window_end_vpos);
13730 struct glyph_row *current_row = current_matrix->rows + vpos;
13731 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13733 for (row = NULL;
13734 row == NULL && vpos >= first_vpos;
13735 --vpos, --current_row, --desired_row)
13737 if (desired_row->enabled_p)
13739 if (desired_row->displays_text_p)
13740 row = desired_row;
13742 else if (current_row->displays_text_p)
13743 row = current_row;
13746 xassert (row != NULL);
13747 w->window_end_vpos = make_number (vpos + 1);
13748 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13749 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13750 xassert (w->window_end_bytepos >= 0);
13751 IF_DEBUG (debug_method_add (w, "C"));
13753 else
13754 abort ();
13756 #if 0 /* This leads to problems, for instance when the cursor is
13757 at ZV, and the cursor line displays no text. */
13758 /* Disable rows below what's displayed in the window. This makes
13759 debugging easier. */
13760 enable_glyph_matrix_rows (current_matrix,
13761 XFASTINT (w->window_end_vpos) + 1,
13762 bottom_vpos, 0);
13763 #endif
13765 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13766 debug_end_vpos = XFASTINT (w->window_end_vpos));
13768 /* Record that display has not been completed. */
13769 w->window_end_valid = Qnil;
13770 w->desired_matrix->no_scrolling_p = 1;
13771 return 3;
13773 #undef GIVE_UP
13778 /***********************************************************************
13779 More debugging support
13780 ***********************************************************************/
13782 #if GLYPH_DEBUG
13784 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13785 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13786 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13789 /* Dump the contents of glyph matrix MATRIX on stderr.
13791 GLYPHS 0 means don't show glyph contents.
13792 GLYPHS 1 means show glyphs in short form
13793 GLYPHS > 1 means show glyphs in long form. */
13795 void
13796 dump_glyph_matrix (matrix, glyphs)
13797 struct glyph_matrix *matrix;
13798 int glyphs;
13800 int i;
13801 for (i = 0; i < matrix->nrows; ++i)
13802 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13806 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13807 the glyph row and area where the glyph comes from. */
13809 void
13810 dump_glyph (row, glyph, area)
13811 struct glyph_row *row;
13812 struct glyph *glyph;
13813 int area;
13815 if (glyph->type == CHAR_GLYPH)
13817 fprintf (stderr,
13818 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13819 glyph - row->glyphs[TEXT_AREA],
13820 'C',
13821 glyph->charpos,
13822 (BUFFERP (glyph->object)
13823 ? 'B'
13824 : (STRINGP (glyph->object)
13825 ? 'S'
13826 : '-')),
13827 glyph->pixel_width,
13828 glyph->u.ch,
13829 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13830 ? glyph->u.ch
13831 : '.'),
13832 glyph->face_id,
13833 glyph->left_box_line_p,
13834 glyph->right_box_line_p);
13836 else if (glyph->type == STRETCH_GLYPH)
13838 fprintf (stderr,
13839 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13840 glyph - row->glyphs[TEXT_AREA],
13841 'S',
13842 glyph->charpos,
13843 (BUFFERP (glyph->object)
13844 ? 'B'
13845 : (STRINGP (glyph->object)
13846 ? 'S'
13847 : '-')),
13848 glyph->pixel_width,
13850 '.',
13851 glyph->face_id,
13852 glyph->left_box_line_p,
13853 glyph->right_box_line_p);
13855 else if (glyph->type == IMAGE_GLYPH)
13857 fprintf (stderr,
13858 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13859 glyph - row->glyphs[TEXT_AREA],
13860 'I',
13861 glyph->charpos,
13862 (BUFFERP (glyph->object)
13863 ? 'B'
13864 : (STRINGP (glyph->object)
13865 ? 'S'
13866 : '-')),
13867 glyph->pixel_width,
13868 glyph->u.img_id,
13869 '.',
13870 glyph->face_id,
13871 glyph->left_box_line_p,
13872 glyph->right_box_line_p);
13877 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13878 GLYPHS 0 means don't show glyph contents.
13879 GLYPHS 1 means show glyphs in short form
13880 GLYPHS > 1 means show glyphs in long form. */
13882 void
13883 dump_glyph_row (row, vpos, glyphs)
13884 struct glyph_row *row;
13885 int vpos, glyphs;
13887 if (glyphs != 1)
13889 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13890 fprintf (stderr, "=======================================================================\n");
13892 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13893 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13894 vpos,
13895 MATRIX_ROW_START_CHARPOS (row),
13896 MATRIX_ROW_END_CHARPOS (row),
13897 row->used[TEXT_AREA],
13898 row->contains_overlapping_glyphs_p,
13899 row->enabled_p,
13900 row->truncated_on_left_p,
13901 row->truncated_on_right_p,
13902 row->overlay_arrow_p,
13903 row->continued_p,
13904 MATRIX_ROW_CONTINUATION_LINE_P (row),
13905 row->displays_text_p,
13906 row->ends_at_zv_p,
13907 row->fill_line_p,
13908 row->ends_in_middle_of_char_p,
13909 row->starts_in_middle_of_char_p,
13910 row->mouse_face_p,
13911 row->x,
13912 row->y,
13913 row->pixel_width,
13914 row->height,
13915 row->visible_height,
13916 row->ascent,
13917 row->phys_ascent);
13918 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13919 row->end.overlay_string_index,
13920 row->continuation_lines_width);
13921 fprintf (stderr, "%9d %5d\n",
13922 CHARPOS (row->start.string_pos),
13923 CHARPOS (row->end.string_pos));
13924 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13925 row->end.dpvec_index);
13928 if (glyphs > 1)
13930 int area;
13932 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13934 struct glyph *glyph = row->glyphs[area];
13935 struct glyph *glyph_end = glyph + row->used[area];
13937 /* Glyph for a line end in text. */
13938 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13939 ++glyph_end;
13941 if (glyph < glyph_end)
13942 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13944 for (; glyph < glyph_end; ++glyph)
13945 dump_glyph (row, glyph, area);
13948 else if (glyphs == 1)
13950 int area;
13952 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13954 char *s = (char *) alloca (row->used[area] + 1);
13955 int i;
13957 for (i = 0; i < row->used[area]; ++i)
13959 struct glyph *glyph = row->glyphs[area] + i;
13960 if (glyph->type == CHAR_GLYPH
13961 && glyph->u.ch < 0x80
13962 && glyph->u.ch >= ' ')
13963 s[i] = glyph->u.ch;
13964 else
13965 s[i] = '.';
13968 s[i] = '\0';
13969 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13975 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13976 Sdump_glyph_matrix, 0, 1, "p",
13977 doc: /* Dump the current matrix of the selected window to stderr.
13978 Shows contents of glyph row structures. With non-nil
13979 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13980 glyphs in short form, otherwise show glyphs in long form. */)
13981 (glyphs)
13982 Lisp_Object glyphs;
13984 struct window *w = XWINDOW (selected_window);
13985 struct buffer *buffer = XBUFFER (w->buffer);
13987 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13988 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13989 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13990 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13991 fprintf (stderr, "=============================================\n");
13992 dump_glyph_matrix (w->current_matrix,
13993 NILP (glyphs) ? 0 : XINT (glyphs));
13994 return Qnil;
13998 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13999 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14002 struct frame *f = XFRAME (selected_frame);
14003 dump_glyph_matrix (f->current_matrix, 1);
14004 return Qnil;
14008 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14009 doc: /* Dump glyph row ROW to stderr.
14010 GLYPH 0 means don't dump glyphs.
14011 GLYPH 1 means dump glyphs in short form.
14012 GLYPH > 1 or omitted means dump glyphs in long form. */)
14013 (row, glyphs)
14014 Lisp_Object row, glyphs;
14016 struct glyph_matrix *matrix;
14017 int vpos;
14019 CHECK_NUMBER (row);
14020 matrix = XWINDOW (selected_window)->current_matrix;
14021 vpos = XINT (row);
14022 if (vpos >= 0 && vpos < matrix->nrows)
14023 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14024 vpos,
14025 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14026 return Qnil;
14030 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14031 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14032 GLYPH 0 means don't dump glyphs.
14033 GLYPH 1 means dump glyphs in short form.
14034 GLYPH > 1 or omitted means dump glyphs in long form. */)
14035 (row, glyphs)
14036 Lisp_Object row, glyphs;
14038 struct frame *sf = SELECTED_FRAME ();
14039 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14040 int vpos;
14042 CHECK_NUMBER (row);
14043 vpos = XINT (row);
14044 if (vpos >= 0 && vpos < m->nrows)
14045 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14046 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14047 return Qnil;
14051 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14052 doc: /* Toggle tracing of redisplay.
14053 With ARG, turn tracing on if and only if ARG is positive. */)
14054 (arg)
14055 Lisp_Object arg;
14057 if (NILP (arg))
14058 trace_redisplay_p = !trace_redisplay_p;
14059 else
14061 arg = Fprefix_numeric_value (arg);
14062 trace_redisplay_p = XINT (arg) > 0;
14065 return Qnil;
14069 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14070 doc: /* Like `format', but print result to stderr.
14071 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14072 (nargs, args)
14073 int nargs;
14074 Lisp_Object *args;
14076 Lisp_Object s = Fformat (nargs, args);
14077 fprintf (stderr, "%s", SDATA (s));
14078 return Qnil;
14081 #endif /* GLYPH_DEBUG */
14085 /***********************************************************************
14086 Building Desired Matrix Rows
14087 ***********************************************************************/
14089 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14090 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14092 static struct glyph_row *
14093 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14094 struct window *w;
14095 Lisp_Object overlay_arrow_string;
14097 struct frame *f = XFRAME (WINDOW_FRAME (w));
14098 struct buffer *buffer = XBUFFER (w->buffer);
14099 struct buffer *old = current_buffer;
14100 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14101 int arrow_len = SCHARS (overlay_arrow_string);
14102 const unsigned char *arrow_end = arrow_string + arrow_len;
14103 const unsigned char *p;
14104 struct it it;
14105 int multibyte_p;
14106 int n_glyphs_before;
14108 set_buffer_temp (buffer);
14109 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14110 it.glyph_row->used[TEXT_AREA] = 0;
14111 SET_TEXT_POS (it.position, 0, 0);
14113 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14114 p = arrow_string;
14115 while (p < arrow_end)
14117 Lisp_Object face, ilisp;
14119 /* Get the next character. */
14120 if (multibyte_p)
14121 it.c = string_char_and_length (p, arrow_len, &it.len);
14122 else
14123 it.c = *p, it.len = 1;
14124 p += it.len;
14126 /* Get its face. */
14127 ilisp = make_number (p - arrow_string);
14128 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14129 it.face_id = compute_char_face (f, it.c, face);
14131 /* Compute its width, get its glyphs. */
14132 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14133 SET_TEXT_POS (it.position, -1, -1);
14134 PRODUCE_GLYPHS (&it);
14136 /* If this character doesn't fit any more in the line, we have
14137 to remove some glyphs. */
14138 if (it.current_x > it.last_visible_x)
14140 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14141 break;
14145 set_buffer_temp (old);
14146 return it.glyph_row;
14150 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14151 glyphs are only inserted for terminal frames since we can't really
14152 win with truncation glyphs when partially visible glyphs are
14153 involved. Which glyphs to insert is determined by
14154 produce_special_glyphs. */
14156 static void
14157 insert_left_trunc_glyphs (it)
14158 struct it *it;
14160 struct it truncate_it;
14161 struct glyph *from, *end, *to, *toend;
14163 xassert (!FRAME_WINDOW_P (it->f));
14165 /* Get the truncation glyphs. */
14166 truncate_it = *it;
14167 truncate_it.current_x = 0;
14168 truncate_it.face_id = DEFAULT_FACE_ID;
14169 truncate_it.glyph_row = &scratch_glyph_row;
14170 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14171 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14172 truncate_it.object = make_number (0);
14173 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14175 /* Overwrite glyphs from IT with truncation glyphs. */
14176 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14177 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14178 to = it->glyph_row->glyphs[TEXT_AREA];
14179 toend = to + it->glyph_row->used[TEXT_AREA];
14181 while (from < end)
14182 *to++ = *from++;
14184 /* There may be padding glyphs left over. Overwrite them too. */
14185 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14187 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14188 while (from < end)
14189 *to++ = *from++;
14192 if (to > toend)
14193 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14197 /* Compute the pixel height and width of IT->glyph_row.
14199 Most of the time, ascent and height of a display line will be equal
14200 to the max_ascent and max_height values of the display iterator
14201 structure. This is not the case if
14203 1. We hit ZV without displaying anything. In this case, max_ascent
14204 and max_height will be zero.
14206 2. We have some glyphs that don't contribute to the line height.
14207 (The glyph row flag contributes_to_line_height_p is for future
14208 pixmap extensions).
14210 The first case is easily covered by using default values because in
14211 these cases, the line height does not really matter, except that it
14212 must not be zero. */
14214 static void
14215 compute_line_metrics (it)
14216 struct it *it;
14218 struct glyph_row *row = it->glyph_row;
14219 int area, i;
14221 if (FRAME_WINDOW_P (it->f))
14223 int i, min_y, max_y;
14225 /* The line may consist of one space only, that was added to
14226 place the cursor on it. If so, the row's height hasn't been
14227 computed yet. */
14228 if (row->height == 0)
14230 if (it->max_ascent + it->max_descent == 0)
14231 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14232 row->ascent = it->max_ascent;
14233 row->height = it->max_ascent + it->max_descent;
14234 row->phys_ascent = it->max_phys_ascent;
14235 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14238 /* Compute the width of this line. */
14239 row->pixel_width = row->x;
14240 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14241 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14243 xassert (row->pixel_width >= 0);
14244 xassert (row->ascent >= 0 && row->height > 0);
14246 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14247 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14249 /* If first line's physical ascent is larger than its logical
14250 ascent, use the physical ascent, and make the row taller.
14251 This makes accented characters fully visible. */
14252 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14253 && row->phys_ascent > row->ascent)
14255 row->height += row->phys_ascent - row->ascent;
14256 row->ascent = row->phys_ascent;
14259 /* Compute how much of the line is visible. */
14260 row->visible_height = row->height;
14262 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14263 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14265 if (row->y < min_y)
14266 row->visible_height -= min_y - row->y;
14267 if (row->y + row->height > max_y)
14268 row->visible_height -= row->y + row->height - max_y;
14270 else
14272 row->pixel_width = row->used[TEXT_AREA];
14273 if (row->continued_p)
14274 row->pixel_width -= it->continuation_pixel_width;
14275 else if (row->truncated_on_right_p)
14276 row->pixel_width -= it->truncation_pixel_width;
14277 row->ascent = row->phys_ascent = 0;
14278 row->height = row->phys_height = row->visible_height = 1;
14281 /* Compute a hash code for this row. */
14282 row->hash = 0;
14283 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14284 for (i = 0; i < row->used[area]; ++i)
14285 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14286 + row->glyphs[area][i].u.val
14287 + row->glyphs[area][i].face_id
14288 + row->glyphs[area][i].padding_p
14289 + (row->glyphs[area][i].type << 2));
14291 it->max_ascent = it->max_descent = 0;
14292 it->max_phys_ascent = it->max_phys_descent = 0;
14296 /* Append one space to the glyph row of iterator IT if doing a
14297 window-based redisplay. The space has the same face as
14298 IT->face_id. Value is non-zero if a space was added.
14300 This function is called to make sure that there is always one glyph
14301 at the end of a glyph row that the cursor can be set on under
14302 window-systems. (If there weren't such a glyph we would not know
14303 how wide and tall a box cursor should be displayed).
14305 At the same time this space let's a nicely handle clearing to the
14306 end of the line if the row ends in italic text. */
14308 static int
14309 append_space_for_newline (it, default_face_p)
14310 struct it *it;
14311 int default_face_p;
14313 if (FRAME_WINDOW_P (it->f))
14315 int n = it->glyph_row->used[TEXT_AREA];
14317 if (it->glyph_row->glyphs[TEXT_AREA] + n
14318 < it->glyph_row->glyphs[1 + TEXT_AREA])
14320 /* Save some values that must not be changed.
14321 Must save IT->c and IT->len because otherwise
14322 ITERATOR_AT_END_P wouldn't work anymore after
14323 append_space_for_newline has been called. */
14324 enum display_element_type saved_what = it->what;
14325 int saved_c = it->c, saved_len = it->len;
14326 int saved_x = it->current_x;
14327 int saved_face_id = it->face_id;
14328 struct text_pos saved_pos;
14329 Lisp_Object saved_object;
14330 struct face *face;
14332 saved_object = it->object;
14333 saved_pos = it->position;
14335 it->what = IT_CHARACTER;
14336 bzero (&it->position, sizeof it->position);
14337 it->object = make_number (0);
14338 it->c = ' ';
14339 it->len = 1;
14341 if (default_face_p)
14342 it->face_id = DEFAULT_FACE_ID;
14343 else if (it->face_before_selective_p)
14344 it->face_id = it->saved_face_id;
14345 face = FACE_FROM_ID (it->f, it->face_id);
14346 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14348 PRODUCE_GLYPHS (it);
14350 it->override_ascent = -1;
14351 it->constrain_row_ascent_descent_p = 0;
14352 it->current_x = saved_x;
14353 it->object = saved_object;
14354 it->position = saved_pos;
14355 it->what = saved_what;
14356 it->face_id = saved_face_id;
14357 it->len = saved_len;
14358 it->c = saved_c;
14359 return 1;
14363 return 0;
14367 /* Extend the face of the last glyph in the text area of IT->glyph_row
14368 to the end of the display line. Called from display_line.
14369 If the glyph row is empty, add a space glyph to it so that we
14370 know the face to draw. Set the glyph row flag fill_line_p. */
14372 static void
14373 extend_face_to_end_of_line (it)
14374 struct it *it;
14376 struct face *face;
14377 struct frame *f = it->f;
14379 /* If line is already filled, do nothing. */
14380 if (it->current_x >= it->last_visible_x)
14381 return;
14383 /* Face extension extends the background and box of IT->face_id
14384 to the end of the line. If the background equals the background
14385 of the frame, we don't have to do anything. */
14386 if (it->face_before_selective_p)
14387 face = FACE_FROM_ID (it->f, it->saved_face_id);
14388 else
14389 face = FACE_FROM_ID (f, it->face_id);
14391 if (FRAME_WINDOW_P (f)
14392 && face->box == FACE_NO_BOX
14393 && face->background == FRAME_BACKGROUND_PIXEL (f)
14394 && !face->stipple)
14395 return;
14397 /* Set the glyph row flag indicating that the face of the last glyph
14398 in the text area has to be drawn to the end of the text area. */
14399 it->glyph_row->fill_line_p = 1;
14401 /* If current character of IT is not ASCII, make sure we have the
14402 ASCII face. This will be automatically undone the next time
14403 get_next_display_element returns a multibyte character. Note
14404 that the character will always be single byte in unibyte text. */
14405 if (!SINGLE_BYTE_CHAR_P (it->c))
14407 it->face_id = FACE_FOR_CHAR (f, face, 0);
14410 if (FRAME_WINDOW_P (f))
14412 /* If the row is empty, add a space with the current face of IT,
14413 so that we know which face to draw. */
14414 if (it->glyph_row->used[TEXT_AREA] == 0)
14416 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14417 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14418 it->glyph_row->used[TEXT_AREA] = 1;
14421 else
14423 /* Save some values that must not be changed. */
14424 int saved_x = it->current_x;
14425 struct text_pos saved_pos;
14426 Lisp_Object saved_object;
14427 enum display_element_type saved_what = it->what;
14428 int saved_face_id = it->face_id;
14430 saved_object = it->object;
14431 saved_pos = it->position;
14433 it->what = IT_CHARACTER;
14434 bzero (&it->position, sizeof it->position);
14435 it->object = make_number (0);
14436 it->c = ' ';
14437 it->len = 1;
14438 it->face_id = face->id;
14440 PRODUCE_GLYPHS (it);
14442 while (it->current_x <= it->last_visible_x)
14443 PRODUCE_GLYPHS (it);
14445 /* Don't count these blanks really. It would let us insert a left
14446 truncation glyph below and make us set the cursor on them, maybe. */
14447 it->current_x = saved_x;
14448 it->object = saved_object;
14449 it->position = saved_pos;
14450 it->what = saved_what;
14451 it->face_id = saved_face_id;
14456 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14457 trailing whitespace. */
14459 static int
14460 trailing_whitespace_p (charpos)
14461 int charpos;
14463 int bytepos = CHAR_TO_BYTE (charpos);
14464 int c = 0;
14466 while (bytepos < ZV_BYTE
14467 && (c = FETCH_CHAR (bytepos),
14468 c == ' ' || c == '\t'))
14469 ++bytepos;
14471 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14473 if (bytepos != PT_BYTE)
14474 return 1;
14476 return 0;
14480 /* Highlight trailing whitespace, if any, in ROW. */
14482 void
14483 highlight_trailing_whitespace (f, row)
14484 struct frame *f;
14485 struct glyph_row *row;
14487 int used = row->used[TEXT_AREA];
14489 if (used)
14491 struct glyph *start = row->glyphs[TEXT_AREA];
14492 struct glyph *glyph = start + used - 1;
14494 /* Skip over glyphs inserted to display the cursor at the
14495 end of a line, for extending the face of the last glyph
14496 to the end of the line on terminals, and for truncation
14497 and continuation glyphs. */
14498 while (glyph >= start
14499 && glyph->type == CHAR_GLYPH
14500 && INTEGERP (glyph->object))
14501 --glyph;
14503 /* If last glyph is a space or stretch, and it's trailing
14504 whitespace, set the face of all trailing whitespace glyphs in
14505 IT->glyph_row to `trailing-whitespace'. */
14506 if (glyph >= start
14507 && BUFFERP (glyph->object)
14508 && (glyph->type == STRETCH_GLYPH
14509 || (glyph->type == CHAR_GLYPH
14510 && glyph->u.ch == ' '))
14511 && trailing_whitespace_p (glyph->charpos))
14513 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14515 while (glyph >= start
14516 && BUFFERP (glyph->object)
14517 && (glyph->type == STRETCH_GLYPH
14518 || (glyph->type == CHAR_GLYPH
14519 && glyph->u.ch == ' ')))
14520 (glyph--)->face_id = face_id;
14526 /* Value is non-zero if glyph row ROW in window W should be
14527 used to hold the cursor. */
14529 static int
14530 cursor_row_p (w, row)
14531 struct window *w;
14532 struct glyph_row *row;
14534 int cursor_row_p = 1;
14536 if (PT == MATRIX_ROW_END_CHARPOS (row))
14538 /* If the row ends with a newline from a string, we don't want
14539 the cursor there (if the row is continued it doesn't end in a
14540 newline). */
14541 if (CHARPOS (row->end.string_pos) >= 0
14542 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14543 cursor_row_p = row->continued_p;
14545 /* If the row ends at ZV, display the cursor at the end of that
14546 row instead of at the start of the row below. */
14547 else if (row->ends_at_zv_p)
14548 cursor_row_p = 1;
14549 else
14550 cursor_row_p = 0;
14553 return cursor_row_p;
14557 /* Construct the glyph row IT->glyph_row in the desired matrix of
14558 IT->w from text at the current position of IT. See dispextern.h
14559 for an overview of struct it. Value is non-zero if
14560 IT->glyph_row displays text, as opposed to a line displaying ZV
14561 only. */
14563 static int
14564 display_line (it)
14565 struct it *it;
14567 struct glyph_row *row = it->glyph_row;
14568 int overlay_arrow_bitmap;
14569 Lisp_Object overlay_arrow_string;
14571 /* We always start displaying at hpos zero even if hscrolled. */
14572 xassert (it->hpos == 0 && it->current_x == 0);
14574 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14575 >= it->w->desired_matrix->nrows)
14577 it->w->nrows_scale_factor++;
14578 fonts_changed_p = 1;
14579 return 0;
14582 /* Is IT->w showing the region? */
14583 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14585 /* Clear the result glyph row and enable it. */
14586 prepare_desired_row (row);
14588 row->y = it->current_y;
14589 row->start = it->start;
14590 row->continuation_lines_width = it->continuation_lines_width;
14591 row->displays_text_p = 1;
14592 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14593 it->starts_in_middle_of_char_p = 0;
14595 /* Arrange the overlays nicely for our purposes. Usually, we call
14596 display_line on only one line at a time, in which case this
14597 can't really hurt too much, or we call it on lines which appear
14598 one after another in the buffer, in which case all calls to
14599 recenter_overlay_lists but the first will be pretty cheap. */
14600 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14602 /* Move over display elements that are not visible because we are
14603 hscrolled. This may stop at an x-position < IT->first_visible_x
14604 if the first glyph is partially visible or if we hit a line end. */
14605 if (it->current_x < it->first_visible_x)
14606 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14607 MOVE_TO_POS | MOVE_TO_X);
14609 /* Get the initial row height. This is either the height of the
14610 text hscrolled, if there is any, or zero. */
14611 row->ascent = it->max_ascent;
14612 row->height = it->max_ascent + it->max_descent;
14613 row->phys_ascent = it->max_phys_ascent;
14614 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14616 /* Loop generating characters. The loop is left with IT on the next
14617 character to display. */
14618 while (1)
14620 int n_glyphs_before, hpos_before, x_before;
14621 int x, i, nglyphs;
14622 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14624 /* Retrieve the next thing to display. Value is zero if end of
14625 buffer reached. */
14626 if (!get_next_display_element (it))
14628 /* Maybe add a space at the end of this line that is used to
14629 display the cursor there under X. Set the charpos of the
14630 first glyph of blank lines not corresponding to any text
14631 to -1. */
14632 #ifdef HAVE_WINDOW_SYSTEM
14633 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14634 row->exact_window_width_line_p = 1;
14635 else
14636 #endif /* HAVE_WINDOW_SYSTEM */
14637 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14638 || row->used[TEXT_AREA] == 0)
14640 row->glyphs[TEXT_AREA]->charpos = -1;
14641 row->displays_text_p = 0;
14643 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14644 && (!MINI_WINDOW_P (it->w)
14645 || (minibuf_level && EQ (it->window, minibuf_window))))
14646 row->indicate_empty_line_p = 1;
14649 it->continuation_lines_width = 0;
14650 row->ends_at_zv_p = 1;
14651 break;
14654 /* Now, get the metrics of what we want to display. This also
14655 generates glyphs in `row' (which is IT->glyph_row). */
14656 n_glyphs_before = row->used[TEXT_AREA];
14657 x = it->current_x;
14659 /* Remember the line height so far in case the next element doesn't
14660 fit on the line. */
14661 if (!it->truncate_lines_p)
14663 ascent = it->max_ascent;
14664 descent = it->max_descent;
14665 phys_ascent = it->max_phys_ascent;
14666 phys_descent = it->max_phys_descent;
14669 PRODUCE_GLYPHS (it);
14671 /* If this display element was in marginal areas, continue with
14672 the next one. */
14673 if (it->area != TEXT_AREA)
14675 row->ascent = max (row->ascent, it->max_ascent);
14676 row->height = max (row->height, it->max_ascent + it->max_descent);
14677 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14678 row->phys_height = max (row->phys_height,
14679 it->max_phys_ascent + it->max_phys_descent);
14680 set_iterator_to_next (it, 1);
14681 continue;
14684 /* Does the display element fit on the line? If we truncate
14685 lines, we should draw past the right edge of the window. If
14686 we don't truncate, we want to stop so that we can display the
14687 continuation glyph before the right margin. If lines are
14688 continued, there are two possible strategies for characters
14689 resulting in more than 1 glyph (e.g. tabs): Display as many
14690 glyphs as possible in this line and leave the rest for the
14691 continuation line, or display the whole element in the next
14692 line. Original redisplay did the former, so we do it also. */
14693 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14694 hpos_before = it->hpos;
14695 x_before = x;
14697 if (/* Not a newline. */
14698 nglyphs > 0
14699 /* Glyphs produced fit entirely in the line. */
14700 && it->current_x < it->last_visible_x)
14702 it->hpos += nglyphs;
14703 row->ascent = max (row->ascent, it->max_ascent);
14704 row->height = max (row->height, it->max_ascent + it->max_descent);
14705 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14706 row->phys_height = max (row->phys_height,
14707 it->max_phys_ascent + it->max_phys_descent);
14708 if (it->current_x - it->pixel_width < it->first_visible_x)
14709 row->x = x - it->first_visible_x;
14711 else
14713 int new_x;
14714 struct glyph *glyph;
14716 for (i = 0; i < nglyphs; ++i, x = new_x)
14718 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14719 new_x = x + glyph->pixel_width;
14721 if (/* Lines are continued. */
14722 !it->truncate_lines_p
14723 && (/* Glyph doesn't fit on the line. */
14724 new_x > it->last_visible_x
14725 /* Or it fits exactly on a window system frame. */
14726 || (new_x == it->last_visible_x
14727 && FRAME_WINDOW_P (it->f))))
14729 /* End of a continued line. */
14731 if (it->hpos == 0
14732 || (new_x == it->last_visible_x
14733 && FRAME_WINDOW_P (it->f)))
14735 /* Current glyph is the only one on the line or
14736 fits exactly on the line. We must continue
14737 the line because we can't draw the cursor
14738 after the glyph. */
14739 row->continued_p = 1;
14740 it->current_x = new_x;
14741 it->continuation_lines_width += new_x;
14742 ++it->hpos;
14743 if (i == nglyphs - 1)
14745 set_iterator_to_next (it, 1);
14746 #ifdef HAVE_WINDOW_SYSTEM
14747 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14749 if (!get_next_display_element (it))
14751 row->exact_window_width_line_p = 1;
14752 it->continuation_lines_width = 0;
14753 row->continued_p = 0;
14754 row->ends_at_zv_p = 1;
14756 else if (ITERATOR_AT_END_OF_LINE_P (it))
14758 row->continued_p = 0;
14759 row->exact_window_width_line_p = 1;
14762 #endif /* HAVE_WINDOW_SYSTEM */
14765 else if (CHAR_GLYPH_PADDING_P (*glyph)
14766 && !FRAME_WINDOW_P (it->f))
14768 /* A padding glyph that doesn't fit on this line.
14769 This means the whole character doesn't fit
14770 on the line. */
14771 row->used[TEXT_AREA] = n_glyphs_before;
14773 /* Fill the rest of the row with continuation
14774 glyphs like in 20.x. */
14775 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14776 < row->glyphs[1 + TEXT_AREA])
14777 produce_special_glyphs (it, IT_CONTINUATION);
14779 row->continued_p = 1;
14780 it->current_x = x_before;
14781 it->continuation_lines_width += x_before;
14783 /* Restore the height to what it was before the
14784 element not fitting on the line. */
14785 it->max_ascent = ascent;
14786 it->max_descent = descent;
14787 it->max_phys_ascent = phys_ascent;
14788 it->max_phys_descent = phys_descent;
14790 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14792 /* A TAB that extends past the right edge of the
14793 window. This produces a single glyph on
14794 window system frames. We leave the glyph in
14795 this row and let it fill the row, but don't
14796 consume the TAB. */
14797 it->continuation_lines_width += it->last_visible_x;
14798 row->ends_in_middle_of_char_p = 1;
14799 row->continued_p = 1;
14800 glyph->pixel_width = it->last_visible_x - x;
14801 it->starts_in_middle_of_char_p = 1;
14803 else
14805 /* Something other than a TAB that draws past
14806 the right edge of the window. Restore
14807 positions to values before the element. */
14808 row->used[TEXT_AREA] = n_glyphs_before + i;
14810 /* Display continuation glyphs. */
14811 if (!FRAME_WINDOW_P (it->f))
14812 produce_special_glyphs (it, IT_CONTINUATION);
14813 row->continued_p = 1;
14815 it->continuation_lines_width += x;
14817 if (nglyphs > 1 && i > 0)
14819 row->ends_in_middle_of_char_p = 1;
14820 it->starts_in_middle_of_char_p = 1;
14823 /* Restore the height to what it was before the
14824 element not fitting on the line. */
14825 it->max_ascent = ascent;
14826 it->max_descent = descent;
14827 it->max_phys_ascent = phys_ascent;
14828 it->max_phys_descent = phys_descent;
14831 break;
14833 else if (new_x > it->first_visible_x)
14835 /* Increment number of glyphs actually displayed. */
14836 ++it->hpos;
14838 if (x < it->first_visible_x)
14839 /* Glyph is partially visible, i.e. row starts at
14840 negative X position. */
14841 row->x = x - it->first_visible_x;
14843 else
14845 /* Glyph is completely off the left margin of the
14846 window. This should not happen because of the
14847 move_it_in_display_line at the start of this
14848 function, unless the text display area of the
14849 window is empty. */
14850 xassert (it->first_visible_x <= it->last_visible_x);
14854 row->ascent = max (row->ascent, it->max_ascent);
14855 row->height = max (row->height, it->max_ascent + it->max_descent);
14856 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14857 row->phys_height = max (row->phys_height,
14858 it->max_phys_ascent + it->max_phys_descent);
14860 /* End of this display line if row is continued. */
14861 if (row->continued_p || row->ends_at_zv_p)
14862 break;
14865 at_end_of_line:
14866 /* Is this a line end? If yes, we're also done, after making
14867 sure that a non-default face is extended up to the right
14868 margin of the window. */
14869 if (ITERATOR_AT_END_OF_LINE_P (it))
14871 int used_before = row->used[TEXT_AREA];
14873 row->ends_in_newline_from_string_p = STRINGP (it->object);
14875 #ifdef HAVE_WINDOW_SYSTEM
14876 /* Add a space at the end of the line that is used to
14877 display the cursor there. */
14878 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14879 append_space_for_newline (it, 0);
14880 #endif /* HAVE_WINDOW_SYSTEM */
14882 /* Extend the face to the end of the line. */
14883 extend_face_to_end_of_line (it);
14885 /* Make sure we have the position. */
14886 if (used_before == 0)
14887 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14889 /* Consume the line end. This skips over invisible lines. */
14890 set_iterator_to_next (it, 1);
14891 it->continuation_lines_width = 0;
14892 break;
14895 /* Proceed with next display element. Note that this skips
14896 over lines invisible because of selective display. */
14897 set_iterator_to_next (it, 1);
14899 /* If we truncate lines, we are done when the last displayed
14900 glyphs reach past the right margin of the window. */
14901 if (it->truncate_lines_p
14902 && (FRAME_WINDOW_P (it->f)
14903 ? (it->current_x >= it->last_visible_x)
14904 : (it->current_x > it->last_visible_x)))
14906 /* Maybe add truncation glyphs. */
14907 if (!FRAME_WINDOW_P (it->f))
14909 int i, n;
14911 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14912 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14913 break;
14915 for (n = row->used[TEXT_AREA]; i < n; ++i)
14917 row->used[TEXT_AREA] = i;
14918 produce_special_glyphs (it, IT_TRUNCATION);
14921 #ifdef HAVE_WINDOW_SYSTEM
14922 else
14924 /* Don't truncate if we can overflow newline into fringe. */
14925 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14927 if (!get_next_display_element (it))
14929 #ifdef HAVE_WINDOW_SYSTEM
14930 it->continuation_lines_width = 0;
14931 row->ends_at_zv_p = 1;
14932 row->exact_window_width_line_p = 1;
14933 break;
14934 #endif /* HAVE_WINDOW_SYSTEM */
14936 if (ITERATOR_AT_END_OF_LINE_P (it))
14938 row->exact_window_width_line_p = 1;
14939 goto at_end_of_line;
14943 #endif /* HAVE_WINDOW_SYSTEM */
14945 row->truncated_on_right_p = 1;
14946 it->continuation_lines_width = 0;
14947 reseat_at_next_visible_line_start (it, 0);
14948 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14949 it->hpos = hpos_before;
14950 it->current_x = x_before;
14951 break;
14955 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14956 at the left window margin. */
14957 if (it->first_visible_x
14958 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14960 if (!FRAME_WINDOW_P (it->f))
14961 insert_left_trunc_glyphs (it);
14962 row->truncated_on_left_p = 1;
14965 /* If the start of this line is the overlay arrow-position, then
14966 mark this glyph row as the one containing the overlay arrow.
14967 This is clearly a mess with variable size fonts. It would be
14968 better to let it be displayed like cursors under X. */
14969 if (! overlay_arrow_seen
14970 && (overlay_arrow_string
14971 = overlay_arrow_at_row (it, row, &overlay_arrow_bitmap),
14972 !NILP (overlay_arrow_string)))
14974 /* Overlay arrow in window redisplay is a fringe bitmap. */
14975 if (STRINGP (overlay_arrow_string))
14977 struct glyph_row *arrow_row
14978 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14979 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14980 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14981 struct glyph *p = row->glyphs[TEXT_AREA];
14982 struct glyph *p2, *end;
14984 /* Copy the arrow glyphs. */
14985 while (glyph < arrow_end)
14986 *p++ = *glyph++;
14988 /* Throw away padding glyphs. */
14989 p2 = p;
14990 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14991 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14992 ++p2;
14993 if (p2 > p)
14995 while (p2 < end)
14996 *p++ = *p2++;
14997 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15000 else
15002 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
15003 row->overlay_arrow_p = 1;
15005 overlay_arrow_seen = 1;
15008 /* Compute pixel dimensions of this line. */
15009 compute_line_metrics (it);
15011 /* Remember the position at which this line ends. */
15012 row->end = it->current;
15014 /* Save fringe bitmaps in this row. */
15015 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15016 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15017 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15018 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15020 it->left_user_fringe_bitmap = 0;
15021 it->left_user_fringe_face_id = 0;
15022 it->right_user_fringe_bitmap = 0;
15023 it->right_user_fringe_face_id = 0;
15025 /* Maybe set the cursor. */
15026 if (it->w->cursor.vpos < 0
15027 && PT >= MATRIX_ROW_START_CHARPOS (row)
15028 && PT <= MATRIX_ROW_END_CHARPOS (row)
15029 && cursor_row_p (it->w, row))
15030 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15032 /* Highlight trailing whitespace. */
15033 if (!NILP (Vshow_trailing_whitespace))
15034 highlight_trailing_whitespace (it->f, it->glyph_row);
15036 /* Prepare for the next line. This line starts horizontally at (X
15037 HPOS) = (0 0). Vertical positions are incremented. As a
15038 convenience for the caller, IT->glyph_row is set to the next
15039 row to be used. */
15040 it->current_x = it->hpos = 0;
15041 it->current_y += row->height;
15042 ++it->vpos;
15043 ++it->glyph_row;
15044 it->start = it->current;
15045 return row->displays_text_p;
15050 /***********************************************************************
15051 Menu Bar
15052 ***********************************************************************/
15054 /* Redisplay the menu bar in the frame for window W.
15056 The menu bar of X frames that don't have X toolkit support is
15057 displayed in a special window W->frame->menu_bar_window.
15059 The menu bar of terminal frames is treated specially as far as
15060 glyph matrices are concerned. Menu bar lines are not part of
15061 windows, so the update is done directly on the frame matrix rows
15062 for the menu bar. */
15064 static void
15065 display_menu_bar (w)
15066 struct window *w;
15068 struct frame *f = XFRAME (WINDOW_FRAME (w));
15069 struct it it;
15070 Lisp_Object items;
15071 int i;
15073 /* Don't do all this for graphical frames. */
15074 #ifdef HAVE_NTGUI
15075 if (!NILP (Vwindow_system))
15076 return;
15077 #endif
15078 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15079 if (FRAME_X_P (f))
15080 return;
15081 #endif
15082 #ifdef MAC_OS
15083 if (FRAME_MAC_P (f))
15084 return;
15085 #endif
15087 #ifdef USE_X_TOOLKIT
15088 xassert (!FRAME_WINDOW_P (f));
15089 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15090 it.first_visible_x = 0;
15091 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15092 #else /* not USE_X_TOOLKIT */
15093 if (FRAME_WINDOW_P (f))
15095 /* Menu bar lines are displayed in the desired matrix of the
15096 dummy window menu_bar_window. */
15097 struct window *menu_w;
15098 xassert (WINDOWP (f->menu_bar_window));
15099 menu_w = XWINDOW (f->menu_bar_window);
15100 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15101 MENU_FACE_ID);
15102 it.first_visible_x = 0;
15103 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15105 else
15107 /* This is a TTY frame, i.e. character hpos/vpos are used as
15108 pixel x/y. */
15109 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15110 MENU_FACE_ID);
15111 it.first_visible_x = 0;
15112 it.last_visible_x = FRAME_COLS (f);
15114 #endif /* not USE_X_TOOLKIT */
15116 if (! mode_line_inverse_video)
15117 /* Force the menu-bar to be displayed in the default face. */
15118 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15120 /* Clear all rows of the menu bar. */
15121 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15123 struct glyph_row *row = it.glyph_row + i;
15124 clear_glyph_row (row);
15125 row->enabled_p = 1;
15126 row->full_width_p = 1;
15129 /* Display all items of the menu bar. */
15130 items = FRAME_MENU_BAR_ITEMS (it.f);
15131 for (i = 0; i < XVECTOR (items)->size; i += 4)
15133 Lisp_Object string;
15135 /* Stop at nil string. */
15136 string = AREF (items, i + 1);
15137 if (NILP (string))
15138 break;
15140 /* Remember where item was displayed. */
15141 AREF (items, i + 3) = make_number (it.hpos);
15143 /* Display the item, pad with one space. */
15144 if (it.current_x < it.last_visible_x)
15145 display_string (NULL, string, Qnil, 0, 0, &it,
15146 SCHARS (string) + 1, 0, 0, -1);
15149 /* Fill out the line with spaces. */
15150 if (it.current_x < it.last_visible_x)
15151 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15153 /* Compute the total height of the lines. */
15154 compute_line_metrics (&it);
15159 /***********************************************************************
15160 Mode Line
15161 ***********************************************************************/
15163 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15164 FORCE is non-zero, redisplay mode lines unconditionally.
15165 Otherwise, redisplay only mode lines that are garbaged. Value is
15166 the number of windows whose mode lines were redisplayed. */
15168 static int
15169 redisplay_mode_lines (window, force)
15170 Lisp_Object window;
15171 int force;
15173 int nwindows = 0;
15175 while (!NILP (window))
15177 struct window *w = XWINDOW (window);
15179 if (WINDOWP (w->hchild))
15180 nwindows += redisplay_mode_lines (w->hchild, force);
15181 else if (WINDOWP (w->vchild))
15182 nwindows += redisplay_mode_lines (w->vchild, force);
15183 else if (force
15184 || FRAME_GARBAGED_P (XFRAME (w->frame))
15185 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15187 struct text_pos lpoint;
15188 struct buffer *old = current_buffer;
15190 /* Set the window's buffer for the mode line display. */
15191 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15192 set_buffer_internal_1 (XBUFFER (w->buffer));
15194 /* Point refers normally to the selected window. For any
15195 other window, set up appropriate value. */
15196 if (!EQ (window, selected_window))
15198 struct text_pos pt;
15200 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15201 if (CHARPOS (pt) < BEGV)
15202 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15203 else if (CHARPOS (pt) > (ZV - 1))
15204 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15205 else
15206 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15209 /* Display mode lines. */
15210 clear_glyph_matrix (w->desired_matrix);
15211 if (display_mode_lines (w))
15213 ++nwindows;
15214 w->must_be_updated_p = 1;
15217 /* Restore old settings. */
15218 set_buffer_internal_1 (old);
15219 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15222 window = w->next;
15225 return nwindows;
15229 /* Display the mode and/or top line of window W. Value is the number
15230 of mode lines displayed. */
15232 static int
15233 display_mode_lines (w)
15234 struct window *w;
15236 Lisp_Object old_selected_window, old_selected_frame;
15237 int n = 0;
15239 old_selected_frame = selected_frame;
15240 selected_frame = w->frame;
15241 old_selected_window = selected_window;
15242 XSETWINDOW (selected_window, w);
15244 /* These will be set while the mode line specs are processed. */
15245 line_number_displayed = 0;
15246 w->column_number_displayed = Qnil;
15248 if (WINDOW_WANTS_MODELINE_P (w))
15250 struct window *sel_w = XWINDOW (old_selected_window);
15252 /* Select mode line face based on the real selected window. */
15253 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15254 current_buffer->mode_line_format);
15255 ++n;
15258 if (WINDOW_WANTS_HEADER_LINE_P (w))
15260 display_mode_line (w, HEADER_LINE_FACE_ID,
15261 current_buffer->header_line_format);
15262 ++n;
15265 selected_frame = old_selected_frame;
15266 selected_window = old_selected_window;
15267 return n;
15271 /* Display mode or top line of window W. FACE_ID specifies which line
15272 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15273 FORMAT is the mode line format to display. Value is the pixel
15274 height of the mode line displayed. */
15276 static int
15277 display_mode_line (w, face_id, format)
15278 struct window *w;
15279 enum face_id face_id;
15280 Lisp_Object format;
15282 struct it it;
15283 struct face *face;
15285 init_iterator (&it, w, -1, -1, NULL, face_id);
15286 prepare_desired_row (it.glyph_row);
15288 it.glyph_row->mode_line_p = 1;
15290 if (! mode_line_inverse_video)
15291 /* Force the mode-line to be displayed in the default face. */
15292 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15294 /* Temporarily make frame's keyboard the current kboard so that
15295 kboard-local variables in the mode_line_format will get the right
15296 values. */
15297 push_frame_kboard (it.f);
15298 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15299 pop_frame_kboard ();
15301 /* Fill up with spaces. */
15302 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15304 compute_line_metrics (&it);
15305 it.glyph_row->full_width_p = 1;
15306 it.glyph_row->continued_p = 0;
15307 it.glyph_row->truncated_on_left_p = 0;
15308 it.glyph_row->truncated_on_right_p = 0;
15310 /* Make a 3D mode-line have a shadow at its right end. */
15311 face = FACE_FROM_ID (it.f, face_id);
15312 extend_face_to_end_of_line (&it);
15313 if (face->box != FACE_NO_BOX)
15315 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15316 + it.glyph_row->used[TEXT_AREA] - 1);
15317 last->right_box_line_p = 1;
15320 return it.glyph_row->height;
15323 /* Alist that caches the results of :propertize.
15324 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15325 Lisp_Object mode_line_proptrans_alist;
15327 /* List of strings making up the mode-line. */
15328 Lisp_Object mode_line_string_list;
15330 /* Base face property when building propertized mode line string. */
15331 static Lisp_Object mode_line_string_face;
15332 static Lisp_Object mode_line_string_face_prop;
15335 /* Contribute ELT to the mode line for window IT->w. How it
15336 translates into text depends on its data type.
15338 IT describes the display environment in which we display, as usual.
15340 DEPTH is the depth in recursion. It is used to prevent
15341 infinite recursion here.
15343 FIELD_WIDTH is the number of characters the display of ELT should
15344 occupy in the mode line, and PRECISION is the maximum number of
15345 characters to display from ELT's representation. See
15346 display_string for details.
15348 Returns the hpos of the end of the text generated by ELT.
15350 PROPS is a property list to add to any string we encounter.
15352 If RISKY is nonzero, remove (disregard) any properties in any string
15353 we encounter, and ignore :eval and :propertize.
15355 If the global variable `frame_title_ptr' is non-NULL, then the output
15356 is passed to `store_frame_title' instead of `display_string'. */
15358 static int
15359 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15360 struct it *it;
15361 int depth;
15362 int field_width, precision;
15363 Lisp_Object elt, props;
15364 int risky;
15366 int n = 0, field, prec;
15367 int literal = 0;
15369 tail_recurse:
15370 if (depth > 100)
15371 elt = build_string ("*too-deep*");
15373 depth++;
15375 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15377 case Lisp_String:
15379 /* A string: output it and check for %-constructs within it. */
15380 unsigned char c;
15381 const unsigned char *this, *lisp_string;
15383 if (!NILP (props) || risky)
15385 Lisp_Object oprops, aelt;
15386 oprops = Ftext_properties_at (make_number (0), elt);
15388 /* If the starting string's properties are not what
15389 we want, translate the string. Also, if the string
15390 is risky, do that anyway. */
15392 if (NILP (Fequal (props, oprops)) || risky)
15394 /* If the starting string has properties,
15395 merge the specified ones onto the existing ones. */
15396 if (! NILP (oprops) && !risky)
15398 Lisp_Object tem;
15400 oprops = Fcopy_sequence (oprops);
15401 tem = props;
15402 while (CONSP (tem))
15404 oprops = Fplist_put (oprops, XCAR (tem),
15405 XCAR (XCDR (tem)));
15406 tem = XCDR (XCDR (tem));
15408 props = oprops;
15411 aelt = Fassoc (elt, mode_line_proptrans_alist);
15412 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15414 mode_line_proptrans_alist
15415 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15416 elt = XCAR (aelt);
15418 else
15420 Lisp_Object tem;
15422 elt = Fcopy_sequence (elt);
15423 Fset_text_properties (make_number (0), Flength (elt),
15424 props, elt);
15425 /* Add this item to mode_line_proptrans_alist. */
15426 mode_line_proptrans_alist
15427 = Fcons (Fcons (elt, props),
15428 mode_line_proptrans_alist);
15429 /* Truncate mode_line_proptrans_alist
15430 to at most 50 elements. */
15431 tem = Fnthcdr (make_number (50),
15432 mode_line_proptrans_alist);
15433 if (! NILP (tem))
15434 XSETCDR (tem, Qnil);
15439 this = SDATA (elt);
15440 lisp_string = this;
15442 if (literal)
15444 prec = precision - n;
15445 if (frame_title_ptr)
15446 n += store_frame_title (SDATA (elt), -1, prec);
15447 else if (!NILP (mode_line_string_list))
15448 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15449 else
15450 n += display_string (NULL, elt, Qnil, 0, 0, it,
15451 0, prec, 0, STRING_MULTIBYTE (elt));
15453 break;
15456 while ((precision <= 0 || n < precision)
15457 && *this
15458 && (frame_title_ptr
15459 || !NILP (mode_line_string_list)
15460 || it->current_x < it->last_visible_x))
15462 const unsigned char *last = this;
15464 /* Advance to end of string or next format specifier. */
15465 while ((c = *this++) != '\0' && c != '%')
15468 if (this - 1 != last)
15470 int nchars, nbytes;
15472 /* Output to end of string or up to '%'. Field width
15473 is length of string. Don't output more than
15474 PRECISION allows us. */
15475 --this;
15477 prec = c_string_width (last, this - last, precision - n,
15478 &nchars, &nbytes);
15480 if (frame_title_ptr)
15481 n += store_frame_title (last, 0, prec);
15482 else if (!NILP (mode_line_string_list))
15484 int bytepos = last - lisp_string;
15485 int charpos = string_byte_to_char (elt, bytepos);
15486 int endpos = (precision <= 0 ? SCHARS (elt)
15487 : charpos + nchars);
15489 n += store_mode_line_string (NULL,
15490 Fsubstring (elt, make_number (charpos),
15491 make_number (endpos)),
15492 0, 0, 0, Qnil);
15494 else
15496 int bytepos = last - lisp_string;
15497 int charpos = string_byte_to_char (elt, bytepos);
15498 n += display_string (NULL, elt, Qnil, 0, charpos,
15499 it, 0, prec, 0,
15500 STRING_MULTIBYTE (elt));
15503 else /* c == '%' */
15505 const unsigned char *percent_position = this;
15507 /* Get the specified minimum width. Zero means
15508 don't pad. */
15509 field = 0;
15510 while ((c = *this++) >= '0' && c <= '9')
15511 field = field * 10 + c - '0';
15513 /* Don't pad beyond the total padding allowed. */
15514 if (field_width - n > 0 && field > field_width - n)
15515 field = field_width - n;
15517 /* Note that either PRECISION <= 0 or N < PRECISION. */
15518 prec = precision - n;
15520 if (c == 'M')
15521 n += display_mode_element (it, depth, field, prec,
15522 Vglobal_mode_string, props,
15523 risky);
15524 else if (c != 0)
15526 int multibyte;
15527 int bytepos, charpos;
15528 unsigned char *spec;
15530 bytepos = percent_position - lisp_string;
15531 charpos = (STRING_MULTIBYTE (elt)
15532 ? string_byte_to_char (elt, bytepos)
15533 : bytepos);
15535 spec
15536 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15538 if (frame_title_ptr)
15539 n += store_frame_title (spec, field, prec);
15540 else if (!NILP (mode_line_string_list))
15542 int len = strlen (spec);
15543 Lisp_Object tem = make_string (spec, len);
15544 props = Ftext_properties_at (make_number (charpos), elt);
15545 /* Should only keep face property in props */
15546 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15548 else
15550 int nglyphs_before, nwritten;
15552 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15553 nwritten = display_string (spec, Qnil, elt,
15554 charpos, 0, it,
15555 field, prec, 0,
15556 multibyte);
15558 /* Assign to the glyphs written above the
15559 string where the `%x' came from, position
15560 of the `%'. */
15561 if (nwritten > 0)
15563 struct glyph *glyph
15564 = (it->glyph_row->glyphs[TEXT_AREA]
15565 + nglyphs_before);
15566 int i;
15568 for (i = 0; i < nwritten; ++i)
15570 glyph[i].object = elt;
15571 glyph[i].charpos = charpos;
15574 n += nwritten;
15578 else /* c == 0 */
15579 break;
15583 break;
15585 case Lisp_Symbol:
15586 /* A symbol: process the value of the symbol recursively
15587 as if it appeared here directly. Avoid error if symbol void.
15588 Special case: if value of symbol is a string, output the string
15589 literally. */
15591 register Lisp_Object tem;
15593 /* If the variable is not marked as risky to set
15594 then its contents are risky to use. */
15595 if (NILP (Fget (elt, Qrisky_local_variable)))
15596 risky = 1;
15598 tem = Fboundp (elt);
15599 if (!NILP (tem))
15601 tem = Fsymbol_value (elt);
15602 /* If value is a string, output that string literally:
15603 don't check for % within it. */
15604 if (STRINGP (tem))
15605 literal = 1;
15607 if (!EQ (tem, elt))
15609 /* Give up right away for nil or t. */
15610 elt = tem;
15611 goto tail_recurse;
15615 break;
15617 case Lisp_Cons:
15619 register Lisp_Object car, tem;
15621 /* A cons cell: five distinct cases.
15622 If first element is :eval or :propertize, do something special.
15623 If first element is a string or a cons, process all the elements
15624 and effectively concatenate them.
15625 If first element is a negative number, truncate displaying cdr to
15626 at most that many characters. If positive, pad (with spaces)
15627 to at least that many characters.
15628 If first element is a symbol, process the cadr or caddr recursively
15629 according to whether the symbol's value is non-nil or nil. */
15630 car = XCAR (elt);
15631 if (EQ (car, QCeval))
15633 /* An element of the form (:eval FORM) means evaluate FORM
15634 and use the result as mode line elements. */
15636 if (risky)
15637 break;
15639 if (CONSP (XCDR (elt)))
15641 Lisp_Object spec;
15642 spec = safe_eval (XCAR (XCDR (elt)));
15643 n += display_mode_element (it, depth, field_width - n,
15644 precision - n, spec, props,
15645 risky);
15648 else if (EQ (car, QCpropertize))
15650 /* An element of the form (:propertize ELT PROPS...)
15651 means display ELT but applying properties PROPS. */
15653 if (risky)
15654 break;
15656 if (CONSP (XCDR (elt)))
15657 n += display_mode_element (it, depth, field_width - n,
15658 precision - n, XCAR (XCDR (elt)),
15659 XCDR (XCDR (elt)), risky);
15661 else if (SYMBOLP (car))
15663 tem = Fboundp (car);
15664 elt = XCDR (elt);
15665 if (!CONSP (elt))
15666 goto invalid;
15667 /* elt is now the cdr, and we know it is a cons cell.
15668 Use its car if CAR has a non-nil value. */
15669 if (!NILP (tem))
15671 tem = Fsymbol_value (car);
15672 if (!NILP (tem))
15674 elt = XCAR (elt);
15675 goto tail_recurse;
15678 /* Symbol's value is nil (or symbol is unbound)
15679 Get the cddr of the original list
15680 and if possible find the caddr and use that. */
15681 elt = XCDR (elt);
15682 if (NILP (elt))
15683 break;
15684 else if (!CONSP (elt))
15685 goto invalid;
15686 elt = XCAR (elt);
15687 goto tail_recurse;
15689 else if (INTEGERP (car))
15691 register int lim = XINT (car);
15692 elt = XCDR (elt);
15693 if (lim < 0)
15695 /* Negative int means reduce maximum width. */
15696 if (precision <= 0)
15697 precision = -lim;
15698 else
15699 precision = min (precision, -lim);
15701 else if (lim > 0)
15703 /* Padding specified. Don't let it be more than
15704 current maximum. */
15705 if (precision > 0)
15706 lim = min (precision, lim);
15708 /* If that's more padding than already wanted, queue it.
15709 But don't reduce padding already specified even if
15710 that is beyond the current truncation point. */
15711 field_width = max (lim, field_width);
15713 goto tail_recurse;
15715 else if (STRINGP (car) || CONSP (car))
15717 register int limit = 50;
15718 /* Limit is to protect against circular lists. */
15719 while (CONSP (elt)
15720 && --limit > 0
15721 && (precision <= 0 || n < precision))
15723 n += display_mode_element (it, depth, field_width - n,
15724 precision - n, XCAR (elt),
15725 props, risky);
15726 elt = XCDR (elt);
15730 break;
15732 default:
15733 invalid:
15734 elt = build_string ("*invalid*");
15735 goto tail_recurse;
15738 /* Pad to FIELD_WIDTH. */
15739 if (field_width > 0 && n < field_width)
15741 if (frame_title_ptr)
15742 n += store_frame_title ("", field_width - n, 0);
15743 else if (!NILP (mode_line_string_list))
15744 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15745 else
15746 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15747 0, 0, 0);
15750 return n;
15753 /* Store a mode-line string element in mode_line_string_list.
15755 If STRING is non-null, display that C string. Otherwise, the Lisp
15756 string LISP_STRING is displayed.
15758 FIELD_WIDTH is the minimum number of output glyphs to produce.
15759 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15760 with spaces. FIELD_WIDTH <= 0 means don't pad.
15762 PRECISION is the maximum number of characters to output from
15763 STRING. PRECISION <= 0 means don't truncate the string.
15765 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15766 properties to the string.
15768 PROPS are the properties to add to the string.
15769 The mode_line_string_face face property is always added to the string.
15772 static int
15773 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15774 char *string;
15775 Lisp_Object lisp_string;
15776 int copy_string;
15777 int field_width;
15778 int precision;
15779 Lisp_Object props;
15781 int len;
15782 int n = 0;
15784 if (string != NULL)
15786 len = strlen (string);
15787 if (precision > 0 && len > precision)
15788 len = precision;
15789 lisp_string = make_string (string, len);
15790 if (NILP (props))
15791 props = mode_line_string_face_prop;
15792 else if (!NILP (mode_line_string_face))
15794 Lisp_Object face = Fplist_get (props, Qface);
15795 props = Fcopy_sequence (props);
15796 if (NILP (face))
15797 face = mode_line_string_face;
15798 else
15799 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15800 props = Fplist_put (props, Qface, face);
15802 Fadd_text_properties (make_number (0), make_number (len),
15803 props, lisp_string);
15805 else
15807 len = XFASTINT (Flength (lisp_string));
15808 if (precision > 0 && len > precision)
15810 len = precision;
15811 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15812 precision = -1;
15814 if (!NILP (mode_line_string_face))
15816 Lisp_Object face;
15817 if (NILP (props))
15818 props = Ftext_properties_at (make_number (0), lisp_string);
15819 face = Fplist_get (props, Qface);
15820 if (NILP (face))
15821 face = mode_line_string_face;
15822 else
15823 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15824 props = Fcons (Qface, Fcons (face, Qnil));
15825 if (copy_string)
15826 lisp_string = Fcopy_sequence (lisp_string);
15828 if (!NILP (props))
15829 Fadd_text_properties (make_number (0), make_number (len),
15830 props, lisp_string);
15833 if (len > 0)
15835 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15836 n += len;
15839 if (field_width > len)
15841 field_width -= len;
15842 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15843 if (!NILP (props))
15844 Fadd_text_properties (make_number (0), make_number (field_width),
15845 props, lisp_string);
15846 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15847 n += field_width;
15850 return n;
15854 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15855 0, 4, 0,
15856 doc: /* Return the mode-line of selected window as a string.
15857 First optional arg FORMAT specifies a different format string (see
15858 `mode-line-format' for details) to use. If FORMAT is t, return
15859 the buffer's header-line. Second optional arg WINDOW specifies a
15860 different window to use as the context for the formatting.
15861 If third optional arg NO-PROPS is non-nil, string is not propertized.
15862 Fourth optional arg BUFFER specifies which buffer to use. */)
15863 (format, window, no_props, buffer)
15864 Lisp_Object format, window, no_props, buffer;
15866 struct it it;
15867 int len;
15868 struct window *w;
15869 struct buffer *old_buffer = NULL;
15870 enum face_id face_id = DEFAULT_FACE_ID;
15872 if (NILP (window))
15873 window = selected_window;
15874 CHECK_WINDOW (window);
15875 w = XWINDOW (window);
15877 if (NILP (buffer))
15878 buffer = w->buffer;
15880 CHECK_BUFFER (buffer);
15882 if (XBUFFER (buffer) != current_buffer)
15884 old_buffer = current_buffer;
15885 set_buffer_internal_1 (XBUFFER (buffer));
15888 if (NILP (format) || EQ (format, Qt))
15890 face_id = (NILP (format)
15891 ? CURRENT_MODE_LINE_FACE_ID (w)
15892 : HEADER_LINE_FACE_ID);
15893 format = (NILP (format)
15894 ? current_buffer->mode_line_format
15895 : current_buffer->header_line_format);
15898 init_iterator (&it, w, -1, -1, NULL, face_id);
15900 if (NILP (no_props))
15902 mode_line_string_face
15903 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15904 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15905 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15907 mode_line_string_face_prop
15908 = (NILP (mode_line_string_face) ? Qnil
15909 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15911 /* We need a dummy last element in mode_line_string_list to
15912 indicate we are building the propertized mode-line string.
15913 Using mode_line_string_face_prop here GC protects it. */
15914 mode_line_string_list
15915 = Fcons (mode_line_string_face_prop, Qnil);
15916 frame_title_ptr = NULL;
15918 else
15920 mode_line_string_face_prop = Qnil;
15921 mode_line_string_list = Qnil;
15922 frame_title_ptr = frame_title_buf;
15925 push_frame_kboard (it.f);
15926 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15927 pop_frame_kboard ();
15929 if (old_buffer)
15930 set_buffer_internal_1 (old_buffer);
15932 if (NILP (no_props))
15934 Lisp_Object str;
15935 mode_line_string_list = Fnreverse (mode_line_string_list);
15936 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15937 make_string ("", 0));
15938 mode_line_string_face_prop = Qnil;
15939 mode_line_string_list = Qnil;
15940 return str;
15943 len = frame_title_ptr - frame_title_buf;
15944 if (len > 0 && frame_title_ptr[-1] == '-')
15946 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15947 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15949 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15950 if (len > frame_title_ptr - frame_title_buf)
15951 len = frame_title_ptr - frame_title_buf;
15954 frame_title_ptr = NULL;
15955 return make_string (frame_title_buf, len);
15958 /* Write a null-terminated, right justified decimal representation of
15959 the positive integer D to BUF using a minimal field width WIDTH. */
15961 static void
15962 pint2str (buf, width, d)
15963 register char *buf;
15964 register int width;
15965 register int d;
15967 register char *p = buf;
15969 if (d <= 0)
15970 *p++ = '0';
15971 else
15973 while (d > 0)
15975 *p++ = d % 10 + '0';
15976 d /= 10;
15980 for (width -= (int) (p - buf); width > 0; --width)
15981 *p++ = ' ';
15982 *p-- = '\0';
15983 while (p > buf)
15985 d = *buf;
15986 *buf++ = *p;
15987 *p-- = d;
15991 /* Write a null-terminated, right justified decimal and "human
15992 readable" representation of the nonnegative integer D to BUF using
15993 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15995 static const char power_letter[] =
15997 0, /* not used */
15998 'k', /* kilo */
15999 'M', /* mega */
16000 'G', /* giga */
16001 'T', /* tera */
16002 'P', /* peta */
16003 'E', /* exa */
16004 'Z', /* zetta */
16005 'Y' /* yotta */
16008 static void
16009 pint2hrstr (buf, width, d)
16010 char *buf;
16011 int width;
16012 int d;
16014 /* We aim to represent the nonnegative integer D as
16015 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16016 int quotient = d;
16017 int remainder = 0;
16018 /* -1 means: do not use TENTHS. */
16019 int tenths = -1;
16020 int exponent = 0;
16022 /* Length of QUOTIENT.TENTHS as a string. */
16023 int length;
16025 char * psuffix;
16026 char * p;
16028 if (1000 <= quotient)
16030 /* Scale to the appropriate EXPONENT. */
16033 remainder = quotient % 1000;
16034 quotient /= 1000;
16035 exponent++;
16037 while (1000 <= quotient);
16039 /* Round to nearest and decide whether to use TENTHS or not. */
16040 if (quotient <= 9)
16042 tenths = remainder / 100;
16043 if (50 <= remainder % 100)
16044 if (tenths < 9)
16045 tenths++;
16046 else
16048 quotient++;
16049 if (quotient == 10)
16050 tenths = -1;
16051 else
16052 tenths = 0;
16055 else
16056 if (500 <= remainder)
16057 if (quotient < 999)
16058 quotient++;
16059 else
16061 quotient = 1;
16062 exponent++;
16063 tenths = 0;
16067 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16068 if (tenths == -1 && quotient <= 99)
16069 if (quotient <= 9)
16070 length = 1;
16071 else
16072 length = 2;
16073 else
16074 length = 3;
16075 p = psuffix = buf + max (width, length);
16077 /* Print EXPONENT. */
16078 if (exponent)
16079 *psuffix++ = power_letter[exponent];
16080 *psuffix = '\0';
16082 /* Print TENTHS. */
16083 if (tenths >= 0)
16085 *--p = '0' + tenths;
16086 *--p = '.';
16089 /* Print QUOTIENT. */
16092 int digit = quotient % 10;
16093 *--p = '0' + digit;
16095 while ((quotient /= 10) != 0);
16097 /* Print leading spaces. */
16098 while (buf < p)
16099 *--p = ' ';
16102 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16103 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16104 type of CODING_SYSTEM. Return updated pointer into BUF. */
16106 static unsigned char invalid_eol_type[] = "(*invalid*)";
16108 static char *
16109 decode_mode_spec_coding (coding_system, buf, eol_flag)
16110 Lisp_Object coding_system;
16111 register char *buf;
16112 int eol_flag;
16114 Lisp_Object val;
16115 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16116 const unsigned char *eol_str;
16117 int eol_str_len;
16118 /* The EOL conversion we are using. */
16119 Lisp_Object eoltype;
16121 val = Fget (coding_system, Qcoding_system);
16122 eoltype = Qnil;
16124 if (!VECTORP (val)) /* Not yet decided. */
16126 if (multibyte)
16127 *buf++ = '-';
16128 if (eol_flag)
16129 eoltype = eol_mnemonic_undecided;
16130 /* Don't mention EOL conversion if it isn't decided. */
16132 else
16134 Lisp_Object eolvalue;
16136 eolvalue = Fget (coding_system, Qeol_type);
16138 if (multibyte)
16139 *buf++ = XFASTINT (AREF (val, 1));
16141 if (eol_flag)
16143 /* The EOL conversion that is normal on this system. */
16145 if (NILP (eolvalue)) /* Not yet decided. */
16146 eoltype = eol_mnemonic_undecided;
16147 else if (VECTORP (eolvalue)) /* Not yet decided. */
16148 eoltype = eol_mnemonic_undecided;
16149 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16150 eoltype = (XFASTINT (eolvalue) == 0
16151 ? eol_mnemonic_unix
16152 : (XFASTINT (eolvalue) == 1
16153 ? eol_mnemonic_dos : eol_mnemonic_mac));
16157 if (eol_flag)
16159 /* Mention the EOL conversion if it is not the usual one. */
16160 if (STRINGP (eoltype))
16162 eol_str = SDATA (eoltype);
16163 eol_str_len = SBYTES (eoltype);
16165 else if (INTEGERP (eoltype)
16166 && CHAR_VALID_P (XINT (eoltype), 0))
16168 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16169 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16170 eol_str = tmp;
16172 else
16174 eol_str = invalid_eol_type;
16175 eol_str_len = sizeof (invalid_eol_type) - 1;
16177 bcopy (eol_str, buf, eol_str_len);
16178 buf += eol_str_len;
16181 return buf;
16184 /* Return a string for the output of a mode line %-spec for window W,
16185 generated by character C. PRECISION >= 0 means don't return a
16186 string longer than that value. FIELD_WIDTH > 0 means pad the
16187 string returned with spaces to that value. Return 1 in *MULTIBYTE
16188 if the result is multibyte text.
16190 Note we operate on the current buffer for most purposes,
16191 the exception being w->base_line_pos. */
16193 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16195 static char *
16196 decode_mode_spec (w, c, field_width, precision, multibyte)
16197 struct window *w;
16198 register int c;
16199 int field_width, precision;
16200 int *multibyte;
16202 Lisp_Object obj;
16203 struct frame *f = XFRAME (WINDOW_FRAME (w));
16204 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16205 struct buffer *b = current_buffer;
16207 obj = Qnil;
16208 *multibyte = 0;
16210 switch (c)
16212 case '*':
16213 if (!NILP (b->read_only))
16214 return "%";
16215 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16216 return "*";
16217 return "-";
16219 case '+':
16220 /* This differs from %* only for a modified read-only buffer. */
16221 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16222 return "*";
16223 if (!NILP (b->read_only))
16224 return "%";
16225 return "-";
16227 case '&':
16228 /* This differs from %* in ignoring read-only-ness. */
16229 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16230 return "*";
16231 return "-";
16233 case '%':
16234 return "%";
16236 case '[':
16238 int i;
16239 char *p;
16241 if (command_loop_level > 5)
16242 return "[[[... ";
16243 p = decode_mode_spec_buf;
16244 for (i = 0; i < command_loop_level; i++)
16245 *p++ = '[';
16246 *p = 0;
16247 return decode_mode_spec_buf;
16250 case ']':
16252 int i;
16253 char *p;
16255 if (command_loop_level > 5)
16256 return " ...]]]";
16257 p = decode_mode_spec_buf;
16258 for (i = 0; i < command_loop_level; i++)
16259 *p++ = ']';
16260 *p = 0;
16261 return decode_mode_spec_buf;
16264 case '-':
16266 register int i;
16268 /* Let lots_of_dashes be a string of infinite length. */
16269 if (!NILP (mode_line_string_list))
16270 return "--";
16271 if (field_width <= 0
16272 || field_width > sizeof (lots_of_dashes))
16274 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16275 decode_mode_spec_buf[i] = '-';
16276 decode_mode_spec_buf[i] = '\0';
16277 return decode_mode_spec_buf;
16279 else
16280 return lots_of_dashes;
16283 case 'b':
16284 obj = b->name;
16285 break;
16287 case 'c':
16289 int col = (int) current_column (); /* iftc */
16290 w->column_number_displayed = make_number (col);
16291 pint2str (decode_mode_spec_buf, field_width, col);
16292 return decode_mode_spec_buf;
16295 case 'F':
16296 /* %F displays the frame name. */
16297 if (!NILP (f->title))
16298 return (char *) SDATA (f->title);
16299 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16300 return (char *) SDATA (f->name);
16301 return "Emacs";
16303 case 'f':
16304 obj = b->filename;
16305 break;
16307 case 'i':
16309 int size = ZV - BEGV;
16310 pint2str (decode_mode_spec_buf, field_width, size);
16311 return decode_mode_spec_buf;
16314 case 'I':
16316 int size = ZV - BEGV;
16317 pint2hrstr (decode_mode_spec_buf, field_width, size);
16318 return decode_mode_spec_buf;
16321 case 'l':
16323 int startpos = XMARKER (w->start)->charpos;
16324 int startpos_byte = marker_byte_position (w->start);
16325 int line, linepos, linepos_byte, topline;
16326 int nlines, junk;
16327 int height = WINDOW_TOTAL_LINES (w);
16329 /* If we decided that this buffer isn't suitable for line numbers,
16330 don't forget that too fast. */
16331 if (EQ (w->base_line_pos, w->buffer))
16332 goto no_value;
16333 /* But do forget it, if the window shows a different buffer now. */
16334 else if (BUFFERP (w->base_line_pos))
16335 w->base_line_pos = Qnil;
16337 /* If the buffer is very big, don't waste time. */
16338 if (INTEGERP (Vline_number_display_limit)
16339 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16341 w->base_line_pos = Qnil;
16342 w->base_line_number = Qnil;
16343 goto no_value;
16346 if (!NILP (w->base_line_number)
16347 && !NILP (w->base_line_pos)
16348 && XFASTINT (w->base_line_pos) <= startpos)
16350 line = XFASTINT (w->base_line_number);
16351 linepos = XFASTINT (w->base_line_pos);
16352 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16354 else
16356 line = 1;
16357 linepos = BUF_BEGV (b);
16358 linepos_byte = BUF_BEGV_BYTE (b);
16361 /* Count lines from base line to window start position. */
16362 nlines = display_count_lines (linepos, linepos_byte,
16363 startpos_byte,
16364 startpos, &junk);
16366 topline = nlines + line;
16368 /* Determine a new base line, if the old one is too close
16369 or too far away, or if we did not have one.
16370 "Too close" means it's plausible a scroll-down would
16371 go back past it. */
16372 if (startpos == BUF_BEGV (b))
16374 w->base_line_number = make_number (topline);
16375 w->base_line_pos = make_number (BUF_BEGV (b));
16377 else if (nlines < height + 25 || nlines > height * 3 + 50
16378 || linepos == BUF_BEGV (b))
16380 int limit = BUF_BEGV (b);
16381 int limit_byte = BUF_BEGV_BYTE (b);
16382 int position;
16383 int distance = (height * 2 + 30) * line_number_display_limit_width;
16385 if (startpos - distance > limit)
16387 limit = startpos - distance;
16388 limit_byte = CHAR_TO_BYTE (limit);
16391 nlines = display_count_lines (startpos, startpos_byte,
16392 limit_byte,
16393 - (height * 2 + 30),
16394 &position);
16395 /* If we couldn't find the lines we wanted within
16396 line_number_display_limit_width chars per line,
16397 give up on line numbers for this window. */
16398 if (position == limit_byte && limit == startpos - distance)
16400 w->base_line_pos = w->buffer;
16401 w->base_line_number = Qnil;
16402 goto no_value;
16405 w->base_line_number = make_number (topline - nlines);
16406 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16409 /* Now count lines from the start pos to point. */
16410 nlines = display_count_lines (startpos, startpos_byte,
16411 PT_BYTE, PT, &junk);
16413 /* Record that we did display the line number. */
16414 line_number_displayed = 1;
16416 /* Make the string to show. */
16417 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16418 return decode_mode_spec_buf;
16419 no_value:
16421 char* p = decode_mode_spec_buf;
16422 int pad = field_width - 2;
16423 while (pad-- > 0)
16424 *p++ = ' ';
16425 *p++ = '?';
16426 *p++ = '?';
16427 *p = '\0';
16428 return decode_mode_spec_buf;
16431 break;
16433 case 'm':
16434 obj = b->mode_name;
16435 break;
16437 case 'n':
16438 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16439 return " Narrow";
16440 break;
16442 case 'p':
16444 int pos = marker_position (w->start);
16445 int total = BUF_ZV (b) - BUF_BEGV (b);
16447 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16449 if (pos <= BUF_BEGV (b))
16450 return "All";
16451 else
16452 return "Bottom";
16454 else if (pos <= BUF_BEGV (b))
16455 return "Top";
16456 else
16458 if (total > 1000000)
16459 /* Do it differently for a large value, to avoid overflow. */
16460 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16461 else
16462 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16463 /* We can't normally display a 3-digit number,
16464 so get us a 2-digit number that is close. */
16465 if (total == 100)
16466 total = 99;
16467 sprintf (decode_mode_spec_buf, "%2d%%", total);
16468 return decode_mode_spec_buf;
16472 /* Display percentage of size above the bottom of the screen. */
16473 case 'P':
16475 int toppos = marker_position (w->start);
16476 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16477 int total = BUF_ZV (b) - BUF_BEGV (b);
16479 if (botpos >= BUF_ZV (b))
16481 if (toppos <= BUF_BEGV (b))
16482 return "All";
16483 else
16484 return "Bottom";
16486 else
16488 if (total > 1000000)
16489 /* Do it differently for a large value, to avoid overflow. */
16490 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16491 else
16492 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16493 /* We can't normally display a 3-digit number,
16494 so get us a 2-digit number that is close. */
16495 if (total == 100)
16496 total = 99;
16497 if (toppos <= BUF_BEGV (b))
16498 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16499 else
16500 sprintf (decode_mode_spec_buf, "%2d%%", total);
16501 return decode_mode_spec_buf;
16505 case 's':
16506 /* status of process */
16507 obj = Fget_buffer_process (Fcurrent_buffer ());
16508 if (NILP (obj))
16509 return "no process";
16510 #ifdef subprocesses
16511 obj = Fsymbol_name (Fprocess_status (obj));
16512 #endif
16513 break;
16515 case 't': /* indicate TEXT or BINARY */
16516 #ifdef MODE_LINE_BINARY_TEXT
16517 return MODE_LINE_BINARY_TEXT (b);
16518 #else
16519 return "T";
16520 #endif
16522 case 'z':
16523 /* coding-system (not including end-of-line format) */
16524 case 'Z':
16525 /* coding-system (including end-of-line type) */
16527 int eol_flag = (c == 'Z');
16528 char *p = decode_mode_spec_buf;
16530 if (! FRAME_WINDOW_P (f))
16532 /* No need to mention EOL here--the terminal never needs
16533 to do EOL conversion. */
16534 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16535 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16537 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16538 p, eol_flag);
16540 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16541 #ifdef subprocesses
16542 obj = Fget_buffer_process (Fcurrent_buffer ());
16543 if (PROCESSP (obj))
16545 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16546 p, eol_flag);
16547 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16548 p, eol_flag);
16550 #endif /* subprocesses */
16551 #endif /* 0 */
16552 *p = 0;
16553 return decode_mode_spec_buf;
16557 if (STRINGP (obj))
16559 *multibyte = STRING_MULTIBYTE (obj);
16560 return (char *) SDATA (obj);
16562 else
16563 return "";
16567 /* Count up to COUNT lines starting from START / START_BYTE.
16568 But don't go beyond LIMIT_BYTE.
16569 Return the number of lines thus found (always nonnegative).
16571 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16573 static int
16574 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16575 int start, start_byte, limit_byte, count;
16576 int *byte_pos_ptr;
16578 register unsigned char *cursor;
16579 unsigned char *base;
16581 register int ceiling;
16582 register unsigned char *ceiling_addr;
16583 int orig_count = count;
16585 /* If we are not in selective display mode,
16586 check only for newlines. */
16587 int selective_display = (!NILP (current_buffer->selective_display)
16588 && !INTEGERP (current_buffer->selective_display));
16590 if (count > 0)
16592 while (start_byte < limit_byte)
16594 ceiling = BUFFER_CEILING_OF (start_byte);
16595 ceiling = min (limit_byte - 1, ceiling);
16596 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16597 base = (cursor = BYTE_POS_ADDR (start_byte));
16598 while (1)
16600 if (selective_display)
16601 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16603 else
16604 while (*cursor != '\n' && ++cursor != ceiling_addr)
16607 if (cursor != ceiling_addr)
16609 if (--count == 0)
16611 start_byte += cursor - base + 1;
16612 *byte_pos_ptr = start_byte;
16613 return orig_count;
16615 else
16616 if (++cursor == ceiling_addr)
16617 break;
16619 else
16620 break;
16622 start_byte += cursor - base;
16625 else
16627 while (start_byte > limit_byte)
16629 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16630 ceiling = max (limit_byte, ceiling);
16631 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16632 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16633 while (1)
16635 if (selective_display)
16636 while (--cursor != ceiling_addr
16637 && *cursor != '\n' && *cursor != 015)
16639 else
16640 while (--cursor != ceiling_addr && *cursor != '\n')
16643 if (cursor != ceiling_addr)
16645 if (++count == 0)
16647 start_byte += cursor - base + 1;
16648 *byte_pos_ptr = start_byte;
16649 /* When scanning backwards, we should
16650 not count the newline posterior to which we stop. */
16651 return - orig_count - 1;
16654 else
16655 break;
16657 /* Here we add 1 to compensate for the last decrement
16658 of CURSOR, which took it past the valid range. */
16659 start_byte += cursor - base + 1;
16663 *byte_pos_ptr = limit_byte;
16665 if (count < 0)
16666 return - orig_count + count;
16667 return orig_count - count;
16673 /***********************************************************************
16674 Displaying strings
16675 ***********************************************************************/
16677 /* Display a NUL-terminated string, starting with index START.
16679 If STRING is non-null, display that C string. Otherwise, the Lisp
16680 string LISP_STRING is displayed.
16682 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16683 FACE_STRING. Display STRING or LISP_STRING with the face at
16684 FACE_STRING_POS in FACE_STRING:
16686 Display the string in the environment given by IT, but use the
16687 standard display table, temporarily.
16689 FIELD_WIDTH is the minimum number of output glyphs to produce.
16690 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16691 with spaces. If STRING has more characters, more than FIELD_WIDTH
16692 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16694 PRECISION is the maximum number of characters to output from
16695 STRING. PRECISION < 0 means don't truncate the string.
16697 This is roughly equivalent to printf format specifiers:
16699 FIELD_WIDTH PRECISION PRINTF
16700 ----------------------------------------
16701 -1 -1 %s
16702 -1 10 %.10s
16703 10 -1 %10s
16704 20 10 %20.10s
16706 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16707 display them, and < 0 means obey the current buffer's value of
16708 enable_multibyte_characters.
16710 Value is the number of glyphs produced. */
16712 static int
16713 display_string (string, lisp_string, face_string, face_string_pos,
16714 start, it, field_width, precision, max_x, multibyte)
16715 unsigned char *string;
16716 Lisp_Object lisp_string;
16717 Lisp_Object face_string;
16718 int face_string_pos;
16719 int start;
16720 struct it *it;
16721 int field_width, precision, max_x;
16722 int multibyte;
16724 int hpos_at_start = it->hpos;
16725 int saved_face_id = it->face_id;
16726 struct glyph_row *row = it->glyph_row;
16728 /* Initialize the iterator IT for iteration over STRING beginning
16729 with index START. */
16730 reseat_to_string (it, string, lisp_string, start,
16731 precision, field_width, multibyte);
16733 /* If displaying STRING, set up the face of the iterator
16734 from LISP_STRING, if that's given. */
16735 if (STRINGP (face_string))
16737 int endptr;
16738 struct face *face;
16740 it->face_id
16741 = face_at_string_position (it->w, face_string, face_string_pos,
16742 0, it->region_beg_charpos,
16743 it->region_end_charpos,
16744 &endptr, it->base_face_id, 0);
16745 face = FACE_FROM_ID (it->f, it->face_id);
16746 it->face_box_p = face->box != FACE_NO_BOX;
16749 /* Set max_x to the maximum allowed X position. Don't let it go
16750 beyond the right edge of the window. */
16751 if (max_x <= 0)
16752 max_x = it->last_visible_x;
16753 else
16754 max_x = min (max_x, it->last_visible_x);
16756 /* Skip over display elements that are not visible. because IT->w is
16757 hscrolled. */
16758 if (it->current_x < it->first_visible_x)
16759 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16760 MOVE_TO_POS | MOVE_TO_X);
16762 row->ascent = it->max_ascent;
16763 row->height = it->max_ascent + it->max_descent;
16764 row->phys_ascent = it->max_phys_ascent;
16765 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16767 /* This condition is for the case that we are called with current_x
16768 past last_visible_x. */
16769 while (it->current_x < max_x)
16771 int x_before, x, n_glyphs_before, i, nglyphs;
16773 /* Get the next display element. */
16774 if (!get_next_display_element (it))
16775 break;
16777 /* Produce glyphs. */
16778 x_before = it->current_x;
16779 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16780 PRODUCE_GLYPHS (it);
16782 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16783 i = 0;
16784 x = x_before;
16785 while (i < nglyphs)
16787 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16789 if (!it->truncate_lines_p
16790 && x + glyph->pixel_width > max_x)
16792 /* End of continued line or max_x reached. */
16793 if (CHAR_GLYPH_PADDING_P (*glyph))
16795 /* A wide character is unbreakable. */
16796 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16797 it->current_x = x_before;
16799 else
16801 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16802 it->current_x = x;
16804 break;
16806 else if (x + glyph->pixel_width > it->first_visible_x)
16808 /* Glyph is at least partially visible. */
16809 ++it->hpos;
16810 if (x < it->first_visible_x)
16811 it->glyph_row->x = x - it->first_visible_x;
16813 else
16815 /* Glyph is off the left margin of the display area.
16816 Should not happen. */
16817 abort ();
16820 row->ascent = max (row->ascent, it->max_ascent);
16821 row->height = max (row->height, it->max_ascent + it->max_descent);
16822 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16823 row->phys_height = max (row->phys_height,
16824 it->max_phys_ascent + it->max_phys_descent);
16825 x += glyph->pixel_width;
16826 ++i;
16829 /* Stop if max_x reached. */
16830 if (i < nglyphs)
16831 break;
16833 /* Stop at line ends. */
16834 if (ITERATOR_AT_END_OF_LINE_P (it))
16836 it->continuation_lines_width = 0;
16837 break;
16840 set_iterator_to_next (it, 1);
16842 /* Stop if truncating at the right edge. */
16843 if (it->truncate_lines_p
16844 && it->current_x >= it->last_visible_x)
16846 /* Add truncation mark, but don't do it if the line is
16847 truncated at a padding space. */
16848 if (IT_CHARPOS (*it) < it->string_nchars)
16850 if (!FRAME_WINDOW_P (it->f))
16852 int i, n;
16854 if (it->current_x > it->last_visible_x)
16856 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16857 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16858 break;
16859 for (n = row->used[TEXT_AREA]; i < n; ++i)
16861 row->used[TEXT_AREA] = i;
16862 produce_special_glyphs (it, IT_TRUNCATION);
16865 produce_special_glyphs (it, IT_TRUNCATION);
16867 it->glyph_row->truncated_on_right_p = 1;
16869 break;
16873 /* Maybe insert a truncation at the left. */
16874 if (it->first_visible_x
16875 && IT_CHARPOS (*it) > 0)
16877 if (!FRAME_WINDOW_P (it->f))
16878 insert_left_trunc_glyphs (it);
16879 it->glyph_row->truncated_on_left_p = 1;
16882 it->face_id = saved_face_id;
16884 /* Value is number of columns displayed. */
16885 return it->hpos - hpos_at_start;
16890 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16891 appears as an element of LIST or as the car of an element of LIST.
16892 If PROPVAL is a list, compare each element against LIST in that
16893 way, and return 1/2 if any element of PROPVAL is found in LIST.
16894 Otherwise return 0. This function cannot quit.
16895 The return value is 2 if the text is invisible but with an ellipsis
16896 and 1 if it's invisible and without an ellipsis. */
16899 invisible_p (propval, list)
16900 register Lisp_Object propval;
16901 Lisp_Object list;
16903 register Lisp_Object tail, proptail;
16905 for (tail = list; CONSP (tail); tail = XCDR (tail))
16907 register Lisp_Object tem;
16908 tem = XCAR (tail);
16909 if (EQ (propval, tem))
16910 return 1;
16911 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16912 return NILP (XCDR (tem)) ? 1 : 2;
16915 if (CONSP (propval))
16917 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16919 Lisp_Object propelt;
16920 propelt = XCAR (proptail);
16921 for (tail = list; CONSP (tail); tail = XCDR (tail))
16923 register Lisp_Object tem;
16924 tem = XCAR (tail);
16925 if (EQ (propelt, tem))
16926 return 1;
16927 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16928 return NILP (XCDR (tem)) ? 1 : 2;
16933 return 0;
16936 /* Calculate a width or height in pixels from a specification using
16937 the following elements:
16939 SPEC ::=
16940 NUM - a (fractional) multiple of the default font width/height
16941 (NUM) - specifies exactly NUM pixels
16942 UNIT - a fixed number of pixels, see below.
16943 ELEMENT - size of a display element in pixels, see below.
16944 (NUM . SPEC) - equals NUM * SPEC
16945 (+ SPEC SPEC ...) - add pixel values
16946 (- SPEC SPEC ...) - subtract pixel values
16947 (- SPEC) - negate pixel value
16949 NUM ::=
16950 INT or FLOAT - a number constant
16951 SYMBOL - use symbol's (buffer local) variable binding.
16953 UNIT ::=
16954 in - pixels per inch *)
16955 mm - pixels per 1/1000 meter *)
16956 cm - pixels per 1/100 meter *)
16957 width - width of current font in pixels.
16958 height - height of current font in pixels.
16960 *) using the ratio(s) defined in display-pixels-per-inch.
16962 ELEMENT ::=
16964 left-fringe - left fringe width in pixels
16965 right-fringe - right fringe width in pixels
16967 left-margin - left margin width in pixels
16968 right-margin - right margin width in pixels
16970 scroll-bar - scroll-bar area width in pixels
16972 Examples:
16974 Pixels corresponding to 5 inches:
16975 (5 . in)
16977 Total width of non-text areas on left side of window (if scroll-bar is on left):
16978 '(space :width (+ left-fringe left-margin scroll-bar))
16980 Align to first text column (in header line):
16981 '(space :align-to 0)
16983 Align to middle of text area minus half the width of variable `my-image'
16984 containing a loaded image:
16985 '(space :align-to (0.5 . (- text my-image)))
16987 Width of left margin minus width of 1 character in the default font:
16988 '(space :width (- left-margin 1))
16990 Width of left margin minus width of 2 characters in the current font:
16991 '(space :width (- left-margin (2 . width)))
16993 Center 1 character over left-margin (in header line):
16994 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16996 Different ways to express width of left fringe plus left margin minus one pixel:
16997 '(space :width (- (+ left-fringe left-margin) (1)))
16998 '(space :width (+ left-fringe left-margin (- (1))))
16999 '(space :width (+ left-fringe left-margin (-1)))
17003 #define NUMVAL(X) \
17004 ((INTEGERP (X) || FLOATP (X)) \
17005 ? XFLOATINT (X) \
17006 : - 1)
17009 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17010 double *res;
17011 struct it *it;
17012 Lisp_Object prop;
17013 void *font;
17014 int width_p, *align_to;
17016 double pixels;
17018 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17019 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17021 if (NILP (prop))
17022 return OK_PIXELS (0);
17024 if (SYMBOLP (prop))
17026 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17028 char *unit = SDATA (SYMBOL_NAME (prop));
17030 if (unit[0] == 'i' && unit[1] == 'n')
17031 pixels = 1.0;
17032 else if (unit[0] == 'm' && unit[1] == 'm')
17033 pixels = 25.4;
17034 else if (unit[0] == 'c' && unit[1] == 'm')
17035 pixels = 2.54;
17036 else
17037 pixels = 0;
17038 if (pixels > 0)
17040 double ppi;
17041 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17042 || (CONSP (Vdisplay_pixels_per_inch)
17043 && (ppi = (width_p
17044 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17045 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17046 ppi > 0)))
17047 return OK_PIXELS (ppi / pixels);
17049 return 0;
17053 #ifdef HAVE_WINDOW_SYSTEM
17054 if (EQ (prop, Qheight))
17055 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17056 if (EQ (prop, Qwidth))
17057 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17058 #else
17059 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17060 return OK_PIXELS (1);
17061 #endif
17063 if (EQ (prop, Qtext))
17064 return OK_PIXELS (width_p
17065 ? window_box_width (it->w, TEXT_AREA)
17066 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17068 if (align_to && *align_to < 0)
17070 *res = 0;
17071 if (EQ (prop, Qleft))
17072 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17073 if (EQ (prop, Qright))
17074 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17075 if (EQ (prop, Qcenter))
17076 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17077 + window_box_width (it->w, TEXT_AREA) / 2);
17078 if (EQ (prop, Qleft_fringe))
17079 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17080 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17081 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17082 if (EQ (prop, Qright_fringe))
17083 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17084 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17085 : window_box_right_offset (it->w, TEXT_AREA));
17086 if (EQ (prop, Qleft_margin))
17087 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17088 if (EQ (prop, Qright_margin))
17089 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17090 if (EQ (prop, Qscroll_bar))
17091 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17093 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17094 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17095 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17096 : 0)));
17098 else
17100 if (EQ (prop, Qleft_fringe))
17101 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17102 if (EQ (prop, Qright_fringe))
17103 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17104 if (EQ (prop, Qleft_margin))
17105 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17106 if (EQ (prop, Qright_margin))
17107 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17108 if (EQ (prop, Qscroll_bar))
17109 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17112 prop = Fbuffer_local_value (prop, it->w->buffer);
17115 if (INTEGERP (prop) || FLOATP (prop))
17117 int base_unit = (width_p
17118 ? FRAME_COLUMN_WIDTH (it->f)
17119 : FRAME_LINE_HEIGHT (it->f));
17120 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17123 if (CONSP (prop))
17125 Lisp_Object car = XCAR (prop);
17126 Lisp_Object cdr = XCDR (prop);
17128 if (SYMBOLP (car))
17130 #ifdef HAVE_WINDOW_SYSTEM
17131 if (valid_image_p (prop))
17133 int id = lookup_image (it->f, prop);
17134 struct image *img = IMAGE_FROM_ID (it->f, id);
17136 return OK_PIXELS (width_p ? img->width : img->height);
17138 #endif
17139 if (EQ (car, Qplus) || EQ (car, Qminus))
17141 int first = 1;
17142 double px;
17144 pixels = 0;
17145 while (CONSP (cdr))
17147 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17148 font, width_p, align_to))
17149 return 0;
17150 if (first)
17151 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17152 else
17153 pixels += px;
17154 cdr = XCDR (cdr);
17156 if (EQ (car, Qminus))
17157 pixels = -pixels;
17158 return OK_PIXELS (pixels);
17161 car = Fbuffer_local_value (car, it->w->buffer);
17164 if (INTEGERP (car) || FLOATP (car))
17166 double fact;
17167 pixels = XFLOATINT (car);
17168 if (NILP (cdr))
17169 return OK_PIXELS (pixels);
17170 if (calc_pixel_width_or_height (&fact, it, cdr,
17171 font, width_p, align_to))
17172 return OK_PIXELS (pixels * fact);
17173 return 0;
17176 return 0;
17179 return 0;
17183 /***********************************************************************
17184 Glyph Display
17185 ***********************************************************************/
17187 #ifdef HAVE_WINDOW_SYSTEM
17189 #if GLYPH_DEBUG
17191 void
17192 dump_glyph_string (s)
17193 struct glyph_string *s;
17195 fprintf (stderr, "glyph string\n");
17196 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17197 s->x, s->y, s->width, s->height);
17198 fprintf (stderr, " ybase = %d\n", s->ybase);
17199 fprintf (stderr, " hl = %d\n", s->hl);
17200 fprintf (stderr, " left overhang = %d, right = %d\n",
17201 s->left_overhang, s->right_overhang);
17202 fprintf (stderr, " nchars = %d\n", s->nchars);
17203 fprintf (stderr, " extends to end of line = %d\n",
17204 s->extends_to_end_of_line_p);
17205 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17206 fprintf (stderr, " bg width = %d\n", s->background_width);
17209 #endif /* GLYPH_DEBUG */
17211 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17212 of XChar2b structures for S; it can't be allocated in
17213 init_glyph_string because it must be allocated via `alloca'. W
17214 is the window on which S is drawn. ROW and AREA are the glyph row
17215 and area within the row from which S is constructed. START is the
17216 index of the first glyph structure covered by S. HL is a
17217 face-override for drawing S. */
17219 #ifdef HAVE_NTGUI
17220 #define OPTIONAL_HDC(hdc) hdc,
17221 #define DECLARE_HDC(hdc) HDC hdc;
17222 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17223 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17224 #endif
17226 #ifndef OPTIONAL_HDC
17227 #define OPTIONAL_HDC(hdc)
17228 #define DECLARE_HDC(hdc)
17229 #define ALLOCATE_HDC(hdc, f)
17230 #define RELEASE_HDC(hdc, f)
17231 #endif
17233 static void
17234 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17235 struct glyph_string *s;
17236 DECLARE_HDC (hdc)
17237 XChar2b *char2b;
17238 struct window *w;
17239 struct glyph_row *row;
17240 enum glyph_row_area area;
17241 int start;
17242 enum draw_glyphs_face hl;
17244 bzero (s, sizeof *s);
17245 s->w = w;
17246 s->f = XFRAME (w->frame);
17247 #ifdef HAVE_NTGUI
17248 s->hdc = hdc;
17249 #endif
17250 s->display = FRAME_X_DISPLAY (s->f);
17251 s->window = FRAME_X_WINDOW (s->f);
17252 s->char2b = char2b;
17253 s->hl = hl;
17254 s->row = row;
17255 s->area = area;
17256 s->first_glyph = row->glyphs[area] + start;
17257 s->height = row->height;
17258 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17260 /* Display the internal border below the tool-bar window. */
17261 if (s->w == XWINDOW (s->f->tool_bar_window))
17262 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17264 s->ybase = s->y + row->ascent;
17268 /* Append the list of glyph strings with head H and tail T to the list
17269 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17271 static INLINE void
17272 append_glyph_string_lists (head, tail, h, t)
17273 struct glyph_string **head, **tail;
17274 struct glyph_string *h, *t;
17276 if (h)
17278 if (*head)
17279 (*tail)->next = h;
17280 else
17281 *head = h;
17282 h->prev = *tail;
17283 *tail = t;
17288 /* Prepend the list of glyph strings with head H and tail T to the
17289 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17290 result. */
17292 static INLINE void
17293 prepend_glyph_string_lists (head, tail, h, t)
17294 struct glyph_string **head, **tail;
17295 struct glyph_string *h, *t;
17297 if (h)
17299 if (*head)
17300 (*head)->prev = t;
17301 else
17302 *tail = t;
17303 t->next = *head;
17304 *head = h;
17309 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17310 Set *HEAD and *TAIL to the resulting list. */
17312 static INLINE void
17313 append_glyph_string (head, tail, s)
17314 struct glyph_string **head, **tail;
17315 struct glyph_string *s;
17317 s->next = s->prev = NULL;
17318 append_glyph_string_lists (head, tail, s, s);
17322 /* Get face and two-byte form of character glyph GLYPH on frame F.
17323 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17324 a pointer to a realized face that is ready for display. */
17326 static INLINE struct face *
17327 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17328 struct frame *f;
17329 struct glyph *glyph;
17330 XChar2b *char2b;
17331 int *two_byte_p;
17333 struct face *face;
17335 xassert (glyph->type == CHAR_GLYPH);
17336 face = FACE_FROM_ID (f, glyph->face_id);
17338 if (two_byte_p)
17339 *two_byte_p = 0;
17341 if (!glyph->multibyte_p)
17343 /* Unibyte case. We don't have to encode, but we have to make
17344 sure to use a face suitable for unibyte. */
17345 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17347 else if (glyph->u.ch < 128
17348 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17350 /* Case of ASCII in a face known to fit ASCII. */
17351 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17353 else
17355 int c1, c2, charset;
17357 /* Split characters into bytes. If c2 is -1 afterwards, C is
17358 really a one-byte character so that byte1 is zero. */
17359 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17360 if (c2 > 0)
17361 STORE_XCHAR2B (char2b, c1, c2);
17362 else
17363 STORE_XCHAR2B (char2b, 0, c1);
17365 /* Maybe encode the character in *CHAR2B. */
17366 if (charset != CHARSET_ASCII)
17368 struct font_info *font_info
17369 = FONT_INFO_FROM_ID (f, face->font_info_id);
17370 if (font_info)
17371 glyph->font_type
17372 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17376 /* Make sure X resources of the face are allocated. */
17377 xassert (face != NULL);
17378 PREPARE_FACE_FOR_DISPLAY (f, face);
17379 return face;
17383 /* Fill glyph string S with composition components specified by S->cmp.
17385 FACES is an array of faces for all components of this composition.
17386 S->gidx is the index of the first component for S.
17387 OVERLAPS_P non-zero means S should draw the foreground only, and
17388 use its physical height for clipping.
17390 Value is the index of a component not in S. */
17392 static int
17393 fill_composite_glyph_string (s, faces, overlaps_p)
17394 struct glyph_string *s;
17395 struct face **faces;
17396 int overlaps_p;
17398 int i;
17400 xassert (s);
17402 s->for_overlaps_p = overlaps_p;
17404 s->face = faces[s->gidx];
17405 s->font = s->face->font;
17406 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17408 /* For all glyphs of this composition, starting at the offset
17409 S->gidx, until we reach the end of the definition or encounter a
17410 glyph that requires the different face, add it to S. */
17411 ++s->nchars;
17412 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17413 ++s->nchars;
17415 /* All glyph strings for the same composition has the same width,
17416 i.e. the width set for the first component of the composition. */
17418 s->width = s->first_glyph->pixel_width;
17420 /* If the specified font could not be loaded, use the frame's
17421 default font, but record the fact that we couldn't load it in
17422 the glyph string so that we can draw rectangles for the
17423 characters of the glyph string. */
17424 if (s->font == NULL)
17426 s->font_not_found_p = 1;
17427 s->font = FRAME_FONT (s->f);
17430 /* Adjust base line for subscript/superscript text. */
17431 s->ybase += s->first_glyph->voffset;
17433 xassert (s->face && s->face->gc);
17435 /* This glyph string must always be drawn with 16-bit functions. */
17436 s->two_byte_p = 1;
17438 return s->gidx + s->nchars;
17442 /* Fill glyph string S from a sequence of character glyphs.
17444 FACE_ID is the face id of the string. START is the index of the
17445 first glyph to consider, END is the index of the last + 1.
17446 OVERLAPS_P non-zero means S should draw the foreground only, and
17447 use its physical height for clipping.
17449 Value is the index of the first glyph not in S. */
17451 static int
17452 fill_glyph_string (s, face_id, start, end, overlaps_p)
17453 struct glyph_string *s;
17454 int face_id;
17455 int start, end, overlaps_p;
17457 struct glyph *glyph, *last;
17458 int voffset;
17459 int glyph_not_available_p;
17461 xassert (s->f == XFRAME (s->w->frame));
17462 xassert (s->nchars == 0);
17463 xassert (start >= 0 && end > start);
17465 s->for_overlaps_p = overlaps_p,
17466 glyph = s->row->glyphs[s->area] + start;
17467 last = s->row->glyphs[s->area] + end;
17468 voffset = glyph->voffset;
17470 glyph_not_available_p = glyph->glyph_not_available_p;
17472 while (glyph < last
17473 && glyph->type == CHAR_GLYPH
17474 && glyph->voffset == voffset
17475 /* Same face id implies same font, nowadays. */
17476 && glyph->face_id == face_id
17477 && glyph->glyph_not_available_p == glyph_not_available_p)
17479 int two_byte_p;
17481 s->face = get_glyph_face_and_encoding (s->f, glyph,
17482 s->char2b + s->nchars,
17483 &two_byte_p);
17484 s->two_byte_p = two_byte_p;
17485 ++s->nchars;
17486 xassert (s->nchars <= end - start);
17487 s->width += glyph->pixel_width;
17488 ++glyph;
17491 s->font = s->face->font;
17492 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17494 /* If the specified font could not be loaded, use the frame's font,
17495 but record the fact that we couldn't load it in
17496 S->font_not_found_p so that we can draw rectangles for the
17497 characters of the glyph string. */
17498 if (s->font == NULL || glyph_not_available_p)
17500 s->font_not_found_p = 1;
17501 s->font = FRAME_FONT (s->f);
17504 /* Adjust base line for subscript/superscript text. */
17505 s->ybase += voffset;
17507 xassert (s->face && s->face->gc);
17508 return glyph - s->row->glyphs[s->area];
17512 /* Fill glyph string S from image glyph S->first_glyph. */
17514 static void
17515 fill_image_glyph_string (s)
17516 struct glyph_string *s;
17518 xassert (s->first_glyph->type == IMAGE_GLYPH);
17519 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17520 xassert (s->img);
17521 s->slice = s->first_glyph->slice;
17522 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17523 s->font = s->face->font;
17524 s->width = s->first_glyph->pixel_width;
17526 /* Adjust base line for subscript/superscript text. */
17527 s->ybase += s->first_glyph->voffset;
17531 /* Fill glyph string S from a sequence of stretch glyphs.
17533 ROW is the glyph row in which the glyphs are found, AREA is the
17534 area within the row. START is the index of the first glyph to
17535 consider, END is the index of the last + 1.
17537 Value is the index of the first glyph not in S. */
17539 static int
17540 fill_stretch_glyph_string (s, row, area, start, end)
17541 struct glyph_string *s;
17542 struct glyph_row *row;
17543 enum glyph_row_area area;
17544 int start, end;
17546 struct glyph *glyph, *last;
17547 int voffset, face_id;
17549 xassert (s->first_glyph->type == STRETCH_GLYPH);
17551 glyph = s->row->glyphs[s->area] + start;
17552 last = s->row->glyphs[s->area] + end;
17553 face_id = glyph->face_id;
17554 s->face = FACE_FROM_ID (s->f, face_id);
17555 s->font = s->face->font;
17556 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17557 s->width = glyph->pixel_width;
17558 voffset = glyph->voffset;
17560 for (++glyph;
17561 (glyph < last
17562 && glyph->type == STRETCH_GLYPH
17563 && glyph->voffset == voffset
17564 && glyph->face_id == face_id);
17565 ++glyph)
17566 s->width += glyph->pixel_width;
17568 /* Adjust base line for subscript/superscript text. */
17569 s->ybase += voffset;
17571 /* The case that face->gc == 0 is handled when drawing the glyph
17572 string by calling PREPARE_FACE_FOR_DISPLAY. */
17573 xassert (s->face);
17574 return glyph - s->row->glyphs[s->area];
17578 /* EXPORT for RIF:
17579 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17580 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17581 assumed to be zero. */
17583 void
17584 x_get_glyph_overhangs (glyph, f, left, right)
17585 struct glyph *glyph;
17586 struct frame *f;
17587 int *left, *right;
17589 *left = *right = 0;
17591 if (glyph->type == CHAR_GLYPH)
17593 XFontStruct *font;
17594 struct face *face;
17595 struct font_info *font_info;
17596 XChar2b char2b;
17597 XCharStruct *pcm;
17599 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17600 font = face->font;
17601 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17602 if (font /* ++KFS: Should this be font_info ? */
17603 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17605 if (pcm->rbearing > pcm->width)
17606 *right = pcm->rbearing - pcm->width;
17607 if (pcm->lbearing < 0)
17608 *left = -pcm->lbearing;
17614 /* Return the index of the first glyph preceding glyph string S that
17615 is overwritten by S because of S's left overhang. Value is -1
17616 if no glyphs are overwritten. */
17618 static int
17619 left_overwritten (s)
17620 struct glyph_string *s;
17622 int k;
17624 if (s->left_overhang)
17626 int x = 0, i;
17627 struct glyph *glyphs = s->row->glyphs[s->area];
17628 int first = s->first_glyph - glyphs;
17630 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17631 x -= glyphs[i].pixel_width;
17633 k = i + 1;
17635 else
17636 k = -1;
17638 return k;
17642 /* Return the index of the first glyph preceding glyph string S that
17643 is overwriting S because of its right overhang. Value is -1 if no
17644 glyph in front of S overwrites S. */
17646 static int
17647 left_overwriting (s)
17648 struct glyph_string *s;
17650 int i, k, x;
17651 struct glyph *glyphs = s->row->glyphs[s->area];
17652 int first = s->first_glyph - glyphs;
17654 k = -1;
17655 x = 0;
17656 for (i = first - 1; i >= 0; --i)
17658 int left, right;
17659 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17660 if (x + right > 0)
17661 k = i;
17662 x -= glyphs[i].pixel_width;
17665 return k;
17669 /* Return the index of the last glyph following glyph string S that is
17670 not overwritten by S because of S's right overhang. Value is -1 if
17671 no such glyph is found. */
17673 static int
17674 right_overwritten (s)
17675 struct glyph_string *s;
17677 int k = -1;
17679 if (s->right_overhang)
17681 int x = 0, i;
17682 struct glyph *glyphs = s->row->glyphs[s->area];
17683 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17684 int end = s->row->used[s->area];
17686 for (i = first; i < end && s->right_overhang > x; ++i)
17687 x += glyphs[i].pixel_width;
17689 k = i;
17692 return k;
17696 /* Return the index of the last glyph following glyph string S that
17697 overwrites S because of its left overhang. Value is negative
17698 if no such glyph is found. */
17700 static int
17701 right_overwriting (s)
17702 struct glyph_string *s;
17704 int i, k, x;
17705 int end = s->row->used[s->area];
17706 struct glyph *glyphs = s->row->glyphs[s->area];
17707 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17709 k = -1;
17710 x = 0;
17711 for (i = first; i < end; ++i)
17713 int left, right;
17714 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17715 if (x - left < 0)
17716 k = i;
17717 x += glyphs[i].pixel_width;
17720 return k;
17724 /* Get face and two-byte form of character C in face FACE_ID on frame
17725 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17726 means we want to display multibyte text. DISPLAY_P non-zero means
17727 make sure that X resources for the face returned are allocated.
17728 Value is a pointer to a realized face that is ready for display if
17729 DISPLAY_P is non-zero. */
17731 static INLINE struct face *
17732 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17733 struct frame *f;
17734 int c, face_id;
17735 XChar2b *char2b;
17736 int multibyte_p, display_p;
17738 struct face *face = FACE_FROM_ID (f, face_id);
17740 if (!multibyte_p)
17742 /* Unibyte case. We don't have to encode, but we have to make
17743 sure to use a face suitable for unibyte. */
17744 STORE_XCHAR2B (char2b, 0, c);
17745 face_id = FACE_FOR_CHAR (f, face, c);
17746 face = FACE_FROM_ID (f, face_id);
17748 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17750 /* Case of ASCII in a face known to fit ASCII. */
17751 STORE_XCHAR2B (char2b, 0, c);
17753 else
17755 int c1, c2, charset;
17757 /* Split characters into bytes. If c2 is -1 afterwards, C is
17758 really a one-byte character so that byte1 is zero. */
17759 SPLIT_CHAR (c, charset, c1, c2);
17760 if (c2 > 0)
17761 STORE_XCHAR2B (char2b, c1, c2);
17762 else
17763 STORE_XCHAR2B (char2b, 0, c1);
17765 /* Maybe encode the character in *CHAR2B. */
17766 if (face->font != NULL)
17768 struct font_info *font_info
17769 = FONT_INFO_FROM_ID (f, face->font_info_id);
17770 if (font_info)
17771 rif->encode_char (c, char2b, font_info, 0);
17775 /* Make sure X resources of the face are allocated. */
17776 #ifdef HAVE_X_WINDOWS
17777 if (display_p)
17778 #endif
17780 xassert (face != NULL);
17781 PREPARE_FACE_FOR_DISPLAY (f, face);
17784 return face;
17788 /* Set background width of glyph string S. START is the index of the
17789 first glyph following S. LAST_X is the right-most x-position + 1
17790 in the drawing area. */
17792 static INLINE void
17793 set_glyph_string_background_width (s, start, last_x)
17794 struct glyph_string *s;
17795 int start;
17796 int last_x;
17798 /* If the face of this glyph string has to be drawn to the end of
17799 the drawing area, set S->extends_to_end_of_line_p. */
17800 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17802 if (start == s->row->used[s->area]
17803 && s->area == TEXT_AREA
17804 && ((s->hl == DRAW_NORMAL_TEXT
17805 && (s->row->fill_line_p
17806 || s->face->background != default_face->background
17807 || s->face->stipple != default_face->stipple
17808 || s->row->mouse_face_p))
17809 || s->hl == DRAW_MOUSE_FACE
17810 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17811 && s->row->fill_line_p)))
17812 s->extends_to_end_of_line_p = 1;
17814 /* If S extends its face to the end of the line, set its
17815 background_width to the distance to the right edge of the drawing
17816 area. */
17817 if (s->extends_to_end_of_line_p)
17818 s->background_width = last_x - s->x + 1;
17819 else
17820 s->background_width = s->width;
17824 /* Compute overhangs and x-positions for glyph string S and its
17825 predecessors, or successors. X is the starting x-position for S.
17826 BACKWARD_P non-zero means process predecessors. */
17828 static void
17829 compute_overhangs_and_x (s, x, backward_p)
17830 struct glyph_string *s;
17831 int x;
17832 int backward_p;
17834 if (backward_p)
17836 while (s)
17838 if (rif->compute_glyph_string_overhangs)
17839 rif->compute_glyph_string_overhangs (s);
17840 x -= s->width;
17841 s->x = x;
17842 s = s->prev;
17845 else
17847 while (s)
17849 if (rif->compute_glyph_string_overhangs)
17850 rif->compute_glyph_string_overhangs (s);
17851 s->x = x;
17852 x += s->width;
17853 s = s->next;
17860 /* The following macros are only called from draw_glyphs below.
17861 They reference the following parameters of that function directly:
17862 `w', `row', `area', and `overlap_p'
17863 as well as the following local variables:
17864 `s', `f', and `hdc' (in W32) */
17866 #ifdef HAVE_NTGUI
17867 /* On W32, silently add local `hdc' variable to argument list of
17868 init_glyph_string. */
17869 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17870 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17871 #else
17872 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17873 init_glyph_string (s, char2b, w, row, area, start, hl)
17874 #endif
17876 /* Add a glyph string for a stretch glyph to the list of strings
17877 between HEAD and TAIL. START is the index of the stretch glyph in
17878 row area AREA of glyph row ROW. END is the index of the last glyph
17879 in that glyph row area. X is the current output position assigned
17880 to the new glyph string constructed. HL overrides that face of the
17881 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17882 is the right-most x-position of the drawing area. */
17884 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17885 and below -- keep them on one line. */
17886 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17887 do \
17889 s = (struct glyph_string *) alloca (sizeof *s); \
17890 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17891 START = fill_stretch_glyph_string (s, row, area, START, END); \
17892 append_glyph_string (&HEAD, &TAIL, s); \
17893 s->x = (X); \
17895 while (0)
17898 /* Add a glyph string for an image glyph to the list of strings
17899 between HEAD and TAIL. START is the index of the image glyph in
17900 row area AREA of glyph row ROW. END is the index of the last glyph
17901 in that glyph row area. X is the current output position assigned
17902 to the new glyph string constructed. HL overrides that face of the
17903 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17904 is the right-most x-position of the drawing area. */
17906 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17907 do \
17909 s = (struct glyph_string *) alloca (sizeof *s); \
17910 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17911 fill_image_glyph_string (s); \
17912 append_glyph_string (&HEAD, &TAIL, s); \
17913 ++START; \
17914 s->x = (X); \
17916 while (0)
17919 /* Add a glyph string for a sequence of character glyphs to the list
17920 of strings between HEAD and TAIL. START is the index of the first
17921 glyph in row area AREA of glyph row ROW that is part of the new
17922 glyph string. END is the index of the last glyph in that glyph row
17923 area. X is the current output position assigned to the new glyph
17924 string constructed. HL overrides that face of the glyph; e.g. it
17925 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17926 right-most x-position of the drawing area. */
17928 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17929 do \
17931 int c, face_id; \
17932 XChar2b *char2b; \
17934 c = (row)->glyphs[area][START].u.ch; \
17935 face_id = (row)->glyphs[area][START].face_id; \
17937 s = (struct glyph_string *) alloca (sizeof *s); \
17938 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17939 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17940 append_glyph_string (&HEAD, &TAIL, s); \
17941 s->x = (X); \
17942 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17944 while (0)
17947 /* Add a glyph string for a composite sequence to the list of strings
17948 between HEAD and TAIL. START is the index of the first glyph in
17949 row area AREA of glyph row ROW that is part of the new glyph
17950 string. END is the index of the last glyph in that glyph row area.
17951 X is the current output position assigned to the new glyph string
17952 constructed. HL overrides that face of the glyph; e.g. it is
17953 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17954 x-position of the drawing area. */
17956 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17957 do { \
17958 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17959 int face_id = (row)->glyphs[area][START].face_id; \
17960 struct face *base_face = FACE_FROM_ID (f, face_id); \
17961 struct composition *cmp = composition_table[cmp_id]; \
17962 int glyph_len = cmp->glyph_len; \
17963 XChar2b *char2b; \
17964 struct face **faces; \
17965 struct glyph_string *first_s = NULL; \
17966 int n; \
17968 base_face = base_face->ascii_face; \
17969 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17970 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17971 /* At first, fill in `char2b' and `faces'. */ \
17972 for (n = 0; n < glyph_len; n++) \
17974 int c = COMPOSITION_GLYPH (cmp, n); \
17975 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17976 faces[n] = FACE_FROM_ID (f, this_face_id); \
17977 get_char_face_and_encoding (f, c, this_face_id, \
17978 char2b + n, 1, 1); \
17981 /* Make glyph_strings for each glyph sequence that is drawable by \
17982 the same face, and append them to HEAD/TAIL. */ \
17983 for (n = 0; n < cmp->glyph_len;) \
17985 s = (struct glyph_string *) alloca (sizeof *s); \
17986 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17987 append_glyph_string (&(HEAD), &(TAIL), s); \
17988 s->cmp = cmp; \
17989 s->gidx = n; \
17990 s->x = (X); \
17992 if (n == 0) \
17993 first_s = s; \
17995 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17998 ++START; \
17999 s = first_s; \
18000 } while (0)
18003 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18004 of AREA of glyph row ROW on window W between indices START and END.
18005 HL overrides the face for drawing glyph strings, e.g. it is
18006 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18007 x-positions of the drawing area.
18009 This is an ugly monster macro construct because we must use alloca
18010 to allocate glyph strings (because draw_glyphs can be called
18011 asynchronously). */
18013 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18014 do \
18016 HEAD = TAIL = NULL; \
18017 while (START < END) \
18019 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18020 switch (first_glyph->type) \
18022 case CHAR_GLYPH: \
18023 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18024 HL, X, LAST_X); \
18025 break; \
18027 case COMPOSITE_GLYPH: \
18028 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18029 HL, X, LAST_X); \
18030 break; \
18032 case STRETCH_GLYPH: \
18033 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18034 HL, X, LAST_X); \
18035 break; \
18037 case IMAGE_GLYPH: \
18038 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18039 HL, X, LAST_X); \
18040 break; \
18042 default: \
18043 abort (); \
18046 set_glyph_string_background_width (s, START, LAST_X); \
18047 (X) += s->width; \
18050 while (0)
18053 /* Draw glyphs between START and END in AREA of ROW on window W,
18054 starting at x-position X. X is relative to AREA in W. HL is a
18055 face-override with the following meaning:
18057 DRAW_NORMAL_TEXT draw normally
18058 DRAW_CURSOR draw in cursor face
18059 DRAW_MOUSE_FACE draw in mouse face.
18060 DRAW_INVERSE_VIDEO draw in mode line face
18061 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18062 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18064 If OVERLAPS_P is non-zero, draw only the foreground of characters
18065 and clip to the physical height of ROW.
18067 Value is the x-position reached, relative to AREA of W. */
18069 static int
18070 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18071 struct window *w;
18072 int x;
18073 struct glyph_row *row;
18074 enum glyph_row_area area;
18075 int start, end;
18076 enum draw_glyphs_face hl;
18077 int overlaps_p;
18079 struct glyph_string *head, *tail;
18080 struct glyph_string *s;
18081 int last_x, area_width;
18082 int x_reached;
18083 int i, j;
18084 struct frame *f = XFRAME (WINDOW_FRAME (w));
18085 DECLARE_HDC (hdc);
18087 ALLOCATE_HDC (hdc, f);
18089 /* Let's rather be paranoid than getting a SEGV. */
18090 end = min (end, row->used[area]);
18091 start = max (0, start);
18092 start = min (end, start);
18094 /* Translate X to frame coordinates. Set last_x to the right
18095 end of the drawing area. */
18096 if (row->full_width_p)
18098 /* X is relative to the left edge of W, without scroll bars
18099 or fringes. */
18100 x += WINDOW_LEFT_EDGE_X (w);
18101 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18103 else
18105 int area_left = window_box_left (w, area);
18106 x += area_left;
18107 area_width = window_box_width (w, area);
18108 last_x = area_left + area_width;
18111 /* Build a doubly-linked list of glyph_string structures between
18112 head and tail from what we have to draw. Note that the macro
18113 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18114 the reason we use a separate variable `i'. */
18115 i = start;
18116 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18117 if (tail)
18118 x_reached = tail->x + tail->background_width;
18119 else
18120 x_reached = x;
18122 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18123 the row, redraw some glyphs in front or following the glyph
18124 strings built above. */
18125 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18127 int dummy_x = 0;
18128 struct glyph_string *h, *t;
18130 /* Compute overhangs for all glyph strings. */
18131 if (rif->compute_glyph_string_overhangs)
18132 for (s = head; s; s = s->next)
18133 rif->compute_glyph_string_overhangs (s);
18135 /* Prepend glyph strings for glyphs in front of the first glyph
18136 string that are overwritten because of the first glyph
18137 string's left overhang. The background of all strings
18138 prepended must be drawn because the first glyph string
18139 draws over it. */
18140 i = left_overwritten (head);
18141 if (i >= 0)
18143 j = i;
18144 BUILD_GLYPH_STRINGS (j, start, h, t,
18145 DRAW_NORMAL_TEXT, dummy_x, last_x);
18146 start = i;
18147 compute_overhangs_and_x (t, head->x, 1);
18148 prepend_glyph_string_lists (&head, &tail, h, t);
18151 /* Prepend glyph strings for glyphs in front of the first glyph
18152 string that overwrite that glyph string because of their
18153 right overhang. For these strings, only the foreground must
18154 be drawn, because it draws over the glyph string at `head'.
18155 The background must not be drawn because this would overwrite
18156 right overhangs of preceding glyphs for which no glyph
18157 strings exist. */
18158 i = left_overwriting (head);
18159 if (i >= 0)
18161 BUILD_GLYPH_STRINGS (i, start, h, t,
18162 DRAW_NORMAL_TEXT, dummy_x, last_x);
18163 for (s = h; s; s = s->next)
18164 s->background_filled_p = 1;
18165 compute_overhangs_and_x (t, head->x, 1);
18166 prepend_glyph_string_lists (&head, &tail, h, t);
18169 /* Append glyphs strings for glyphs following the last glyph
18170 string tail that are overwritten by tail. The background of
18171 these strings has to be drawn because tail's foreground draws
18172 over it. */
18173 i = right_overwritten (tail);
18174 if (i >= 0)
18176 BUILD_GLYPH_STRINGS (end, i, h, t,
18177 DRAW_NORMAL_TEXT, x, last_x);
18178 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18179 append_glyph_string_lists (&head, &tail, h, t);
18182 /* Append glyph strings for glyphs following the last glyph
18183 string tail that overwrite tail. The foreground of such
18184 glyphs has to be drawn because it writes into the background
18185 of tail. The background must not be drawn because it could
18186 paint over the foreground of following glyphs. */
18187 i = right_overwriting (tail);
18188 if (i >= 0)
18190 BUILD_GLYPH_STRINGS (end, i, h, t,
18191 DRAW_NORMAL_TEXT, x, last_x);
18192 for (s = h; s; s = s->next)
18193 s->background_filled_p = 1;
18194 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18195 append_glyph_string_lists (&head, &tail, h, t);
18199 /* Draw all strings. */
18200 for (s = head; s; s = s->next)
18201 rif->draw_glyph_string (s);
18203 if (area == TEXT_AREA
18204 && !row->full_width_p
18205 /* When drawing overlapping rows, only the glyph strings'
18206 foreground is drawn, which doesn't erase a cursor
18207 completely. */
18208 && !overlaps_p)
18210 int x0 = head ? head->x : x;
18211 int x1 = tail ? tail->x + tail->background_width : x;
18213 int text_left = window_box_left (w, TEXT_AREA);
18214 x0 -= text_left;
18215 x1 -= text_left;
18217 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18218 row->y, MATRIX_ROW_BOTTOM_Y (row));
18221 /* Value is the x-position up to which drawn, relative to AREA of W.
18222 This doesn't include parts drawn because of overhangs. */
18223 if (row->full_width_p)
18224 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18225 else
18226 x_reached -= window_box_left (w, area);
18228 RELEASE_HDC (hdc, f);
18230 return x_reached;
18234 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18235 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18237 static INLINE void
18238 append_glyph (it)
18239 struct it *it;
18241 struct glyph *glyph;
18242 enum glyph_row_area area = it->area;
18244 xassert (it->glyph_row);
18245 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18247 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18248 if (glyph < it->glyph_row->glyphs[area + 1])
18250 glyph->charpos = CHARPOS (it->position);
18251 glyph->object = it->object;
18252 glyph->pixel_width = it->pixel_width;
18253 glyph->ascent = it->ascent;
18254 glyph->descent = it->descent;
18255 glyph->voffset = it->voffset;
18256 glyph->type = CHAR_GLYPH;
18257 glyph->multibyte_p = it->multibyte_p;
18258 glyph->left_box_line_p = it->start_of_box_run_p;
18259 glyph->right_box_line_p = it->end_of_box_run_p;
18260 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18261 || it->phys_descent > it->descent);
18262 glyph->padding_p = 0;
18263 glyph->glyph_not_available_p = it->glyph_not_available_p;
18264 glyph->face_id = it->face_id;
18265 glyph->u.ch = it->char_to_display;
18266 glyph->slice = null_glyph_slice;
18267 glyph->font_type = FONT_TYPE_UNKNOWN;
18268 ++it->glyph_row->used[area];
18270 else if (!fonts_changed_p)
18272 it->w->ncols_scale_factor++;
18273 fonts_changed_p = 1;
18277 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18278 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18280 static INLINE void
18281 append_composite_glyph (it)
18282 struct it *it;
18284 struct glyph *glyph;
18285 enum glyph_row_area area = it->area;
18287 xassert (it->glyph_row);
18289 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18290 if (glyph < it->glyph_row->glyphs[area + 1])
18292 glyph->charpos = CHARPOS (it->position);
18293 glyph->object = it->object;
18294 glyph->pixel_width = it->pixel_width;
18295 glyph->ascent = it->ascent;
18296 glyph->descent = it->descent;
18297 glyph->voffset = it->voffset;
18298 glyph->type = COMPOSITE_GLYPH;
18299 glyph->multibyte_p = it->multibyte_p;
18300 glyph->left_box_line_p = it->start_of_box_run_p;
18301 glyph->right_box_line_p = it->end_of_box_run_p;
18302 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18303 || it->phys_descent > it->descent);
18304 glyph->padding_p = 0;
18305 glyph->glyph_not_available_p = 0;
18306 glyph->face_id = it->face_id;
18307 glyph->u.cmp_id = it->cmp_id;
18308 glyph->slice = null_glyph_slice;
18309 glyph->font_type = FONT_TYPE_UNKNOWN;
18310 ++it->glyph_row->used[area];
18312 else if (!fonts_changed_p)
18314 it->w->ncols_scale_factor++;
18315 fonts_changed_p = 1;
18320 /* Change IT->ascent and IT->height according to the setting of
18321 IT->voffset. */
18323 static INLINE void
18324 take_vertical_position_into_account (it)
18325 struct it *it;
18327 if (it->voffset)
18329 if (it->voffset < 0)
18330 /* Increase the ascent so that we can display the text higher
18331 in the line. */
18332 it->ascent -= it->voffset;
18333 else
18334 /* Increase the descent so that we can display the text lower
18335 in the line. */
18336 it->descent += it->voffset;
18341 /* Produce glyphs/get display metrics for the image IT is loaded with.
18342 See the description of struct display_iterator in dispextern.h for
18343 an overview of struct display_iterator. */
18345 static void
18346 produce_image_glyph (it)
18347 struct it *it;
18349 struct image *img;
18350 struct face *face;
18351 int face_ascent, glyph_ascent;
18352 struct glyph_slice slice;
18354 xassert (it->what == IT_IMAGE);
18356 face = FACE_FROM_ID (it->f, it->face_id);
18357 xassert (face);
18358 /* Make sure X resources of the face is loaded. */
18359 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18361 if (it->image_id < 0)
18363 /* Fringe bitmap. */
18364 it->ascent = it->phys_ascent = 0;
18365 it->descent = it->phys_descent = 0;
18366 it->pixel_width = 0;
18367 it->nglyphs = 0;
18368 return;
18371 img = IMAGE_FROM_ID (it->f, it->image_id);
18372 xassert (img);
18373 /* Make sure X resources of the image is loaded. */
18374 prepare_image_for_display (it->f, img);
18376 slice.x = slice.y = 0;
18377 slice.width = img->width;
18378 slice.height = img->height;
18380 if (INTEGERP (it->slice.x))
18381 slice.x = XINT (it->slice.x);
18382 else if (FLOATP (it->slice.x))
18383 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18385 if (INTEGERP (it->slice.y))
18386 slice.y = XINT (it->slice.y);
18387 else if (FLOATP (it->slice.y))
18388 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18390 if (INTEGERP (it->slice.width))
18391 slice.width = XINT (it->slice.width);
18392 else if (FLOATP (it->slice.width))
18393 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18395 if (INTEGERP (it->slice.height))
18396 slice.height = XINT (it->slice.height);
18397 else if (FLOATP (it->slice.height))
18398 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18400 if (slice.x >= img->width)
18401 slice.x = img->width;
18402 if (slice.y >= img->height)
18403 slice.y = img->height;
18404 if (slice.x + slice.width >= img->width)
18405 slice.width = img->width - slice.x;
18406 if (slice.y + slice.height > img->height)
18407 slice.height = img->height - slice.y;
18409 if (slice.width == 0 || slice.height == 0)
18410 return;
18412 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18414 it->descent = slice.height - glyph_ascent;
18415 if (slice.y == 0)
18416 it->descent += img->vmargin;
18417 if (slice.y + slice.height == img->height)
18418 it->descent += img->vmargin;
18419 it->phys_descent = it->descent;
18421 it->pixel_width = slice.width;
18422 if (slice.x == 0)
18423 it->pixel_width += img->hmargin;
18424 if (slice.x + slice.width == img->width)
18425 it->pixel_width += img->hmargin;
18427 /* It's quite possible for images to have an ascent greater than
18428 their height, so don't get confused in that case. */
18429 if (it->descent < 0)
18430 it->descent = 0;
18432 #if 0 /* this breaks image tiling */
18433 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18434 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18435 if (face_ascent > it->ascent)
18436 it->ascent = it->phys_ascent = face_ascent;
18437 #endif
18439 it->nglyphs = 1;
18441 if (face->box != FACE_NO_BOX)
18443 if (face->box_line_width > 0)
18445 if (slice.y == 0)
18446 it->ascent += face->box_line_width;
18447 if (slice.y + slice.height == img->height)
18448 it->descent += face->box_line_width;
18451 if (it->start_of_box_run_p && slice.x == 0)
18452 it->pixel_width += abs (face->box_line_width);
18453 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18454 it->pixel_width += abs (face->box_line_width);
18457 take_vertical_position_into_account (it);
18459 if (it->glyph_row)
18461 struct glyph *glyph;
18462 enum glyph_row_area area = it->area;
18464 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18465 if (glyph < it->glyph_row->glyphs[area + 1])
18467 glyph->charpos = CHARPOS (it->position);
18468 glyph->object = it->object;
18469 glyph->pixel_width = it->pixel_width;
18470 glyph->ascent = glyph_ascent;
18471 glyph->descent = it->descent;
18472 glyph->voffset = it->voffset;
18473 glyph->type = IMAGE_GLYPH;
18474 glyph->multibyte_p = it->multibyte_p;
18475 glyph->left_box_line_p = it->start_of_box_run_p;
18476 glyph->right_box_line_p = it->end_of_box_run_p;
18477 glyph->overlaps_vertically_p = 0;
18478 glyph->padding_p = 0;
18479 glyph->glyph_not_available_p = 0;
18480 glyph->face_id = it->face_id;
18481 glyph->u.img_id = img->id;
18482 glyph->slice = slice;
18483 glyph->font_type = FONT_TYPE_UNKNOWN;
18484 ++it->glyph_row->used[area];
18486 else if (!fonts_changed_p)
18488 it->w->ncols_scale_factor++;
18489 fonts_changed_p = 1;
18495 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18496 of the glyph, WIDTH and HEIGHT are the width and height of the
18497 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18499 static void
18500 append_stretch_glyph (it, object, width, height, ascent)
18501 struct it *it;
18502 Lisp_Object object;
18503 int width, height;
18504 int ascent;
18506 struct glyph *glyph;
18507 enum glyph_row_area area = it->area;
18509 xassert (ascent >= 0 && ascent <= height);
18511 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18512 if (glyph < it->glyph_row->glyphs[area + 1])
18514 glyph->charpos = CHARPOS (it->position);
18515 glyph->object = object;
18516 glyph->pixel_width = width;
18517 glyph->ascent = ascent;
18518 glyph->descent = height - ascent;
18519 glyph->voffset = it->voffset;
18520 glyph->type = STRETCH_GLYPH;
18521 glyph->multibyte_p = it->multibyte_p;
18522 glyph->left_box_line_p = it->start_of_box_run_p;
18523 glyph->right_box_line_p = it->end_of_box_run_p;
18524 glyph->overlaps_vertically_p = 0;
18525 glyph->padding_p = 0;
18526 glyph->glyph_not_available_p = 0;
18527 glyph->face_id = it->face_id;
18528 glyph->u.stretch.ascent = ascent;
18529 glyph->u.stretch.height = height;
18530 glyph->slice = null_glyph_slice;
18531 glyph->font_type = FONT_TYPE_UNKNOWN;
18532 ++it->glyph_row->used[area];
18534 else if (!fonts_changed_p)
18536 it->w->ncols_scale_factor++;
18537 fonts_changed_p = 1;
18542 /* Produce a stretch glyph for iterator IT. IT->object is the value
18543 of the glyph property displayed. The value must be a list
18544 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18545 being recognized:
18547 1. `:width WIDTH' specifies that the space should be WIDTH *
18548 canonical char width wide. WIDTH may be an integer or floating
18549 point number.
18551 2. `:relative-width FACTOR' specifies that the width of the stretch
18552 should be computed from the width of the first character having the
18553 `glyph' property, and should be FACTOR times that width.
18555 3. `:align-to HPOS' specifies that the space should be wide enough
18556 to reach HPOS, a value in canonical character units.
18558 Exactly one of the above pairs must be present.
18560 4. `:height HEIGHT' specifies that the height of the stretch produced
18561 should be HEIGHT, measured in canonical character units.
18563 5. `:relative-height FACTOR' specifies that the height of the
18564 stretch should be FACTOR times the height of the characters having
18565 the glyph property.
18567 Either none or exactly one of 4 or 5 must be present.
18569 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18570 of the stretch should be used for the ascent of the stretch.
18571 ASCENT must be in the range 0 <= ASCENT <= 100. */
18573 static void
18574 produce_stretch_glyph (it)
18575 struct it *it;
18577 /* (space :width WIDTH :height HEIGHT ...) */
18578 Lisp_Object prop, plist;
18579 int width = 0, height = 0, align_to = -1;
18580 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18581 int ascent = 0;
18582 double tem;
18583 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18584 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18586 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18588 /* List should start with `space'. */
18589 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18590 plist = XCDR (it->object);
18592 /* Compute the width of the stretch. */
18593 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18594 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18596 /* Absolute width `:width WIDTH' specified and valid. */
18597 zero_width_ok_p = 1;
18598 width = (int)tem;
18600 else if (prop = Fplist_get (plist, QCrelative_width),
18601 NUMVAL (prop) > 0)
18603 /* Relative width `:relative-width FACTOR' specified and valid.
18604 Compute the width of the characters having the `glyph'
18605 property. */
18606 struct it it2;
18607 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18609 it2 = *it;
18610 if (it->multibyte_p)
18612 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18613 - IT_BYTEPOS (*it));
18614 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18616 else
18617 it2.c = *p, it2.len = 1;
18619 it2.glyph_row = NULL;
18620 it2.what = IT_CHARACTER;
18621 x_produce_glyphs (&it2);
18622 width = NUMVAL (prop) * it2.pixel_width;
18624 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18625 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18627 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18628 align_to = (align_to < 0
18630 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18631 else if (align_to < 0)
18632 align_to = window_box_left_offset (it->w, TEXT_AREA);
18633 width = max (0, (int)tem + align_to - it->current_x);
18634 zero_width_ok_p = 1;
18636 else
18637 /* Nothing specified -> width defaults to canonical char width. */
18638 width = FRAME_COLUMN_WIDTH (it->f);
18640 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18641 width = 1;
18643 /* Compute height. */
18644 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18645 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18647 height = (int)tem;
18648 zero_height_ok_p = 1;
18650 else if (prop = Fplist_get (plist, QCrelative_height),
18651 NUMVAL (prop) > 0)
18652 height = FONT_HEIGHT (font) * NUMVAL (prop);
18653 else
18654 height = FONT_HEIGHT (font);
18656 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18657 height = 1;
18659 /* Compute percentage of height used for ascent. If
18660 `:ascent ASCENT' is present and valid, use that. Otherwise,
18661 derive the ascent from the font in use. */
18662 if (prop = Fplist_get (plist, QCascent),
18663 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18664 ascent = height * NUMVAL (prop) / 100.0;
18665 else if (!NILP (prop)
18666 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18667 ascent = min (max (0, (int)tem), height);
18668 else
18669 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18671 if (width > 0 && height > 0 && it->glyph_row)
18673 Lisp_Object object = it->stack[it->sp - 1].string;
18674 if (!STRINGP (object))
18675 object = it->w->buffer;
18676 append_stretch_glyph (it, object, width, height, ascent);
18679 it->pixel_width = width;
18680 it->ascent = it->phys_ascent = ascent;
18681 it->descent = it->phys_descent = height - it->ascent;
18682 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18684 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18686 if (face->box_line_width > 0)
18688 it->ascent += face->box_line_width;
18689 it->descent += face->box_line_width;
18692 if (it->start_of_box_run_p)
18693 it->pixel_width += abs (face->box_line_width);
18694 if (it->end_of_box_run_p)
18695 it->pixel_width += abs (face->box_line_width);
18698 take_vertical_position_into_account (it);
18701 /* Calculate line-height and line-spacing properties.
18702 An integer value specifies explicit pixel value.
18703 A float value specifies relative value to current face height.
18704 A cons (float . face-name) specifies relative value to
18705 height of specified face font.
18707 Returns height in pixels, or nil. */
18709 static Lisp_Object
18710 calc_line_height_property (it, prop, font, boff, total)
18711 struct it *it;
18712 Lisp_Object prop;
18713 XFontStruct *font;
18714 int boff, *total;
18716 Lisp_Object position, val;
18717 Lisp_Object face_name = Qnil;
18718 int ascent, descent, height, override;
18720 if (STRINGP (it->object))
18721 position = make_number (IT_STRING_CHARPOS (*it));
18722 else if (BUFFERP (it->object))
18723 position = make_number (IT_CHARPOS (*it));
18724 else
18725 return Qnil;
18727 val = Fget_char_property (position, prop, it->object);
18729 if (NILP (val))
18730 return val;
18732 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18734 *total = 1;
18735 val = XCDR (val);
18738 if (INTEGERP (val))
18739 return val;
18741 if (CONSP (val))
18743 face_name = XCDR (val);
18744 val = XCAR (val);
18746 else if (SYMBOLP (val))
18748 face_name = val;
18749 val = Qnil;
18752 override = EQ (prop, Qline_height);
18754 if (NILP (face_name))
18756 font = FRAME_FONT (it->f);
18757 boff = FRAME_BASELINE_OFFSET (it->f);
18759 else if (EQ (face_name, Qt))
18761 override = 0;
18763 else
18765 int face_id;
18766 struct face *face;
18767 struct font_info *font_info;
18769 face_id = lookup_named_face (it->f, face_name, ' ');
18770 if (face_id < 0)
18771 return make_number (-1);
18773 face = FACE_FROM_ID (it->f, face_id);
18774 font = face->font;
18775 if (font == NULL)
18776 return make_number (-1);
18778 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18779 boff = font_info->baseline_offset;
18780 if (font_info->vertical_centering)
18781 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18784 ascent = FONT_BASE (font) + boff;
18785 descent = FONT_DESCENT (font) - boff;
18787 if (override)
18789 it->override_ascent = ascent;
18790 it->override_descent = descent;
18791 it->override_boff = boff;
18794 height = ascent + descent;
18795 if (FLOATP (val))
18796 height = (int)(XFLOAT_DATA (val) * height);
18797 else if (INTEGERP (val))
18798 height *= XINT (val);
18800 return make_number (height);
18804 /* RIF:
18805 Produce glyphs/get display metrics for the display element IT is
18806 loaded with. See the description of struct display_iterator in
18807 dispextern.h for an overview of struct display_iterator. */
18809 void
18810 x_produce_glyphs (it)
18811 struct it *it;
18813 int extra_line_spacing = it->extra_line_spacing;
18815 it->glyph_not_available_p = 0;
18817 if (it->what == IT_CHARACTER)
18819 XChar2b char2b;
18820 XFontStruct *font;
18821 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18822 XCharStruct *pcm;
18823 int font_not_found_p;
18824 struct font_info *font_info;
18825 int boff; /* baseline offset */
18826 /* We may change it->multibyte_p upon unibyte<->multibyte
18827 conversion. So, save the current value now and restore it
18828 later.
18830 Note: It seems that we don't have to record multibyte_p in
18831 struct glyph because the character code itself tells if or
18832 not the character is multibyte. Thus, in the future, we must
18833 consider eliminating the field `multibyte_p' in the struct
18834 glyph. */
18835 int saved_multibyte_p = it->multibyte_p;
18837 /* Maybe translate single-byte characters to multibyte, or the
18838 other way. */
18839 it->char_to_display = it->c;
18840 if (!ASCII_BYTE_P (it->c))
18842 if (unibyte_display_via_language_environment
18843 && SINGLE_BYTE_CHAR_P (it->c)
18844 && (it->c >= 0240
18845 || !NILP (Vnonascii_translation_table)))
18847 it->char_to_display = unibyte_char_to_multibyte (it->c);
18848 it->multibyte_p = 1;
18849 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18850 face = FACE_FROM_ID (it->f, it->face_id);
18852 else if (!SINGLE_BYTE_CHAR_P (it->c)
18853 && !it->multibyte_p)
18855 it->multibyte_p = 1;
18856 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18857 face = FACE_FROM_ID (it->f, it->face_id);
18861 /* Get font to use. Encode IT->char_to_display. */
18862 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18863 &char2b, it->multibyte_p, 0);
18864 font = face->font;
18866 /* When no suitable font found, use the default font. */
18867 font_not_found_p = font == NULL;
18868 if (font_not_found_p)
18870 font = FRAME_FONT (it->f);
18871 boff = FRAME_BASELINE_OFFSET (it->f);
18872 font_info = NULL;
18874 else
18876 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18877 boff = font_info->baseline_offset;
18878 if (font_info->vertical_centering)
18879 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18882 if (it->char_to_display >= ' '
18883 && (!it->multibyte_p || it->char_to_display < 128))
18885 /* Either unibyte or ASCII. */
18886 int stretched_p;
18888 it->nglyphs = 1;
18890 pcm = rif->per_char_metric (font, &char2b,
18891 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18893 if (it->override_ascent >= 0)
18895 it->ascent = it->override_ascent;
18896 it->descent = it->override_descent;
18897 boff = it->override_boff;
18899 else
18901 it->ascent = FONT_BASE (font) + boff;
18902 it->descent = FONT_DESCENT (font) - boff;
18905 if (pcm)
18907 it->phys_ascent = pcm->ascent + boff;
18908 it->phys_descent = pcm->descent - boff;
18909 it->pixel_width = pcm->width;
18911 else
18913 it->glyph_not_available_p = 1;
18914 it->phys_ascent = it->ascent;
18915 it->phys_descent = it->descent;
18916 it->pixel_width = FONT_WIDTH (font);
18919 if (it->constrain_row_ascent_descent_p)
18921 if (it->descent > it->max_descent)
18923 it->ascent += it->descent - it->max_descent;
18924 it->descent = it->max_descent;
18926 if (it->ascent > it->max_ascent)
18928 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18929 it->ascent = it->max_ascent;
18931 it->phys_ascent = min (it->phys_ascent, it->ascent);
18932 it->phys_descent = min (it->phys_descent, it->descent);
18933 extra_line_spacing = 0;
18936 /* If this is a space inside a region of text with
18937 `space-width' property, change its width. */
18938 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18939 if (stretched_p)
18940 it->pixel_width *= XFLOATINT (it->space_width);
18942 /* If face has a box, add the box thickness to the character
18943 height. If character has a box line to the left and/or
18944 right, add the box line width to the character's width. */
18945 if (face->box != FACE_NO_BOX)
18947 int thick = face->box_line_width;
18949 if (thick > 0)
18951 it->ascent += thick;
18952 it->descent += thick;
18954 else
18955 thick = -thick;
18957 if (it->start_of_box_run_p)
18958 it->pixel_width += thick;
18959 if (it->end_of_box_run_p)
18960 it->pixel_width += thick;
18963 /* If face has an overline, add the height of the overline
18964 (1 pixel) and a 1 pixel margin to the character height. */
18965 if (face->overline_p)
18966 it->ascent += 2;
18968 if (it->constrain_row_ascent_descent_p)
18970 if (it->ascent > it->max_ascent)
18971 it->ascent = it->max_ascent;
18972 if (it->descent > it->max_descent)
18973 it->descent = it->max_descent;
18976 take_vertical_position_into_account (it);
18978 /* If we have to actually produce glyphs, do it. */
18979 if (it->glyph_row)
18981 if (stretched_p)
18983 /* Translate a space with a `space-width' property
18984 into a stretch glyph. */
18985 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18986 / FONT_HEIGHT (font));
18987 append_stretch_glyph (it, it->object, it->pixel_width,
18988 it->ascent + it->descent, ascent);
18990 else
18991 append_glyph (it);
18993 /* If characters with lbearing or rbearing are displayed
18994 in this line, record that fact in a flag of the
18995 glyph row. This is used to optimize X output code. */
18996 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18997 it->glyph_row->contains_overlapping_glyphs_p = 1;
19000 else if (it->char_to_display == '\n')
19002 /* A newline has no width but we need the height of the line.
19003 But if previous part of the line set a height, don't
19004 increase that height */
19006 Lisp_Object height;
19008 it->override_ascent = -1;
19009 it->pixel_width = 0;
19010 it->nglyphs = 0;
19012 height = calc_line_height_property(it, Qline_height, font, boff, 0);
19014 if (it->override_ascent >= 0)
19016 it->ascent = it->override_ascent;
19017 it->descent = it->override_descent;
19018 boff = it->override_boff;
19020 else
19022 it->ascent = FONT_BASE (font) + boff;
19023 it->descent = FONT_DESCENT (font) - boff;
19026 if (EQ (height, make_number(0)))
19028 if (it->descent > it->max_descent)
19030 it->ascent += it->descent - it->max_descent;
19031 it->descent = it->max_descent;
19033 if (it->ascent > it->max_ascent)
19035 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19036 it->ascent = it->max_ascent;
19038 it->phys_ascent = min (it->phys_ascent, it->ascent);
19039 it->phys_descent = min (it->phys_descent, it->descent);
19040 it->constrain_row_ascent_descent_p = 1;
19041 extra_line_spacing = 0;
19043 else
19045 Lisp_Object spacing;
19046 int total = 0;
19048 it->phys_ascent = it->ascent;
19049 it->phys_descent = it->descent;
19051 if ((it->max_ascent > 0 || it->max_descent > 0)
19052 && face->box != FACE_NO_BOX
19053 && face->box_line_width > 0)
19055 it->ascent += face->box_line_width;
19056 it->descent += face->box_line_width;
19058 if (!NILP (height)
19059 && XINT (height) > it->ascent + it->descent)
19060 it->ascent = XINT (height) - it->descent;
19062 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
19063 if (INTEGERP (spacing))
19065 extra_line_spacing = XINT (spacing);
19066 if (total)
19067 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19071 else if (it->char_to_display == '\t')
19073 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19074 int x = it->current_x + it->continuation_lines_width;
19075 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19077 /* If the distance from the current position to the next tab
19078 stop is less than a canonical character width, use the
19079 tab stop after that. */
19080 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19081 next_tab_x += tab_width;
19083 it->pixel_width = next_tab_x - x;
19084 it->nglyphs = 1;
19085 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19086 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19088 if (it->glyph_row)
19090 append_stretch_glyph (it, it->object, it->pixel_width,
19091 it->ascent + it->descent, it->ascent);
19094 else
19096 /* A multi-byte character. Assume that the display width of the
19097 character is the width of the character multiplied by the
19098 width of the font. */
19100 /* If we found a font, this font should give us the right
19101 metrics. If we didn't find a font, use the frame's
19102 default font and calculate the width of the character
19103 from the charset width; this is what old redisplay code
19104 did. */
19106 pcm = rif->per_char_metric (font, &char2b,
19107 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19109 if (font_not_found_p || !pcm)
19111 int charset = CHAR_CHARSET (it->char_to_display);
19113 it->glyph_not_available_p = 1;
19114 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19115 * CHARSET_WIDTH (charset));
19116 it->phys_ascent = FONT_BASE (font) + boff;
19117 it->phys_descent = FONT_DESCENT (font) - boff;
19119 else
19121 it->pixel_width = pcm->width;
19122 it->phys_ascent = pcm->ascent + boff;
19123 it->phys_descent = pcm->descent - boff;
19124 if (it->glyph_row
19125 && (pcm->lbearing < 0
19126 || pcm->rbearing > pcm->width))
19127 it->glyph_row->contains_overlapping_glyphs_p = 1;
19129 it->nglyphs = 1;
19130 it->ascent = FONT_BASE (font) + boff;
19131 it->descent = FONT_DESCENT (font) - boff;
19132 if (face->box != FACE_NO_BOX)
19134 int thick = face->box_line_width;
19136 if (thick > 0)
19138 it->ascent += thick;
19139 it->descent += thick;
19141 else
19142 thick = - thick;
19144 if (it->start_of_box_run_p)
19145 it->pixel_width += thick;
19146 if (it->end_of_box_run_p)
19147 it->pixel_width += thick;
19150 /* If face has an overline, add the height of the overline
19151 (1 pixel) and a 1 pixel margin to the character height. */
19152 if (face->overline_p)
19153 it->ascent += 2;
19155 take_vertical_position_into_account (it);
19157 if (it->glyph_row)
19158 append_glyph (it);
19160 it->multibyte_p = saved_multibyte_p;
19162 else if (it->what == IT_COMPOSITION)
19164 /* Note: A composition is represented as one glyph in the
19165 glyph matrix. There are no padding glyphs. */
19166 XChar2b char2b;
19167 XFontStruct *font;
19168 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19169 XCharStruct *pcm;
19170 int font_not_found_p;
19171 struct font_info *font_info;
19172 int boff; /* baseline offset */
19173 struct composition *cmp = composition_table[it->cmp_id];
19175 /* Maybe translate single-byte characters to multibyte. */
19176 it->char_to_display = it->c;
19177 if (unibyte_display_via_language_environment
19178 && SINGLE_BYTE_CHAR_P (it->c)
19179 && (it->c >= 0240
19180 || (it->c >= 0200
19181 && !NILP (Vnonascii_translation_table))))
19183 it->char_to_display = unibyte_char_to_multibyte (it->c);
19186 /* Get face and font to use. Encode IT->char_to_display. */
19187 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19188 face = FACE_FROM_ID (it->f, it->face_id);
19189 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19190 &char2b, it->multibyte_p, 0);
19191 font = face->font;
19193 /* When no suitable font found, use the default font. */
19194 font_not_found_p = font == NULL;
19195 if (font_not_found_p)
19197 font = FRAME_FONT (it->f);
19198 boff = FRAME_BASELINE_OFFSET (it->f);
19199 font_info = NULL;
19201 else
19203 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19204 boff = font_info->baseline_offset;
19205 if (font_info->vertical_centering)
19206 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19209 /* There are no padding glyphs, so there is only one glyph to
19210 produce for the composition. Important is that pixel_width,
19211 ascent and descent are the values of what is drawn by
19212 draw_glyphs (i.e. the values of the overall glyphs composed). */
19213 it->nglyphs = 1;
19215 /* If we have not yet calculated pixel size data of glyphs of
19216 the composition for the current face font, calculate them
19217 now. Theoretically, we have to check all fonts for the
19218 glyphs, but that requires much time and memory space. So,
19219 here we check only the font of the first glyph. This leads
19220 to incorrect display very rarely, and C-l (recenter) can
19221 correct the display anyway. */
19222 if (cmp->font != (void *) font)
19224 /* Ascent and descent of the font of the first character of
19225 this composition (adjusted by baseline offset). Ascent
19226 and descent of overall glyphs should not be less than
19227 them respectively. */
19228 int font_ascent = FONT_BASE (font) + boff;
19229 int font_descent = FONT_DESCENT (font) - boff;
19230 /* Bounding box of the overall glyphs. */
19231 int leftmost, rightmost, lowest, highest;
19232 int i, width, ascent, descent;
19234 cmp->font = (void *) font;
19236 /* Initialize the bounding box. */
19237 if (font_info
19238 && (pcm = rif->per_char_metric (font, &char2b,
19239 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19241 width = pcm->width;
19242 ascent = pcm->ascent;
19243 descent = pcm->descent;
19245 else
19247 width = FONT_WIDTH (font);
19248 ascent = FONT_BASE (font);
19249 descent = FONT_DESCENT (font);
19252 rightmost = width;
19253 lowest = - descent + boff;
19254 highest = ascent + boff;
19255 leftmost = 0;
19257 if (font_info
19258 && font_info->default_ascent
19259 && CHAR_TABLE_P (Vuse_default_ascent)
19260 && !NILP (Faref (Vuse_default_ascent,
19261 make_number (it->char_to_display))))
19262 highest = font_info->default_ascent + boff;
19264 /* Draw the first glyph at the normal position. It may be
19265 shifted to right later if some other glyphs are drawn at
19266 the left. */
19267 cmp->offsets[0] = 0;
19268 cmp->offsets[1] = boff;
19270 /* Set cmp->offsets for the remaining glyphs. */
19271 for (i = 1; i < cmp->glyph_len; i++)
19273 int left, right, btm, top;
19274 int ch = COMPOSITION_GLYPH (cmp, i);
19275 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19277 face = FACE_FROM_ID (it->f, face_id);
19278 get_char_face_and_encoding (it->f, ch, face->id,
19279 &char2b, it->multibyte_p, 0);
19280 font = face->font;
19281 if (font == NULL)
19283 font = FRAME_FONT (it->f);
19284 boff = FRAME_BASELINE_OFFSET (it->f);
19285 font_info = NULL;
19287 else
19289 font_info
19290 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19291 boff = font_info->baseline_offset;
19292 if (font_info->vertical_centering)
19293 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19296 if (font_info
19297 && (pcm = rif->per_char_metric (font, &char2b,
19298 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19300 width = pcm->width;
19301 ascent = pcm->ascent;
19302 descent = pcm->descent;
19304 else
19306 width = FONT_WIDTH (font);
19307 ascent = 1;
19308 descent = 0;
19311 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19313 /* Relative composition with or without
19314 alternate chars. */
19315 left = (leftmost + rightmost - width) / 2;
19316 btm = - descent + boff;
19317 if (font_info && font_info->relative_compose
19318 && (! CHAR_TABLE_P (Vignore_relative_composition)
19319 || NILP (Faref (Vignore_relative_composition,
19320 make_number (ch)))))
19323 if (- descent >= font_info->relative_compose)
19324 /* One extra pixel between two glyphs. */
19325 btm = highest + 1;
19326 else if (ascent <= 0)
19327 /* One extra pixel between two glyphs. */
19328 btm = lowest - 1 - ascent - descent;
19331 else
19333 /* A composition rule is specified by an integer
19334 value that encodes global and new reference
19335 points (GREF and NREF). GREF and NREF are
19336 specified by numbers as below:
19338 0---1---2 -- ascent
19342 9--10--11 -- center
19344 ---3---4---5--- baseline
19346 6---7---8 -- descent
19348 int rule = COMPOSITION_RULE (cmp, i);
19349 int gref, nref, grefx, grefy, nrefx, nrefy;
19351 COMPOSITION_DECODE_RULE (rule, gref, nref);
19352 grefx = gref % 3, nrefx = nref % 3;
19353 grefy = gref / 3, nrefy = nref / 3;
19355 left = (leftmost
19356 + grefx * (rightmost - leftmost) / 2
19357 - nrefx * width / 2);
19358 btm = ((grefy == 0 ? highest
19359 : grefy == 1 ? 0
19360 : grefy == 2 ? lowest
19361 : (highest + lowest) / 2)
19362 - (nrefy == 0 ? ascent + descent
19363 : nrefy == 1 ? descent - boff
19364 : nrefy == 2 ? 0
19365 : (ascent + descent) / 2));
19368 cmp->offsets[i * 2] = left;
19369 cmp->offsets[i * 2 + 1] = btm + descent;
19371 /* Update the bounding box of the overall glyphs. */
19372 right = left + width;
19373 top = btm + descent + ascent;
19374 if (left < leftmost)
19375 leftmost = left;
19376 if (right > rightmost)
19377 rightmost = right;
19378 if (top > highest)
19379 highest = top;
19380 if (btm < lowest)
19381 lowest = btm;
19384 /* If there are glyphs whose x-offsets are negative,
19385 shift all glyphs to the right and make all x-offsets
19386 non-negative. */
19387 if (leftmost < 0)
19389 for (i = 0; i < cmp->glyph_len; i++)
19390 cmp->offsets[i * 2] -= leftmost;
19391 rightmost -= leftmost;
19394 cmp->pixel_width = rightmost;
19395 cmp->ascent = highest;
19396 cmp->descent = - lowest;
19397 if (cmp->ascent < font_ascent)
19398 cmp->ascent = font_ascent;
19399 if (cmp->descent < font_descent)
19400 cmp->descent = font_descent;
19403 it->pixel_width = cmp->pixel_width;
19404 it->ascent = it->phys_ascent = cmp->ascent;
19405 it->descent = it->phys_descent = cmp->descent;
19407 if (face->box != FACE_NO_BOX)
19409 int thick = face->box_line_width;
19411 if (thick > 0)
19413 it->ascent += thick;
19414 it->descent += thick;
19416 else
19417 thick = - thick;
19419 if (it->start_of_box_run_p)
19420 it->pixel_width += thick;
19421 if (it->end_of_box_run_p)
19422 it->pixel_width += thick;
19425 /* If face has an overline, add the height of the overline
19426 (1 pixel) and a 1 pixel margin to the character height. */
19427 if (face->overline_p)
19428 it->ascent += 2;
19430 take_vertical_position_into_account (it);
19432 if (it->glyph_row)
19433 append_composite_glyph (it);
19435 else if (it->what == IT_IMAGE)
19436 produce_image_glyph (it);
19437 else if (it->what == IT_STRETCH)
19438 produce_stretch_glyph (it);
19440 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19441 because this isn't true for images with `:ascent 100'. */
19442 xassert (it->ascent >= 0 && it->descent >= 0);
19443 if (it->area == TEXT_AREA)
19444 it->current_x += it->pixel_width;
19446 if (extra_line_spacing > 0)
19447 it->descent += extra_line_spacing;
19449 it->max_ascent = max (it->max_ascent, it->ascent);
19450 it->max_descent = max (it->max_descent, it->descent);
19451 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19452 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19455 /* EXPORT for RIF:
19456 Output LEN glyphs starting at START at the nominal cursor position.
19457 Advance the nominal cursor over the text. The global variable
19458 updated_window contains the window being updated, updated_row is
19459 the glyph row being updated, and updated_area is the area of that
19460 row being updated. */
19462 void
19463 x_write_glyphs (start, len)
19464 struct glyph *start;
19465 int len;
19467 int x, hpos;
19469 xassert (updated_window && updated_row);
19470 BLOCK_INPUT;
19472 /* Write glyphs. */
19474 hpos = start - updated_row->glyphs[updated_area];
19475 x = draw_glyphs (updated_window, output_cursor.x,
19476 updated_row, updated_area,
19477 hpos, hpos + len,
19478 DRAW_NORMAL_TEXT, 0);
19480 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19481 if (updated_area == TEXT_AREA
19482 && updated_window->phys_cursor_on_p
19483 && updated_window->phys_cursor.vpos == output_cursor.vpos
19484 && updated_window->phys_cursor.hpos >= hpos
19485 && updated_window->phys_cursor.hpos < hpos + len)
19486 updated_window->phys_cursor_on_p = 0;
19488 UNBLOCK_INPUT;
19490 /* Advance the output cursor. */
19491 output_cursor.hpos += len;
19492 output_cursor.x = x;
19496 /* EXPORT for RIF:
19497 Insert LEN glyphs from START at the nominal cursor position. */
19499 void
19500 x_insert_glyphs (start, len)
19501 struct glyph *start;
19502 int len;
19504 struct frame *f;
19505 struct window *w;
19506 int line_height, shift_by_width, shifted_region_width;
19507 struct glyph_row *row;
19508 struct glyph *glyph;
19509 int frame_x, frame_y, hpos;
19511 xassert (updated_window && updated_row);
19512 BLOCK_INPUT;
19513 w = updated_window;
19514 f = XFRAME (WINDOW_FRAME (w));
19516 /* Get the height of the line we are in. */
19517 row = updated_row;
19518 line_height = row->height;
19520 /* Get the width of the glyphs to insert. */
19521 shift_by_width = 0;
19522 for (glyph = start; glyph < start + len; ++glyph)
19523 shift_by_width += glyph->pixel_width;
19525 /* Get the width of the region to shift right. */
19526 shifted_region_width = (window_box_width (w, updated_area)
19527 - output_cursor.x
19528 - shift_by_width);
19530 /* Shift right. */
19531 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19532 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19534 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19535 line_height, shift_by_width);
19537 /* Write the glyphs. */
19538 hpos = start - row->glyphs[updated_area];
19539 draw_glyphs (w, output_cursor.x, row, updated_area,
19540 hpos, hpos + len,
19541 DRAW_NORMAL_TEXT, 0);
19543 /* Advance the output cursor. */
19544 output_cursor.hpos += len;
19545 output_cursor.x += shift_by_width;
19546 UNBLOCK_INPUT;
19550 /* EXPORT for RIF:
19551 Erase the current text line from the nominal cursor position
19552 (inclusive) to pixel column TO_X (exclusive). The idea is that
19553 everything from TO_X onward is already erased.
19555 TO_X is a pixel position relative to updated_area of
19556 updated_window. TO_X == -1 means clear to the end of this area. */
19558 void
19559 x_clear_end_of_line (to_x)
19560 int to_x;
19562 struct frame *f;
19563 struct window *w = updated_window;
19564 int max_x, min_y, max_y;
19565 int from_x, from_y, to_y;
19567 xassert (updated_window && updated_row);
19568 f = XFRAME (w->frame);
19570 if (updated_row->full_width_p)
19571 max_x = WINDOW_TOTAL_WIDTH (w);
19572 else
19573 max_x = window_box_width (w, updated_area);
19574 max_y = window_text_bottom_y (w);
19576 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19577 of window. For TO_X > 0, truncate to end of drawing area. */
19578 if (to_x == 0)
19579 return;
19580 else if (to_x < 0)
19581 to_x = max_x;
19582 else
19583 to_x = min (to_x, max_x);
19585 to_y = min (max_y, output_cursor.y + updated_row->height);
19587 /* Notice if the cursor will be cleared by this operation. */
19588 if (!updated_row->full_width_p)
19589 notice_overwritten_cursor (w, updated_area,
19590 output_cursor.x, -1,
19591 updated_row->y,
19592 MATRIX_ROW_BOTTOM_Y (updated_row));
19594 from_x = output_cursor.x;
19596 /* Translate to frame coordinates. */
19597 if (updated_row->full_width_p)
19599 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19600 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19602 else
19604 int area_left = window_box_left (w, updated_area);
19605 from_x += area_left;
19606 to_x += area_left;
19609 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19610 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19611 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19613 /* Prevent inadvertently clearing to end of the X window. */
19614 if (to_x > from_x && to_y > from_y)
19616 BLOCK_INPUT;
19617 rif->clear_frame_area (f, from_x, from_y,
19618 to_x - from_x, to_y - from_y);
19619 UNBLOCK_INPUT;
19623 #endif /* HAVE_WINDOW_SYSTEM */
19627 /***********************************************************************
19628 Cursor types
19629 ***********************************************************************/
19631 /* Value is the internal representation of the specified cursor type
19632 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19633 of the bar cursor. */
19635 static enum text_cursor_kinds
19636 get_specified_cursor_type (arg, width)
19637 Lisp_Object arg;
19638 int *width;
19640 enum text_cursor_kinds type;
19642 if (NILP (arg))
19643 return NO_CURSOR;
19645 if (EQ (arg, Qbox))
19646 return FILLED_BOX_CURSOR;
19648 if (EQ (arg, Qhollow))
19649 return HOLLOW_BOX_CURSOR;
19651 if (EQ (arg, Qbar))
19653 *width = 2;
19654 return BAR_CURSOR;
19657 if (CONSP (arg)
19658 && EQ (XCAR (arg), Qbar)
19659 && INTEGERP (XCDR (arg))
19660 && XINT (XCDR (arg)) >= 0)
19662 *width = XINT (XCDR (arg));
19663 return BAR_CURSOR;
19666 if (EQ (arg, Qhbar))
19668 *width = 2;
19669 return HBAR_CURSOR;
19672 if (CONSP (arg)
19673 && EQ (XCAR (arg), Qhbar)
19674 && INTEGERP (XCDR (arg))
19675 && XINT (XCDR (arg)) >= 0)
19677 *width = XINT (XCDR (arg));
19678 return HBAR_CURSOR;
19681 /* Treat anything unknown as "hollow box cursor".
19682 It was bad to signal an error; people have trouble fixing
19683 .Xdefaults with Emacs, when it has something bad in it. */
19684 type = HOLLOW_BOX_CURSOR;
19686 return type;
19689 /* Set the default cursor types for specified frame. */
19690 void
19691 set_frame_cursor_types (f, arg)
19692 struct frame *f;
19693 Lisp_Object arg;
19695 int width;
19696 Lisp_Object tem;
19698 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19699 FRAME_CURSOR_WIDTH (f) = width;
19701 /* By default, set up the blink-off state depending on the on-state. */
19703 tem = Fassoc (arg, Vblink_cursor_alist);
19704 if (!NILP (tem))
19706 FRAME_BLINK_OFF_CURSOR (f)
19707 = get_specified_cursor_type (XCDR (tem), &width);
19708 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19710 else
19711 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19715 /* Return the cursor we want to be displayed in window W. Return
19716 width of bar/hbar cursor through WIDTH arg. Return with
19717 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19718 (i.e. if the `system caret' should track this cursor).
19720 In a mini-buffer window, we want the cursor only to appear if we
19721 are reading input from this window. For the selected window, we
19722 want the cursor type given by the frame parameter or buffer local
19723 setting of cursor-type. If explicitly marked off, draw no cursor.
19724 In all other cases, we want a hollow box cursor. */
19726 static enum text_cursor_kinds
19727 get_window_cursor_type (w, glyph, width, active_cursor)
19728 struct window *w;
19729 struct glyph *glyph;
19730 int *width;
19731 int *active_cursor;
19733 struct frame *f = XFRAME (w->frame);
19734 struct buffer *b = XBUFFER (w->buffer);
19735 int cursor_type = DEFAULT_CURSOR;
19736 Lisp_Object alt_cursor;
19737 int non_selected = 0;
19739 *active_cursor = 1;
19741 /* Echo area */
19742 if (cursor_in_echo_area
19743 && FRAME_HAS_MINIBUF_P (f)
19744 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19746 if (w == XWINDOW (echo_area_window))
19748 *width = FRAME_CURSOR_WIDTH (f);
19749 return FRAME_DESIRED_CURSOR (f);
19752 *active_cursor = 0;
19753 non_selected = 1;
19756 /* Nonselected window or nonselected frame. */
19757 else if (w != XWINDOW (f->selected_window)
19758 #ifdef HAVE_WINDOW_SYSTEM
19759 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19760 #endif
19763 *active_cursor = 0;
19765 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19766 return NO_CURSOR;
19768 non_selected = 1;
19771 /* Never display a cursor in a window in which cursor-type is nil. */
19772 if (NILP (b->cursor_type))
19773 return NO_CURSOR;
19775 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19776 if (non_selected)
19778 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19779 return get_specified_cursor_type (alt_cursor, width);
19782 /* Get the normal cursor type for this window. */
19783 if (EQ (b->cursor_type, Qt))
19785 cursor_type = FRAME_DESIRED_CURSOR (f);
19786 *width = FRAME_CURSOR_WIDTH (f);
19788 else
19789 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19791 /* Use normal cursor if not blinked off. */
19792 if (!w->cursor_off_p)
19794 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19795 if (cursor_type == FILLED_BOX_CURSOR)
19796 cursor_type = HOLLOW_BOX_CURSOR;
19798 return cursor_type;
19801 /* Cursor is blinked off, so determine how to "toggle" it. */
19803 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19804 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19805 return get_specified_cursor_type (XCDR (alt_cursor), width);
19807 /* Then see if frame has specified a specific blink off cursor type. */
19808 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19810 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19811 return FRAME_BLINK_OFF_CURSOR (f);
19814 #if 0
19815 /* Some people liked having a permanently visible blinking cursor,
19816 while others had very strong opinions against it. So it was
19817 decided to remove it. KFS 2003-09-03 */
19819 /* Finally perform built-in cursor blinking:
19820 filled box <-> hollow box
19821 wide [h]bar <-> narrow [h]bar
19822 narrow [h]bar <-> no cursor
19823 other type <-> no cursor */
19825 if (cursor_type == FILLED_BOX_CURSOR)
19826 return HOLLOW_BOX_CURSOR;
19828 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19830 *width = 1;
19831 return cursor_type;
19833 #endif
19835 return NO_CURSOR;
19839 #ifdef HAVE_WINDOW_SYSTEM
19841 /* Notice when the text cursor of window W has been completely
19842 overwritten by a drawing operation that outputs glyphs in AREA
19843 starting at X0 and ending at X1 in the line starting at Y0 and
19844 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19845 the rest of the line after X0 has been written. Y coordinates
19846 are window-relative. */
19848 static void
19849 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19850 struct window *w;
19851 enum glyph_row_area area;
19852 int x0, y0, x1, y1;
19854 int cx0, cx1, cy0, cy1;
19855 struct glyph_row *row;
19857 if (!w->phys_cursor_on_p)
19858 return;
19859 if (area != TEXT_AREA)
19860 return;
19862 row = w->current_matrix->rows + w->phys_cursor.vpos;
19863 if (!row->displays_text_p)
19864 return;
19866 if (row->cursor_in_fringe_p)
19868 row->cursor_in_fringe_p = 0;
19869 draw_fringe_bitmap (w, row, 0);
19870 w->phys_cursor_on_p = 0;
19871 return;
19874 cx0 = w->phys_cursor.x;
19875 cx1 = cx0 + w->phys_cursor_width;
19876 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19877 return;
19879 /* The cursor image will be completely removed from the
19880 screen if the output area intersects the cursor area in
19881 y-direction. When we draw in [y0 y1[, and some part of
19882 the cursor is at y < y0, that part must have been drawn
19883 before. When scrolling, the cursor is erased before
19884 actually scrolling, so we don't come here. When not
19885 scrolling, the rows above the old cursor row must have
19886 changed, and in this case these rows must have written
19887 over the cursor image.
19889 Likewise if part of the cursor is below y1, with the
19890 exception of the cursor being in the first blank row at
19891 the buffer and window end because update_text_area
19892 doesn't draw that row. (Except when it does, but
19893 that's handled in update_text_area.) */
19895 cy0 = w->phys_cursor.y;
19896 cy1 = cy0 + w->phys_cursor_height;
19897 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19898 return;
19900 w->phys_cursor_on_p = 0;
19903 #endif /* HAVE_WINDOW_SYSTEM */
19906 /************************************************************************
19907 Mouse Face
19908 ************************************************************************/
19910 #ifdef HAVE_WINDOW_SYSTEM
19912 /* EXPORT for RIF:
19913 Fix the display of area AREA of overlapping row ROW in window W. */
19915 void
19916 x_fix_overlapping_area (w, row, area)
19917 struct window *w;
19918 struct glyph_row *row;
19919 enum glyph_row_area area;
19921 int i, x;
19923 BLOCK_INPUT;
19925 x = 0;
19926 for (i = 0; i < row->used[area];)
19928 if (row->glyphs[area][i].overlaps_vertically_p)
19930 int start = i, start_x = x;
19934 x += row->glyphs[area][i].pixel_width;
19935 ++i;
19937 while (i < row->used[area]
19938 && row->glyphs[area][i].overlaps_vertically_p);
19940 draw_glyphs (w, start_x, row, area,
19941 start, i,
19942 DRAW_NORMAL_TEXT, 1);
19944 else
19946 x += row->glyphs[area][i].pixel_width;
19947 ++i;
19951 UNBLOCK_INPUT;
19955 /* EXPORT:
19956 Draw the cursor glyph of window W in glyph row ROW. See the
19957 comment of draw_glyphs for the meaning of HL. */
19959 void
19960 draw_phys_cursor_glyph (w, row, hl)
19961 struct window *w;
19962 struct glyph_row *row;
19963 enum draw_glyphs_face hl;
19965 /* If cursor hpos is out of bounds, don't draw garbage. This can
19966 happen in mini-buffer windows when switching between echo area
19967 glyphs and mini-buffer. */
19968 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19970 int on_p = w->phys_cursor_on_p;
19971 int x1;
19972 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19973 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19974 hl, 0);
19975 w->phys_cursor_on_p = on_p;
19977 if (hl == DRAW_CURSOR)
19978 w->phys_cursor_width = x1 - w->phys_cursor.x;
19979 /* When we erase the cursor, and ROW is overlapped by other
19980 rows, make sure that these overlapping parts of other rows
19981 are redrawn. */
19982 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19984 if (row > w->current_matrix->rows
19985 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19986 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19988 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19989 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19990 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19996 /* EXPORT:
19997 Erase the image of a cursor of window W from the screen. */
19999 void
20000 erase_phys_cursor (w)
20001 struct window *w;
20003 struct frame *f = XFRAME (w->frame);
20004 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20005 int hpos = w->phys_cursor.hpos;
20006 int vpos = w->phys_cursor.vpos;
20007 int mouse_face_here_p = 0;
20008 struct glyph_matrix *active_glyphs = w->current_matrix;
20009 struct glyph_row *cursor_row;
20010 struct glyph *cursor_glyph;
20011 enum draw_glyphs_face hl;
20013 /* No cursor displayed or row invalidated => nothing to do on the
20014 screen. */
20015 if (w->phys_cursor_type == NO_CURSOR)
20016 goto mark_cursor_off;
20018 /* VPOS >= active_glyphs->nrows means that window has been resized.
20019 Don't bother to erase the cursor. */
20020 if (vpos >= active_glyphs->nrows)
20021 goto mark_cursor_off;
20023 /* If row containing cursor is marked invalid, there is nothing we
20024 can do. */
20025 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20026 if (!cursor_row->enabled_p)
20027 goto mark_cursor_off;
20029 /* If row is completely invisible, don't attempt to delete a cursor which
20030 isn't there. This can happen if cursor is at top of a window, and
20031 we switch to a buffer with a header line in that window. */
20032 if (cursor_row->visible_height <= 0)
20033 goto mark_cursor_off;
20035 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20036 if (cursor_row->cursor_in_fringe_p)
20038 cursor_row->cursor_in_fringe_p = 0;
20039 draw_fringe_bitmap (w, cursor_row, 0);
20040 goto mark_cursor_off;
20043 /* This can happen when the new row is shorter than the old one.
20044 In this case, either draw_glyphs or clear_end_of_line
20045 should have cleared the cursor. Note that we wouldn't be
20046 able to erase the cursor in this case because we don't have a
20047 cursor glyph at hand. */
20048 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20049 goto mark_cursor_off;
20051 /* If the cursor is in the mouse face area, redisplay that when
20052 we clear the cursor. */
20053 if (! NILP (dpyinfo->mouse_face_window)
20054 && w == XWINDOW (dpyinfo->mouse_face_window)
20055 && (vpos > dpyinfo->mouse_face_beg_row
20056 || (vpos == dpyinfo->mouse_face_beg_row
20057 && hpos >= dpyinfo->mouse_face_beg_col))
20058 && (vpos < dpyinfo->mouse_face_end_row
20059 || (vpos == dpyinfo->mouse_face_end_row
20060 && hpos < dpyinfo->mouse_face_end_col))
20061 /* Don't redraw the cursor's spot in mouse face if it is at the
20062 end of a line (on a newline). The cursor appears there, but
20063 mouse highlighting does not. */
20064 && cursor_row->used[TEXT_AREA] > hpos)
20065 mouse_face_here_p = 1;
20067 /* Maybe clear the display under the cursor. */
20068 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20070 int x, y;
20071 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20073 cursor_glyph = get_phys_cursor_glyph (w);
20074 if (cursor_glyph == NULL)
20075 goto mark_cursor_off;
20077 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20078 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20080 rif->clear_frame_area (f, x, y,
20081 cursor_glyph->pixel_width, cursor_row->visible_height);
20084 /* Erase the cursor by redrawing the character underneath it. */
20085 if (mouse_face_here_p)
20086 hl = DRAW_MOUSE_FACE;
20087 else
20088 hl = DRAW_NORMAL_TEXT;
20089 draw_phys_cursor_glyph (w, cursor_row, hl);
20091 mark_cursor_off:
20092 w->phys_cursor_on_p = 0;
20093 w->phys_cursor_type = NO_CURSOR;
20097 /* EXPORT:
20098 Display or clear cursor of window W. If ON is zero, clear the
20099 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20100 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20102 void
20103 display_and_set_cursor (w, on, hpos, vpos, x, y)
20104 struct window *w;
20105 int on, hpos, vpos, x, y;
20107 struct frame *f = XFRAME (w->frame);
20108 int new_cursor_type;
20109 int new_cursor_width;
20110 int active_cursor;
20111 struct glyph_row *glyph_row;
20112 struct glyph *glyph;
20114 /* This is pointless on invisible frames, and dangerous on garbaged
20115 windows and frames; in the latter case, the frame or window may
20116 be in the midst of changing its size, and x and y may be off the
20117 window. */
20118 if (! FRAME_VISIBLE_P (f)
20119 || FRAME_GARBAGED_P (f)
20120 || vpos >= w->current_matrix->nrows
20121 || hpos >= w->current_matrix->matrix_w)
20122 return;
20124 /* If cursor is off and we want it off, return quickly. */
20125 if (!on && !w->phys_cursor_on_p)
20126 return;
20128 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20129 /* If cursor row is not enabled, we don't really know where to
20130 display the cursor. */
20131 if (!glyph_row->enabled_p)
20133 w->phys_cursor_on_p = 0;
20134 return;
20137 glyph = NULL;
20138 if (!glyph_row->exact_window_width_line_p
20139 || hpos < glyph_row->used[TEXT_AREA])
20140 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20142 xassert (interrupt_input_blocked);
20144 /* Set new_cursor_type to the cursor we want to be displayed. */
20145 new_cursor_type = get_window_cursor_type (w, glyph,
20146 &new_cursor_width, &active_cursor);
20148 /* If cursor is currently being shown and we don't want it to be or
20149 it is in the wrong place, or the cursor type is not what we want,
20150 erase it. */
20151 if (w->phys_cursor_on_p
20152 && (!on
20153 || w->phys_cursor.x != x
20154 || w->phys_cursor.y != y
20155 || new_cursor_type != w->phys_cursor_type
20156 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20157 && new_cursor_width != w->phys_cursor_width)))
20158 erase_phys_cursor (w);
20160 /* Don't check phys_cursor_on_p here because that flag is only set
20161 to zero in some cases where we know that the cursor has been
20162 completely erased, to avoid the extra work of erasing the cursor
20163 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20164 still not be visible, or it has only been partly erased. */
20165 if (on)
20167 w->phys_cursor_ascent = glyph_row->ascent;
20168 w->phys_cursor_height = glyph_row->height;
20170 /* Set phys_cursor_.* before x_draw_.* is called because some
20171 of them may need the information. */
20172 w->phys_cursor.x = x;
20173 w->phys_cursor.y = glyph_row->y;
20174 w->phys_cursor.hpos = hpos;
20175 w->phys_cursor.vpos = vpos;
20178 rif->draw_window_cursor (w, glyph_row, x, y,
20179 new_cursor_type, new_cursor_width,
20180 on, active_cursor);
20184 /* Switch the display of W's cursor on or off, according to the value
20185 of ON. */
20187 static void
20188 update_window_cursor (w, on)
20189 struct window *w;
20190 int on;
20192 /* Don't update cursor in windows whose frame is in the process
20193 of being deleted. */
20194 if (w->current_matrix)
20196 BLOCK_INPUT;
20197 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20198 w->phys_cursor.x, w->phys_cursor.y);
20199 UNBLOCK_INPUT;
20204 /* Call update_window_cursor with parameter ON_P on all leaf windows
20205 in the window tree rooted at W. */
20207 static void
20208 update_cursor_in_window_tree (w, on_p)
20209 struct window *w;
20210 int on_p;
20212 while (w)
20214 if (!NILP (w->hchild))
20215 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20216 else if (!NILP (w->vchild))
20217 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20218 else
20219 update_window_cursor (w, on_p);
20221 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20226 /* EXPORT:
20227 Display the cursor on window W, or clear it, according to ON_P.
20228 Don't change the cursor's position. */
20230 void
20231 x_update_cursor (f, on_p)
20232 struct frame *f;
20233 int on_p;
20235 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20239 /* EXPORT:
20240 Clear the cursor of window W to background color, and mark the
20241 cursor as not shown. This is used when the text where the cursor
20242 is is about to be rewritten. */
20244 void
20245 x_clear_cursor (w)
20246 struct window *w;
20248 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20249 update_window_cursor (w, 0);
20253 /* EXPORT:
20254 Display the active region described by mouse_face_* according to DRAW. */
20256 void
20257 show_mouse_face (dpyinfo, draw)
20258 Display_Info *dpyinfo;
20259 enum draw_glyphs_face draw;
20261 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20262 struct frame *f = XFRAME (WINDOW_FRAME (w));
20264 if (/* If window is in the process of being destroyed, don't bother
20265 to do anything. */
20266 w->current_matrix != NULL
20267 /* Don't update mouse highlight if hidden */
20268 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20269 /* Recognize when we are called to operate on rows that don't exist
20270 anymore. This can happen when a window is split. */
20271 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20273 int phys_cursor_on_p = w->phys_cursor_on_p;
20274 struct glyph_row *row, *first, *last;
20276 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20277 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20279 for (row = first; row <= last && row->enabled_p; ++row)
20281 int start_hpos, end_hpos, start_x;
20283 /* For all but the first row, the highlight starts at column 0. */
20284 if (row == first)
20286 start_hpos = dpyinfo->mouse_face_beg_col;
20287 start_x = dpyinfo->mouse_face_beg_x;
20289 else
20291 start_hpos = 0;
20292 start_x = 0;
20295 if (row == last)
20296 end_hpos = dpyinfo->mouse_face_end_col;
20297 else
20298 end_hpos = row->used[TEXT_AREA];
20300 if (end_hpos > start_hpos)
20302 draw_glyphs (w, start_x, row, TEXT_AREA,
20303 start_hpos, end_hpos,
20304 draw, 0);
20306 row->mouse_face_p
20307 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20311 /* When we've written over the cursor, arrange for it to
20312 be displayed again. */
20313 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20315 BLOCK_INPUT;
20316 display_and_set_cursor (w, 1,
20317 w->phys_cursor.hpos, w->phys_cursor.vpos,
20318 w->phys_cursor.x, w->phys_cursor.y);
20319 UNBLOCK_INPUT;
20323 /* Change the mouse cursor. */
20324 if (draw == DRAW_NORMAL_TEXT)
20325 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20326 else if (draw == DRAW_MOUSE_FACE)
20327 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20328 else
20329 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20332 /* EXPORT:
20333 Clear out the mouse-highlighted active region.
20334 Redraw it un-highlighted first. Value is non-zero if mouse
20335 face was actually drawn unhighlighted. */
20338 clear_mouse_face (dpyinfo)
20339 Display_Info *dpyinfo;
20341 int cleared = 0;
20343 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20345 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20346 cleared = 1;
20349 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20350 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20351 dpyinfo->mouse_face_window = Qnil;
20352 dpyinfo->mouse_face_overlay = Qnil;
20353 return cleared;
20357 /* EXPORT:
20358 Non-zero if physical cursor of window W is within mouse face. */
20361 cursor_in_mouse_face_p (w)
20362 struct window *w;
20364 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20365 int in_mouse_face = 0;
20367 if (WINDOWP (dpyinfo->mouse_face_window)
20368 && XWINDOW (dpyinfo->mouse_face_window) == w)
20370 int hpos = w->phys_cursor.hpos;
20371 int vpos = w->phys_cursor.vpos;
20373 if (vpos >= dpyinfo->mouse_face_beg_row
20374 && vpos <= dpyinfo->mouse_face_end_row
20375 && (vpos > dpyinfo->mouse_face_beg_row
20376 || hpos >= dpyinfo->mouse_face_beg_col)
20377 && (vpos < dpyinfo->mouse_face_end_row
20378 || hpos < dpyinfo->mouse_face_end_col
20379 || dpyinfo->mouse_face_past_end))
20380 in_mouse_face = 1;
20383 return in_mouse_face;
20389 /* Find the glyph matrix position of buffer position CHARPOS in window
20390 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20391 current glyphs must be up to date. If CHARPOS is above window
20392 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20393 of last line in W. In the row containing CHARPOS, stop before glyphs
20394 having STOP as object. */
20396 #if 1 /* This is a version of fast_find_position that's more correct
20397 in the presence of hscrolling, for example. I didn't install
20398 it right away because the problem fixed is minor, it failed
20399 in 20.x as well, and I think it's too risky to install
20400 so near the release of 21.1. 2001-09-25 gerd. */
20402 static int
20403 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20404 struct window *w;
20405 int charpos;
20406 int *hpos, *vpos, *x, *y;
20407 Lisp_Object stop;
20409 struct glyph_row *row, *first;
20410 struct glyph *glyph, *end;
20411 int past_end = 0;
20413 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20414 row = row_containing_pos (w, charpos, first, NULL, 0);
20415 if (row == NULL)
20417 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20419 *x = *y = *hpos = *vpos = 0;
20420 return 1;
20422 else
20424 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20425 past_end = 1;
20429 *x = row->x;
20430 *y = row->y;
20431 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20433 glyph = row->glyphs[TEXT_AREA];
20434 end = glyph + row->used[TEXT_AREA];
20436 /* Skip over glyphs not having an object at the start of the row.
20437 These are special glyphs like truncation marks on terminal
20438 frames. */
20439 if (row->displays_text_p)
20440 while (glyph < end
20441 && INTEGERP (glyph->object)
20442 && !EQ (stop, glyph->object)
20443 && glyph->charpos < 0)
20445 *x += glyph->pixel_width;
20446 ++glyph;
20449 while (glyph < end
20450 && !INTEGERP (glyph->object)
20451 && !EQ (stop, glyph->object)
20452 && (!BUFFERP (glyph->object)
20453 || glyph->charpos < charpos))
20455 *x += glyph->pixel_width;
20456 ++glyph;
20459 *hpos = glyph - row->glyphs[TEXT_AREA];
20460 return !past_end;
20463 #else /* not 1 */
20465 static int
20466 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20467 struct window *w;
20468 int pos;
20469 int *hpos, *vpos, *x, *y;
20470 Lisp_Object stop;
20472 int i;
20473 int lastcol;
20474 int maybe_next_line_p = 0;
20475 int line_start_position;
20476 int yb = window_text_bottom_y (w);
20477 struct glyph_row *row, *best_row;
20478 int row_vpos, best_row_vpos;
20479 int current_x;
20481 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20482 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20484 while (row->y < yb)
20486 if (row->used[TEXT_AREA])
20487 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20488 else
20489 line_start_position = 0;
20491 if (line_start_position > pos)
20492 break;
20493 /* If the position sought is the end of the buffer,
20494 don't include the blank lines at the bottom of the window. */
20495 else if (line_start_position == pos
20496 && pos == BUF_ZV (XBUFFER (w->buffer)))
20498 maybe_next_line_p = 1;
20499 break;
20501 else if (line_start_position > 0)
20503 best_row = row;
20504 best_row_vpos = row_vpos;
20507 if (row->y + row->height >= yb)
20508 break;
20510 ++row;
20511 ++row_vpos;
20514 /* Find the right column within BEST_ROW. */
20515 lastcol = 0;
20516 current_x = best_row->x;
20517 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20519 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20520 int charpos = glyph->charpos;
20522 if (BUFFERP (glyph->object))
20524 if (charpos == pos)
20526 *hpos = i;
20527 *vpos = best_row_vpos;
20528 *x = current_x;
20529 *y = best_row->y;
20530 return 1;
20532 else if (charpos > pos)
20533 break;
20535 else if (EQ (glyph->object, stop))
20536 break;
20538 if (charpos > 0)
20539 lastcol = i;
20540 current_x += glyph->pixel_width;
20543 /* If we're looking for the end of the buffer,
20544 and we didn't find it in the line we scanned,
20545 use the start of the following line. */
20546 if (maybe_next_line_p)
20548 ++best_row;
20549 ++best_row_vpos;
20550 lastcol = 0;
20551 current_x = best_row->x;
20554 *vpos = best_row_vpos;
20555 *hpos = lastcol + 1;
20556 *x = current_x;
20557 *y = best_row->y;
20558 return 0;
20561 #endif /* not 1 */
20564 /* Find the position of the glyph for position POS in OBJECT in
20565 window W's current matrix, and return in *X, *Y the pixel
20566 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20568 RIGHT_P non-zero means return the position of the right edge of the
20569 glyph, RIGHT_P zero means return the left edge position.
20571 If no glyph for POS exists in the matrix, return the position of
20572 the glyph with the next smaller position that is in the matrix, if
20573 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20574 exists in the matrix, return the position of the glyph with the
20575 next larger position in OBJECT.
20577 Value is non-zero if a glyph was found. */
20579 static int
20580 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20581 struct window *w;
20582 int pos;
20583 Lisp_Object object;
20584 int *hpos, *vpos, *x, *y;
20585 int right_p;
20587 int yb = window_text_bottom_y (w);
20588 struct glyph_row *r;
20589 struct glyph *best_glyph = NULL;
20590 struct glyph_row *best_row = NULL;
20591 int best_x = 0;
20593 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20594 r->enabled_p && r->y < yb;
20595 ++r)
20597 struct glyph *g = r->glyphs[TEXT_AREA];
20598 struct glyph *e = g + r->used[TEXT_AREA];
20599 int gx;
20601 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20602 if (EQ (g->object, object))
20604 if (g->charpos == pos)
20606 best_glyph = g;
20607 best_x = gx;
20608 best_row = r;
20609 goto found;
20611 else if (best_glyph == NULL
20612 || ((abs (g->charpos - pos)
20613 < abs (best_glyph->charpos - pos))
20614 && (right_p
20615 ? g->charpos < pos
20616 : g->charpos > pos)))
20618 best_glyph = g;
20619 best_x = gx;
20620 best_row = r;
20625 found:
20627 if (best_glyph)
20629 *x = best_x;
20630 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20632 if (right_p)
20634 *x += best_glyph->pixel_width;
20635 ++*hpos;
20638 *y = best_row->y;
20639 *vpos = best_row - w->current_matrix->rows;
20642 return best_glyph != NULL;
20646 /* See if position X, Y is within a hot-spot of an image. */
20648 static int
20649 on_hot_spot_p (hot_spot, x, y)
20650 Lisp_Object hot_spot;
20651 int x, y;
20653 if (!CONSP (hot_spot))
20654 return 0;
20656 if (EQ (XCAR (hot_spot), Qrect))
20658 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20659 Lisp_Object rect = XCDR (hot_spot);
20660 Lisp_Object tem;
20661 if (!CONSP (rect))
20662 return 0;
20663 if (!CONSP (XCAR (rect)))
20664 return 0;
20665 if (!CONSP (XCDR (rect)))
20666 return 0;
20667 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20668 return 0;
20669 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20670 return 0;
20671 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20672 return 0;
20673 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20674 return 0;
20675 return 1;
20677 else if (EQ (XCAR (hot_spot), Qcircle))
20679 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20680 Lisp_Object circ = XCDR (hot_spot);
20681 Lisp_Object lr, lx0, ly0;
20682 if (CONSP (circ)
20683 && CONSP (XCAR (circ))
20684 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20685 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20686 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20688 double r = XFLOATINT (lr);
20689 double dx = XINT (lx0) - x;
20690 double dy = XINT (ly0) - y;
20691 return (dx * dx + dy * dy <= r * r);
20694 else if (EQ (XCAR (hot_spot), Qpoly))
20696 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20697 if (VECTORP (XCDR (hot_spot)))
20699 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20700 Lisp_Object *poly = v->contents;
20701 int n = v->size;
20702 int i;
20703 int inside = 0;
20704 Lisp_Object lx, ly;
20705 int x0, y0;
20707 /* Need an even number of coordinates, and at least 3 edges. */
20708 if (n < 6 || n & 1)
20709 return 0;
20711 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20712 If count is odd, we are inside polygon. Pixels on edges
20713 may or may not be included depending on actual geometry of the
20714 polygon. */
20715 if ((lx = poly[n-2], !INTEGERP (lx))
20716 || (ly = poly[n-1], !INTEGERP (lx)))
20717 return 0;
20718 x0 = XINT (lx), y0 = XINT (ly);
20719 for (i = 0; i < n; i += 2)
20721 int x1 = x0, y1 = y0;
20722 if ((lx = poly[i], !INTEGERP (lx))
20723 || (ly = poly[i+1], !INTEGERP (ly)))
20724 return 0;
20725 x0 = XINT (lx), y0 = XINT (ly);
20727 /* Does this segment cross the X line? */
20728 if (x0 >= x)
20730 if (x1 >= x)
20731 continue;
20733 else if (x1 < x)
20734 continue;
20735 if (y > y0 && y > y1)
20736 continue;
20737 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20738 inside = !inside;
20740 return inside;
20743 /* If we don't understand the format, pretend we're not in the hot-spot. */
20744 return 0;
20747 Lisp_Object
20748 find_hot_spot (map, x, y)
20749 Lisp_Object map;
20750 int x, y;
20752 while (CONSP (map))
20754 if (CONSP (XCAR (map))
20755 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20756 return XCAR (map);
20757 map = XCDR (map);
20760 return Qnil;
20763 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20764 3, 3, 0,
20765 doc: /* Lookup in image map MAP coordinates X and Y.
20766 An image map is an alist where each element has the format (AREA ID PLIST).
20767 An AREA is specified as either a rectangle, a circle, or a polygon:
20768 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20769 pixel coordinates of the upper left and bottom right corners.
20770 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20771 and the radius of the circle; r may be a float or integer.
20772 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20773 vector describes one corner in the polygon.
20774 Returns the alist element for the first matching AREA in MAP. */)
20775 (map, x, y)
20776 Lisp_Object map;
20777 Lisp_Object x, y;
20779 if (NILP (map))
20780 return Qnil;
20782 CHECK_NUMBER (x);
20783 CHECK_NUMBER (y);
20785 return find_hot_spot (map, XINT (x), XINT (y));
20789 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20790 static void
20791 define_frame_cursor1 (f, cursor, pointer)
20792 struct frame *f;
20793 Cursor cursor;
20794 Lisp_Object pointer;
20796 /* Do not change cursor shape while dragging mouse. */
20797 if (!NILP (do_mouse_tracking))
20798 return;
20800 if (!NILP (pointer))
20802 if (EQ (pointer, Qarrow))
20803 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20804 else if (EQ (pointer, Qhand))
20805 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20806 else if (EQ (pointer, Qtext))
20807 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20808 else if (EQ (pointer, intern ("hdrag")))
20809 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20810 #ifdef HAVE_X_WINDOWS
20811 else if (EQ (pointer, intern ("vdrag")))
20812 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20813 #endif
20814 else if (EQ (pointer, intern ("hourglass")))
20815 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20816 else if (EQ (pointer, Qmodeline))
20817 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20818 else
20819 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20822 if (cursor != No_Cursor)
20823 rif->define_frame_cursor (f, cursor);
20826 /* Take proper action when mouse has moved to the mode or header line
20827 or marginal area AREA of window W, x-position X and y-position Y.
20828 X is relative to the start of the text display area of W, so the
20829 width of bitmap areas and scroll bars must be subtracted to get a
20830 position relative to the start of the mode line. */
20832 static void
20833 note_mode_line_or_margin_highlight (w, x, y, area)
20834 struct window *w;
20835 int x, y;
20836 enum window_part area;
20838 struct frame *f = XFRAME (w->frame);
20839 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20840 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20841 Lisp_Object pointer = Qnil;
20842 int charpos, dx, dy, width, height;
20843 Lisp_Object string, object = Qnil;
20844 Lisp_Object pos, help;
20846 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20847 string = mode_line_string (w, area, &x, &y, &charpos,
20848 &object, &dx, &dy, &width, &height);
20849 else
20851 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20852 string = marginal_area_string (w, area, &x, &y, &charpos,
20853 &object, &dx, &dy, &width, &height);
20856 help = Qnil;
20858 if (IMAGEP (object))
20860 Lisp_Object image_map, hotspot;
20861 if ((image_map = Fplist_get (XCDR (object), QCmap),
20862 !NILP (image_map))
20863 && (hotspot = find_hot_spot (image_map, dx, dy),
20864 CONSP (hotspot))
20865 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20867 Lisp_Object area_id, plist;
20869 area_id = XCAR (hotspot);
20870 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20871 If so, we could look for mouse-enter, mouse-leave
20872 properties in PLIST (and do something...). */
20873 if ((plist = XCDR (hotspot), CONSP (plist)))
20875 pointer = Fplist_get (plist, Qpointer);
20876 if (NILP (pointer))
20877 pointer = Qhand;
20878 help = Fplist_get (plist, Qhelp_echo);
20879 if (!NILP (help))
20881 help_echo_string = help;
20882 /* Is this correct? ++kfs */
20883 XSETWINDOW (help_echo_window, w);
20884 help_echo_object = w->buffer;
20885 help_echo_pos = charpos;
20888 if (NILP (pointer))
20889 pointer = Fplist_get (XCDR (object), QCpointer);
20893 if (STRINGP (string))
20895 pos = make_number (charpos);
20896 /* If we're on a string with `help-echo' text property, arrange
20897 for the help to be displayed. This is done by setting the
20898 global variable help_echo_string to the help string. */
20899 help = Fget_text_property (pos, Qhelp_echo, string);
20900 if (!NILP (help))
20902 help_echo_string = help;
20903 XSETWINDOW (help_echo_window, w);
20904 help_echo_object = string;
20905 help_echo_pos = charpos;
20908 if (NILP (pointer))
20909 pointer = Fget_text_property (pos, Qpointer, string);
20911 /* Change the mouse pointer according to what is under X/Y. */
20912 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20914 Lisp_Object map;
20915 map = Fget_text_property (pos, Qlocal_map, string);
20916 if (!KEYMAPP (map))
20917 map = Fget_text_property (pos, Qkeymap, string);
20918 if (!KEYMAPP (map))
20919 cursor = dpyinfo->vertical_scroll_bar_cursor;
20923 define_frame_cursor1 (f, cursor, pointer);
20927 /* EXPORT:
20928 Take proper action when the mouse has moved to position X, Y on
20929 frame F as regards highlighting characters that have mouse-face
20930 properties. Also de-highlighting chars where the mouse was before.
20931 X and Y can be negative or out of range. */
20933 void
20934 note_mouse_highlight (f, x, y)
20935 struct frame *f;
20936 int x, y;
20938 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20939 enum window_part part;
20940 Lisp_Object window;
20941 struct window *w;
20942 Cursor cursor = No_Cursor;
20943 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20944 struct buffer *b;
20946 /* When a menu is active, don't highlight because this looks odd. */
20947 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20948 if (popup_activated ())
20949 return;
20950 #endif
20952 if (NILP (Vmouse_highlight)
20953 || !f->glyphs_initialized_p)
20954 return;
20956 dpyinfo->mouse_face_mouse_x = x;
20957 dpyinfo->mouse_face_mouse_y = y;
20958 dpyinfo->mouse_face_mouse_frame = f;
20960 if (dpyinfo->mouse_face_defer)
20961 return;
20963 if (gc_in_progress)
20965 dpyinfo->mouse_face_deferred_gc = 1;
20966 return;
20969 /* Which window is that in? */
20970 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20972 /* If we were displaying active text in another window, clear that. */
20973 if (! EQ (window, dpyinfo->mouse_face_window))
20974 clear_mouse_face (dpyinfo);
20976 /* Not on a window -> return. */
20977 if (!WINDOWP (window))
20978 return;
20980 /* Reset help_echo_string. It will get recomputed below. */
20981 help_echo_string = Qnil;
20983 /* Convert to window-relative pixel coordinates. */
20984 w = XWINDOW (window);
20985 frame_to_window_pixel_xy (w, &x, &y);
20987 /* Handle tool-bar window differently since it doesn't display a
20988 buffer. */
20989 if (EQ (window, f->tool_bar_window))
20991 note_tool_bar_highlight (f, x, y);
20992 return;
20995 /* Mouse is on the mode, header line or margin? */
20996 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20997 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20999 note_mode_line_or_margin_highlight (w, x, y, part);
21000 return;
21003 if (part == ON_VERTICAL_BORDER)
21004 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21005 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21006 || part == ON_SCROLL_BAR)
21007 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21008 else
21009 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21011 /* Are we in a window whose display is up to date?
21012 And verify the buffer's text has not changed. */
21013 b = XBUFFER (w->buffer);
21014 if (part == ON_TEXT
21015 && EQ (w->window_end_valid, w->buffer)
21016 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21017 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21019 int hpos, vpos, pos, i, dx, dy, area;
21020 struct glyph *glyph;
21021 Lisp_Object object;
21022 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21023 Lisp_Object *overlay_vec = NULL;
21024 int noverlays;
21025 struct buffer *obuf;
21026 int obegv, ozv, same_region;
21028 /* Find the glyph under X/Y. */
21029 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21031 /* Look for :pointer property on image. */
21032 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21034 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21035 if (img != NULL && IMAGEP (img->spec))
21037 Lisp_Object image_map, hotspot;
21038 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21039 !NILP (image_map))
21040 && (hotspot = find_hot_spot (image_map,
21041 glyph->slice.x + dx,
21042 glyph->slice.y + dy),
21043 CONSP (hotspot))
21044 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21046 Lisp_Object area_id, plist;
21048 area_id = XCAR (hotspot);
21049 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21050 If so, we could look for mouse-enter, mouse-leave
21051 properties in PLIST (and do something...). */
21052 if ((plist = XCDR (hotspot), CONSP (plist)))
21054 pointer = Fplist_get (plist, Qpointer);
21055 if (NILP (pointer))
21056 pointer = Qhand;
21057 help_echo_string = Fplist_get (plist, Qhelp_echo);
21058 if (!NILP (help_echo_string))
21060 help_echo_window = window;
21061 help_echo_object = glyph->object;
21062 help_echo_pos = glyph->charpos;
21066 if (NILP (pointer))
21067 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21071 /* Clear mouse face if X/Y not over text. */
21072 if (glyph == NULL
21073 || area != TEXT_AREA
21074 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21076 if (clear_mouse_face (dpyinfo))
21077 cursor = No_Cursor;
21078 if (NILP (pointer))
21080 if (area != TEXT_AREA)
21081 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21082 else
21083 pointer = Vvoid_text_area_pointer;
21085 goto set_cursor;
21088 pos = glyph->charpos;
21089 object = glyph->object;
21090 if (!STRINGP (object) && !BUFFERP (object))
21091 goto set_cursor;
21093 /* If we get an out-of-range value, return now; avoid an error. */
21094 if (BUFFERP (object) && pos > BUF_Z (b))
21095 goto set_cursor;
21097 /* Make the window's buffer temporarily current for
21098 overlays_at and compute_char_face. */
21099 obuf = current_buffer;
21100 current_buffer = b;
21101 obegv = BEGV;
21102 ozv = ZV;
21103 BEGV = BEG;
21104 ZV = Z;
21106 /* Is this char mouse-active or does it have help-echo? */
21107 position = make_number (pos);
21109 if (BUFFERP (object))
21111 /* Put all the overlays we want in a vector in overlay_vec. */
21112 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21113 /* Sort overlays into increasing priority order. */
21114 noverlays = sort_overlays (overlay_vec, noverlays, w);
21116 else
21117 noverlays = 0;
21119 same_region = (EQ (window, dpyinfo->mouse_face_window)
21120 && vpos >= dpyinfo->mouse_face_beg_row
21121 && vpos <= dpyinfo->mouse_face_end_row
21122 && (vpos > dpyinfo->mouse_face_beg_row
21123 || hpos >= dpyinfo->mouse_face_beg_col)
21124 && (vpos < dpyinfo->mouse_face_end_row
21125 || hpos < dpyinfo->mouse_face_end_col
21126 || dpyinfo->mouse_face_past_end));
21128 if (same_region)
21129 cursor = No_Cursor;
21131 /* Check mouse-face highlighting. */
21132 if (! same_region
21133 /* If there exists an overlay with mouse-face overlapping
21134 the one we are currently highlighting, we have to
21135 check if we enter the overlapping overlay, and then
21136 highlight only that. */
21137 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21138 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21140 /* Find the highest priority overlay that has a mouse-face
21141 property. */
21142 overlay = Qnil;
21143 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21145 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21146 if (!NILP (mouse_face))
21147 overlay = overlay_vec[i];
21150 /* If we're actually highlighting the same overlay as
21151 before, there's no need to do that again. */
21152 if (!NILP (overlay)
21153 && EQ (overlay, dpyinfo->mouse_face_overlay))
21154 goto check_help_echo;
21156 dpyinfo->mouse_face_overlay = overlay;
21158 /* Clear the display of the old active region, if any. */
21159 if (clear_mouse_face (dpyinfo))
21160 cursor = No_Cursor;
21162 /* If no overlay applies, get a text property. */
21163 if (NILP (overlay))
21164 mouse_face = Fget_text_property (position, Qmouse_face, object);
21166 /* Handle the overlay case. */
21167 if (!NILP (overlay))
21169 /* Find the range of text around this char that
21170 should be active. */
21171 Lisp_Object before, after;
21172 int ignore;
21174 before = Foverlay_start (overlay);
21175 after = Foverlay_end (overlay);
21176 /* Record this as the current active region. */
21177 fast_find_position (w, XFASTINT (before),
21178 &dpyinfo->mouse_face_beg_col,
21179 &dpyinfo->mouse_face_beg_row,
21180 &dpyinfo->mouse_face_beg_x,
21181 &dpyinfo->mouse_face_beg_y, Qnil);
21183 dpyinfo->mouse_face_past_end
21184 = !fast_find_position (w, XFASTINT (after),
21185 &dpyinfo->mouse_face_end_col,
21186 &dpyinfo->mouse_face_end_row,
21187 &dpyinfo->mouse_face_end_x,
21188 &dpyinfo->mouse_face_end_y, Qnil);
21189 dpyinfo->mouse_face_window = window;
21191 dpyinfo->mouse_face_face_id
21192 = face_at_buffer_position (w, pos, 0, 0,
21193 &ignore, pos + 1,
21194 !dpyinfo->mouse_face_hidden);
21196 /* Display it as active. */
21197 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21198 cursor = No_Cursor;
21200 /* Handle the text property case. */
21201 else if (!NILP (mouse_face) && BUFFERP (object))
21203 /* Find the range of text around this char that
21204 should be active. */
21205 Lisp_Object before, after, beginning, end;
21206 int ignore;
21208 beginning = Fmarker_position (w->start);
21209 end = make_number (BUF_Z (XBUFFER (object))
21210 - XFASTINT (w->window_end_pos));
21211 before
21212 = Fprevious_single_property_change (make_number (pos + 1),
21213 Qmouse_face,
21214 object, beginning);
21215 after
21216 = Fnext_single_property_change (position, Qmouse_face,
21217 object, end);
21219 /* Record this as the current active region. */
21220 fast_find_position (w, XFASTINT (before),
21221 &dpyinfo->mouse_face_beg_col,
21222 &dpyinfo->mouse_face_beg_row,
21223 &dpyinfo->mouse_face_beg_x,
21224 &dpyinfo->mouse_face_beg_y, Qnil);
21225 dpyinfo->mouse_face_past_end
21226 = !fast_find_position (w, XFASTINT (after),
21227 &dpyinfo->mouse_face_end_col,
21228 &dpyinfo->mouse_face_end_row,
21229 &dpyinfo->mouse_face_end_x,
21230 &dpyinfo->mouse_face_end_y, Qnil);
21231 dpyinfo->mouse_face_window = window;
21233 if (BUFFERP (object))
21234 dpyinfo->mouse_face_face_id
21235 = face_at_buffer_position (w, pos, 0, 0,
21236 &ignore, pos + 1,
21237 !dpyinfo->mouse_face_hidden);
21239 /* Display it as active. */
21240 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21241 cursor = No_Cursor;
21243 else if (!NILP (mouse_face) && STRINGP (object))
21245 Lisp_Object b, e;
21246 int ignore;
21248 b = Fprevious_single_property_change (make_number (pos + 1),
21249 Qmouse_face,
21250 object, Qnil);
21251 e = Fnext_single_property_change (position, Qmouse_face,
21252 object, Qnil);
21253 if (NILP (b))
21254 b = make_number (0);
21255 if (NILP (e))
21256 e = make_number (SCHARS (object) - 1);
21257 fast_find_string_pos (w, XINT (b), object,
21258 &dpyinfo->mouse_face_beg_col,
21259 &dpyinfo->mouse_face_beg_row,
21260 &dpyinfo->mouse_face_beg_x,
21261 &dpyinfo->mouse_face_beg_y, 0);
21262 fast_find_string_pos (w, XINT (e), object,
21263 &dpyinfo->mouse_face_end_col,
21264 &dpyinfo->mouse_face_end_row,
21265 &dpyinfo->mouse_face_end_x,
21266 &dpyinfo->mouse_face_end_y, 1);
21267 dpyinfo->mouse_face_past_end = 0;
21268 dpyinfo->mouse_face_window = window;
21269 dpyinfo->mouse_face_face_id
21270 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21271 glyph->face_id, 1);
21272 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21273 cursor = No_Cursor;
21275 else if (STRINGP (object) && NILP (mouse_face))
21277 /* A string which doesn't have mouse-face, but
21278 the text ``under'' it might have. */
21279 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21280 int start = MATRIX_ROW_START_CHARPOS (r);
21282 pos = string_buffer_position (w, object, start);
21283 if (pos > 0)
21284 mouse_face = get_char_property_and_overlay (make_number (pos),
21285 Qmouse_face,
21286 w->buffer,
21287 &overlay);
21288 if (!NILP (mouse_face) && !NILP (overlay))
21290 Lisp_Object before = Foverlay_start (overlay);
21291 Lisp_Object after = Foverlay_end (overlay);
21292 int ignore;
21294 /* Note that we might not be able to find position
21295 BEFORE in the glyph matrix if the overlay is
21296 entirely covered by a `display' property. In
21297 this case, we overshoot. So let's stop in
21298 the glyph matrix before glyphs for OBJECT. */
21299 fast_find_position (w, XFASTINT (before),
21300 &dpyinfo->mouse_face_beg_col,
21301 &dpyinfo->mouse_face_beg_row,
21302 &dpyinfo->mouse_face_beg_x,
21303 &dpyinfo->mouse_face_beg_y,
21304 object);
21306 dpyinfo->mouse_face_past_end
21307 = !fast_find_position (w, XFASTINT (after),
21308 &dpyinfo->mouse_face_end_col,
21309 &dpyinfo->mouse_face_end_row,
21310 &dpyinfo->mouse_face_end_x,
21311 &dpyinfo->mouse_face_end_y,
21312 Qnil);
21313 dpyinfo->mouse_face_window = window;
21314 dpyinfo->mouse_face_face_id
21315 = face_at_buffer_position (w, pos, 0, 0,
21316 &ignore, pos + 1,
21317 !dpyinfo->mouse_face_hidden);
21319 /* Display it as active. */
21320 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21321 cursor = No_Cursor;
21326 check_help_echo:
21328 /* Look for a `help-echo' property. */
21329 if (NILP (help_echo_string)) {
21330 Lisp_Object help, overlay;
21332 /* Check overlays first. */
21333 help = overlay = Qnil;
21334 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21336 overlay = overlay_vec[i];
21337 help = Foverlay_get (overlay, Qhelp_echo);
21340 if (!NILP (help))
21342 help_echo_string = help;
21343 help_echo_window = window;
21344 help_echo_object = overlay;
21345 help_echo_pos = pos;
21347 else
21349 Lisp_Object object = glyph->object;
21350 int charpos = glyph->charpos;
21352 /* Try text properties. */
21353 if (STRINGP (object)
21354 && charpos >= 0
21355 && charpos < SCHARS (object))
21357 help = Fget_text_property (make_number (charpos),
21358 Qhelp_echo, object);
21359 if (NILP (help))
21361 /* If the string itself doesn't specify a help-echo,
21362 see if the buffer text ``under'' it does. */
21363 struct glyph_row *r
21364 = MATRIX_ROW (w->current_matrix, vpos);
21365 int start = MATRIX_ROW_START_CHARPOS (r);
21366 int pos = string_buffer_position (w, object, start);
21367 if (pos > 0)
21369 help = Fget_char_property (make_number (pos),
21370 Qhelp_echo, w->buffer);
21371 if (!NILP (help))
21373 charpos = pos;
21374 object = w->buffer;
21379 else if (BUFFERP (object)
21380 && charpos >= BEGV
21381 && charpos < ZV)
21382 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21383 object);
21385 if (!NILP (help))
21387 help_echo_string = help;
21388 help_echo_window = window;
21389 help_echo_object = object;
21390 help_echo_pos = charpos;
21395 /* Look for a `pointer' property. */
21396 if (NILP (pointer))
21398 /* Check overlays first. */
21399 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21400 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21402 if (NILP (pointer))
21404 Lisp_Object object = glyph->object;
21405 int charpos = glyph->charpos;
21407 /* Try text properties. */
21408 if (STRINGP (object)
21409 && charpos >= 0
21410 && charpos < SCHARS (object))
21412 pointer = Fget_text_property (make_number (charpos),
21413 Qpointer, object);
21414 if (NILP (pointer))
21416 /* If the string itself doesn't specify a pointer,
21417 see if the buffer text ``under'' it does. */
21418 struct glyph_row *r
21419 = MATRIX_ROW (w->current_matrix, vpos);
21420 int start = MATRIX_ROW_START_CHARPOS (r);
21421 int pos = string_buffer_position (w, object, start);
21422 if (pos > 0)
21423 pointer = Fget_char_property (make_number (pos),
21424 Qpointer, w->buffer);
21427 else if (BUFFERP (object)
21428 && charpos >= BEGV
21429 && charpos < ZV)
21430 pointer = Fget_text_property (make_number (charpos),
21431 Qpointer, object);
21435 BEGV = obegv;
21436 ZV = ozv;
21437 current_buffer = obuf;
21440 set_cursor:
21442 define_frame_cursor1 (f, cursor, pointer);
21446 /* EXPORT for RIF:
21447 Clear any mouse-face on window W. This function is part of the
21448 redisplay interface, and is called from try_window_id and similar
21449 functions to ensure the mouse-highlight is off. */
21451 void
21452 x_clear_window_mouse_face (w)
21453 struct window *w;
21455 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21456 Lisp_Object window;
21458 BLOCK_INPUT;
21459 XSETWINDOW (window, w);
21460 if (EQ (window, dpyinfo->mouse_face_window))
21461 clear_mouse_face (dpyinfo);
21462 UNBLOCK_INPUT;
21466 /* EXPORT:
21467 Just discard the mouse face information for frame F, if any.
21468 This is used when the size of F is changed. */
21470 void
21471 cancel_mouse_face (f)
21472 struct frame *f;
21474 Lisp_Object window;
21475 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21477 window = dpyinfo->mouse_face_window;
21478 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21480 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21481 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21482 dpyinfo->mouse_face_window = Qnil;
21487 #endif /* HAVE_WINDOW_SYSTEM */
21490 /***********************************************************************
21491 Exposure Events
21492 ***********************************************************************/
21494 #ifdef HAVE_WINDOW_SYSTEM
21496 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21497 which intersects rectangle R. R is in window-relative coordinates. */
21499 static void
21500 expose_area (w, row, r, area)
21501 struct window *w;
21502 struct glyph_row *row;
21503 XRectangle *r;
21504 enum glyph_row_area area;
21506 struct glyph *first = row->glyphs[area];
21507 struct glyph *end = row->glyphs[area] + row->used[area];
21508 struct glyph *last;
21509 int first_x, start_x, x;
21511 if (area == TEXT_AREA && row->fill_line_p)
21512 /* If row extends face to end of line write the whole line. */
21513 draw_glyphs (w, 0, row, area,
21514 0, row->used[area],
21515 DRAW_NORMAL_TEXT, 0);
21516 else
21518 /* Set START_X to the window-relative start position for drawing glyphs of
21519 AREA. The first glyph of the text area can be partially visible.
21520 The first glyphs of other areas cannot. */
21521 start_x = window_box_left_offset (w, area);
21522 x = start_x;
21523 if (area == TEXT_AREA)
21524 x += row->x;
21526 /* Find the first glyph that must be redrawn. */
21527 while (first < end
21528 && x + first->pixel_width < r->x)
21530 x += first->pixel_width;
21531 ++first;
21534 /* Find the last one. */
21535 last = first;
21536 first_x = x;
21537 while (last < end
21538 && x < r->x + r->width)
21540 x += last->pixel_width;
21541 ++last;
21544 /* Repaint. */
21545 if (last > first)
21546 draw_glyphs (w, first_x - start_x, row, area,
21547 first - row->glyphs[area], last - row->glyphs[area],
21548 DRAW_NORMAL_TEXT, 0);
21553 /* Redraw the parts of the glyph row ROW on window W intersecting
21554 rectangle R. R is in window-relative coordinates. Value is
21555 non-zero if mouse-face was overwritten. */
21557 static int
21558 expose_line (w, row, r)
21559 struct window *w;
21560 struct glyph_row *row;
21561 XRectangle *r;
21563 xassert (row->enabled_p);
21565 if (row->mode_line_p || w->pseudo_window_p)
21566 draw_glyphs (w, 0, row, TEXT_AREA,
21567 0, row->used[TEXT_AREA],
21568 DRAW_NORMAL_TEXT, 0);
21569 else
21571 if (row->used[LEFT_MARGIN_AREA])
21572 expose_area (w, row, r, LEFT_MARGIN_AREA);
21573 if (row->used[TEXT_AREA])
21574 expose_area (w, row, r, TEXT_AREA);
21575 if (row->used[RIGHT_MARGIN_AREA])
21576 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21577 draw_row_fringe_bitmaps (w, row);
21580 return row->mouse_face_p;
21584 /* Redraw those parts of glyphs rows during expose event handling that
21585 overlap other rows. Redrawing of an exposed line writes over parts
21586 of lines overlapping that exposed line; this function fixes that.
21588 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21589 row in W's current matrix that is exposed and overlaps other rows.
21590 LAST_OVERLAPPING_ROW is the last such row. */
21592 static void
21593 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21594 struct window *w;
21595 struct glyph_row *first_overlapping_row;
21596 struct glyph_row *last_overlapping_row;
21598 struct glyph_row *row;
21600 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21601 if (row->overlapping_p)
21603 xassert (row->enabled_p && !row->mode_line_p);
21605 if (row->used[LEFT_MARGIN_AREA])
21606 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21608 if (row->used[TEXT_AREA])
21609 x_fix_overlapping_area (w, row, TEXT_AREA);
21611 if (row->used[RIGHT_MARGIN_AREA])
21612 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21617 /* Return non-zero if W's cursor intersects rectangle R. */
21619 static int
21620 phys_cursor_in_rect_p (w, r)
21621 struct window *w;
21622 XRectangle *r;
21624 XRectangle cr, result;
21625 struct glyph *cursor_glyph;
21627 cursor_glyph = get_phys_cursor_glyph (w);
21628 if (cursor_glyph)
21630 /* r is relative to W's box, but w->phys_cursor.x is relative
21631 to left edge of W's TEXT area. Adjust it. */
21632 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21633 cr.y = w->phys_cursor.y;
21634 cr.width = cursor_glyph->pixel_width;
21635 cr.height = w->phys_cursor_height;
21636 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21637 I assume the effect is the same -- and this is portable. */
21638 return x_intersect_rectangles (&cr, r, &result);
21640 else
21641 return 0;
21645 /* EXPORT:
21646 Draw a vertical window border to the right of window W if W doesn't
21647 have vertical scroll bars. */
21649 void
21650 x_draw_vertical_border (w)
21651 struct window *w;
21653 /* We could do better, if we knew what type of scroll-bar the adjacent
21654 windows (on either side) have... But we don't :-(
21655 However, I think this works ok. ++KFS 2003-04-25 */
21657 /* Redraw borders between horizontally adjacent windows. Don't
21658 do it for frames with vertical scroll bars because either the
21659 right scroll bar of a window, or the left scroll bar of its
21660 neighbor will suffice as a border. */
21661 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
21662 return;
21664 if (!WINDOW_RIGHTMOST_P (w)
21665 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21667 int x0, x1, y0, y1;
21669 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21670 y1 -= 1;
21672 rif->draw_vertical_window_border (w, x1, y0, y1);
21674 else if (!WINDOW_LEFTMOST_P (w)
21675 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21677 int x0, x1, y0, y1;
21679 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21680 y1 -= 1;
21682 rif->draw_vertical_window_border (w, x0, y0, y1);
21687 /* Redraw the part of window W intersection rectangle FR. Pixel
21688 coordinates in FR are frame-relative. Call this function with
21689 input blocked. Value is non-zero if the exposure overwrites
21690 mouse-face. */
21692 static int
21693 expose_window (w, fr)
21694 struct window *w;
21695 XRectangle *fr;
21697 struct frame *f = XFRAME (w->frame);
21698 XRectangle wr, r;
21699 int mouse_face_overwritten_p = 0;
21701 /* If window is not yet fully initialized, do nothing. This can
21702 happen when toolkit scroll bars are used and a window is split.
21703 Reconfiguring the scroll bar will generate an expose for a newly
21704 created window. */
21705 if (w->current_matrix == NULL)
21706 return 0;
21708 /* When we're currently updating the window, display and current
21709 matrix usually don't agree. Arrange for a thorough display
21710 later. */
21711 if (w == updated_window)
21713 SET_FRAME_GARBAGED (f);
21714 return 0;
21717 /* Frame-relative pixel rectangle of W. */
21718 wr.x = WINDOW_LEFT_EDGE_X (w);
21719 wr.y = WINDOW_TOP_EDGE_Y (w);
21720 wr.width = WINDOW_TOTAL_WIDTH (w);
21721 wr.height = WINDOW_TOTAL_HEIGHT (w);
21723 if (x_intersect_rectangles (fr, &wr, &r))
21725 int yb = window_text_bottom_y (w);
21726 struct glyph_row *row;
21727 int cursor_cleared_p;
21728 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21730 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21731 r.x, r.y, r.width, r.height));
21733 /* Convert to window coordinates. */
21734 r.x -= WINDOW_LEFT_EDGE_X (w);
21735 r.y -= WINDOW_TOP_EDGE_Y (w);
21737 /* Turn off the cursor. */
21738 if (!w->pseudo_window_p
21739 && phys_cursor_in_rect_p (w, &r))
21741 x_clear_cursor (w);
21742 cursor_cleared_p = 1;
21744 else
21745 cursor_cleared_p = 0;
21747 /* Update lines intersecting rectangle R. */
21748 first_overlapping_row = last_overlapping_row = NULL;
21749 for (row = w->current_matrix->rows;
21750 row->enabled_p;
21751 ++row)
21753 int y0 = row->y;
21754 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21756 if ((y0 >= r.y && y0 < r.y + r.height)
21757 || (y1 > r.y && y1 < r.y + r.height)
21758 || (r.y >= y0 && r.y < y1)
21759 || (r.y + r.height > y0 && r.y + r.height < y1))
21761 if (row->overlapping_p)
21763 if (first_overlapping_row == NULL)
21764 first_overlapping_row = row;
21765 last_overlapping_row = row;
21768 if (expose_line (w, row, &r))
21769 mouse_face_overwritten_p = 1;
21772 if (y1 >= yb)
21773 break;
21776 /* Display the mode line if there is one. */
21777 if (WINDOW_WANTS_MODELINE_P (w)
21778 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21779 row->enabled_p)
21780 && row->y < r.y + r.height)
21782 if (expose_line (w, row, &r))
21783 mouse_face_overwritten_p = 1;
21786 if (!w->pseudo_window_p)
21788 /* Fix the display of overlapping rows. */
21789 if (first_overlapping_row)
21790 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21792 /* Draw border between windows. */
21793 x_draw_vertical_border (w);
21795 /* Turn the cursor on again. */
21796 if (cursor_cleared_p)
21797 update_window_cursor (w, 1);
21801 #ifdef HAVE_CARBON
21802 /* Display scroll bar for this window. */
21803 if (!NILP (w->vertical_scroll_bar))
21805 /* ++KFS:
21806 If this doesn't work here (maybe some header files are missing),
21807 make a function in macterm.c and call it to do the job! */
21808 ControlHandle ch
21809 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21811 Draw1Control (ch);
21813 #endif
21815 return mouse_face_overwritten_p;
21820 /* Redraw (parts) of all windows in the window tree rooted at W that
21821 intersect R. R contains frame pixel coordinates. Value is
21822 non-zero if the exposure overwrites mouse-face. */
21824 static int
21825 expose_window_tree (w, r)
21826 struct window *w;
21827 XRectangle *r;
21829 struct frame *f = XFRAME (w->frame);
21830 int mouse_face_overwritten_p = 0;
21832 while (w && !FRAME_GARBAGED_P (f))
21834 if (!NILP (w->hchild))
21835 mouse_face_overwritten_p
21836 |= expose_window_tree (XWINDOW (w->hchild), r);
21837 else if (!NILP (w->vchild))
21838 mouse_face_overwritten_p
21839 |= expose_window_tree (XWINDOW (w->vchild), r);
21840 else
21841 mouse_face_overwritten_p |= expose_window (w, r);
21843 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21846 return mouse_face_overwritten_p;
21850 /* EXPORT:
21851 Redisplay an exposed area of frame F. X and Y are the upper-left
21852 corner of the exposed rectangle. W and H are width and height of
21853 the exposed area. All are pixel values. W or H zero means redraw
21854 the entire frame. */
21856 void
21857 expose_frame (f, x, y, w, h)
21858 struct frame *f;
21859 int x, y, w, h;
21861 XRectangle r;
21862 int mouse_face_overwritten_p = 0;
21864 TRACE ((stderr, "expose_frame "));
21866 /* No need to redraw if frame will be redrawn soon. */
21867 if (FRAME_GARBAGED_P (f))
21869 TRACE ((stderr, " garbaged\n"));
21870 return;
21873 #ifdef HAVE_CARBON
21874 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21875 or deactivated here, for unknown reasons, activated scroll bars
21876 are shown in deactivated frames in some instances. */
21877 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21878 activate_scroll_bars (f);
21879 else
21880 deactivate_scroll_bars (f);
21881 #endif
21883 /* If basic faces haven't been realized yet, there is no point in
21884 trying to redraw anything. This can happen when we get an expose
21885 event while Emacs is starting, e.g. by moving another window. */
21886 if (FRAME_FACE_CACHE (f) == NULL
21887 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21889 TRACE ((stderr, " no faces\n"));
21890 return;
21893 if (w == 0 || h == 0)
21895 r.x = r.y = 0;
21896 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21897 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21899 else
21901 r.x = x;
21902 r.y = y;
21903 r.width = w;
21904 r.height = h;
21907 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21908 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21910 if (WINDOWP (f->tool_bar_window))
21911 mouse_face_overwritten_p
21912 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21914 #ifdef HAVE_X_WINDOWS
21915 #ifndef MSDOS
21916 #ifndef USE_X_TOOLKIT
21917 if (WINDOWP (f->menu_bar_window))
21918 mouse_face_overwritten_p
21919 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21920 #endif /* not USE_X_TOOLKIT */
21921 #endif
21922 #endif
21924 /* Some window managers support a focus-follows-mouse style with
21925 delayed raising of frames. Imagine a partially obscured frame,
21926 and moving the mouse into partially obscured mouse-face on that
21927 frame. The visible part of the mouse-face will be highlighted,
21928 then the WM raises the obscured frame. With at least one WM, KDE
21929 2.1, Emacs is not getting any event for the raising of the frame
21930 (even tried with SubstructureRedirectMask), only Expose events.
21931 These expose events will draw text normally, i.e. not
21932 highlighted. Which means we must redo the highlight here.
21933 Subsume it under ``we love X''. --gerd 2001-08-15 */
21934 /* Included in Windows version because Windows most likely does not
21935 do the right thing if any third party tool offers
21936 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21937 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21939 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21940 if (f == dpyinfo->mouse_face_mouse_frame)
21942 int x = dpyinfo->mouse_face_mouse_x;
21943 int y = dpyinfo->mouse_face_mouse_y;
21944 clear_mouse_face (dpyinfo);
21945 note_mouse_highlight (f, x, y);
21951 /* EXPORT:
21952 Determine the intersection of two rectangles R1 and R2. Return
21953 the intersection in *RESULT. Value is non-zero if RESULT is not
21954 empty. */
21957 x_intersect_rectangles (r1, r2, result)
21958 XRectangle *r1, *r2, *result;
21960 XRectangle *left, *right;
21961 XRectangle *upper, *lower;
21962 int intersection_p = 0;
21964 /* Rearrange so that R1 is the left-most rectangle. */
21965 if (r1->x < r2->x)
21966 left = r1, right = r2;
21967 else
21968 left = r2, right = r1;
21970 /* X0 of the intersection is right.x0, if this is inside R1,
21971 otherwise there is no intersection. */
21972 if (right->x <= left->x + left->width)
21974 result->x = right->x;
21976 /* The right end of the intersection is the minimum of the
21977 the right ends of left and right. */
21978 result->width = (min (left->x + left->width, right->x + right->width)
21979 - result->x);
21981 /* Same game for Y. */
21982 if (r1->y < r2->y)
21983 upper = r1, lower = r2;
21984 else
21985 upper = r2, lower = r1;
21987 /* The upper end of the intersection is lower.y0, if this is inside
21988 of upper. Otherwise, there is no intersection. */
21989 if (lower->y <= upper->y + upper->height)
21991 result->y = lower->y;
21993 /* The lower end of the intersection is the minimum of the lower
21994 ends of upper and lower. */
21995 result->height = (min (lower->y + lower->height,
21996 upper->y + upper->height)
21997 - result->y);
21998 intersection_p = 1;
22002 return intersection_p;
22005 #endif /* HAVE_WINDOW_SYSTEM */
22008 /***********************************************************************
22009 Initialization
22010 ***********************************************************************/
22012 void
22013 syms_of_xdisp ()
22015 Vwith_echo_area_save_vector = Qnil;
22016 staticpro (&Vwith_echo_area_save_vector);
22018 Vmessage_stack = Qnil;
22019 staticpro (&Vmessage_stack);
22021 Qinhibit_redisplay = intern ("inhibit-redisplay");
22022 staticpro (&Qinhibit_redisplay);
22024 message_dolog_marker1 = Fmake_marker ();
22025 staticpro (&message_dolog_marker1);
22026 message_dolog_marker2 = Fmake_marker ();
22027 staticpro (&message_dolog_marker2);
22028 message_dolog_marker3 = Fmake_marker ();
22029 staticpro (&message_dolog_marker3);
22031 #if GLYPH_DEBUG
22032 defsubr (&Sdump_frame_glyph_matrix);
22033 defsubr (&Sdump_glyph_matrix);
22034 defsubr (&Sdump_glyph_row);
22035 defsubr (&Sdump_tool_bar_row);
22036 defsubr (&Strace_redisplay);
22037 defsubr (&Strace_to_stderr);
22038 #endif
22039 #ifdef HAVE_WINDOW_SYSTEM
22040 defsubr (&Stool_bar_lines_needed);
22041 defsubr (&Slookup_image_map);
22042 #endif
22043 defsubr (&Sformat_mode_line);
22045 staticpro (&Qmenu_bar_update_hook);
22046 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22048 staticpro (&Qoverriding_terminal_local_map);
22049 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22051 staticpro (&Qoverriding_local_map);
22052 Qoverriding_local_map = intern ("overriding-local-map");
22054 staticpro (&Qwindow_scroll_functions);
22055 Qwindow_scroll_functions = intern ("window-scroll-functions");
22057 staticpro (&Qredisplay_end_trigger_functions);
22058 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22060 staticpro (&Qinhibit_point_motion_hooks);
22061 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22063 QCdata = intern (":data");
22064 staticpro (&QCdata);
22065 Qdisplay = intern ("display");
22066 staticpro (&Qdisplay);
22067 Qspace_width = intern ("space-width");
22068 staticpro (&Qspace_width);
22069 Qraise = intern ("raise");
22070 staticpro (&Qraise);
22071 Qslice = intern ("slice");
22072 staticpro (&Qslice);
22073 Qspace = intern ("space");
22074 staticpro (&Qspace);
22075 Qmargin = intern ("margin");
22076 staticpro (&Qmargin);
22077 Qpointer = intern ("pointer");
22078 staticpro (&Qpointer);
22079 Qleft_margin = intern ("left-margin");
22080 staticpro (&Qleft_margin);
22081 Qright_margin = intern ("right-margin");
22082 staticpro (&Qright_margin);
22083 Qcenter = intern ("center");
22084 staticpro (&Qcenter);
22085 Qline_height = intern ("line-height");
22086 staticpro (&Qline_height);
22087 Qtotal = intern ("total");
22088 staticpro (&Qtotal);
22089 QCalign_to = intern (":align-to");
22090 staticpro (&QCalign_to);
22091 QCrelative_width = intern (":relative-width");
22092 staticpro (&QCrelative_width);
22093 QCrelative_height = intern (":relative-height");
22094 staticpro (&QCrelative_height);
22095 QCeval = intern (":eval");
22096 staticpro (&QCeval);
22097 QCpropertize = intern (":propertize");
22098 staticpro (&QCpropertize);
22099 QCfile = intern (":file");
22100 staticpro (&QCfile);
22101 Qfontified = intern ("fontified");
22102 staticpro (&Qfontified);
22103 Qfontification_functions = intern ("fontification-functions");
22104 staticpro (&Qfontification_functions);
22105 Qtrailing_whitespace = intern ("trailing-whitespace");
22106 staticpro (&Qtrailing_whitespace);
22107 Qimage = intern ("image");
22108 staticpro (&Qimage);
22109 QCmap = intern (":map");
22110 staticpro (&QCmap);
22111 QCpointer = intern (":pointer");
22112 staticpro (&QCpointer);
22113 Qrect = intern ("rect");
22114 staticpro (&Qrect);
22115 Qcircle = intern ("circle");
22116 staticpro (&Qcircle);
22117 Qpoly = intern ("poly");
22118 staticpro (&Qpoly);
22119 Qmessage_truncate_lines = intern ("message-truncate-lines");
22120 staticpro (&Qmessage_truncate_lines);
22121 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22122 staticpro (&Qcursor_in_non_selected_windows);
22123 Qgrow_only = intern ("grow-only");
22124 staticpro (&Qgrow_only);
22125 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22126 staticpro (&Qinhibit_menubar_update);
22127 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22128 staticpro (&Qinhibit_eval_during_redisplay);
22129 Qposition = intern ("position");
22130 staticpro (&Qposition);
22131 Qbuffer_position = intern ("buffer-position");
22132 staticpro (&Qbuffer_position);
22133 Qobject = intern ("object");
22134 staticpro (&Qobject);
22135 Qbar = intern ("bar");
22136 staticpro (&Qbar);
22137 Qhbar = intern ("hbar");
22138 staticpro (&Qhbar);
22139 Qbox = intern ("box");
22140 staticpro (&Qbox);
22141 Qhollow = intern ("hollow");
22142 staticpro (&Qhollow);
22143 Qhand = intern ("hand");
22144 staticpro (&Qhand);
22145 Qarrow = intern ("arrow");
22146 staticpro (&Qarrow);
22147 Qtext = intern ("text");
22148 staticpro (&Qtext);
22149 Qrisky_local_variable = intern ("risky-local-variable");
22150 staticpro (&Qrisky_local_variable);
22151 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22152 staticpro (&Qinhibit_free_realized_faces);
22154 list_of_error = Fcons (Fcons (intern ("error"),
22155 Fcons (intern ("void-variable"), Qnil)),
22156 Qnil);
22157 staticpro (&list_of_error);
22159 Qlast_arrow_position = intern ("last-arrow-position");
22160 staticpro (&Qlast_arrow_position);
22161 Qlast_arrow_string = intern ("last-arrow-string");
22162 staticpro (&Qlast_arrow_string);
22164 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22165 staticpro (&Qoverlay_arrow_string);
22166 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22167 staticpro (&Qoverlay_arrow_bitmap);
22169 echo_buffer[0] = echo_buffer[1] = Qnil;
22170 staticpro (&echo_buffer[0]);
22171 staticpro (&echo_buffer[1]);
22173 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22174 staticpro (&echo_area_buffer[0]);
22175 staticpro (&echo_area_buffer[1]);
22177 Vmessages_buffer_name = build_string ("*Messages*");
22178 staticpro (&Vmessages_buffer_name);
22180 mode_line_proptrans_alist = Qnil;
22181 staticpro (&mode_line_proptrans_alist);
22183 mode_line_string_list = Qnil;
22184 staticpro (&mode_line_string_list);
22186 help_echo_string = Qnil;
22187 staticpro (&help_echo_string);
22188 help_echo_object = Qnil;
22189 staticpro (&help_echo_object);
22190 help_echo_window = Qnil;
22191 staticpro (&help_echo_window);
22192 previous_help_echo_string = Qnil;
22193 staticpro (&previous_help_echo_string);
22194 help_echo_pos = -1;
22196 #ifdef HAVE_WINDOW_SYSTEM
22197 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22198 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22199 For example, if a block cursor is over a tab, it will be drawn as
22200 wide as that tab on the display. */);
22201 x_stretch_cursor_p = 0;
22202 #endif
22204 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22205 doc: /* *Non-nil means highlight trailing whitespace.
22206 The face used for trailing whitespace is `trailing-whitespace'. */);
22207 Vshow_trailing_whitespace = Qnil;
22209 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22210 doc: /* *The pointer shape to show in void text areas.
22211 Nil means to show the text pointer. Other options are `arrow', `text',
22212 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22213 Vvoid_text_area_pointer = Qarrow;
22215 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22216 doc: /* Non-nil means don't actually do any redisplay.
22217 This is used for internal purposes. */);
22218 Vinhibit_redisplay = Qnil;
22220 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22221 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22222 Vglobal_mode_string = Qnil;
22224 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22225 doc: /* Marker for where to display an arrow on top of the buffer text.
22226 This must be the beginning of a line in order to work.
22227 See also `overlay-arrow-string'. */);
22228 Voverlay_arrow_position = Qnil;
22230 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22231 doc: /* String to display as an arrow in non-window frames.
22232 See also `overlay-arrow-position'. */);
22233 Voverlay_arrow_string = Qnil;
22235 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22236 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22237 The symbols on this list are examined during redisplay to determine
22238 where to display overlay arrows. */);
22239 Voverlay_arrow_variable_list
22240 = Fcons (intern ("overlay-arrow-position"), Qnil);
22242 DEFVAR_INT ("scroll-step", &scroll_step,
22243 doc: /* *The number of lines to try scrolling a window by when point moves out.
22244 If that fails to bring point back on frame, point is centered instead.
22245 If this is zero, point is always centered after it moves off frame.
22246 If you want scrolling to always be a line at a time, you should set
22247 `scroll-conservatively' to a large value rather than set this to 1. */);
22249 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22250 doc: /* *Scroll up to this many lines, to bring point back on screen.
22251 A value of zero means to scroll the text to center point vertically
22252 in the window. */);
22253 scroll_conservatively = 0;
22255 DEFVAR_INT ("scroll-margin", &scroll_margin,
22256 doc: /* *Number of lines of margin at the top and bottom of a window.
22257 Recenter the window whenever point gets within this many lines
22258 of the top or bottom of the window. */);
22259 scroll_margin = 0;
22261 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22262 doc: /* Pixels per inch on current display.
22263 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22264 Vdisplay_pixels_per_inch = make_float (72.0);
22266 #if GLYPH_DEBUG
22267 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22268 #endif
22270 DEFVAR_BOOL ("truncate-partial-width-windows",
22271 &truncate_partial_width_windows,
22272 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22273 truncate_partial_width_windows = 1;
22275 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22276 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22277 Any other value means to use the appropriate face, `mode-line',
22278 `header-line', or `menu' respectively. */);
22279 mode_line_inverse_video = 1;
22281 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22282 doc: /* *Maximum buffer size for which line number should be displayed.
22283 If the buffer is bigger than this, the line number does not appear
22284 in the mode line. A value of nil means no limit. */);
22285 Vline_number_display_limit = Qnil;
22287 DEFVAR_INT ("line-number-display-limit-width",
22288 &line_number_display_limit_width,
22289 doc: /* *Maximum line width (in characters) for line number display.
22290 If the average length of the lines near point is bigger than this, then the
22291 line number may be omitted from the mode line. */);
22292 line_number_display_limit_width = 200;
22294 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22295 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22296 highlight_nonselected_windows = 0;
22298 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22299 doc: /* Non-nil if more than one frame is visible on this display.
22300 Minibuffer-only frames don't count, but iconified frames do.
22301 This variable is not guaranteed to be accurate except while processing
22302 `frame-title-format' and `icon-title-format'. */);
22304 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22305 doc: /* Template for displaying the title bar of visible frames.
22306 \(Assuming the window manager supports this feature.)
22307 This variable has the same structure as `mode-line-format' (which see),
22308 and is used only on frames for which no explicit name has been set
22309 \(see `modify-frame-parameters'). */);
22311 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22312 doc: /* Template for displaying the title bar of an iconified frame.
22313 \(Assuming the window manager supports this feature.)
22314 This variable has the same structure as `mode-line-format' (which see),
22315 and is used only on frames for which no explicit name has been set
22316 \(see `modify-frame-parameters'). */);
22317 Vicon_title_format
22318 = Vframe_title_format
22319 = Fcons (intern ("multiple-frames"),
22320 Fcons (build_string ("%b"),
22321 Fcons (Fcons (empty_string,
22322 Fcons (intern ("invocation-name"),
22323 Fcons (build_string ("@"),
22324 Fcons (intern ("system-name"),
22325 Qnil)))),
22326 Qnil)));
22328 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22329 doc: /* Maximum number of lines to keep in the message log buffer.
22330 If nil, disable message logging. If t, log messages but don't truncate
22331 the buffer when it becomes large. */);
22332 Vmessage_log_max = make_number (50);
22334 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22335 doc: /* Functions called before redisplay, if window sizes have changed.
22336 The value should be a list of functions that take one argument.
22337 Just before redisplay, for each frame, if any of its windows have changed
22338 size since the last redisplay, or have been split or deleted,
22339 all the functions in the list are called, with the frame as argument. */);
22340 Vwindow_size_change_functions = Qnil;
22342 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22343 doc: /* List of functions to call before redisplaying a window with scrolling.
22344 Each function is called with two arguments, the window
22345 and its new display-start position. Note that the value of `window-end'
22346 is not valid when these functions are called. */);
22347 Vwindow_scroll_functions = Qnil;
22349 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22350 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22351 mouse_autoselect_window = 0;
22353 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22354 doc: /* *Non-nil means automatically resize tool-bars.
22355 This increases a tool-bar's height if not all tool-bar items are visible.
22356 It decreases a tool-bar's height when it would display blank lines
22357 otherwise. */);
22358 auto_resize_tool_bars_p = 1;
22360 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22361 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22362 auto_raise_tool_bar_buttons_p = 1;
22364 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22365 doc: /* *Margin around tool-bar buttons in pixels.
22366 If an integer, use that for both horizontal and vertical margins.
22367 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22368 HORZ specifying the horizontal margin, and VERT specifying the
22369 vertical margin. */);
22370 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22372 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22373 doc: /* *Relief thickness of tool-bar buttons. */);
22374 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22376 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22377 doc: /* List of functions to call to fontify regions of text.
22378 Each function is called with one argument POS. Functions must
22379 fontify a region starting at POS in the current buffer, and give
22380 fontified regions the property `fontified'. */);
22381 Vfontification_functions = Qnil;
22382 Fmake_variable_buffer_local (Qfontification_functions);
22384 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22385 &unibyte_display_via_language_environment,
22386 doc: /* *Non-nil means display unibyte text according to language environment.
22387 Specifically this means that unibyte non-ASCII characters
22388 are displayed by converting them to the equivalent multibyte characters
22389 according to the current language environment. As a result, they are
22390 displayed according to the current fontset. */);
22391 unibyte_display_via_language_environment = 0;
22393 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22394 doc: /* *Maximum height for resizing mini-windows.
22395 If a float, it specifies a fraction of the mini-window frame's height.
22396 If an integer, it specifies a number of lines. */);
22397 Vmax_mini_window_height = make_float (0.25);
22399 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22400 doc: /* *How to resize mini-windows.
22401 A value of nil means don't automatically resize mini-windows.
22402 A value of t means resize them to fit the text displayed in them.
22403 A value of `grow-only', the default, means let mini-windows grow
22404 only, until their display becomes empty, at which point the windows
22405 go back to their normal size. */);
22406 Vresize_mini_windows = Qgrow_only;
22408 DEFVAR_LISP ("cursor-in-non-selected-windows",
22409 &Vcursor_in_non_selected_windows,
22410 doc: /* *Cursor type to display in non-selected windows.
22411 t means to use hollow box cursor. See `cursor-type' for other values. */);
22412 Vcursor_in_non_selected_windows = Qt;
22414 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22415 doc: /* Alist specifying how to blink the cursor off.
22416 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22417 `cursor-type' frame-parameter or variable equals ON-STATE,
22418 comparing using `equal', Emacs uses OFF-STATE to specify
22419 how to blink it off. */);
22420 Vblink_cursor_alist = Qnil;
22422 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22423 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22424 automatic_hscrolling_p = 1;
22426 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22427 doc: /* *How many columns away from the window edge point is allowed to get
22428 before automatic hscrolling will horizontally scroll the window. */);
22429 hscroll_margin = 5;
22431 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22432 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22433 When point is less than `automatic-hscroll-margin' columns from the window
22434 edge, automatic hscrolling will scroll the window by the amount of columns
22435 determined by this variable. If its value is a positive integer, scroll that
22436 many columns. If it's a positive floating-point number, it specifies the
22437 fraction of the window's width to scroll. If it's nil or zero, point will be
22438 centered horizontally after the scroll. Any other value, including negative
22439 numbers, are treated as if the value were zero.
22441 Automatic hscrolling always moves point outside the scroll margin, so if
22442 point was more than scroll step columns inside the margin, the window will
22443 scroll more than the value given by the scroll step.
22445 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22446 and `scroll-right' overrides this variable's effect. */);
22447 Vhscroll_step = make_number (0);
22449 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22450 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22451 Bind this around calls to `message' to let it take effect. */);
22452 message_truncate_lines = 0;
22454 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22455 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22456 Can be used to update submenus whose contents should vary. */);
22457 Vmenu_bar_update_hook = Qnil;
22459 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22460 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22461 inhibit_menubar_update = 0;
22463 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22464 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22465 inhibit_eval_during_redisplay = 0;
22467 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22468 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22469 inhibit_free_realized_faces = 0;
22471 #if GLYPH_DEBUG
22472 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22473 doc: /* Inhibit try_window_id display optimization. */);
22474 inhibit_try_window_id = 0;
22476 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22477 doc: /* Inhibit try_window_reusing display optimization. */);
22478 inhibit_try_window_reusing = 0;
22480 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22481 doc: /* Inhibit try_cursor_movement display optimization. */);
22482 inhibit_try_cursor_movement = 0;
22483 #endif /* GLYPH_DEBUG */
22487 /* Initialize this module when Emacs starts. */
22489 void
22490 init_xdisp ()
22492 Lisp_Object root_window;
22493 struct window *mini_w;
22495 current_header_line_height = current_mode_line_height = -1;
22497 CHARPOS (this_line_start_pos) = 0;
22499 mini_w = XWINDOW (minibuf_window);
22500 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22502 if (!noninteractive)
22504 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22505 int i;
22507 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22508 set_window_height (root_window,
22509 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22511 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22512 set_window_height (minibuf_window, 1, 0);
22514 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22515 mini_w->total_cols = make_number (FRAME_COLS (f));
22517 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22518 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22519 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22521 /* The default ellipsis glyphs `...'. */
22522 for (i = 0; i < 3; ++i)
22523 default_invis_vector[i] = make_number ('.');
22527 /* Allocate the buffer for frame titles.
22528 Also used for `format-mode-line'. */
22529 int size = 100;
22530 frame_title_buf = (char *) xmalloc (size);
22531 frame_title_buf_end = frame_title_buf + size;
22532 frame_title_ptr = NULL;
22535 help_echo_showing_p = 0;
22539 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22540 (do not change this comment) */