*** empty log message ***
[emacs.git] / src / xdisp.c
blob3241822e7b495da76e1c301b7c339ef1530815d0
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"
202 Cursor No_Cursor;
203 #endif
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
209 #define INFINITY 10000000
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
217 extern int interrupt_input;
218 extern int command_loop_level;
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245 /* 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 Qmargin, Qpointer;
305 extern Lisp_Object Qheight;
306 extern Lisp_Object QCwidth, QCheight, QCascent;
307 extern Lisp_Object Qscroll_bar;
309 /* Non-nil means highlight trailing whitespace. */
311 Lisp_Object Vshow_trailing_whitespace;
313 #ifdef HAVE_WINDOW_SYSTEM
314 /* Non-nil means that newline may flow into the right fringe. */
316 Lisp_Object Voverflow_newline_into_fringe;
317 #endif /* HAVE_WINDOW_SYSTEM */
319 /* Test if overflow newline into fringe. Called with iterator IT
320 at or past right window margin, and with IT->current_x set. */
322 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
323 (!NILP (Voverflow_newline_into_fringe) \
324 && FRAME_WINDOW_P (it->f) \
325 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
326 && it->current_x == it->last_visible_x)
328 /* Non-nil means show the text cursor in void text areas
329 i.e. in blank areas after eol and eob. This used to be
330 the default in 21.3. */
332 Lisp_Object Vvoid_text_area_pointer;
334 /* Name of the face used to highlight trailing whitespace. */
336 Lisp_Object Qtrailing_whitespace;
338 /* The symbol `image' which is the car of the lists used to represent
339 images in Lisp. */
341 Lisp_Object Qimage;
343 /* The image map types. */
344 Lisp_Object QCmap, QCpointer;
345 Lisp_Object Qrect, Qcircle, Qpoly;
347 /* Non-zero means print newline to stdout before next mini-buffer
348 message. */
350 int noninteractive_need_newline;
352 /* Non-zero means print newline to message log before next message. */
354 static int message_log_need_newline;
356 /* Three markers that message_dolog uses.
357 It could allocate them itself, but that causes trouble
358 in handling memory-full errors. */
359 static Lisp_Object message_dolog_marker1;
360 static Lisp_Object message_dolog_marker2;
361 static Lisp_Object message_dolog_marker3;
363 /* The buffer position of the first character appearing entirely or
364 partially on the line of the selected window which contains the
365 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
366 redisplay optimization in redisplay_internal. */
368 static struct text_pos this_line_start_pos;
370 /* Number of characters past the end of the line above, including the
371 terminating newline. */
373 static struct text_pos this_line_end_pos;
375 /* The vertical positions and the height of this line. */
377 static int this_line_vpos;
378 static int this_line_y;
379 static int this_line_pixel_height;
381 /* X position at which this display line starts. Usually zero;
382 negative if first character is partially visible. */
384 static int this_line_start_x;
386 /* Buffer that this_line_.* variables are referring to. */
388 static struct buffer *this_line_buffer;
390 /* Nonzero means truncate lines in all windows less wide than the
391 frame. */
393 int truncate_partial_width_windows;
395 /* A flag to control how to display unibyte 8-bit character. */
397 int unibyte_display_via_language_environment;
399 /* Nonzero means we have more than one non-mini-buffer-only frame.
400 Not guaranteed to be accurate except while parsing
401 frame-title-format. */
403 int multiple_frames;
405 Lisp_Object Vglobal_mode_string;
407 /* Marker for where to display an arrow on top of the buffer text. */
409 Lisp_Object Voverlay_arrow_position;
411 /* String to display for the arrow. Only used on terminal frames. */
413 Lisp_Object Voverlay_arrow_string;
415 /* Values of those variables at last redisplay. However, if
416 Voverlay_arrow_position is a marker, last_arrow_position is its
417 numerical position. */
419 static Lisp_Object last_arrow_position, last_arrow_string;
421 /* Like mode-line-format, but for the title bar on a visible frame. */
423 Lisp_Object Vframe_title_format;
425 /* Like mode-line-format, but for the title bar on an iconified frame. */
427 Lisp_Object Vicon_title_format;
429 /* List of functions to call when a window's size changes. These
430 functions get one arg, a frame on which one or more windows' sizes
431 have changed. */
433 static Lisp_Object Vwindow_size_change_functions;
435 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
437 /* Nonzero if overlay arrow has been displayed once in this window. */
439 static int overlay_arrow_seen;
441 /* Nonzero means highlight the region even in nonselected windows. */
443 int highlight_nonselected_windows;
445 /* If cursor motion alone moves point off frame, try scrolling this
446 many lines up or down if that will bring it back. */
448 static EMACS_INT scroll_step;
450 /* Nonzero means scroll just far enough to bring point back on the
451 screen, when appropriate. */
453 static EMACS_INT scroll_conservatively;
455 /* Recenter the window whenever point gets within this many lines of
456 the top or bottom of the window. This value is translated into a
457 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
458 that there is really a fixed pixel height scroll margin. */
460 EMACS_INT scroll_margin;
462 /* Number of windows showing the buffer of the selected window (or
463 another buffer with the same base buffer). keyboard.c refers to
464 this. */
466 int buffer_shared;
468 /* Vector containing glyphs for an ellipsis `...'. */
470 static Lisp_Object default_invis_vector[3];
472 /* Zero means display the mode-line/header-line/menu-bar in the default face
473 (this slightly odd definition is for compatibility with previous versions
474 of emacs), non-zero means display them using their respective faces.
476 This variable is deprecated. */
478 int mode_line_inverse_video;
480 /* Prompt to display in front of the mini-buffer contents. */
482 Lisp_Object minibuf_prompt;
484 /* Width of current mini-buffer prompt. Only set after display_line
485 of the line that contains the prompt. */
487 int minibuf_prompt_width;
489 /* This is the window where the echo area message was displayed. It
490 is always a mini-buffer window, but it may not be the same window
491 currently active as a mini-buffer. */
493 Lisp_Object echo_area_window;
495 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
496 pushes the current message and the value of
497 message_enable_multibyte on the stack, the function restore_message
498 pops the stack and displays MESSAGE again. */
500 Lisp_Object Vmessage_stack;
502 /* Nonzero means multibyte characters were enabled when the echo area
503 message was specified. */
505 int message_enable_multibyte;
507 /* Nonzero if we should redraw the mode lines on the next redisplay. */
509 int update_mode_lines;
511 /* Nonzero if window sizes or contents have changed since last
512 redisplay that finished. */
514 int windows_or_buffers_changed;
516 /* Nonzero means a frame's cursor type has been changed. */
518 int cursor_type_changed;
520 /* Nonzero after display_mode_line if %l was used and it displayed a
521 line number. */
523 int line_number_displayed;
525 /* Maximum buffer size for which to display line numbers. */
527 Lisp_Object Vline_number_display_limit;
529 /* Line width to consider when repositioning for line number display. */
531 static EMACS_INT line_number_display_limit_width;
533 /* Number of lines to keep in the message log buffer. t means
534 infinite. nil means don't log at all. */
536 Lisp_Object Vmessage_log_max;
538 /* The name of the *Messages* buffer, a string. */
540 static Lisp_Object Vmessages_buffer_name;
542 /* Current, index 0, and last displayed echo area message. Either
543 buffers from echo_buffers, or nil to indicate no message. */
545 Lisp_Object echo_area_buffer[2];
547 /* The buffers referenced from echo_area_buffer. */
549 static Lisp_Object echo_buffer[2];
551 /* A vector saved used in with_area_buffer to reduce consing. */
553 static Lisp_Object Vwith_echo_area_save_vector;
555 /* Non-zero means display_echo_area should display the last echo area
556 message again. Set by redisplay_preserve_echo_area. */
558 static int display_last_displayed_message_p;
560 /* Nonzero if echo area is being used by print; zero if being used by
561 message. */
563 int message_buf_print;
565 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
567 Lisp_Object Qinhibit_menubar_update;
568 int inhibit_menubar_update;
570 /* Maximum height for resizing mini-windows. Either a float
571 specifying a fraction of the available height, or an integer
572 specifying a number of lines. */
574 Lisp_Object Vmax_mini_window_height;
576 /* Non-zero means messages should be displayed with truncated
577 lines instead of being continued. */
579 int message_truncate_lines;
580 Lisp_Object Qmessage_truncate_lines;
582 /* Set to 1 in clear_message to make redisplay_internal aware
583 of an emptied echo area. */
585 static int message_cleared_p;
587 /* Non-zero means we want a hollow cursor in windows that are not
588 selected. Zero means there's no cursor in such windows. */
590 Lisp_Object Vcursor_in_non_selected_windows;
591 Lisp_Object Qcursor_in_non_selected_windows;
593 /* How to blink the default frame cursor off. */
594 Lisp_Object Vblink_cursor_alist;
596 /* A scratch glyph row with contents used for generating truncation
597 glyphs. Also used in direct_output_for_insert. */
599 #define MAX_SCRATCH_GLYPHS 100
600 struct glyph_row scratch_glyph_row;
601 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
603 /* Ascent and height of the last line processed by move_it_to. */
605 static int last_max_ascent, last_height;
607 /* Non-zero if there's a help-echo in the echo area. */
609 int help_echo_showing_p;
611 /* If >= 0, computed, exact values of mode-line and header-line height
612 to use in the macros CURRENT_MODE_LINE_HEIGHT and
613 CURRENT_HEADER_LINE_HEIGHT. */
615 int current_mode_line_height, current_header_line_height;
617 /* The maximum distance to look ahead for text properties. Values
618 that are too small let us call compute_char_face and similar
619 functions too often which is expensive. Values that are too large
620 let us call compute_char_face and alike too often because we
621 might not be interested in text properties that far away. */
623 #define TEXT_PROP_DISTANCE_LIMIT 100
625 #if GLYPH_DEBUG
627 /* Variables to turn off display optimizations from Lisp. */
629 int inhibit_try_window_id, inhibit_try_window_reusing;
630 int inhibit_try_cursor_movement;
632 /* Non-zero means print traces of redisplay if compiled with
633 GLYPH_DEBUG != 0. */
635 int trace_redisplay_p;
637 #endif /* GLYPH_DEBUG */
639 #ifdef DEBUG_TRACE_MOVE
640 /* Non-zero means trace with TRACE_MOVE to stderr. */
641 int trace_move;
643 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
644 #else
645 #define TRACE_MOVE(x) (void) 0
646 #endif
648 /* Non-zero means automatically scroll windows horizontally to make
649 point visible. */
651 int automatic_hscrolling_p;
653 /* How close to the margin can point get before the window is scrolled
654 horizontally. */
655 EMACS_INT hscroll_margin;
657 /* How much to scroll horizontally when point is inside the above margin. */
658 Lisp_Object Vhscroll_step;
660 /* A list of symbols, one for each supported image type. */
662 Lisp_Object Vimage_types;
664 /* The variable `resize-mini-windows'. If nil, don't resize
665 mini-windows. If t, always resize them to fit the text they
666 display. If `grow-only', let mini-windows grow only until they
667 become empty. */
669 Lisp_Object Vresize_mini_windows;
671 /* Buffer being redisplayed -- for redisplay_window_error. */
673 struct buffer *displayed_buffer;
675 /* Value returned from text property handlers (see below). */
677 enum prop_handled
679 HANDLED_NORMALLY,
680 HANDLED_RECOMPUTE_PROPS,
681 HANDLED_OVERLAY_STRING_CONSUMED,
682 HANDLED_RETURN
685 /* A description of text properties that redisplay is interested
686 in. */
688 struct props
690 /* The name of the property. */
691 Lisp_Object *name;
693 /* A unique index for the property. */
694 enum prop_idx idx;
696 /* A handler function called to set up iterator IT from the property
697 at IT's current position. Value is used to steer handle_stop. */
698 enum prop_handled (*handler) P_ ((struct it *it));
701 static enum prop_handled handle_face_prop P_ ((struct it *));
702 static enum prop_handled handle_invisible_prop P_ ((struct it *));
703 static enum prop_handled handle_display_prop P_ ((struct it *));
704 static enum prop_handled handle_composition_prop P_ ((struct it *));
705 static enum prop_handled handle_overlay_change P_ ((struct it *));
706 static enum prop_handled handle_fontified_prop P_ ((struct it *));
708 /* Properties handled by iterators. */
710 static struct props it_props[] =
712 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
713 /* Handle `face' before `display' because some sub-properties of
714 `display' need to know the face. */
715 {&Qface, FACE_PROP_IDX, handle_face_prop},
716 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
717 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
718 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
719 {NULL, 0, NULL}
722 /* Value is the position described by X. If X is a marker, value is
723 the marker_position of X. Otherwise, value is X. */
725 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
727 /* Enumeration returned by some move_it_.* functions internally. */
729 enum move_it_result
731 /* Not used. Undefined value. */
732 MOVE_UNDEFINED,
734 /* Move ended at the requested buffer position or ZV. */
735 MOVE_POS_MATCH_OR_ZV,
737 /* Move ended at the requested X pixel position. */
738 MOVE_X_REACHED,
740 /* Move within a line ended at the end of a line that must be
741 continued. */
742 MOVE_LINE_CONTINUED,
744 /* Move within a line ended at the end of a line that would
745 be displayed truncated. */
746 MOVE_LINE_TRUNCATED,
748 /* Move within a line ended at a line end. */
749 MOVE_NEWLINE_OR_CR
752 /* This counter is used to clear the face cache every once in a while
753 in redisplay_internal. It is incremented for each redisplay.
754 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
755 cleared. */
757 #define CLEAR_FACE_CACHE_COUNT 500
758 static int clear_face_cache_count;
760 /* Record the previous terminal frame we displayed. */
762 static struct frame *previous_terminal_frame;
764 /* Non-zero while redisplay_internal is in progress. */
766 int redisplaying_p;
768 /* Non-zero means don't free realized faces. Bound while freeing
769 realized faces is dangerous because glyph matrices might still
770 reference them. */
772 int inhibit_free_realized_faces;
773 Lisp_Object Qinhibit_free_realized_faces;
775 /* If a string, XTread_socket generates an event to display that string.
776 (The display is done in read_char.) */
778 Lisp_Object help_echo_string;
779 Lisp_Object help_echo_window;
780 Lisp_Object help_echo_object;
781 int help_echo_pos;
783 /* Temporary variable for XTread_socket. */
785 Lisp_Object previous_help_echo_string;
789 /* Function prototypes. */
791 static void setup_for_ellipsis P_ ((struct it *));
792 static void mark_window_display_accurate_1 P_ ((struct window *, int));
793 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
794 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
795 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
796 static int redisplay_mode_lines P_ ((Lisp_Object, int));
797 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
799 #if 0
800 static int invisible_text_between_p P_ ((struct it *, int, int));
801 #endif
803 static int next_element_from_ellipsis P_ ((struct it *));
804 static void pint2str P_ ((char *, int, int));
805 static void pint2hrstr P_ ((char *, int, int));
806 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
807 struct text_pos));
808 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
809 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
810 static void store_frame_title_char P_ ((char));
811 static int store_frame_title P_ ((const unsigned char *, int, int));
812 static void x_consider_frame_title P_ ((Lisp_Object));
813 static void handle_stop P_ ((struct it *));
814 static int tool_bar_lines_needed P_ ((struct frame *));
815 static int single_display_prop_intangible_p P_ ((Lisp_Object));
816 static void ensure_echo_area_buffers P_ ((void));
817 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
818 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
819 static int with_echo_area_buffer P_ ((struct window *, int,
820 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
821 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
822 static void clear_garbaged_frames P_ ((void));
823 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
824 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
825 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
826 static int display_echo_area P_ ((struct window *));
827 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
828 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
829 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
830 static int string_char_and_length P_ ((const unsigned char *, int, int *));
831 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
832 struct text_pos));
833 static int compute_window_start_on_continuation_line P_ ((struct window *));
834 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
835 static void insert_left_trunc_glyphs P_ ((struct it *));
836 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
837 static void extend_face_to_end_of_line P_ ((struct it *));
838 static int append_space P_ ((struct it *, int));
839 static int make_cursor_line_fully_visible P_ ((struct window *));
840 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
841 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
842 static int trailing_whitespace_p P_ ((int));
843 static int message_log_check_duplicate P_ ((int, int, int, int));
844 static void push_it P_ ((struct it *));
845 static void pop_it P_ ((struct it *));
846 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
847 static void select_frame_for_redisplay P_ ((Lisp_Object));
848 static void redisplay_internal P_ ((int));
849 static int echo_area_display P_ ((int));
850 static void redisplay_windows P_ ((Lisp_Object));
851 static void redisplay_window P_ ((Lisp_Object, int));
852 static Lisp_Object redisplay_window_error ();
853 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
854 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
855 static void update_menu_bar P_ ((struct frame *, int));
856 static int try_window_reusing_current_matrix P_ ((struct window *));
857 static int try_window_id P_ ((struct window *));
858 static int display_line P_ ((struct it *));
859 static int display_mode_lines P_ ((struct window *));
860 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
861 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
862 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
863 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
864 static void display_menu_bar P_ ((struct window *));
865 static int display_count_lines P_ ((int, int, int, int, int *));
866 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
867 int, int, struct it *, int, int, int, int));
868 static void compute_line_metrics P_ ((struct it *));
869 static void run_redisplay_end_trigger_hook P_ ((struct it *));
870 static int get_overlay_strings P_ ((struct it *, int));
871 static void next_overlay_string P_ ((struct it *));
872 static void reseat P_ ((struct it *, struct text_pos, int));
873 static void reseat_1 P_ ((struct it *, struct text_pos, int));
874 static void back_to_previous_visible_line_start P_ ((struct it *));
875 static void reseat_at_previous_visible_line_start P_ ((struct it *));
876 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
877 static int next_element_from_display_vector P_ ((struct it *));
878 static int next_element_from_string P_ ((struct it *));
879 static int next_element_from_c_string P_ ((struct it *));
880 static int next_element_from_buffer P_ ((struct it *));
881 static int next_element_from_composition P_ ((struct it *));
882 static int next_element_from_image P_ ((struct it *));
883 static int next_element_from_stretch P_ ((struct it *));
884 static void load_overlay_strings P_ ((struct it *, int));
885 static int init_from_display_pos P_ ((struct it *, struct window *,
886 struct display_pos *));
887 static void reseat_to_string P_ ((struct it *, unsigned char *,
888 Lisp_Object, int, int, int, int));
889 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
890 int, int, int));
891 void move_it_vertically_backward P_ ((struct it *, int));
892 static void init_to_row_start P_ ((struct it *, struct window *,
893 struct glyph_row *));
894 static int init_to_row_end P_ ((struct it *, struct window *,
895 struct glyph_row *));
896 static void back_to_previous_line_start P_ ((struct it *));
897 static int forward_to_next_line_start P_ ((struct it *, int *));
898 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
899 Lisp_Object, int));
900 static struct text_pos string_pos P_ ((int, Lisp_Object));
901 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
902 static int number_of_chars P_ ((unsigned char *, int));
903 static void compute_stop_pos P_ ((struct it *));
904 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
905 Lisp_Object));
906 static int face_before_or_after_it_pos P_ ((struct it *, int));
907 static int next_overlay_change P_ ((int));
908 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
909 Lisp_Object, struct text_pos *,
910 int));
911 static int underlying_face_id P_ ((struct it *));
912 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
913 struct window *));
915 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
916 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
918 #ifdef HAVE_WINDOW_SYSTEM
920 static void update_tool_bar P_ ((struct frame *, int));
921 static void build_desired_tool_bar_string P_ ((struct frame *f));
922 static int redisplay_tool_bar P_ ((struct frame *));
923 static void display_tool_bar_line P_ ((struct it *));
924 static void notice_overwritten_cursor P_ ((struct window *,
925 enum glyph_row_area,
926 int, int, int, int));
930 #endif /* HAVE_WINDOW_SYSTEM */
933 /***********************************************************************
934 Window display dimensions
935 ***********************************************************************/
937 /* Return the bottom boundary y-position for text lines in window W.
938 This is the first y position at which a line cannot start.
939 It is relative to the top of the window.
941 This is the height of W minus the height of a mode line, if any. */
943 INLINE int
944 window_text_bottom_y (w)
945 struct window *w;
947 int height = WINDOW_TOTAL_HEIGHT (w);
949 if (WINDOW_WANTS_MODELINE_P (w))
950 height -= CURRENT_MODE_LINE_HEIGHT (w);
951 return height;
954 /* Return the pixel width of display area AREA of window W. AREA < 0
955 means return the total width of W, not including fringes to
956 the left and right of the window. */
958 INLINE int
959 window_box_width (w, area)
960 struct window *w;
961 int area;
963 int cols = XFASTINT (w->total_cols);
964 int pixels = 0;
966 if (!w->pseudo_window_p)
968 cols -= WINDOW_SCROLL_BAR_COLS (w);
970 if (area == TEXT_AREA)
972 if (INTEGERP (w->left_margin_cols))
973 cols -= XFASTINT (w->left_margin_cols);
974 if (INTEGERP (w->right_margin_cols))
975 cols -= XFASTINT (w->right_margin_cols);
976 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
978 else if (area == LEFT_MARGIN_AREA)
980 cols = (INTEGERP (w->left_margin_cols)
981 ? XFASTINT (w->left_margin_cols) : 0);
982 pixels = 0;
984 else if (area == RIGHT_MARGIN_AREA)
986 cols = (INTEGERP (w->right_margin_cols)
987 ? XFASTINT (w->right_margin_cols) : 0);
988 pixels = 0;
992 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
996 /* Return the pixel height of the display area of window W, not
997 including mode lines of W, if any. */
999 INLINE int
1000 window_box_height (w)
1001 struct window *w;
1003 struct frame *f = XFRAME (w->frame);
1004 int height = WINDOW_TOTAL_HEIGHT (w);
1006 xassert (height >= 0);
1008 /* Note: the code below that determines the mode-line/header-line
1009 height is essentially the same as that contained in the macro
1010 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1011 the appropriate glyph row has its `mode_line_p' flag set,
1012 and if it doesn't, uses estimate_mode_line_height instead. */
1014 if (WINDOW_WANTS_MODELINE_P (w))
1016 struct glyph_row *ml_row
1017 = (w->current_matrix && w->current_matrix->rows
1018 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1019 : 0);
1020 if (ml_row && ml_row->mode_line_p)
1021 height -= ml_row->height;
1022 else
1023 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1026 if (WINDOW_WANTS_HEADER_LINE_P (w))
1028 struct glyph_row *hl_row
1029 = (w->current_matrix && w->current_matrix->rows
1030 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1031 : 0);
1032 if (hl_row && hl_row->mode_line_p)
1033 height -= hl_row->height;
1034 else
1035 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1038 /* With a very small font and a mode-line that's taller than
1039 default, we might end up with a negative height. */
1040 return max (0, height);
1043 /* Return the window-relative coordinate of the left edge of display
1044 area AREA of window W. AREA < 0 means return the left edge of the
1045 whole window, to the right of the left fringe of W. */
1047 INLINE int
1048 window_box_left_offset (w, area)
1049 struct window *w;
1050 int area;
1052 int x;
1054 if (w->pseudo_window_p)
1055 return 0;
1057 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1059 if (area == TEXT_AREA)
1060 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1061 + window_box_width (w, LEFT_MARGIN_AREA));
1062 else if (area == RIGHT_MARGIN_AREA)
1063 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1064 + window_box_width (w, LEFT_MARGIN_AREA)
1065 + window_box_width (w, TEXT_AREA)
1066 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1068 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1069 else if (area == LEFT_MARGIN_AREA
1070 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1071 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1073 return x;
1077 /* Return the window-relative coordinate of the right edge of display
1078 area AREA of window W. AREA < 0 means return the left edge of the
1079 whole window, to the left of the right fringe of W. */
1081 INLINE int
1082 window_box_right_offset (w, area)
1083 struct window *w;
1084 int area;
1086 return window_box_left_offset (w, area) + window_box_width (w, area);
1089 /* Return the frame-relative coordinate of the left edge of display
1090 area AREA of window W. AREA < 0 means return the left edge of the
1091 whole window, to the right of the left fringe of W. */
1093 INLINE int
1094 window_box_left (w, area)
1095 struct window *w;
1096 int area;
1098 struct frame *f = XFRAME (w->frame);
1099 int x;
1101 if (w->pseudo_window_p)
1102 return FRAME_INTERNAL_BORDER_WIDTH (f);
1104 x = (WINDOW_LEFT_EDGE_X (w)
1105 + window_box_left_offset (w, area));
1107 return x;
1111 /* Return the frame-relative coordinate of the right edge of display
1112 area AREA of window W. AREA < 0 means return the left edge of the
1113 whole window, to the left of the right fringe of W. */
1115 INLINE int
1116 window_box_right (w, area)
1117 struct window *w;
1118 int area;
1120 return window_box_left (w, area) + window_box_width (w, area);
1123 /* Get the bounding box of the display area AREA of window W, without
1124 mode lines, in frame-relative coordinates. AREA < 0 means the
1125 whole window, not including the left and right fringes of
1126 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1127 coordinates of the upper-left corner of the box. Return in
1128 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1130 INLINE void
1131 window_box (w, area, box_x, box_y, box_width, box_height)
1132 struct window *w;
1133 int area;
1134 int *box_x, *box_y, *box_width, *box_height;
1136 if (box_width)
1137 *box_width = window_box_width (w, area);
1138 if (box_height)
1139 *box_height = window_box_height (w);
1140 if (box_x)
1141 *box_x = window_box_left (w, area);
1142 if (box_y)
1144 *box_y = WINDOW_TOP_EDGE_Y (w);
1145 if (WINDOW_WANTS_HEADER_LINE_P (w))
1146 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1151 /* Get the bounding box of the display area AREA of window W, without
1152 mode lines. AREA < 0 means the whole window, not including the
1153 left and right fringe of the window. Return in *TOP_LEFT_X
1154 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1155 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1156 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1157 box. */
1159 INLINE void
1160 window_box_edges (w, area, top_left_x, top_left_y,
1161 bottom_right_x, bottom_right_y)
1162 struct window *w;
1163 int area;
1164 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1166 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1167 bottom_right_y);
1168 *bottom_right_x += *top_left_x;
1169 *bottom_right_y += *top_left_y;
1174 /***********************************************************************
1175 Utilities
1176 ***********************************************************************/
1178 /* Return the bottom y-position of the line the iterator IT is in.
1179 This can modify IT's settings. */
1182 line_bottom_y (it)
1183 struct it *it;
1185 int line_height = it->max_ascent + it->max_descent;
1186 int line_top_y = it->current_y;
1188 if (line_height == 0)
1190 if (last_height)
1191 line_height = last_height;
1192 else if (IT_CHARPOS (*it) < ZV)
1194 move_it_by_lines (it, 1, 1);
1195 line_height = (it->max_ascent || it->max_descent
1196 ? it->max_ascent + it->max_descent
1197 : last_height);
1199 else
1201 struct glyph_row *row = it->glyph_row;
1203 /* Use the default character height. */
1204 it->glyph_row = NULL;
1205 it->what = IT_CHARACTER;
1206 it->c = ' ';
1207 it->len = 1;
1208 PRODUCE_GLYPHS (it);
1209 line_height = it->ascent + it->descent;
1210 it->glyph_row = row;
1214 return line_top_y + line_height;
1218 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1219 1 if POS is visible and the line containing POS is fully visible.
1220 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1221 and header-lines heights. */
1224 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1225 struct window *w;
1226 int charpos, *fully, exact_mode_line_heights_p;
1228 struct it it;
1229 struct text_pos top;
1230 int visible_p;
1231 struct buffer *old_buffer = NULL;
1233 if (XBUFFER (w->buffer) != current_buffer)
1235 old_buffer = current_buffer;
1236 set_buffer_internal_1 (XBUFFER (w->buffer));
1239 *fully = visible_p = 0;
1240 SET_TEXT_POS_FROM_MARKER (top, w->start);
1242 /* Compute exact mode line heights, if requested. */
1243 if (exact_mode_line_heights_p)
1245 if (WINDOW_WANTS_MODELINE_P (w))
1246 current_mode_line_height
1247 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1248 current_buffer->mode_line_format);
1250 if (WINDOW_WANTS_HEADER_LINE_P (w))
1251 current_header_line_height
1252 = display_mode_line (w, HEADER_LINE_FACE_ID,
1253 current_buffer->header_line_format);
1256 start_display (&it, w, top);
1257 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1258 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1260 /* Note that we may overshoot because of invisible text. */
1261 if (IT_CHARPOS (it) >= charpos)
1263 int top_y = it.current_y;
1264 int bottom_y = line_bottom_y (&it);
1265 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1267 if (top_y < window_top_y)
1268 visible_p = bottom_y > window_top_y;
1269 else if (top_y < it.last_visible_y)
1271 visible_p = 1;
1272 *fully = bottom_y <= it.last_visible_y;
1275 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1277 move_it_by_lines (&it, 1, 0);
1278 if (charpos < IT_CHARPOS (it))
1280 visible_p = 1;
1281 *fully = 0;
1285 if (old_buffer)
1286 set_buffer_internal_1 (old_buffer);
1288 current_header_line_height = current_mode_line_height = -1;
1289 return visible_p;
1293 /* Return the next character from STR which is MAXLEN bytes long.
1294 Return in *LEN the length of the character. This is like
1295 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1296 we find one, we return a `?', but with the length of the invalid
1297 character. */
1299 static INLINE int
1300 string_char_and_length (str, maxlen, len)
1301 const unsigned char *str;
1302 int maxlen, *len;
1304 int c;
1306 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1307 if (!CHAR_VALID_P (c, 1))
1308 /* We may not change the length here because other places in Emacs
1309 don't use this function, i.e. they silently accept invalid
1310 characters. */
1311 c = '?';
1313 return c;
1318 /* Given a position POS containing a valid character and byte position
1319 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1321 static struct text_pos
1322 string_pos_nchars_ahead (pos, string, nchars)
1323 struct text_pos pos;
1324 Lisp_Object string;
1325 int nchars;
1327 xassert (STRINGP (string) && nchars >= 0);
1329 if (STRING_MULTIBYTE (string))
1331 int rest = SBYTES (string) - BYTEPOS (pos);
1332 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1333 int len;
1335 while (nchars--)
1337 string_char_and_length (p, rest, &len);
1338 p += len, rest -= len;
1339 xassert (rest >= 0);
1340 CHARPOS (pos) += 1;
1341 BYTEPOS (pos) += len;
1344 else
1345 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1347 return pos;
1351 /* Value is the text position, i.e. character and byte position,
1352 for character position CHARPOS in STRING. */
1354 static INLINE struct text_pos
1355 string_pos (charpos, string)
1356 int charpos;
1357 Lisp_Object string;
1359 struct text_pos pos;
1360 xassert (STRINGP (string));
1361 xassert (charpos >= 0);
1362 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1363 return pos;
1367 /* Value is a text position, i.e. character and byte position, for
1368 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1369 means recognize multibyte characters. */
1371 static struct text_pos
1372 c_string_pos (charpos, s, multibyte_p)
1373 int charpos;
1374 unsigned char *s;
1375 int multibyte_p;
1377 struct text_pos pos;
1379 xassert (s != NULL);
1380 xassert (charpos >= 0);
1382 if (multibyte_p)
1384 int rest = strlen (s), len;
1386 SET_TEXT_POS (pos, 0, 0);
1387 while (charpos--)
1389 string_char_and_length (s, rest, &len);
1390 s += len, rest -= len;
1391 xassert (rest >= 0);
1392 CHARPOS (pos) += 1;
1393 BYTEPOS (pos) += len;
1396 else
1397 SET_TEXT_POS (pos, charpos, charpos);
1399 return pos;
1403 /* Value is the number of characters in C string S. MULTIBYTE_P
1404 non-zero means recognize multibyte characters. */
1406 static int
1407 number_of_chars (s, multibyte_p)
1408 unsigned char *s;
1409 int multibyte_p;
1411 int nchars;
1413 if (multibyte_p)
1415 int rest = strlen (s), len;
1416 unsigned char *p = (unsigned char *) s;
1418 for (nchars = 0; rest > 0; ++nchars)
1420 string_char_and_length (p, rest, &len);
1421 rest -= len, p += len;
1424 else
1425 nchars = strlen (s);
1427 return nchars;
1431 /* Compute byte position NEWPOS->bytepos corresponding to
1432 NEWPOS->charpos. POS is a known position in string STRING.
1433 NEWPOS->charpos must be >= POS.charpos. */
1435 static void
1436 compute_string_pos (newpos, pos, string)
1437 struct text_pos *newpos, pos;
1438 Lisp_Object string;
1440 xassert (STRINGP (string));
1441 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1443 if (STRING_MULTIBYTE (string))
1444 *newpos = string_pos_nchars_ahead (pos, string,
1445 CHARPOS (*newpos) - CHARPOS (pos));
1446 else
1447 BYTEPOS (*newpos) = CHARPOS (*newpos);
1450 /* EXPORT:
1451 Return an estimation of the pixel height of mode or top lines on
1452 frame F. FACE_ID specifies what line's height to estimate. */
1455 estimate_mode_line_height (f, face_id)
1456 struct frame *f;
1457 enum face_id face_id;
1459 #ifdef HAVE_WINDOW_SYSTEM
1460 if (FRAME_WINDOW_P (f))
1462 int height = FONT_HEIGHT (FRAME_FONT (f));
1464 /* This function is called so early when Emacs starts that the face
1465 cache and mode line face are not yet initialized. */
1466 if (FRAME_FACE_CACHE (f))
1468 struct face *face = FACE_FROM_ID (f, face_id);
1469 if (face)
1471 if (face->font)
1472 height = FONT_HEIGHT (face->font);
1473 if (face->box_line_width > 0)
1474 height += 2 * face->box_line_width;
1478 return height;
1480 #endif
1482 return 1;
1485 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1486 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1487 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1488 not force the value into range. */
1490 void
1491 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1492 FRAME_PTR f;
1493 register int pix_x, pix_y;
1494 int *x, *y;
1495 NativeRectangle *bounds;
1496 int noclip;
1499 #ifdef HAVE_WINDOW_SYSTEM
1500 if (FRAME_WINDOW_P (f))
1502 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1503 even for negative values. */
1504 if (pix_x < 0)
1505 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1506 if (pix_y < 0)
1507 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1509 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1510 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1512 if (bounds)
1513 STORE_NATIVE_RECT (*bounds,
1514 FRAME_COL_TO_PIXEL_X (f, pix_x),
1515 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1516 FRAME_COLUMN_WIDTH (f) - 1,
1517 FRAME_LINE_HEIGHT (f) - 1);
1519 if (!noclip)
1521 if (pix_x < 0)
1522 pix_x = 0;
1523 else if (pix_x > FRAME_TOTAL_COLS (f))
1524 pix_x = FRAME_TOTAL_COLS (f);
1526 if (pix_y < 0)
1527 pix_y = 0;
1528 else if (pix_y > FRAME_LINES (f))
1529 pix_y = FRAME_LINES (f);
1532 #endif
1534 *x = pix_x;
1535 *y = pix_y;
1539 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1540 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1541 can't tell the positions because W's display is not up to date,
1542 return 0. */
1545 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1546 struct window *w;
1547 int hpos, vpos;
1548 int *frame_x, *frame_y;
1550 #ifdef HAVE_WINDOW_SYSTEM
1551 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1553 int success_p;
1555 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1556 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1558 if (display_completed)
1560 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1561 struct glyph *glyph = row->glyphs[TEXT_AREA];
1562 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1564 hpos = row->x;
1565 vpos = row->y;
1566 while (glyph < end)
1568 hpos += glyph->pixel_width;
1569 ++glyph;
1572 /* If first glyph is partially visible, its first visible position is still 0. */
1573 if (hpos < 0)
1574 hpos = 0;
1576 success_p = 1;
1578 else
1580 hpos = vpos = 0;
1581 success_p = 0;
1584 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1585 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1586 return success_p;
1588 #endif
1590 *frame_x = hpos;
1591 *frame_y = vpos;
1592 return 1;
1596 #ifdef HAVE_WINDOW_SYSTEM
1598 /* Find the glyph under window-relative coordinates X/Y in window W.
1599 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1600 strings. Return in *HPOS and *VPOS the row and column number of
1601 the glyph found. Return in *AREA the glyph area containing X.
1602 Value is a pointer to the glyph found or null if X/Y is not on
1603 text, or we can't tell because W's current matrix is not up to
1604 date. */
1606 static struct glyph *
1607 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1608 struct window *w;
1609 int x, y;
1610 int *hpos, *vpos, *dx, *dy, *area;
1612 struct glyph *glyph, *end;
1613 struct glyph_row *row = NULL;
1614 int x0, i;
1616 /* Find row containing Y. Give up if some row is not enabled. */
1617 for (i = 0; i < w->current_matrix->nrows; ++i)
1619 row = MATRIX_ROW (w->current_matrix, i);
1620 if (!row->enabled_p)
1621 return NULL;
1622 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1623 break;
1626 *vpos = i;
1627 *hpos = 0;
1629 /* Give up if Y is not in the window. */
1630 if (i == w->current_matrix->nrows)
1631 return NULL;
1633 /* Get the glyph area containing X. */
1634 if (w->pseudo_window_p)
1636 *area = TEXT_AREA;
1637 x0 = 0;
1639 else
1641 if (x < window_box_left_offset (w, TEXT_AREA))
1643 *area = LEFT_MARGIN_AREA;
1644 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1646 else if (x < window_box_right_offset (w, TEXT_AREA))
1648 *area = TEXT_AREA;
1649 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1651 else
1653 *area = RIGHT_MARGIN_AREA;
1654 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1658 /* Find glyph containing X. */
1659 glyph = row->glyphs[*area];
1660 end = glyph + row->used[*area];
1661 x -= x0;
1662 while (glyph < end && x >= glyph->pixel_width)
1664 x -= glyph->pixel_width;
1665 ++glyph;
1668 if (glyph == end)
1669 return NULL;
1671 if (dx)
1673 *dx = x;
1674 *dy = y - (row->y + row->ascent - glyph->ascent);
1677 *hpos = glyph - row->glyphs[*area];
1678 return glyph;
1682 /* EXPORT:
1683 Convert frame-relative x/y to coordinates relative to window W.
1684 Takes pseudo-windows into account. */
1686 void
1687 frame_to_window_pixel_xy (w, x, y)
1688 struct window *w;
1689 int *x, *y;
1691 if (w->pseudo_window_p)
1693 /* A pseudo-window is always full-width, and starts at the
1694 left edge of the frame, plus a frame border. */
1695 struct frame *f = XFRAME (w->frame);
1696 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1697 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1699 else
1701 *x -= WINDOW_LEFT_EDGE_X (w);
1702 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1706 /* EXPORT:
1707 Return in *R the clipping rectangle for glyph string S. */
1709 void
1710 get_glyph_string_clip_rect (s, nr)
1711 struct glyph_string *s;
1712 NativeRectangle *nr;
1714 XRectangle r;
1716 if (s->row->full_width_p)
1718 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1719 r.x = WINDOW_LEFT_EDGE_X (s->w);
1720 r.width = WINDOW_TOTAL_WIDTH (s->w);
1722 /* Unless displaying a mode or menu bar line, which are always
1723 fully visible, clip to the visible part of the row. */
1724 if (s->w->pseudo_window_p)
1725 r.height = s->row->visible_height;
1726 else
1727 r.height = s->height;
1729 else
1731 /* This is a text line that may be partially visible. */
1732 r.x = window_box_left (s->w, s->area);
1733 r.width = window_box_width (s->w, s->area);
1734 r.height = s->row->visible_height;
1737 /* If S draws overlapping rows, it's sufficient to use the top and
1738 bottom of the window for clipping because this glyph string
1739 intentionally draws over other lines. */
1740 if (s->for_overlaps_p)
1742 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1743 r.height = window_text_bottom_y (s->w) - r.y;
1745 else
1747 /* Don't use S->y for clipping because it doesn't take partially
1748 visible lines into account. For example, it can be negative for
1749 partially visible lines at the top of a window. */
1750 if (!s->row->full_width_p
1751 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1752 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1753 else
1754 r.y = max (0, s->row->y);
1756 /* If drawing a tool-bar window, draw it over the internal border
1757 at the top of the window. */
1758 if (s->w == XWINDOW (s->f->tool_bar_window))
1759 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1762 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1764 /* If drawing the cursor, don't let glyph draw outside its
1765 advertised boundaries. Cleartype does this under some circumstances. */
1766 if (s->hl == DRAW_CURSOR)
1768 struct glyph *glyph = s->first_glyph;
1769 int height;
1771 if (s->x > r.x)
1773 r.width -= s->x - r.x;
1774 r.x = s->x;
1776 r.width = min (r.width, glyph->pixel_width);
1778 /* Don't draw cursor glyph taller than our actual glyph. */
1779 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1780 if (height < r.height)
1782 r.y = s->ybase + glyph->descent - height;
1783 r.height = height;
1787 #ifdef CONVERT_FROM_XRECT
1788 CONVERT_FROM_XRECT (r, *nr);
1789 #else
1790 *nr = r;
1791 #endif
1794 #endif /* HAVE_WINDOW_SYSTEM */
1797 /***********************************************************************
1798 Lisp form evaluation
1799 ***********************************************************************/
1801 /* Error handler for safe_eval and safe_call. */
1803 static Lisp_Object
1804 safe_eval_handler (arg)
1805 Lisp_Object arg;
1807 add_to_log ("Error during redisplay: %s", arg, Qnil);
1808 return Qnil;
1812 /* Evaluate SEXPR and return the result, or nil if something went
1813 wrong. Prevent redisplay during the evaluation. */
1815 Lisp_Object
1816 safe_eval (sexpr)
1817 Lisp_Object sexpr;
1819 Lisp_Object val;
1821 if (inhibit_eval_during_redisplay)
1822 val = Qnil;
1823 else
1825 int count = SPECPDL_INDEX ();
1826 struct gcpro gcpro1;
1828 GCPRO1 (sexpr);
1829 specbind (Qinhibit_redisplay, Qt);
1830 /* Use Qt to ensure debugger does not run,
1831 so there is no possibility of wanting to redisplay. */
1832 val = internal_condition_case_1 (Feval, sexpr, Qt,
1833 safe_eval_handler);
1834 UNGCPRO;
1835 val = unbind_to (count, val);
1838 return val;
1842 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1843 Return the result, or nil if something went wrong. Prevent
1844 redisplay during the evaluation. */
1846 Lisp_Object
1847 safe_call (nargs, args)
1848 int nargs;
1849 Lisp_Object *args;
1851 Lisp_Object val;
1853 if (inhibit_eval_during_redisplay)
1854 val = Qnil;
1855 else
1857 int count = SPECPDL_INDEX ();
1858 struct gcpro gcpro1;
1860 GCPRO1 (args[0]);
1861 gcpro1.nvars = nargs;
1862 specbind (Qinhibit_redisplay, Qt);
1863 /* Use Qt to ensure debugger does not run,
1864 so there is no possibility of wanting to redisplay. */
1865 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1866 safe_eval_handler);
1867 UNGCPRO;
1868 val = unbind_to (count, val);
1871 return val;
1875 /* Call function FN with one argument ARG.
1876 Return the result, or nil if something went wrong. */
1878 Lisp_Object
1879 safe_call1 (fn, arg)
1880 Lisp_Object fn, arg;
1882 Lisp_Object args[2];
1883 args[0] = fn;
1884 args[1] = arg;
1885 return safe_call (2, args);
1890 /***********************************************************************
1891 Debugging
1892 ***********************************************************************/
1894 #if 0
1896 /* Define CHECK_IT to perform sanity checks on iterators.
1897 This is for debugging. It is too slow to do unconditionally. */
1899 static void
1900 check_it (it)
1901 struct it *it;
1903 if (it->method == next_element_from_string)
1905 xassert (STRINGP (it->string));
1906 xassert (IT_STRING_CHARPOS (*it) >= 0);
1908 else if (it->method == next_element_from_buffer)
1910 /* Check that character and byte positions agree. */
1911 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1914 if (it->dpvec)
1915 xassert (it->current.dpvec_index >= 0);
1916 else
1917 xassert (it->current.dpvec_index < 0);
1920 #define CHECK_IT(IT) check_it ((IT))
1922 #else /* not 0 */
1924 #define CHECK_IT(IT) (void) 0
1926 #endif /* not 0 */
1929 #if GLYPH_DEBUG
1931 /* Check that the window end of window W is what we expect it
1932 to be---the last row in the current matrix displaying text. */
1934 static void
1935 check_window_end (w)
1936 struct window *w;
1938 if (!MINI_WINDOW_P (w)
1939 && !NILP (w->window_end_valid))
1941 struct glyph_row *row;
1942 xassert ((row = MATRIX_ROW (w->current_matrix,
1943 XFASTINT (w->window_end_vpos)),
1944 !row->enabled_p
1945 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1946 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1950 #define CHECK_WINDOW_END(W) check_window_end ((W))
1952 #else /* not GLYPH_DEBUG */
1954 #define CHECK_WINDOW_END(W) (void) 0
1956 #endif /* not GLYPH_DEBUG */
1960 /***********************************************************************
1961 Iterator initialization
1962 ***********************************************************************/
1964 /* Initialize IT for displaying current_buffer in window W, starting
1965 at character position CHARPOS. CHARPOS < 0 means that no buffer
1966 position is specified which is useful when the iterator is assigned
1967 a position later. BYTEPOS is the byte position corresponding to
1968 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1970 If ROW is not null, calls to produce_glyphs with IT as parameter
1971 will produce glyphs in that row.
1973 BASE_FACE_ID is the id of a base face to use. It must be one of
1974 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1975 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1976 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1978 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1979 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1980 will be initialized to use the corresponding mode line glyph row of
1981 the desired matrix of W. */
1983 void
1984 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1985 struct it *it;
1986 struct window *w;
1987 int charpos, bytepos;
1988 struct glyph_row *row;
1989 enum face_id base_face_id;
1991 int highlight_region_p;
1993 /* Some precondition checks. */
1994 xassert (w != NULL && it != NULL);
1995 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1996 && charpos <= ZV));
1998 /* If face attributes have been changed since the last redisplay,
1999 free realized faces now because they depend on face definitions
2000 that might have changed. Don't free faces while there might be
2001 desired matrices pending which reference these faces. */
2002 if (face_change_count && !inhibit_free_realized_faces)
2004 face_change_count = 0;
2005 free_all_realized_faces (Qnil);
2008 /* Use one of the mode line rows of W's desired matrix if
2009 appropriate. */
2010 if (row == NULL)
2012 if (base_face_id == MODE_LINE_FACE_ID
2013 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2014 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2015 else if (base_face_id == HEADER_LINE_FACE_ID)
2016 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2019 /* Clear IT. */
2020 bzero (it, sizeof *it);
2021 it->current.overlay_string_index = -1;
2022 it->current.dpvec_index = -1;
2023 it->base_face_id = base_face_id;
2025 /* The window in which we iterate over current_buffer: */
2026 XSETWINDOW (it->window, w);
2027 it->w = w;
2028 it->f = XFRAME (w->frame);
2030 /* Extra space between lines (on window systems only). */
2031 if (base_face_id == DEFAULT_FACE_ID
2032 && FRAME_WINDOW_P (it->f))
2034 if (NATNUMP (current_buffer->extra_line_spacing))
2035 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2036 else if (it->f->extra_line_spacing > 0)
2037 it->extra_line_spacing = it->f->extra_line_spacing;
2040 /* If realized faces have been removed, e.g. because of face
2041 attribute changes of named faces, recompute them. When running
2042 in batch mode, the face cache of Vterminal_frame is null. If
2043 we happen to get called, make a dummy face cache. */
2044 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2045 init_frame_faces (it->f);
2046 if (FRAME_FACE_CACHE (it->f)->used == 0)
2047 recompute_basic_faces (it->f);
2049 /* Current value of the `space-width', and 'height' properties. */
2050 it->space_width = Qnil;
2051 it->font_height = Qnil;
2053 /* Are control characters displayed as `^C'? */
2054 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2056 /* -1 means everything between a CR and the following line end
2057 is invisible. >0 means lines indented more than this value are
2058 invisible. */
2059 it->selective = (INTEGERP (current_buffer->selective_display)
2060 ? XFASTINT (current_buffer->selective_display)
2061 : (!NILP (current_buffer->selective_display)
2062 ? -1 : 0));
2063 it->selective_display_ellipsis_p
2064 = !NILP (current_buffer->selective_display_ellipses);
2066 /* Display table to use. */
2067 it->dp = window_display_table (w);
2069 /* Are multibyte characters enabled in current_buffer? */
2070 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2072 /* Non-zero if we should highlight the region. */
2073 highlight_region_p
2074 = (!NILP (Vtransient_mark_mode)
2075 && !NILP (current_buffer->mark_active)
2076 && XMARKER (current_buffer->mark)->buffer != 0);
2078 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2079 start and end of a visible region in window IT->w. Set both to
2080 -1 to indicate no region. */
2081 if (highlight_region_p
2082 /* Maybe highlight only in selected window. */
2083 && (/* Either show region everywhere. */
2084 highlight_nonselected_windows
2085 /* Or show region in the selected window. */
2086 || w == XWINDOW (selected_window)
2087 /* Or show the region if we are in the mini-buffer and W is
2088 the window the mini-buffer refers to. */
2089 || (MINI_WINDOW_P (XWINDOW (selected_window))
2090 && WINDOWP (minibuf_selected_window)
2091 && w == XWINDOW (minibuf_selected_window))))
2093 int charpos = marker_position (current_buffer->mark);
2094 it->region_beg_charpos = min (PT, charpos);
2095 it->region_end_charpos = max (PT, charpos);
2097 else
2098 it->region_beg_charpos = it->region_end_charpos = -1;
2100 /* Get the position at which the redisplay_end_trigger hook should
2101 be run, if it is to be run at all. */
2102 if (MARKERP (w->redisplay_end_trigger)
2103 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2104 it->redisplay_end_trigger_charpos
2105 = marker_position (w->redisplay_end_trigger);
2106 else if (INTEGERP (w->redisplay_end_trigger))
2107 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2109 /* Correct bogus values of tab_width. */
2110 it->tab_width = XINT (current_buffer->tab_width);
2111 if (it->tab_width <= 0 || it->tab_width > 1000)
2112 it->tab_width = 8;
2114 /* Are lines in the display truncated? */
2115 it->truncate_lines_p
2116 = (base_face_id != DEFAULT_FACE_ID
2117 || XINT (it->w->hscroll)
2118 || (truncate_partial_width_windows
2119 && !WINDOW_FULL_WIDTH_P (it->w))
2120 || !NILP (current_buffer->truncate_lines));
2122 /* Get dimensions of truncation and continuation glyphs. These are
2123 displayed as fringe bitmaps under X, so we don't need them for such
2124 frames. */
2125 if (!FRAME_WINDOW_P (it->f))
2127 if (it->truncate_lines_p)
2129 /* We will need the truncation glyph. */
2130 xassert (it->glyph_row == NULL);
2131 produce_special_glyphs (it, IT_TRUNCATION);
2132 it->truncation_pixel_width = it->pixel_width;
2134 else
2136 /* We will need the continuation glyph. */
2137 xassert (it->glyph_row == NULL);
2138 produce_special_glyphs (it, IT_CONTINUATION);
2139 it->continuation_pixel_width = it->pixel_width;
2142 /* Reset these values to zero because the produce_special_glyphs
2143 above has changed them. */
2144 it->pixel_width = it->ascent = it->descent = 0;
2145 it->phys_ascent = it->phys_descent = 0;
2148 /* Set this after getting the dimensions of truncation and
2149 continuation glyphs, so that we don't produce glyphs when calling
2150 produce_special_glyphs, above. */
2151 it->glyph_row = row;
2152 it->area = TEXT_AREA;
2154 /* Get the dimensions of the display area. The display area
2155 consists of the visible window area plus a horizontally scrolled
2156 part to the left of the window. All x-values are relative to the
2157 start of this total display area. */
2158 if (base_face_id != DEFAULT_FACE_ID)
2160 /* Mode lines, menu bar in terminal frames. */
2161 it->first_visible_x = 0;
2162 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2164 else
2166 it->first_visible_x
2167 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2168 it->last_visible_x = (it->first_visible_x
2169 + window_box_width (w, TEXT_AREA));
2171 /* If we truncate lines, leave room for the truncator glyph(s) at
2172 the right margin. Otherwise, leave room for the continuation
2173 glyph(s). Truncation and continuation glyphs are not inserted
2174 for window-based redisplay. */
2175 if (!FRAME_WINDOW_P (it->f))
2177 if (it->truncate_lines_p)
2178 it->last_visible_x -= it->truncation_pixel_width;
2179 else
2180 it->last_visible_x -= it->continuation_pixel_width;
2183 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2184 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2187 /* Leave room for a border glyph. */
2188 if (!FRAME_WINDOW_P (it->f)
2189 && !WINDOW_RIGHTMOST_P (it->w))
2190 it->last_visible_x -= 1;
2192 it->last_visible_y = window_text_bottom_y (w);
2194 /* For mode lines and alike, arrange for the first glyph having a
2195 left box line if the face specifies a box. */
2196 if (base_face_id != DEFAULT_FACE_ID)
2198 struct face *face;
2200 it->face_id = base_face_id;
2202 /* If we have a boxed mode line, make the first character appear
2203 with a left box line. */
2204 face = FACE_FROM_ID (it->f, base_face_id);
2205 if (face->box != FACE_NO_BOX)
2206 it->start_of_box_run_p = 1;
2209 /* If a buffer position was specified, set the iterator there,
2210 getting overlays and face properties from that position. */
2211 if (charpos >= BUF_BEG (current_buffer))
2213 it->end_charpos = ZV;
2214 it->face_id = -1;
2215 IT_CHARPOS (*it) = charpos;
2217 /* Compute byte position if not specified. */
2218 if (bytepos < charpos)
2219 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2220 else
2221 IT_BYTEPOS (*it) = bytepos;
2223 it->start = it->current;
2225 /* Compute faces etc. */
2226 reseat (it, it->current.pos, 1);
2229 CHECK_IT (it);
2233 /* Initialize IT for the display of window W with window start POS. */
2235 void
2236 start_display (it, w, pos)
2237 struct it *it;
2238 struct window *w;
2239 struct text_pos pos;
2241 struct glyph_row *row;
2242 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2244 row = w->desired_matrix->rows + first_vpos;
2245 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2246 it->first_vpos = first_vpos;
2248 if (!it->truncate_lines_p)
2250 int start_at_line_beg_p;
2251 int first_y = it->current_y;
2253 /* If window start is not at a line start, skip forward to POS to
2254 get the correct continuation lines width. */
2255 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2256 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2257 if (!start_at_line_beg_p)
2259 int new_x;
2261 reseat_at_previous_visible_line_start (it);
2262 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2264 new_x = it->current_x + it->pixel_width;
2266 /* If lines are continued, this line may end in the middle
2267 of a multi-glyph character (e.g. a control character
2268 displayed as \003, or in the middle of an overlay
2269 string). In this case move_it_to above will not have
2270 taken us to the start of the continuation line but to the
2271 end of the continued line. */
2272 if (it->current_x > 0
2273 && !it->truncate_lines_p /* Lines are continued. */
2274 && (/* And glyph doesn't fit on the line. */
2275 new_x > it->last_visible_x
2276 /* Or it fits exactly and we're on a window
2277 system frame. */
2278 || (new_x == it->last_visible_x
2279 && FRAME_WINDOW_P (it->f))))
2281 if (it->current.dpvec_index >= 0
2282 || it->current.overlay_string_index >= 0)
2284 set_iterator_to_next (it, 1);
2285 move_it_in_display_line_to (it, -1, -1, 0);
2288 it->continuation_lines_width += it->current_x;
2291 /* We're starting a new display line, not affected by the
2292 height of the continued line, so clear the appropriate
2293 fields in the iterator structure. */
2294 it->max_ascent = it->max_descent = 0;
2295 it->max_phys_ascent = it->max_phys_descent = 0;
2297 it->current_y = first_y;
2298 it->vpos = 0;
2299 it->current_x = it->hpos = 0;
2303 #if 0 /* Don't assert the following because start_display is sometimes
2304 called intentionally with a window start that is not at a
2305 line start. Please leave this code in as a comment. */
2307 /* Window start should be on a line start, now. */
2308 xassert (it->continuation_lines_width
2309 || IT_CHARPOS (it) == BEGV
2310 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2311 #endif /* 0 */
2315 /* Return 1 if POS is a position in ellipses displayed for invisible
2316 text. W is the window we display, for text property lookup. */
2318 static int
2319 in_ellipses_for_invisible_text_p (pos, w)
2320 struct display_pos *pos;
2321 struct window *w;
2323 Lisp_Object prop, window;
2324 int ellipses_p = 0;
2325 int charpos = CHARPOS (pos->pos);
2327 /* If POS specifies a position in a display vector, this might
2328 be for an ellipsis displayed for invisible text. We won't
2329 get the iterator set up for delivering that ellipsis unless
2330 we make sure that it gets aware of the invisible text. */
2331 if (pos->dpvec_index >= 0
2332 && pos->overlay_string_index < 0
2333 && CHARPOS (pos->string_pos) < 0
2334 && charpos > BEGV
2335 && (XSETWINDOW (window, w),
2336 prop = Fget_char_property (make_number (charpos),
2337 Qinvisible, window),
2338 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2340 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2341 window);
2342 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2345 return ellipses_p;
2349 /* Initialize IT for stepping through current_buffer in window W,
2350 starting at position POS that includes overlay string and display
2351 vector/ control character translation position information. Value
2352 is zero if there are overlay strings with newlines at POS. */
2354 static int
2355 init_from_display_pos (it, w, pos)
2356 struct it *it;
2357 struct window *w;
2358 struct display_pos *pos;
2360 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2361 int i, overlay_strings_with_newlines = 0;
2363 /* If POS specifies a position in a display vector, this might
2364 be for an ellipsis displayed for invisible text. We won't
2365 get the iterator set up for delivering that ellipsis unless
2366 we make sure that it gets aware of the invisible text. */
2367 if (in_ellipses_for_invisible_text_p (pos, w))
2369 --charpos;
2370 bytepos = 0;
2373 /* Keep in mind: the call to reseat in init_iterator skips invisible
2374 text, so we might end up at a position different from POS. This
2375 is only a problem when POS is a row start after a newline and an
2376 overlay starts there with an after-string, and the overlay has an
2377 invisible property. Since we don't skip invisible text in
2378 display_line and elsewhere immediately after consuming the
2379 newline before the row start, such a POS will not be in a string,
2380 but the call to init_iterator below will move us to the
2381 after-string. */
2382 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2384 for (i = 0; i < it->n_overlay_strings; ++i)
2386 const char *s = SDATA (it->overlay_strings[i]);
2387 const char *e = s + SBYTES (it->overlay_strings[i]);
2389 while (s < e && *s != '\n')
2390 ++s;
2392 if (s < e)
2394 overlay_strings_with_newlines = 1;
2395 break;
2399 /* If position is within an overlay string, set up IT to the right
2400 overlay string. */
2401 if (pos->overlay_string_index >= 0)
2403 int relative_index;
2405 /* If the first overlay string happens to have a `display'
2406 property for an image, the iterator will be set up for that
2407 image, and we have to undo that setup first before we can
2408 correct the overlay string index. */
2409 if (it->method == next_element_from_image)
2410 pop_it (it);
2412 /* We already have the first chunk of overlay strings in
2413 IT->overlay_strings. Load more until the one for
2414 pos->overlay_string_index is in IT->overlay_strings. */
2415 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2417 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2418 it->current.overlay_string_index = 0;
2419 while (n--)
2421 load_overlay_strings (it, 0);
2422 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2426 it->current.overlay_string_index = pos->overlay_string_index;
2427 relative_index = (it->current.overlay_string_index
2428 % OVERLAY_STRING_CHUNK_SIZE);
2429 it->string = it->overlay_strings[relative_index];
2430 xassert (STRINGP (it->string));
2431 it->current.string_pos = pos->string_pos;
2432 it->method = next_element_from_string;
2435 #if 0 /* This is bogus because POS not having an overlay string
2436 position does not mean it's after the string. Example: A
2437 line starting with a before-string and initialization of IT
2438 to the previous row's end position. */
2439 else if (it->current.overlay_string_index >= 0)
2441 /* If POS says we're already after an overlay string ending at
2442 POS, make sure to pop the iterator because it will be in
2443 front of that overlay string. When POS is ZV, we've thereby
2444 also ``processed'' overlay strings at ZV. */
2445 while (it->sp)
2446 pop_it (it);
2447 it->current.overlay_string_index = -1;
2448 it->method = next_element_from_buffer;
2449 if (CHARPOS (pos->pos) == ZV)
2450 it->overlay_strings_at_end_processed_p = 1;
2452 #endif /* 0 */
2454 if (CHARPOS (pos->string_pos) >= 0)
2456 /* Recorded position is not in an overlay string, but in another
2457 string. This can only be a string from a `display' property.
2458 IT should already be filled with that string. */
2459 it->current.string_pos = pos->string_pos;
2460 xassert (STRINGP (it->string));
2463 /* Restore position in display vector translations, control
2464 character translations or ellipses. */
2465 if (pos->dpvec_index >= 0)
2467 if (it->dpvec == NULL)
2468 get_next_display_element (it);
2469 xassert (it->dpvec && it->current.dpvec_index == 0);
2470 it->current.dpvec_index = pos->dpvec_index;
2473 CHECK_IT (it);
2474 return !overlay_strings_with_newlines;
2478 /* Initialize IT for stepping through current_buffer in window W
2479 starting at ROW->start. */
2481 static void
2482 init_to_row_start (it, w, row)
2483 struct it *it;
2484 struct window *w;
2485 struct glyph_row *row;
2487 init_from_display_pos (it, w, &row->start);
2488 it->start = row->start;
2489 it->continuation_lines_width = row->continuation_lines_width;
2490 CHECK_IT (it);
2494 /* Initialize IT for stepping through current_buffer in window W
2495 starting in the line following ROW, i.e. starting at ROW->end.
2496 Value is zero if there are overlay strings with newlines at ROW's
2497 end position. */
2499 static int
2500 init_to_row_end (it, w, row)
2501 struct it *it;
2502 struct window *w;
2503 struct glyph_row *row;
2505 int success = 0;
2507 if (init_from_display_pos (it, w, &row->end))
2509 if (row->continued_p)
2510 it->continuation_lines_width
2511 = row->continuation_lines_width + row->pixel_width;
2512 CHECK_IT (it);
2513 success = 1;
2516 return success;
2522 /***********************************************************************
2523 Text properties
2524 ***********************************************************************/
2526 /* Called when IT reaches IT->stop_charpos. Handle text property and
2527 overlay changes. Set IT->stop_charpos to the next position where
2528 to stop. */
2530 static void
2531 handle_stop (it)
2532 struct it *it;
2534 enum prop_handled handled;
2535 int handle_overlay_change_p = 1;
2536 struct props *p;
2538 it->dpvec = NULL;
2539 it->current.dpvec_index = -1;
2543 handled = HANDLED_NORMALLY;
2545 /* Call text property handlers. */
2546 for (p = it_props; p->handler; ++p)
2548 handled = p->handler (it);
2550 if (handled == HANDLED_RECOMPUTE_PROPS)
2551 break;
2552 else if (handled == HANDLED_RETURN)
2553 return;
2554 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2555 handle_overlay_change_p = 0;
2558 if (handled != HANDLED_RECOMPUTE_PROPS)
2560 /* Don't check for overlay strings below when set to deliver
2561 characters from a display vector. */
2562 if (it->method == next_element_from_display_vector)
2563 handle_overlay_change_p = 0;
2565 /* Handle overlay changes. */
2566 if (handle_overlay_change_p)
2567 handled = handle_overlay_change (it);
2569 /* Determine where to stop next. */
2570 if (handled == HANDLED_NORMALLY)
2571 compute_stop_pos (it);
2574 while (handled == HANDLED_RECOMPUTE_PROPS);
2578 /* Compute IT->stop_charpos from text property and overlay change
2579 information for IT's current position. */
2581 static void
2582 compute_stop_pos (it)
2583 struct it *it;
2585 register INTERVAL iv, next_iv;
2586 Lisp_Object object, limit, position;
2588 /* If nowhere else, stop at the end. */
2589 it->stop_charpos = it->end_charpos;
2591 if (STRINGP (it->string))
2593 /* Strings are usually short, so don't limit the search for
2594 properties. */
2595 object = it->string;
2596 limit = Qnil;
2597 position = make_number (IT_STRING_CHARPOS (*it));
2599 else
2601 int charpos;
2603 /* If next overlay change is in front of the current stop pos
2604 (which is IT->end_charpos), stop there. Note: value of
2605 next_overlay_change is point-max if no overlay change
2606 follows. */
2607 charpos = next_overlay_change (IT_CHARPOS (*it));
2608 if (charpos < it->stop_charpos)
2609 it->stop_charpos = charpos;
2611 /* If showing the region, we have to stop at the region
2612 start or end because the face might change there. */
2613 if (it->region_beg_charpos > 0)
2615 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2616 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2617 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2618 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2621 /* Set up variables for computing the stop position from text
2622 property changes. */
2623 XSETBUFFER (object, current_buffer);
2624 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2625 position = make_number (IT_CHARPOS (*it));
2629 /* Get the interval containing IT's position. Value is a null
2630 interval if there isn't such an interval. */
2631 iv = validate_interval_range (object, &position, &position, 0);
2632 if (!NULL_INTERVAL_P (iv))
2634 Lisp_Object values_here[LAST_PROP_IDX];
2635 struct props *p;
2637 /* Get properties here. */
2638 for (p = it_props; p->handler; ++p)
2639 values_here[p->idx] = textget (iv->plist, *p->name);
2641 /* Look for an interval following iv that has different
2642 properties. */
2643 for (next_iv = next_interval (iv);
2644 (!NULL_INTERVAL_P (next_iv)
2645 && (NILP (limit)
2646 || XFASTINT (limit) > next_iv->position));
2647 next_iv = next_interval (next_iv))
2649 for (p = it_props; p->handler; ++p)
2651 Lisp_Object new_value;
2653 new_value = textget (next_iv->plist, *p->name);
2654 if (!EQ (values_here[p->idx], new_value))
2655 break;
2658 if (p->handler)
2659 break;
2662 if (!NULL_INTERVAL_P (next_iv))
2664 if (INTEGERP (limit)
2665 && next_iv->position >= XFASTINT (limit))
2666 /* No text property change up to limit. */
2667 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2668 else
2669 /* Text properties change in next_iv. */
2670 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2674 xassert (STRINGP (it->string)
2675 || (it->stop_charpos >= BEGV
2676 && it->stop_charpos >= IT_CHARPOS (*it)));
2680 /* Return the position of the next overlay change after POS in
2681 current_buffer. Value is point-max if no overlay change
2682 follows. This is like `next-overlay-change' but doesn't use
2683 xmalloc. */
2685 static int
2686 next_overlay_change (pos)
2687 int pos;
2689 int noverlays;
2690 int endpos;
2691 Lisp_Object *overlays;
2692 int len;
2693 int i;
2695 /* Get all overlays at the given position. */
2696 len = 10;
2697 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2698 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2699 if (noverlays > len)
2701 len = noverlays;
2702 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2703 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2706 /* If any of these overlays ends before endpos,
2707 use its ending point instead. */
2708 for (i = 0; i < noverlays; ++i)
2710 Lisp_Object oend;
2711 int oendpos;
2713 oend = OVERLAY_END (overlays[i]);
2714 oendpos = OVERLAY_POSITION (oend);
2715 endpos = min (endpos, oendpos);
2718 return endpos;
2723 /***********************************************************************
2724 Fontification
2725 ***********************************************************************/
2727 /* Handle changes in the `fontified' property of the current buffer by
2728 calling hook functions from Qfontification_functions to fontify
2729 regions of text. */
2731 static enum prop_handled
2732 handle_fontified_prop (it)
2733 struct it *it;
2735 Lisp_Object prop, pos;
2736 enum prop_handled handled = HANDLED_NORMALLY;
2738 /* Get the value of the `fontified' property at IT's current buffer
2739 position. (The `fontified' property doesn't have a special
2740 meaning in strings.) If the value is nil, call functions from
2741 Qfontification_functions. */
2742 if (!STRINGP (it->string)
2743 && it->s == NULL
2744 && !NILP (Vfontification_functions)
2745 && !NILP (Vrun_hooks)
2746 && (pos = make_number (IT_CHARPOS (*it)),
2747 prop = Fget_char_property (pos, Qfontified, Qnil),
2748 NILP (prop)))
2750 int count = SPECPDL_INDEX ();
2751 Lisp_Object val;
2753 val = Vfontification_functions;
2754 specbind (Qfontification_functions, Qnil);
2756 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2757 safe_call1 (val, pos);
2758 else
2760 Lisp_Object globals, fn;
2761 struct gcpro gcpro1, gcpro2;
2763 globals = Qnil;
2764 GCPRO2 (val, globals);
2766 for (; CONSP (val); val = XCDR (val))
2768 fn = XCAR (val);
2770 if (EQ (fn, Qt))
2772 /* A value of t indicates this hook has a local
2773 binding; it means to run the global binding too.
2774 In a global value, t should not occur. If it
2775 does, we must ignore it to avoid an endless
2776 loop. */
2777 for (globals = Fdefault_value (Qfontification_functions);
2778 CONSP (globals);
2779 globals = XCDR (globals))
2781 fn = XCAR (globals);
2782 if (!EQ (fn, Qt))
2783 safe_call1 (fn, pos);
2786 else
2787 safe_call1 (fn, pos);
2790 UNGCPRO;
2793 unbind_to (count, Qnil);
2795 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2796 something. This avoids an endless loop if they failed to
2797 fontify the text for which reason ever. */
2798 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2799 handled = HANDLED_RECOMPUTE_PROPS;
2802 return handled;
2807 /***********************************************************************
2808 Faces
2809 ***********************************************************************/
2811 /* Set up iterator IT from face properties at its current position.
2812 Called from handle_stop. */
2814 static enum prop_handled
2815 handle_face_prop (it)
2816 struct it *it;
2818 int new_face_id, next_stop;
2820 if (!STRINGP (it->string))
2822 new_face_id
2823 = face_at_buffer_position (it->w,
2824 IT_CHARPOS (*it),
2825 it->region_beg_charpos,
2826 it->region_end_charpos,
2827 &next_stop,
2828 (IT_CHARPOS (*it)
2829 + TEXT_PROP_DISTANCE_LIMIT),
2832 /* Is this a start of a run of characters with box face?
2833 Caveat: this can be called for a freshly initialized
2834 iterator; face_id is -1 in this case. We know that the new
2835 face will not change until limit, i.e. if the new face has a
2836 box, all characters up to limit will have one. But, as
2837 usual, we don't know whether limit is really the end. */
2838 if (new_face_id != it->face_id)
2840 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2842 /* If new face has a box but old face has not, this is
2843 the start of a run of characters with box, i.e. it has
2844 a shadow on the left side. The value of face_id of the
2845 iterator will be -1 if this is the initial call that gets
2846 the face. In this case, we have to look in front of IT's
2847 position and see whether there is a face != new_face_id. */
2848 it->start_of_box_run_p
2849 = (new_face->box != FACE_NO_BOX
2850 && (it->face_id >= 0
2851 || IT_CHARPOS (*it) == BEG
2852 || new_face_id != face_before_it_pos (it)));
2853 it->face_box_p = new_face->box != FACE_NO_BOX;
2856 else
2858 int base_face_id, bufpos;
2860 if (it->current.overlay_string_index >= 0)
2861 bufpos = IT_CHARPOS (*it);
2862 else
2863 bufpos = 0;
2865 /* For strings from a buffer, i.e. overlay strings or strings
2866 from a `display' property, use the face at IT's current
2867 buffer position as the base face to merge with, so that
2868 overlay strings appear in the same face as surrounding
2869 text, unless they specify their own faces. */
2870 base_face_id = underlying_face_id (it);
2872 new_face_id = face_at_string_position (it->w,
2873 it->string,
2874 IT_STRING_CHARPOS (*it),
2875 bufpos,
2876 it->region_beg_charpos,
2877 it->region_end_charpos,
2878 &next_stop,
2879 base_face_id, 0);
2881 #if 0 /* This shouldn't be neccessary. Let's check it. */
2882 /* If IT is used to display a mode line we would really like to
2883 use the mode line face instead of the frame's default face. */
2884 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2885 && new_face_id == DEFAULT_FACE_ID)
2886 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2887 #endif
2889 /* Is this a start of a run of characters with box? Caveat:
2890 this can be called for a freshly allocated iterator; face_id
2891 is -1 is this case. We know that the new face will not
2892 change until the next check pos, i.e. if the new face has a
2893 box, all characters up to that position will have a
2894 box. But, as usual, we don't know whether that position
2895 is really the end. */
2896 if (new_face_id != it->face_id)
2898 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2899 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2901 /* If new face has a box but old face hasn't, this is the
2902 start of a run of characters with box, i.e. it has a
2903 shadow on the left side. */
2904 it->start_of_box_run_p
2905 = new_face->box && (old_face == NULL || !old_face->box);
2906 it->face_box_p = new_face->box != FACE_NO_BOX;
2910 it->face_id = new_face_id;
2911 return HANDLED_NORMALLY;
2915 /* Return the ID of the face ``underlying'' IT's current position,
2916 which is in a string. If the iterator is associated with a
2917 buffer, return the face at IT's current buffer position.
2918 Otherwise, use the iterator's base_face_id. */
2920 static int
2921 underlying_face_id (it)
2922 struct it *it;
2924 int face_id = it->base_face_id, i;
2926 xassert (STRINGP (it->string));
2928 for (i = it->sp - 1; i >= 0; --i)
2929 if (NILP (it->stack[i].string))
2930 face_id = it->stack[i].face_id;
2932 return face_id;
2936 /* Compute the face one character before or after the current position
2937 of IT. BEFORE_P non-zero means get the face in front of IT's
2938 position. Value is the id of the face. */
2940 static int
2941 face_before_or_after_it_pos (it, before_p)
2942 struct it *it;
2943 int before_p;
2945 int face_id, limit;
2946 int next_check_charpos;
2947 struct text_pos pos;
2949 xassert (it->s == NULL);
2951 if (STRINGP (it->string))
2953 int bufpos, base_face_id;
2955 /* No face change past the end of the string (for the case
2956 we are padding with spaces). No face change before the
2957 string start. */
2958 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2959 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2960 return it->face_id;
2962 /* Set pos to the position before or after IT's current position. */
2963 if (before_p)
2964 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2965 else
2966 /* For composition, we must check the character after the
2967 composition. */
2968 pos = (it->what == IT_COMPOSITION
2969 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2970 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2972 if (it->current.overlay_string_index >= 0)
2973 bufpos = IT_CHARPOS (*it);
2974 else
2975 bufpos = 0;
2977 base_face_id = underlying_face_id (it);
2979 /* Get the face for ASCII, or unibyte. */
2980 face_id = face_at_string_position (it->w,
2981 it->string,
2982 CHARPOS (pos),
2983 bufpos,
2984 it->region_beg_charpos,
2985 it->region_end_charpos,
2986 &next_check_charpos,
2987 base_face_id, 0);
2989 /* Correct the face for charsets different from ASCII. Do it
2990 for the multibyte case only. The face returned above is
2991 suitable for unibyte text if IT->string is unibyte. */
2992 if (STRING_MULTIBYTE (it->string))
2994 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2995 int rest = SBYTES (it->string) - BYTEPOS (pos);
2996 int c, len;
2997 struct face *face = FACE_FROM_ID (it->f, face_id);
2999 c = string_char_and_length (p, rest, &len);
3000 face_id = FACE_FOR_CHAR (it->f, face, c);
3003 else
3005 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3006 || (IT_CHARPOS (*it) <= BEGV && before_p))
3007 return it->face_id;
3009 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3010 pos = it->current.pos;
3012 if (before_p)
3013 DEC_TEXT_POS (pos, it->multibyte_p);
3014 else
3016 if (it->what == IT_COMPOSITION)
3017 /* For composition, we must check the position after the
3018 composition. */
3019 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3020 else
3021 INC_TEXT_POS (pos, it->multibyte_p);
3024 /* Determine face for CHARSET_ASCII, or unibyte. */
3025 face_id = face_at_buffer_position (it->w,
3026 CHARPOS (pos),
3027 it->region_beg_charpos,
3028 it->region_end_charpos,
3029 &next_check_charpos,
3030 limit, 0);
3032 /* Correct the face for charsets different from ASCII. Do it
3033 for the multibyte case only. The face returned above is
3034 suitable for unibyte text if current_buffer is unibyte. */
3035 if (it->multibyte_p)
3037 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3038 struct face *face = FACE_FROM_ID (it->f, face_id);
3039 face_id = FACE_FOR_CHAR (it->f, face, c);
3043 return face_id;
3048 /***********************************************************************
3049 Invisible text
3050 ***********************************************************************/
3052 /* Set up iterator IT from invisible properties at its current
3053 position. Called from handle_stop. */
3055 static enum prop_handled
3056 handle_invisible_prop (it)
3057 struct it *it;
3059 enum prop_handled handled = HANDLED_NORMALLY;
3061 if (STRINGP (it->string))
3063 extern Lisp_Object Qinvisible;
3064 Lisp_Object prop, end_charpos, limit, charpos;
3066 /* Get the value of the invisible text property at the
3067 current position. Value will be nil if there is no such
3068 property. */
3069 charpos = make_number (IT_STRING_CHARPOS (*it));
3070 prop = Fget_text_property (charpos, Qinvisible, it->string);
3072 if (!NILP (prop)
3073 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3075 handled = HANDLED_RECOMPUTE_PROPS;
3077 /* Get the position at which the next change of the
3078 invisible text property can be found in IT->string.
3079 Value will be nil if the property value is the same for
3080 all the rest of IT->string. */
3081 XSETINT (limit, SCHARS (it->string));
3082 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3083 it->string, limit);
3085 /* Text at current position is invisible. The next
3086 change in the property is at position end_charpos.
3087 Move IT's current position to that position. */
3088 if (INTEGERP (end_charpos)
3089 && XFASTINT (end_charpos) < XFASTINT (limit))
3091 struct text_pos old;
3092 old = it->current.string_pos;
3093 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3094 compute_string_pos (&it->current.string_pos, old, it->string);
3096 else
3098 /* The rest of the string is invisible. If this is an
3099 overlay string, proceed with the next overlay string
3100 or whatever comes and return a character from there. */
3101 if (it->current.overlay_string_index >= 0)
3103 next_overlay_string (it);
3104 /* Don't check for overlay strings when we just
3105 finished processing them. */
3106 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3108 else
3110 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3111 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3116 else
3118 int invis_p, newpos, next_stop, start_charpos;
3119 Lisp_Object pos, prop, overlay;
3121 /* First of all, is there invisible text at this position? */
3122 start_charpos = IT_CHARPOS (*it);
3123 pos = make_number (IT_CHARPOS (*it));
3124 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3125 &overlay);
3126 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3128 /* If we are on invisible text, skip over it. */
3129 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3131 /* Record whether we have to display an ellipsis for the
3132 invisible text. */
3133 int display_ellipsis_p = invis_p == 2;
3135 handled = HANDLED_RECOMPUTE_PROPS;
3137 /* Loop skipping over invisible text. The loop is left at
3138 ZV or with IT on the first char being visible again. */
3141 /* Try to skip some invisible text. Return value is the
3142 position reached which can be equal to IT's position
3143 if there is nothing invisible here. This skips both
3144 over invisible text properties and overlays with
3145 invisible property. */
3146 newpos = skip_invisible (IT_CHARPOS (*it),
3147 &next_stop, ZV, it->window);
3149 /* If we skipped nothing at all we weren't at invisible
3150 text in the first place. If everything to the end of
3151 the buffer was skipped, end the loop. */
3152 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3153 invis_p = 0;
3154 else
3156 /* We skipped some characters but not necessarily
3157 all there are. Check if we ended up on visible
3158 text. Fget_char_property returns the property of
3159 the char before the given position, i.e. if we
3160 get invis_p = 0, this means that the char at
3161 newpos is visible. */
3162 pos = make_number (newpos);
3163 prop = Fget_char_property (pos, Qinvisible, it->window);
3164 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3167 /* If we ended up on invisible text, proceed to
3168 skip starting with next_stop. */
3169 if (invis_p)
3170 IT_CHARPOS (*it) = next_stop;
3172 while (invis_p);
3174 /* The position newpos is now either ZV or on visible text. */
3175 IT_CHARPOS (*it) = newpos;
3176 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3178 /* If there are before-strings at the start of invisible
3179 text, and the text is invisible because of a text
3180 property, arrange to show before-strings because 20.x did
3181 it that way. (If the text is invisible because of an
3182 overlay property instead of a text property, this is
3183 already handled in the overlay code.) */
3184 if (NILP (overlay)
3185 && get_overlay_strings (it, start_charpos))
3187 handled = HANDLED_RECOMPUTE_PROPS;
3188 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3190 else if (display_ellipsis_p)
3191 setup_for_ellipsis (it);
3195 return handled;
3199 /* Make iterator IT return `...' next. */
3201 static void
3202 setup_for_ellipsis (it)
3203 struct it *it;
3205 if (it->dp
3206 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3208 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3209 it->dpvec = v->contents;
3210 it->dpend = v->contents + v->size;
3212 else
3214 /* Default `...'. */
3215 it->dpvec = default_invis_vector;
3216 it->dpend = default_invis_vector + 3;
3219 /* The ellipsis display does not replace the display of the
3220 character at the new position. Indicate this by setting
3221 IT->dpvec_char_len to zero. */
3222 it->dpvec_char_len = 0;
3224 it->current.dpvec_index = 0;
3225 it->method = next_element_from_display_vector;
3230 /***********************************************************************
3231 'display' property
3232 ***********************************************************************/
3234 /* Set up iterator IT from `display' property at its current position.
3235 Called from handle_stop. */
3237 static enum prop_handled
3238 handle_display_prop (it)
3239 struct it *it;
3241 Lisp_Object prop, object;
3242 struct text_pos *position;
3243 int display_replaced_p = 0;
3245 if (STRINGP (it->string))
3247 object = it->string;
3248 position = &it->current.string_pos;
3250 else
3252 object = it->w->buffer;
3253 position = &it->current.pos;
3256 /* Reset those iterator values set from display property values. */
3257 it->font_height = Qnil;
3258 it->space_width = Qnil;
3259 it->voffset = 0;
3261 /* We don't support recursive `display' properties, i.e. string
3262 values that have a string `display' property, that have a string
3263 `display' property etc. */
3264 if (!it->string_from_display_prop_p)
3265 it->area = TEXT_AREA;
3267 prop = Fget_char_property (make_number (position->charpos),
3268 Qdisplay, object);
3269 if (NILP (prop))
3270 return HANDLED_NORMALLY;
3272 if (CONSP (prop)
3273 /* Simple properties. */
3274 && !EQ (XCAR (prop), Qimage)
3275 && !EQ (XCAR (prop), Qspace)
3276 && !EQ (XCAR (prop), Qwhen)
3277 && !EQ (XCAR (prop), Qspace_width)
3278 && !EQ (XCAR (prop), Qheight)
3279 && !EQ (XCAR (prop), Qraise)
3280 /* Marginal area specifications. */
3281 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3282 && !NILP (XCAR (prop)))
3284 for (; CONSP (prop); prop = XCDR (prop))
3286 if (handle_single_display_prop (it, XCAR (prop), object,
3287 position, display_replaced_p))
3288 display_replaced_p = 1;
3291 else if (VECTORP (prop))
3293 int i;
3294 for (i = 0; i < ASIZE (prop); ++i)
3295 if (handle_single_display_prop (it, AREF (prop, i), object,
3296 position, display_replaced_p))
3297 display_replaced_p = 1;
3299 else
3301 if (handle_single_display_prop (it, prop, object, position, 0))
3302 display_replaced_p = 1;
3305 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3309 /* Value is the position of the end of the `display' property starting
3310 at START_POS in OBJECT. */
3312 static struct text_pos
3313 display_prop_end (it, object, start_pos)
3314 struct it *it;
3315 Lisp_Object object;
3316 struct text_pos start_pos;
3318 Lisp_Object end;
3319 struct text_pos end_pos;
3321 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3322 Qdisplay, object, Qnil);
3323 CHARPOS (end_pos) = XFASTINT (end);
3324 if (STRINGP (object))
3325 compute_string_pos (&end_pos, start_pos, it->string);
3326 else
3327 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3329 return end_pos;
3333 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3334 is the object in which the `display' property was found. *POSITION
3335 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3336 means that we previously saw a display sub-property which already
3337 replaced text display with something else, for example an image;
3338 ignore such properties after the first one has been processed.
3340 If PROP is a `space' or `image' sub-property, set *POSITION to the
3341 end position of the `display' property.
3343 Value is non-zero if something was found which replaces the display
3344 of buffer or string text. */
3346 static int
3347 handle_single_display_prop (it, prop, object, position,
3348 display_replaced_before_p)
3349 struct it *it;
3350 Lisp_Object prop;
3351 Lisp_Object object;
3352 struct text_pos *position;
3353 int display_replaced_before_p;
3355 Lisp_Object value;
3356 int replaces_text_display_p = 0;
3357 Lisp_Object form;
3359 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3360 evaluated. If the result is nil, VALUE is ignored. */
3361 form = Qt;
3362 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3364 prop = XCDR (prop);
3365 if (!CONSP (prop))
3366 return 0;
3367 form = XCAR (prop);
3368 prop = XCDR (prop);
3371 if (!NILP (form) && !EQ (form, Qt))
3373 int count = SPECPDL_INDEX ();
3374 struct gcpro gcpro1;
3376 /* Bind `object' to the object having the `display' property, a
3377 buffer or string. Bind `position' to the position in the
3378 object where the property was found, and `buffer-position'
3379 to the current position in the buffer. */
3380 specbind (Qobject, object);
3381 specbind (Qposition, make_number (CHARPOS (*position)));
3382 specbind (Qbuffer_position,
3383 make_number (STRINGP (object)
3384 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3385 GCPRO1 (form);
3386 form = safe_eval (form);
3387 UNGCPRO;
3388 unbind_to (count, Qnil);
3391 if (NILP (form))
3392 return 0;
3394 if (CONSP (prop)
3395 && EQ (XCAR (prop), Qheight)
3396 && CONSP (XCDR (prop)))
3398 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3399 return 0;
3401 /* `(height HEIGHT)'. */
3402 it->font_height = XCAR (XCDR (prop));
3403 if (!NILP (it->font_height))
3405 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3406 int new_height = -1;
3408 if (CONSP (it->font_height)
3409 && (EQ (XCAR (it->font_height), Qplus)
3410 || EQ (XCAR (it->font_height), Qminus))
3411 && CONSP (XCDR (it->font_height))
3412 && INTEGERP (XCAR (XCDR (it->font_height))))
3414 /* `(+ N)' or `(- N)' where N is an integer. */
3415 int steps = XINT (XCAR (XCDR (it->font_height)));
3416 if (EQ (XCAR (it->font_height), Qplus))
3417 steps = - steps;
3418 it->face_id = smaller_face (it->f, it->face_id, steps);
3420 else if (FUNCTIONP (it->font_height))
3422 /* Call function with current height as argument.
3423 Value is the new height. */
3424 Lisp_Object height;
3425 height = safe_call1 (it->font_height,
3426 face->lface[LFACE_HEIGHT_INDEX]);
3427 if (NUMBERP (height))
3428 new_height = XFLOATINT (height);
3430 else if (NUMBERP (it->font_height))
3432 /* Value is a multiple of the canonical char height. */
3433 struct face *face;
3435 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3436 new_height = (XFLOATINT (it->font_height)
3437 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3439 else
3441 /* Evaluate IT->font_height with `height' bound to the
3442 current specified height to get the new height. */
3443 Lisp_Object value;
3444 int count = SPECPDL_INDEX ();
3446 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3447 value = safe_eval (it->font_height);
3448 unbind_to (count, Qnil);
3450 if (NUMBERP (value))
3451 new_height = XFLOATINT (value);
3454 if (new_height > 0)
3455 it->face_id = face_with_height (it->f, it->face_id, new_height);
3458 else if (CONSP (prop)
3459 && EQ (XCAR (prop), Qspace_width)
3460 && CONSP (XCDR (prop)))
3462 /* `(space_width WIDTH)'. */
3463 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3464 return 0;
3466 value = XCAR (XCDR (prop));
3467 if (NUMBERP (value) && XFLOATINT (value) > 0)
3468 it->space_width = value;
3470 else if (CONSP (prop)
3471 && EQ (XCAR (prop), Qraise)
3472 && CONSP (XCDR (prop)))
3474 /* `(raise FACTOR)'. */
3475 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3476 return 0;
3478 #ifdef HAVE_WINDOW_SYSTEM
3479 value = XCAR (XCDR (prop));
3480 if (NUMBERP (value))
3482 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3483 it->voffset = - (XFLOATINT (value)
3484 * (FONT_HEIGHT (face->font)));
3486 #endif /* HAVE_WINDOW_SYSTEM */
3488 else if (!it->string_from_display_prop_p)
3490 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3491 VALUE) or `((margin nil) VALUE)' or VALUE. */
3492 Lisp_Object location, value;
3493 struct text_pos start_pos;
3494 int valid_p;
3496 /* Characters having this form of property are not displayed, so
3497 we have to find the end of the property. */
3498 start_pos = *position;
3499 *position = display_prop_end (it, object, start_pos);
3500 value = Qnil;
3502 /* Let's stop at the new position and assume that all
3503 text properties change there. */
3504 it->stop_charpos = position->charpos;
3506 location = Qunbound;
3507 if (CONSP (prop) && CONSP (XCAR (prop)))
3509 Lisp_Object tem;
3511 value = XCDR (prop);
3512 if (CONSP (value))
3513 value = XCAR (value);
3515 tem = XCAR (prop);
3516 if (EQ (XCAR (tem), Qmargin)
3517 && (tem = XCDR (tem),
3518 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3519 (NILP (tem)
3520 || EQ (tem, Qleft_margin)
3521 || EQ (tem, Qright_margin))))
3522 location = tem;
3525 if (EQ (location, Qunbound))
3527 location = Qnil;
3528 value = prop;
3531 #ifdef HAVE_WINDOW_SYSTEM
3532 if (FRAME_TERMCAP_P (it->f))
3533 valid_p = STRINGP (value);
3534 else
3535 valid_p = (STRINGP (value)
3536 || (CONSP (value) && EQ (XCAR (value), Qspace))
3537 || valid_image_p (value));
3538 #else /* not HAVE_WINDOW_SYSTEM */
3539 valid_p = STRINGP (value);
3540 #endif /* not HAVE_WINDOW_SYSTEM */
3542 if ((EQ (location, Qleft_margin)
3543 || EQ (location, Qright_margin)
3544 || NILP (location))
3545 && valid_p
3546 && !display_replaced_before_p)
3548 replaces_text_display_p = 1;
3550 /* Save current settings of IT so that we can restore them
3551 when we are finished with the glyph property value. */
3552 push_it (it);
3554 if (NILP (location))
3555 it->area = TEXT_AREA;
3556 else if (EQ (location, Qleft_margin))
3557 it->area = LEFT_MARGIN_AREA;
3558 else
3559 it->area = RIGHT_MARGIN_AREA;
3561 if (STRINGP (value))
3563 it->string = value;
3564 it->multibyte_p = STRING_MULTIBYTE (it->string);
3565 it->current.overlay_string_index = -1;
3566 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3567 it->end_charpos = it->string_nchars = SCHARS (it->string);
3568 it->method = next_element_from_string;
3569 it->stop_charpos = 0;
3570 it->string_from_display_prop_p = 1;
3571 /* Say that we haven't consumed the characters with
3572 `display' property yet. The call to pop_it in
3573 set_iterator_to_next will clean this up. */
3574 *position = start_pos;
3576 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3578 it->method = next_element_from_stretch;
3579 it->object = value;
3580 it->current.pos = it->position = start_pos;
3582 #ifdef HAVE_WINDOW_SYSTEM
3583 else
3585 it->what = IT_IMAGE;
3586 it->image_id = lookup_image (it->f, value);
3587 it->position = start_pos;
3588 it->object = NILP (object) ? it->w->buffer : object;
3589 it->method = next_element_from_image;
3591 /* Say that we haven't consumed the characters with
3592 `display' property yet. The call to pop_it in
3593 set_iterator_to_next will clean this up. */
3594 *position = start_pos;
3596 #endif /* HAVE_WINDOW_SYSTEM */
3598 else
3599 /* Invalid property or property not supported. Restore
3600 the position to what it was before. */
3601 *position = start_pos;
3604 return replaces_text_display_p;
3608 /* Check if PROP is a display sub-property value whose text should be
3609 treated as intangible. */
3611 static int
3612 single_display_prop_intangible_p (prop)
3613 Lisp_Object prop;
3615 /* Skip over `when FORM'. */
3616 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3618 prop = XCDR (prop);
3619 if (!CONSP (prop))
3620 return 0;
3621 prop = XCDR (prop);
3624 if (STRINGP (prop))
3625 return 1;
3627 if (!CONSP (prop))
3628 return 0;
3630 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3631 we don't need to treat text as intangible. */
3632 if (EQ (XCAR (prop), Qmargin))
3634 prop = XCDR (prop);
3635 if (!CONSP (prop))
3636 return 0;
3638 prop = XCDR (prop);
3639 if (!CONSP (prop)
3640 || EQ (XCAR (prop), Qleft_margin)
3641 || EQ (XCAR (prop), Qright_margin))
3642 return 0;
3645 return (CONSP (prop)
3646 && (EQ (XCAR (prop), Qimage)
3647 || EQ (XCAR (prop), Qspace)));
3651 /* Check if PROP is a display property value whose text should be
3652 treated as intangible. */
3655 display_prop_intangible_p (prop)
3656 Lisp_Object prop;
3658 if (CONSP (prop)
3659 && CONSP (XCAR (prop))
3660 && !EQ (Qmargin, XCAR (XCAR (prop))))
3662 /* A list of sub-properties. */
3663 while (CONSP (prop))
3665 if (single_display_prop_intangible_p (XCAR (prop)))
3666 return 1;
3667 prop = XCDR (prop);
3670 else if (VECTORP (prop))
3672 /* A vector of sub-properties. */
3673 int i;
3674 for (i = 0; i < ASIZE (prop); ++i)
3675 if (single_display_prop_intangible_p (AREF (prop, i)))
3676 return 1;
3678 else
3679 return single_display_prop_intangible_p (prop);
3681 return 0;
3685 /* Return 1 if PROP is a display sub-property value containing STRING. */
3687 static int
3688 single_display_prop_string_p (prop, string)
3689 Lisp_Object prop, string;
3691 if (EQ (string, prop))
3692 return 1;
3694 /* Skip over `when FORM'. */
3695 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3697 prop = XCDR (prop);
3698 if (!CONSP (prop))
3699 return 0;
3700 prop = XCDR (prop);
3703 if (CONSP (prop))
3704 /* Skip over `margin LOCATION'. */
3705 if (EQ (XCAR (prop), Qmargin))
3707 prop = XCDR (prop);
3708 if (!CONSP (prop))
3709 return 0;
3711 prop = XCDR (prop);
3712 if (!CONSP (prop))
3713 return 0;
3716 return CONSP (prop) && EQ (XCAR (prop), string);
3720 /* Return 1 if STRING appears in the `display' property PROP. */
3722 static int
3723 display_prop_string_p (prop, string)
3724 Lisp_Object prop, string;
3726 if (CONSP (prop)
3727 && CONSP (XCAR (prop))
3728 && !EQ (Qmargin, XCAR (XCAR (prop))))
3730 /* A list of sub-properties. */
3731 while (CONSP (prop))
3733 if (single_display_prop_string_p (XCAR (prop), string))
3734 return 1;
3735 prop = XCDR (prop);
3738 else if (VECTORP (prop))
3740 /* A vector of sub-properties. */
3741 int i;
3742 for (i = 0; i < ASIZE (prop); ++i)
3743 if (single_display_prop_string_p (AREF (prop, i), string))
3744 return 1;
3746 else
3747 return single_display_prop_string_p (prop, string);
3749 return 0;
3753 /* Determine from which buffer position in W's buffer STRING comes
3754 from. AROUND_CHARPOS is an approximate position where it could
3755 be from. Value is the buffer position or 0 if it couldn't be
3756 determined.
3758 W's buffer must be current.
3760 This function is necessary because we don't record buffer positions
3761 in glyphs generated from strings (to keep struct glyph small).
3762 This function may only use code that doesn't eval because it is
3763 called asynchronously from note_mouse_highlight. */
3766 string_buffer_position (w, string, around_charpos)
3767 struct window *w;
3768 Lisp_Object string;
3769 int around_charpos;
3771 Lisp_Object limit, prop, pos;
3772 const int MAX_DISTANCE = 1000;
3773 int found = 0;
3775 pos = make_number (around_charpos);
3776 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3777 while (!found && !EQ (pos, limit))
3779 prop = Fget_char_property (pos, Qdisplay, Qnil);
3780 if (!NILP (prop) && display_prop_string_p (prop, string))
3781 found = 1;
3782 else
3783 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3786 if (!found)
3788 pos = make_number (around_charpos);
3789 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3790 while (!found && !EQ (pos, limit))
3792 prop = Fget_char_property (pos, Qdisplay, Qnil);
3793 if (!NILP (prop) && display_prop_string_p (prop, string))
3794 found = 1;
3795 else
3796 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3797 limit);
3801 return found ? XINT (pos) : 0;
3806 /***********************************************************************
3807 `composition' property
3808 ***********************************************************************/
3810 /* Set up iterator IT from `composition' property at its current
3811 position. Called from handle_stop. */
3813 static enum prop_handled
3814 handle_composition_prop (it)
3815 struct it *it;
3817 Lisp_Object prop, string;
3818 int pos, pos_byte, end;
3819 enum prop_handled handled = HANDLED_NORMALLY;
3821 if (STRINGP (it->string))
3823 pos = IT_STRING_CHARPOS (*it);
3824 pos_byte = IT_STRING_BYTEPOS (*it);
3825 string = it->string;
3827 else
3829 pos = IT_CHARPOS (*it);
3830 pos_byte = IT_BYTEPOS (*it);
3831 string = Qnil;
3834 /* If there's a valid composition and point is not inside of the
3835 composition (in the case that the composition is from the current
3836 buffer), draw a glyph composed from the composition components. */
3837 if (find_composition (pos, -1, &pos, &end, &prop, string)
3838 && COMPOSITION_VALID_P (pos, end, prop)
3839 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3841 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3843 if (id >= 0)
3845 it->method = next_element_from_composition;
3846 it->cmp_id = id;
3847 it->cmp_len = COMPOSITION_LENGTH (prop);
3848 /* For a terminal, draw only the first character of the
3849 components. */
3850 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3851 it->len = (STRINGP (it->string)
3852 ? string_char_to_byte (it->string, end)
3853 : CHAR_TO_BYTE (end)) - pos_byte;
3854 it->stop_charpos = end;
3855 handled = HANDLED_RETURN;
3859 return handled;
3864 /***********************************************************************
3865 Overlay strings
3866 ***********************************************************************/
3868 /* The following structure is used to record overlay strings for
3869 later sorting in load_overlay_strings. */
3871 struct overlay_entry
3873 Lisp_Object overlay;
3874 Lisp_Object string;
3875 int priority;
3876 int after_string_p;
3880 /* Set up iterator IT from overlay strings at its current position.
3881 Called from handle_stop. */
3883 static enum prop_handled
3884 handle_overlay_change (it)
3885 struct it *it;
3887 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3888 return HANDLED_RECOMPUTE_PROPS;
3889 else
3890 return HANDLED_NORMALLY;
3894 /* Set up the next overlay string for delivery by IT, if there is an
3895 overlay string to deliver. Called by set_iterator_to_next when the
3896 end of the current overlay string is reached. If there are more
3897 overlay strings to display, IT->string and
3898 IT->current.overlay_string_index are set appropriately here.
3899 Otherwise IT->string is set to nil. */
3901 static void
3902 next_overlay_string (it)
3903 struct it *it;
3905 ++it->current.overlay_string_index;
3906 if (it->current.overlay_string_index == it->n_overlay_strings)
3908 /* No more overlay strings. Restore IT's settings to what
3909 they were before overlay strings were processed, and
3910 continue to deliver from current_buffer. */
3911 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3913 pop_it (it);
3914 xassert (it->stop_charpos >= BEGV
3915 && it->stop_charpos <= it->end_charpos);
3916 it->string = Qnil;
3917 it->current.overlay_string_index = -1;
3918 SET_TEXT_POS (it->current.string_pos, -1, -1);
3919 it->n_overlay_strings = 0;
3920 it->method = next_element_from_buffer;
3922 /* If we're at the end of the buffer, record that we have
3923 processed the overlay strings there already, so that
3924 next_element_from_buffer doesn't try it again. */
3925 if (IT_CHARPOS (*it) >= it->end_charpos)
3926 it->overlay_strings_at_end_processed_p = 1;
3928 /* If we have to display `...' for invisible text, set
3929 the iterator up for that. */
3930 if (display_ellipsis_p)
3931 setup_for_ellipsis (it);
3933 else
3935 /* There are more overlay strings to process. If
3936 IT->current.overlay_string_index has advanced to a position
3937 where we must load IT->overlay_strings with more strings, do
3938 it. */
3939 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3941 if (it->current.overlay_string_index && i == 0)
3942 load_overlay_strings (it, 0);
3944 /* Initialize IT to deliver display elements from the overlay
3945 string. */
3946 it->string = it->overlay_strings[i];
3947 it->multibyte_p = STRING_MULTIBYTE (it->string);
3948 SET_TEXT_POS (it->current.string_pos, 0, 0);
3949 it->method = next_element_from_string;
3950 it->stop_charpos = 0;
3953 CHECK_IT (it);
3957 /* Compare two overlay_entry structures E1 and E2. Used as a
3958 comparison function for qsort in load_overlay_strings. Overlay
3959 strings for the same position are sorted so that
3961 1. All after-strings come in front of before-strings, except
3962 when they come from the same overlay.
3964 2. Within after-strings, strings are sorted so that overlay strings
3965 from overlays with higher priorities come first.
3967 2. Within before-strings, strings are sorted so that overlay
3968 strings from overlays with higher priorities come last.
3970 Value is analogous to strcmp. */
3973 static int
3974 compare_overlay_entries (e1, e2)
3975 void *e1, *e2;
3977 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
3978 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
3979 int result;
3981 if (entry1->after_string_p != entry2->after_string_p)
3983 /* Let after-strings appear in front of before-strings if
3984 they come from different overlays. */
3985 if (EQ (entry1->overlay, entry2->overlay))
3986 result = entry1->after_string_p ? 1 : -1;
3987 else
3988 result = entry1->after_string_p ? -1 : 1;
3990 else if (entry1->after_string_p)
3991 /* After-strings sorted in order of decreasing priority. */
3992 result = entry2->priority - entry1->priority;
3993 else
3994 /* Before-strings sorted in order of increasing priority. */
3995 result = entry1->priority - entry2->priority;
3997 return result;
4001 /* Load the vector IT->overlay_strings with overlay strings from IT's
4002 current buffer position, or from CHARPOS if that is > 0. Set
4003 IT->n_overlays to the total number of overlay strings found.
4005 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4006 a time. On entry into load_overlay_strings,
4007 IT->current.overlay_string_index gives the number of overlay
4008 strings that have already been loaded by previous calls to this
4009 function.
4011 IT->add_overlay_start contains an additional overlay start
4012 position to consider for taking overlay strings from, if non-zero.
4013 This position comes into play when the overlay has an `invisible'
4014 property, and both before and after-strings. When we've skipped to
4015 the end of the overlay, because of its `invisible' property, we
4016 nevertheless want its before-string to appear.
4017 IT->add_overlay_start will contain the overlay start position
4018 in this case.
4020 Overlay strings are sorted so that after-string strings come in
4021 front of before-string strings. Within before and after-strings,
4022 strings are sorted by overlay priority. See also function
4023 compare_overlay_entries. */
4025 static void
4026 load_overlay_strings (it, charpos)
4027 struct it *it;
4028 int charpos;
4030 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4031 Lisp_Object overlay, window, str, invisible;
4032 struct Lisp_Overlay *ov;
4033 int start, end;
4034 int size = 20;
4035 int n = 0, i, j, invis_p;
4036 struct overlay_entry *entries
4037 = (struct overlay_entry *) alloca (size * sizeof *entries);
4039 if (charpos <= 0)
4040 charpos = IT_CHARPOS (*it);
4042 /* Append the overlay string STRING of overlay OVERLAY to vector
4043 `entries' which has size `size' and currently contains `n'
4044 elements. AFTER_P non-zero means STRING is an after-string of
4045 OVERLAY. */
4046 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4047 do \
4049 Lisp_Object priority; \
4051 if (n == size) \
4053 int new_size = 2 * size; \
4054 struct overlay_entry *old = entries; \
4055 entries = \
4056 (struct overlay_entry *) alloca (new_size \
4057 * sizeof *entries); \
4058 bcopy (old, entries, size * sizeof *entries); \
4059 size = new_size; \
4062 entries[n].string = (STRING); \
4063 entries[n].overlay = (OVERLAY); \
4064 priority = Foverlay_get ((OVERLAY), Qpriority); \
4065 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4066 entries[n].after_string_p = (AFTER_P); \
4067 ++n; \
4069 while (0)
4071 /* Process overlay before the overlay center. */
4072 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4074 XSETMISC (overlay, ov);
4075 xassert (OVERLAYP (overlay));
4076 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4077 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4079 if (end < charpos)
4080 break;
4082 /* Skip this overlay if it doesn't start or end at IT's current
4083 position. */
4084 if (end != charpos && start != charpos)
4085 continue;
4087 /* Skip this overlay if it doesn't apply to IT->w. */
4088 window = Foverlay_get (overlay, Qwindow);
4089 if (WINDOWP (window) && XWINDOW (window) != it->w)
4090 continue;
4092 /* If the text ``under'' the overlay is invisible, both before-
4093 and after-strings from this overlay are visible; start and
4094 end position are indistinguishable. */
4095 invisible = Foverlay_get (overlay, Qinvisible);
4096 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4098 /* If overlay has a non-empty before-string, record it. */
4099 if ((start == charpos || (end == charpos && invis_p))
4100 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4101 && SCHARS (str))
4102 RECORD_OVERLAY_STRING (overlay, str, 0);
4104 /* If overlay has a non-empty after-string, record it. */
4105 if ((end == charpos || (start == charpos && invis_p))
4106 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4107 && SCHARS (str))
4108 RECORD_OVERLAY_STRING (overlay, str, 1);
4111 /* Process overlays after the overlay center. */
4112 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4114 XSETMISC (overlay, ov);
4115 xassert (OVERLAYP (overlay));
4116 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4117 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4119 if (start > charpos)
4120 break;
4122 /* Skip this overlay if it doesn't start or end at IT's current
4123 position. */
4124 if (end != charpos && start != charpos)
4125 continue;
4127 /* Skip this overlay if it doesn't apply to IT->w. */
4128 window = Foverlay_get (overlay, Qwindow);
4129 if (WINDOWP (window) && XWINDOW (window) != it->w)
4130 continue;
4132 /* If the text ``under'' the overlay is invisible, it has a zero
4133 dimension, and both before- and after-strings apply. */
4134 invisible = Foverlay_get (overlay, Qinvisible);
4135 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4137 /* If overlay has a non-empty before-string, record it. */
4138 if ((start == charpos || (end == charpos && invis_p))
4139 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4140 && SCHARS (str))
4141 RECORD_OVERLAY_STRING (overlay, str, 0);
4143 /* If overlay has a non-empty after-string, record it. */
4144 if ((end == charpos || (start == charpos && invis_p))
4145 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4146 && SCHARS (str))
4147 RECORD_OVERLAY_STRING (overlay, str, 1);
4150 #undef RECORD_OVERLAY_STRING
4152 /* Sort entries. */
4153 if (n > 1)
4154 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4156 /* Record the total number of strings to process. */
4157 it->n_overlay_strings = n;
4159 /* IT->current.overlay_string_index is the number of overlay strings
4160 that have already been consumed by IT. Copy some of the
4161 remaining overlay strings to IT->overlay_strings. */
4162 i = 0;
4163 j = it->current.overlay_string_index;
4164 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4165 it->overlay_strings[i++] = entries[j++].string;
4167 CHECK_IT (it);
4171 /* Get the first chunk of overlay strings at IT's current buffer
4172 position, or at CHARPOS if that is > 0. Value is non-zero if at
4173 least one overlay string was found. */
4175 static int
4176 get_overlay_strings (it, charpos)
4177 struct it *it;
4178 int charpos;
4180 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4181 process. This fills IT->overlay_strings with strings, and sets
4182 IT->n_overlay_strings to the total number of strings to process.
4183 IT->pos.overlay_string_index has to be set temporarily to zero
4184 because load_overlay_strings needs this; it must be set to -1
4185 when no overlay strings are found because a zero value would
4186 indicate a position in the first overlay string. */
4187 it->current.overlay_string_index = 0;
4188 load_overlay_strings (it, charpos);
4190 /* If we found overlay strings, set up IT to deliver display
4191 elements from the first one. Otherwise set up IT to deliver
4192 from current_buffer. */
4193 if (it->n_overlay_strings)
4195 /* Make sure we know settings in current_buffer, so that we can
4196 restore meaningful values when we're done with the overlay
4197 strings. */
4198 compute_stop_pos (it);
4199 xassert (it->face_id >= 0);
4201 /* Save IT's settings. They are restored after all overlay
4202 strings have been processed. */
4203 xassert (it->sp == 0);
4204 push_it (it);
4206 /* Set up IT to deliver display elements from the first overlay
4207 string. */
4208 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4209 it->string = it->overlay_strings[0];
4210 it->stop_charpos = 0;
4211 xassert (STRINGP (it->string));
4212 it->end_charpos = SCHARS (it->string);
4213 it->multibyte_p = STRING_MULTIBYTE (it->string);
4214 it->method = next_element_from_string;
4216 else
4218 it->string = Qnil;
4219 it->current.overlay_string_index = -1;
4220 it->method = next_element_from_buffer;
4223 CHECK_IT (it);
4225 /* Value is non-zero if we found at least one overlay string. */
4226 return STRINGP (it->string);
4231 /***********************************************************************
4232 Saving and restoring state
4233 ***********************************************************************/
4235 /* Save current settings of IT on IT->stack. Called, for example,
4236 before setting up IT for an overlay string, to be able to restore
4237 IT's settings to what they were after the overlay string has been
4238 processed. */
4240 static void
4241 push_it (it)
4242 struct it *it;
4244 struct iterator_stack_entry *p;
4246 xassert (it->sp < 2);
4247 p = it->stack + it->sp;
4249 p->stop_charpos = it->stop_charpos;
4250 xassert (it->face_id >= 0);
4251 p->face_id = it->face_id;
4252 p->string = it->string;
4253 p->pos = it->current;
4254 p->end_charpos = it->end_charpos;
4255 p->string_nchars = it->string_nchars;
4256 p->area = it->area;
4257 p->multibyte_p = it->multibyte_p;
4258 p->space_width = it->space_width;
4259 p->font_height = it->font_height;
4260 p->voffset = it->voffset;
4261 p->string_from_display_prop_p = it->string_from_display_prop_p;
4262 p->display_ellipsis_p = 0;
4263 ++it->sp;
4267 /* Restore IT's settings from IT->stack. Called, for example, when no
4268 more overlay strings must be processed, and we return to delivering
4269 display elements from a buffer, or when the end of a string from a
4270 `display' property is reached and we return to delivering display
4271 elements from an overlay string, or from a buffer. */
4273 static void
4274 pop_it (it)
4275 struct it *it;
4277 struct iterator_stack_entry *p;
4279 xassert (it->sp > 0);
4280 --it->sp;
4281 p = it->stack + it->sp;
4282 it->stop_charpos = p->stop_charpos;
4283 it->face_id = p->face_id;
4284 it->string = p->string;
4285 it->current = p->pos;
4286 it->end_charpos = p->end_charpos;
4287 it->string_nchars = p->string_nchars;
4288 it->area = p->area;
4289 it->multibyte_p = p->multibyte_p;
4290 it->space_width = p->space_width;
4291 it->font_height = p->font_height;
4292 it->voffset = p->voffset;
4293 it->string_from_display_prop_p = p->string_from_display_prop_p;
4298 /***********************************************************************
4299 Moving over lines
4300 ***********************************************************************/
4302 /* Set IT's current position to the previous line start. */
4304 static void
4305 back_to_previous_line_start (it)
4306 struct it *it;
4308 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4309 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4313 /* Move IT to the next line start.
4315 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4316 we skipped over part of the text (as opposed to moving the iterator
4317 continuously over the text). Otherwise, don't change the value
4318 of *SKIPPED_P.
4320 Newlines may come from buffer text, overlay strings, or strings
4321 displayed via the `display' property. That's the reason we can't
4322 simply use find_next_newline_no_quit.
4324 Note that this function may not skip over invisible text that is so
4325 because of text properties and immediately follows a newline. If
4326 it would, function reseat_at_next_visible_line_start, when called
4327 from set_iterator_to_next, would effectively make invisible
4328 characters following a newline part of the wrong glyph row, which
4329 leads to wrong cursor motion. */
4331 static int
4332 forward_to_next_line_start (it, skipped_p)
4333 struct it *it;
4334 int *skipped_p;
4336 int old_selective, newline_found_p, n;
4337 const int MAX_NEWLINE_DISTANCE = 500;
4339 /* If already on a newline, just consume it to avoid unintended
4340 skipping over invisible text below. */
4341 if (it->what == IT_CHARACTER
4342 && it->c == '\n'
4343 && CHARPOS (it->position) == IT_CHARPOS (*it))
4345 set_iterator_to_next (it, 0);
4346 it->c = 0;
4347 return 1;
4350 /* Don't handle selective display in the following. It's (a)
4351 unnecessary because it's done by the caller, and (b) leads to an
4352 infinite recursion because next_element_from_ellipsis indirectly
4353 calls this function. */
4354 old_selective = it->selective;
4355 it->selective = 0;
4357 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4358 from buffer text. */
4359 for (n = newline_found_p = 0;
4360 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4361 n += STRINGP (it->string) ? 0 : 1)
4363 if (!get_next_display_element (it))
4364 return 0;
4365 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4366 set_iterator_to_next (it, 0);
4369 /* If we didn't find a newline near enough, see if we can use a
4370 short-cut. */
4371 if (!newline_found_p)
4373 int start = IT_CHARPOS (*it);
4374 int limit = find_next_newline_no_quit (start, 1);
4375 Lisp_Object pos;
4377 xassert (!STRINGP (it->string));
4379 /* If there isn't any `display' property in sight, and no
4380 overlays, we can just use the position of the newline in
4381 buffer text. */
4382 if (it->stop_charpos >= limit
4383 || ((pos = Fnext_single_property_change (make_number (start),
4384 Qdisplay,
4385 Qnil, make_number (limit)),
4386 NILP (pos))
4387 && next_overlay_change (start) == ZV))
4389 IT_CHARPOS (*it) = limit;
4390 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4391 *skipped_p = newline_found_p = 1;
4393 else
4395 while (get_next_display_element (it)
4396 && !newline_found_p)
4398 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4399 set_iterator_to_next (it, 0);
4404 it->selective = old_selective;
4405 return newline_found_p;
4409 /* Set IT's current position to the previous visible line start. Skip
4410 invisible text that is so either due to text properties or due to
4411 selective display. Caution: this does not change IT->current_x and
4412 IT->hpos. */
4414 static void
4415 back_to_previous_visible_line_start (it)
4416 struct it *it;
4418 int visible_p = 0;
4420 /* Go back one newline if not on BEGV already. */
4421 if (IT_CHARPOS (*it) > BEGV)
4422 back_to_previous_line_start (it);
4424 /* Move over lines that are invisible because of selective display
4425 or text properties. */
4426 while (IT_CHARPOS (*it) > BEGV
4427 && !visible_p)
4429 visible_p = 1;
4431 /* If selective > 0, then lines indented more than that values
4432 are invisible. */
4433 if (it->selective > 0
4434 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4435 (double) it->selective)) /* iftc */
4436 visible_p = 0;
4437 else
4439 Lisp_Object prop;
4441 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4442 Qinvisible, it->window);
4443 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4444 visible_p = 0;
4447 /* Back one more newline if the current one is invisible. */
4448 if (!visible_p)
4449 back_to_previous_line_start (it);
4452 xassert (IT_CHARPOS (*it) >= BEGV);
4453 xassert (IT_CHARPOS (*it) == BEGV
4454 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4455 CHECK_IT (it);
4459 /* Reseat iterator IT at the previous visible line start. Skip
4460 invisible text that is so either due to text properties or due to
4461 selective display. At the end, update IT's overlay information,
4462 face information etc. */
4464 static void
4465 reseat_at_previous_visible_line_start (it)
4466 struct it *it;
4468 back_to_previous_visible_line_start (it);
4469 reseat (it, it->current.pos, 1);
4470 CHECK_IT (it);
4474 /* Reseat iterator IT on the next visible line start in the current
4475 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4476 preceding the line start. Skip over invisible text that is so
4477 because of selective display. Compute faces, overlays etc at the
4478 new position. Note that this function does not skip over text that
4479 is invisible because of text properties. */
4481 static void
4482 reseat_at_next_visible_line_start (it, on_newline_p)
4483 struct it *it;
4484 int on_newline_p;
4486 int newline_found_p, skipped_p = 0;
4488 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4490 /* Skip over lines that are invisible because they are indented
4491 more than the value of IT->selective. */
4492 if (it->selective > 0)
4493 while (IT_CHARPOS (*it) < ZV
4494 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4495 (double) it->selective)) /* iftc */
4497 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4498 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4501 /* Position on the newline if that's what's requested. */
4502 if (on_newline_p && newline_found_p)
4504 if (STRINGP (it->string))
4506 if (IT_STRING_CHARPOS (*it) > 0)
4508 --IT_STRING_CHARPOS (*it);
4509 --IT_STRING_BYTEPOS (*it);
4512 else if (IT_CHARPOS (*it) > BEGV)
4514 --IT_CHARPOS (*it);
4515 --IT_BYTEPOS (*it);
4516 reseat (it, it->current.pos, 0);
4519 else if (skipped_p)
4520 reseat (it, it->current.pos, 0);
4522 CHECK_IT (it);
4527 /***********************************************************************
4528 Changing an iterator's position
4529 ***********************************************************************/
4531 /* Change IT's current position to POS in current_buffer. If FORCE_P
4532 is non-zero, always check for text properties at the new position.
4533 Otherwise, text properties are only looked up if POS >=
4534 IT->check_charpos of a property. */
4536 static void
4537 reseat (it, pos, force_p)
4538 struct it *it;
4539 struct text_pos pos;
4540 int force_p;
4542 int original_pos = IT_CHARPOS (*it);
4544 reseat_1 (it, pos, 0);
4546 /* Determine where to check text properties. Avoid doing it
4547 where possible because text property lookup is very expensive. */
4548 if (force_p
4549 || CHARPOS (pos) > it->stop_charpos
4550 || CHARPOS (pos) < original_pos)
4551 handle_stop (it);
4553 CHECK_IT (it);
4557 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4558 IT->stop_pos to POS, also. */
4560 static void
4561 reseat_1 (it, pos, set_stop_p)
4562 struct it *it;
4563 struct text_pos pos;
4564 int set_stop_p;
4566 /* Don't call this function when scanning a C string. */
4567 xassert (it->s == NULL);
4569 /* POS must be a reasonable value. */
4570 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4572 it->current.pos = it->position = pos;
4573 XSETBUFFER (it->object, current_buffer);
4574 it->end_charpos = ZV;
4575 it->dpvec = NULL;
4576 it->current.dpvec_index = -1;
4577 it->current.overlay_string_index = -1;
4578 IT_STRING_CHARPOS (*it) = -1;
4579 IT_STRING_BYTEPOS (*it) = -1;
4580 it->string = Qnil;
4581 it->method = next_element_from_buffer;
4582 /* RMS: I added this to fix a bug in move_it_vertically_backward
4583 where it->area continued to relate to the starting point
4584 for the backward motion. Bug report from
4585 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4586 However, I am not sure whether reseat still does the right thing
4587 in general after this change. */
4588 it->area = TEXT_AREA;
4589 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4590 it->sp = 0;
4591 it->face_before_selective_p = 0;
4593 if (set_stop_p)
4594 it->stop_charpos = CHARPOS (pos);
4598 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4599 If S is non-null, it is a C string to iterate over. Otherwise,
4600 STRING gives a Lisp string to iterate over.
4602 If PRECISION > 0, don't return more then PRECISION number of
4603 characters from the string.
4605 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4606 characters have been returned. FIELD_WIDTH < 0 means an infinite
4607 field width.
4609 MULTIBYTE = 0 means disable processing of multibyte characters,
4610 MULTIBYTE > 0 means enable it,
4611 MULTIBYTE < 0 means use IT->multibyte_p.
4613 IT must be initialized via a prior call to init_iterator before
4614 calling this function. */
4616 static void
4617 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4618 struct it *it;
4619 unsigned char *s;
4620 Lisp_Object string;
4621 int charpos;
4622 int precision, field_width, multibyte;
4624 /* No region in strings. */
4625 it->region_beg_charpos = it->region_end_charpos = -1;
4627 /* No text property checks performed by default, but see below. */
4628 it->stop_charpos = -1;
4630 /* Set iterator position and end position. */
4631 bzero (&it->current, sizeof it->current);
4632 it->current.overlay_string_index = -1;
4633 it->current.dpvec_index = -1;
4634 xassert (charpos >= 0);
4636 /* If STRING is specified, use its multibyteness, otherwise use the
4637 setting of MULTIBYTE, if specified. */
4638 if (multibyte >= 0)
4639 it->multibyte_p = multibyte > 0;
4641 if (s == NULL)
4643 xassert (STRINGP (string));
4644 it->string = string;
4645 it->s = NULL;
4646 it->end_charpos = it->string_nchars = SCHARS (string);
4647 it->method = next_element_from_string;
4648 it->current.string_pos = string_pos (charpos, string);
4650 else
4652 it->s = s;
4653 it->string = Qnil;
4655 /* Note that we use IT->current.pos, not it->current.string_pos,
4656 for displaying C strings. */
4657 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4658 if (it->multibyte_p)
4660 it->current.pos = c_string_pos (charpos, s, 1);
4661 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4663 else
4665 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4666 it->end_charpos = it->string_nchars = strlen (s);
4669 it->method = next_element_from_c_string;
4672 /* PRECISION > 0 means don't return more than PRECISION characters
4673 from the string. */
4674 if (precision > 0 && it->end_charpos - charpos > precision)
4675 it->end_charpos = it->string_nchars = charpos + precision;
4677 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4678 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4679 FIELD_WIDTH < 0 means infinite field width. This is useful for
4680 padding with `-' at the end of a mode line. */
4681 if (field_width < 0)
4682 field_width = INFINITY;
4683 if (field_width > it->end_charpos - charpos)
4684 it->end_charpos = charpos + field_width;
4686 /* Use the standard display table for displaying strings. */
4687 if (DISP_TABLE_P (Vstandard_display_table))
4688 it->dp = XCHAR_TABLE (Vstandard_display_table);
4690 it->stop_charpos = charpos;
4691 CHECK_IT (it);
4696 /***********************************************************************
4697 Iteration
4698 ***********************************************************************/
4700 /* Load IT's display element fields with information about the next
4701 display element from the current position of IT. Value is zero if
4702 end of buffer (or C string) is reached. */
4705 get_next_display_element (it)
4706 struct it *it;
4708 /* Non-zero means that we found a display element. Zero means that
4709 we hit the end of what we iterate over. Performance note: the
4710 function pointer `method' used here turns out to be faster than
4711 using a sequence of if-statements. */
4712 int success_p = (*it->method) (it);
4714 if (it->what == IT_CHARACTER)
4716 /* Map via display table or translate control characters.
4717 IT->c, IT->len etc. have been set to the next character by
4718 the function call above. If we have a display table, and it
4719 contains an entry for IT->c, translate it. Don't do this if
4720 IT->c itself comes from a display table, otherwise we could
4721 end up in an infinite recursion. (An alternative could be to
4722 count the recursion depth of this function and signal an
4723 error when a certain maximum depth is reached.) Is it worth
4724 it? */
4725 if (success_p && it->dpvec == NULL)
4727 Lisp_Object dv;
4729 if (it->dp
4730 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4731 VECTORP (dv)))
4733 struct Lisp_Vector *v = XVECTOR (dv);
4735 /* Return the first character from the display table
4736 entry, if not empty. If empty, don't display the
4737 current character. */
4738 if (v->size)
4740 it->dpvec_char_len = it->len;
4741 it->dpvec = v->contents;
4742 it->dpend = v->contents + v->size;
4743 it->current.dpvec_index = 0;
4744 it->method = next_element_from_display_vector;
4745 success_p = get_next_display_element (it);
4747 else
4749 set_iterator_to_next (it, 0);
4750 success_p = get_next_display_element (it);
4754 /* Translate control characters into `\003' or `^C' form.
4755 Control characters coming from a display table entry are
4756 currently not translated because we use IT->dpvec to hold
4757 the translation. This could easily be changed but I
4758 don't believe that it is worth doing.
4760 If it->multibyte_p is nonzero, eight-bit characters and
4761 non-printable multibyte characters are also translated to
4762 octal form.
4764 If it->multibyte_p is zero, eight-bit characters that
4765 don't have corresponding multibyte char code are also
4766 translated to octal form. */
4767 else if ((it->c < ' '
4768 && (it->area != TEXT_AREA
4769 || (it->c != '\n' && it->c != '\t')))
4770 || (it->multibyte_p
4771 ? ((it->c >= 127
4772 && it->len == 1)
4773 || !CHAR_PRINTABLE_P (it->c))
4774 : (it->c >= 127
4775 && it->c == unibyte_char_to_multibyte (it->c))))
4777 /* IT->c is a control character which must be displayed
4778 either as '\003' or as `^C' where the '\\' and '^'
4779 can be defined in the display table. Fill
4780 IT->ctl_chars with glyphs for what we have to
4781 display. Then, set IT->dpvec to these glyphs. */
4782 GLYPH g;
4784 if (it->c < 128 && it->ctl_arrow_p)
4786 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4787 if (it->dp
4788 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4789 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4790 g = XINT (DISP_CTRL_GLYPH (it->dp));
4791 else
4792 g = FAST_MAKE_GLYPH ('^', 0);
4793 XSETINT (it->ctl_chars[0], g);
4795 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4796 XSETINT (it->ctl_chars[1], g);
4798 /* Set up IT->dpvec and return first character from it. */
4799 it->dpvec_char_len = it->len;
4800 it->dpvec = it->ctl_chars;
4801 it->dpend = it->dpvec + 2;
4802 it->current.dpvec_index = 0;
4803 it->method = next_element_from_display_vector;
4804 get_next_display_element (it);
4806 else
4808 unsigned char str[MAX_MULTIBYTE_LENGTH];
4809 int len;
4810 int i;
4811 GLYPH escape_glyph;
4813 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4814 if (it->dp
4815 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4816 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4817 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4818 else
4819 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4821 if (SINGLE_BYTE_CHAR_P (it->c))
4822 str[0] = it->c, len = 1;
4823 else
4825 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4826 if (len < 0)
4828 /* It's an invalid character, which
4829 shouldn't happen actually, but due to
4830 bugs it may happen. Let's print the char
4831 as is, there's not much meaningful we can
4832 do with it. */
4833 str[0] = it->c;
4834 str[1] = it->c >> 8;
4835 str[2] = it->c >> 16;
4836 str[3] = it->c >> 24;
4837 len = 4;
4841 for (i = 0; i < len; i++)
4843 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4844 /* Insert three more glyphs into IT->ctl_chars for
4845 the octal display of the character. */
4846 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4847 XSETINT (it->ctl_chars[i * 4 + 1], g);
4848 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4849 XSETINT (it->ctl_chars[i * 4 + 2], g);
4850 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4851 XSETINT (it->ctl_chars[i * 4 + 3], g);
4854 /* Set up IT->dpvec and return the first character
4855 from it. */
4856 it->dpvec_char_len = it->len;
4857 it->dpvec = it->ctl_chars;
4858 it->dpend = it->dpvec + len * 4;
4859 it->current.dpvec_index = 0;
4860 it->method = next_element_from_display_vector;
4861 get_next_display_element (it);
4866 /* Adjust face id for a multibyte character. There are no
4867 multibyte character in unibyte text. */
4868 if (it->multibyte_p
4869 && success_p
4870 && FRAME_WINDOW_P (it->f))
4872 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4873 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4877 /* Is this character the last one of a run of characters with
4878 box? If yes, set IT->end_of_box_run_p to 1. */
4879 if (it->face_box_p
4880 && it->s == NULL)
4882 int face_id;
4883 struct face *face;
4885 it->end_of_box_run_p
4886 = ((face_id = face_after_it_pos (it),
4887 face_id != it->face_id)
4888 && (face = FACE_FROM_ID (it->f, face_id),
4889 face->box == FACE_NO_BOX));
4892 /* Value is 0 if end of buffer or string reached. */
4893 return success_p;
4897 /* Move IT to the next display element.
4899 RESEAT_P non-zero means if called on a newline in buffer text,
4900 skip to the next visible line start.
4902 Functions get_next_display_element and set_iterator_to_next are
4903 separate because I find this arrangement easier to handle than a
4904 get_next_display_element function that also increments IT's
4905 position. The way it is we can first look at an iterator's current
4906 display element, decide whether it fits on a line, and if it does,
4907 increment the iterator position. The other way around we probably
4908 would either need a flag indicating whether the iterator has to be
4909 incremented the next time, or we would have to implement a
4910 decrement position function which would not be easy to write. */
4912 void
4913 set_iterator_to_next (it, reseat_p)
4914 struct it *it;
4915 int reseat_p;
4917 /* Reset flags indicating start and end of a sequence of characters
4918 with box. Reset them at the start of this function because
4919 moving the iterator to a new position might set them. */
4920 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4922 if (it->method == next_element_from_buffer)
4924 /* The current display element of IT is a character from
4925 current_buffer. Advance in the buffer, and maybe skip over
4926 invisible lines that are so because of selective display. */
4927 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4928 reseat_at_next_visible_line_start (it, 0);
4929 else
4931 xassert (it->len != 0);
4932 IT_BYTEPOS (*it) += it->len;
4933 IT_CHARPOS (*it) += 1;
4934 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4937 else if (it->method == next_element_from_composition)
4939 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4940 if (STRINGP (it->string))
4942 IT_STRING_BYTEPOS (*it) += it->len;
4943 IT_STRING_CHARPOS (*it) += it->cmp_len;
4944 it->method = next_element_from_string;
4945 goto consider_string_end;
4947 else
4949 IT_BYTEPOS (*it) += it->len;
4950 IT_CHARPOS (*it) += it->cmp_len;
4951 it->method = next_element_from_buffer;
4954 else if (it->method == next_element_from_c_string)
4956 /* Current display element of IT is from a C string. */
4957 IT_BYTEPOS (*it) += it->len;
4958 IT_CHARPOS (*it) += 1;
4960 else if (it->method == next_element_from_display_vector)
4962 /* Current display element of IT is from a display table entry.
4963 Advance in the display table definition. Reset it to null if
4964 end reached, and continue with characters from buffers/
4965 strings. */
4966 ++it->current.dpvec_index;
4968 /* Restore face of the iterator to what they were before the
4969 display vector entry (these entries may contain faces). */
4970 it->face_id = it->saved_face_id;
4972 if (it->dpvec + it->current.dpvec_index == it->dpend)
4974 if (it->s)
4975 it->method = next_element_from_c_string;
4976 else if (STRINGP (it->string))
4977 it->method = next_element_from_string;
4978 else
4979 it->method = next_element_from_buffer;
4981 it->dpvec = NULL;
4982 it->current.dpvec_index = -1;
4984 /* Skip over characters which were displayed via IT->dpvec. */
4985 if (it->dpvec_char_len < 0)
4986 reseat_at_next_visible_line_start (it, 1);
4987 else if (it->dpvec_char_len > 0)
4989 it->len = it->dpvec_char_len;
4990 set_iterator_to_next (it, reseat_p);
4994 else if (it->method == next_element_from_string)
4996 /* Current display element is a character from a Lisp string. */
4997 xassert (it->s == NULL && STRINGP (it->string));
4998 IT_STRING_BYTEPOS (*it) += it->len;
4999 IT_STRING_CHARPOS (*it) += 1;
5001 consider_string_end:
5003 if (it->current.overlay_string_index >= 0)
5005 /* IT->string is an overlay string. Advance to the
5006 next, if there is one. */
5007 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5008 next_overlay_string (it);
5010 else
5012 /* IT->string is not an overlay string. If we reached
5013 its end, and there is something on IT->stack, proceed
5014 with what is on the stack. This can be either another
5015 string, this time an overlay string, or a buffer. */
5016 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5017 && it->sp > 0)
5019 pop_it (it);
5020 if (!STRINGP (it->string))
5021 it->method = next_element_from_buffer;
5022 else
5023 goto consider_string_end;
5027 else if (it->method == next_element_from_image
5028 || it->method == next_element_from_stretch)
5030 /* The position etc with which we have to proceed are on
5031 the stack. The position may be at the end of a string,
5032 if the `display' property takes up the whole string. */
5033 pop_it (it);
5034 it->image_id = 0;
5035 if (STRINGP (it->string))
5037 it->method = next_element_from_string;
5038 goto consider_string_end;
5040 else
5041 it->method = next_element_from_buffer;
5043 else
5044 /* There are no other methods defined, so this should be a bug. */
5045 abort ();
5047 xassert (it->method != next_element_from_string
5048 || (STRINGP (it->string)
5049 && IT_STRING_CHARPOS (*it) >= 0));
5053 /* Load IT's display element fields with information about the next
5054 display element which comes from a display table entry or from the
5055 result of translating a control character to one of the forms `^C'
5056 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5058 static int
5059 next_element_from_display_vector (it)
5060 struct it *it;
5062 /* Precondition. */
5063 xassert (it->dpvec && it->current.dpvec_index >= 0);
5065 /* Remember the current face id in case glyphs specify faces.
5066 IT's face is restored in set_iterator_to_next. */
5067 it->saved_face_id = it->face_id;
5069 if (INTEGERP (*it->dpvec)
5070 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5072 int lface_id;
5073 GLYPH g;
5075 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5076 it->c = FAST_GLYPH_CHAR (g);
5077 it->len = CHAR_BYTES (it->c);
5079 /* The entry may contain a face id to use. Such a face id is
5080 the id of a Lisp face, not a realized face. A face id of
5081 zero means no face is specified. */
5082 lface_id = FAST_GLYPH_FACE (g);
5083 if (lface_id)
5085 /* The function returns -1 if lface_id is invalid. */
5086 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5087 if (face_id >= 0)
5088 it->face_id = face_id;
5091 else
5092 /* Display table entry is invalid. Return a space. */
5093 it->c = ' ', it->len = 1;
5095 /* Don't change position and object of the iterator here. They are
5096 still the values of the character that had this display table
5097 entry or was translated, and that's what we want. */
5098 it->what = IT_CHARACTER;
5099 return 1;
5103 /* Load IT with the next display element from Lisp string IT->string.
5104 IT->current.string_pos is the current position within the string.
5105 If IT->current.overlay_string_index >= 0, the Lisp string is an
5106 overlay string. */
5108 static int
5109 next_element_from_string (it)
5110 struct it *it;
5112 struct text_pos position;
5114 xassert (STRINGP (it->string));
5115 xassert (IT_STRING_CHARPOS (*it) >= 0);
5116 position = it->current.string_pos;
5118 /* Time to check for invisible text? */
5119 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5120 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5122 handle_stop (it);
5124 /* Since a handler may have changed IT->method, we must
5125 recurse here. */
5126 return get_next_display_element (it);
5129 if (it->current.overlay_string_index >= 0)
5131 /* Get the next character from an overlay string. In overlay
5132 strings, There is no field width or padding with spaces to
5133 do. */
5134 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5136 it->what = IT_EOB;
5137 return 0;
5139 else if (STRING_MULTIBYTE (it->string))
5141 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5142 const unsigned char *s = (SDATA (it->string)
5143 + IT_STRING_BYTEPOS (*it));
5144 it->c = string_char_and_length (s, remaining, &it->len);
5146 else
5148 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5149 it->len = 1;
5152 else
5154 /* Get the next character from a Lisp string that is not an
5155 overlay string. Such strings come from the mode line, for
5156 example. We may have to pad with spaces, or truncate the
5157 string. See also next_element_from_c_string. */
5158 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5160 it->what = IT_EOB;
5161 return 0;
5163 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5165 /* Pad with spaces. */
5166 it->c = ' ', it->len = 1;
5167 CHARPOS (position) = BYTEPOS (position) = -1;
5169 else if (STRING_MULTIBYTE (it->string))
5171 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5172 const unsigned char *s = (SDATA (it->string)
5173 + IT_STRING_BYTEPOS (*it));
5174 it->c = string_char_and_length (s, maxlen, &it->len);
5176 else
5178 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5179 it->len = 1;
5183 /* Record what we have and where it came from. Note that we store a
5184 buffer position in IT->position although it could arguably be a
5185 string position. */
5186 it->what = IT_CHARACTER;
5187 it->object = it->string;
5188 it->position = position;
5189 return 1;
5193 /* Load IT with next display element from C string IT->s.
5194 IT->string_nchars is the maximum number of characters to return
5195 from the string. IT->end_charpos may be greater than
5196 IT->string_nchars when this function is called, in which case we
5197 may have to return padding spaces. Value is zero if end of string
5198 reached, including padding spaces. */
5200 static int
5201 next_element_from_c_string (it)
5202 struct it *it;
5204 int success_p = 1;
5206 xassert (it->s);
5207 it->what = IT_CHARACTER;
5208 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5209 it->object = Qnil;
5211 /* IT's position can be greater IT->string_nchars in case a field
5212 width or precision has been specified when the iterator was
5213 initialized. */
5214 if (IT_CHARPOS (*it) >= it->end_charpos)
5216 /* End of the game. */
5217 it->what = IT_EOB;
5218 success_p = 0;
5220 else if (IT_CHARPOS (*it) >= it->string_nchars)
5222 /* Pad with spaces. */
5223 it->c = ' ', it->len = 1;
5224 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5226 else if (it->multibyte_p)
5228 /* Implementation note: The calls to strlen apparently aren't a
5229 performance problem because there is no noticeable performance
5230 difference between Emacs running in unibyte or multibyte mode. */
5231 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5232 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5233 maxlen, &it->len);
5235 else
5236 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5238 return success_p;
5242 /* Set up IT to return characters from an ellipsis, if appropriate.
5243 The definition of the ellipsis glyphs may come from a display table
5244 entry. This function Fills IT with the first glyph from the
5245 ellipsis if an ellipsis is to be displayed. */
5247 static int
5248 next_element_from_ellipsis (it)
5249 struct it *it;
5251 if (it->selective_display_ellipsis_p)
5253 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5255 /* Use the display table definition for `...'. Invalid glyphs
5256 will be handled by the method returning elements from dpvec. */
5257 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5258 it->dpvec_char_len = it->len;
5259 it->dpvec = v->contents;
5260 it->dpend = v->contents + v->size;
5261 it->current.dpvec_index = 0;
5262 it->method = next_element_from_display_vector;
5264 else
5266 /* Use default `...' which is stored in default_invis_vector. */
5267 it->dpvec_char_len = it->len;
5268 it->dpvec = default_invis_vector;
5269 it->dpend = default_invis_vector + 3;
5270 it->current.dpvec_index = 0;
5271 it->method = next_element_from_display_vector;
5274 else
5276 /* The face at the current position may be different from the
5277 face we find after the invisible text. Remember what it
5278 was in IT->saved_face_id, and signal that it's there by
5279 setting face_before_selective_p. */
5280 it->saved_face_id = it->face_id;
5281 it->method = next_element_from_buffer;
5282 reseat_at_next_visible_line_start (it, 1);
5283 it->face_before_selective_p = 1;
5286 return get_next_display_element (it);
5290 /* Deliver an image display element. The iterator IT is already
5291 filled with image information (done in handle_display_prop). Value
5292 is always 1. */
5295 static int
5296 next_element_from_image (it)
5297 struct it *it;
5299 it->what = IT_IMAGE;
5300 return 1;
5304 /* Fill iterator IT with next display element from a stretch glyph
5305 property. IT->object is the value of the text property. Value is
5306 always 1. */
5308 static int
5309 next_element_from_stretch (it)
5310 struct it *it;
5312 it->what = IT_STRETCH;
5313 return 1;
5317 /* Load IT with the next display element from current_buffer. Value
5318 is zero if end of buffer reached. IT->stop_charpos is the next
5319 position at which to stop and check for text properties or buffer
5320 end. */
5322 static int
5323 next_element_from_buffer (it)
5324 struct it *it;
5326 int success_p = 1;
5328 /* Check this assumption, otherwise, we would never enter the
5329 if-statement, below. */
5330 xassert (IT_CHARPOS (*it) >= BEGV
5331 && IT_CHARPOS (*it) <= it->stop_charpos);
5333 if (IT_CHARPOS (*it) >= it->stop_charpos)
5335 if (IT_CHARPOS (*it) >= it->end_charpos)
5337 int overlay_strings_follow_p;
5339 /* End of the game, except when overlay strings follow that
5340 haven't been returned yet. */
5341 if (it->overlay_strings_at_end_processed_p)
5342 overlay_strings_follow_p = 0;
5343 else
5345 it->overlay_strings_at_end_processed_p = 1;
5346 overlay_strings_follow_p = get_overlay_strings (it, 0);
5349 if (overlay_strings_follow_p)
5350 success_p = get_next_display_element (it);
5351 else
5353 it->what = IT_EOB;
5354 it->position = it->current.pos;
5355 success_p = 0;
5358 else
5360 handle_stop (it);
5361 return get_next_display_element (it);
5364 else
5366 /* No face changes, overlays etc. in sight, so just return a
5367 character from current_buffer. */
5368 unsigned char *p;
5370 /* Maybe run the redisplay end trigger hook. Performance note:
5371 This doesn't seem to cost measurable time. */
5372 if (it->redisplay_end_trigger_charpos
5373 && it->glyph_row
5374 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5375 run_redisplay_end_trigger_hook (it);
5377 /* Get the next character, maybe multibyte. */
5378 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5379 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5381 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5382 - IT_BYTEPOS (*it));
5383 it->c = string_char_and_length (p, maxlen, &it->len);
5385 else
5386 it->c = *p, it->len = 1;
5388 /* Record what we have and where it came from. */
5389 it->what = IT_CHARACTER;;
5390 it->object = it->w->buffer;
5391 it->position = it->current.pos;
5393 /* Normally we return the character found above, except when we
5394 really want to return an ellipsis for selective display. */
5395 if (it->selective)
5397 if (it->c == '\n')
5399 /* A value of selective > 0 means hide lines indented more
5400 than that number of columns. */
5401 if (it->selective > 0
5402 && IT_CHARPOS (*it) + 1 < ZV
5403 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5404 IT_BYTEPOS (*it) + 1,
5405 (double) it->selective)) /* iftc */
5407 success_p = next_element_from_ellipsis (it);
5408 it->dpvec_char_len = -1;
5411 else if (it->c == '\r' && it->selective == -1)
5413 /* A value of selective == -1 means that everything from the
5414 CR to the end of the line is invisible, with maybe an
5415 ellipsis displayed for it. */
5416 success_p = next_element_from_ellipsis (it);
5417 it->dpvec_char_len = -1;
5422 /* Value is zero if end of buffer reached. */
5423 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5424 return success_p;
5428 /* Run the redisplay end trigger hook for IT. */
5430 static void
5431 run_redisplay_end_trigger_hook (it)
5432 struct it *it;
5434 Lisp_Object args[3];
5436 /* IT->glyph_row should be non-null, i.e. we should be actually
5437 displaying something, or otherwise we should not run the hook. */
5438 xassert (it->glyph_row);
5440 /* Set up hook arguments. */
5441 args[0] = Qredisplay_end_trigger_functions;
5442 args[1] = it->window;
5443 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5444 it->redisplay_end_trigger_charpos = 0;
5446 /* Since we are *trying* to run these functions, don't try to run
5447 them again, even if they get an error. */
5448 it->w->redisplay_end_trigger = Qnil;
5449 Frun_hook_with_args (3, args);
5451 /* Notice if it changed the face of the character we are on. */
5452 handle_face_prop (it);
5456 /* Deliver a composition display element. The iterator IT is already
5457 filled with composition information (done in
5458 handle_composition_prop). Value is always 1. */
5460 static int
5461 next_element_from_composition (it)
5462 struct it *it;
5464 it->what = IT_COMPOSITION;
5465 it->position = (STRINGP (it->string)
5466 ? it->current.string_pos
5467 : it->current.pos);
5468 return 1;
5473 /***********************************************************************
5474 Moving an iterator without producing glyphs
5475 ***********************************************************************/
5477 /* Move iterator IT to a specified buffer or X position within one
5478 line on the display without producing glyphs.
5480 OP should be a bit mask including some or all of these bits:
5481 MOVE_TO_X: Stop on reaching x-position TO_X.
5482 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5483 Regardless of OP's value, stop in reaching the end of the display line.
5485 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5486 This means, in particular, that TO_X includes window's horizontal
5487 scroll amount.
5489 The return value has several possible values that
5490 say what condition caused the scan to stop:
5492 MOVE_POS_MATCH_OR_ZV
5493 - when TO_POS or ZV was reached.
5495 MOVE_X_REACHED
5496 -when TO_X was reached before TO_POS or ZV were reached.
5498 MOVE_LINE_CONTINUED
5499 - when we reached the end of the display area and the line must
5500 be continued.
5502 MOVE_LINE_TRUNCATED
5503 - when we reached the end of the display area and the line is
5504 truncated.
5506 MOVE_NEWLINE_OR_CR
5507 - when we stopped at a line end, i.e. a newline or a CR and selective
5508 display is on. */
5510 static enum move_it_result
5511 move_it_in_display_line_to (it, to_charpos, to_x, op)
5512 struct it *it;
5513 int to_charpos, to_x, op;
5515 enum move_it_result result = MOVE_UNDEFINED;
5516 struct glyph_row *saved_glyph_row;
5518 /* Don't produce glyphs in produce_glyphs. */
5519 saved_glyph_row = it->glyph_row;
5520 it->glyph_row = NULL;
5522 while (1)
5524 int x, i, ascent = 0, descent = 0;
5526 /* Stop when ZV or TO_CHARPOS reached. */
5527 if (!get_next_display_element (it)
5528 || ((op & MOVE_TO_POS) != 0
5529 && BUFFERP (it->object)
5530 && IT_CHARPOS (*it) >= to_charpos))
5532 result = MOVE_POS_MATCH_OR_ZV;
5533 break;
5536 /* The call to produce_glyphs will get the metrics of the
5537 display element IT is loaded with. We record in x the
5538 x-position before this display element in case it does not
5539 fit on the line. */
5540 x = it->current_x;
5542 /* Remember the line height so far in case the next element doesn't
5543 fit on the line. */
5544 if (!it->truncate_lines_p)
5546 ascent = it->max_ascent;
5547 descent = it->max_descent;
5550 PRODUCE_GLYPHS (it);
5552 if (it->area != TEXT_AREA)
5554 set_iterator_to_next (it, 1);
5555 continue;
5558 /* The number of glyphs we get back in IT->nglyphs will normally
5559 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5560 character on a terminal frame, or (iii) a line end. For the
5561 second case, IT->nglyphs - 1 padding glyphs will be present
5562 (on X frames, there is only one glyph produced for a
5563 composite character.
5565 The behavior implemented below means, for continuation lines,
5566 that as many spaces of a TAB as fit on the current line are
5567 displayed there. For terminal frames, as many glyphs of a
5568 multi-glyph character are displayed in the current line, too.
5569 This is what the old redisplay code did, and we keep it that
5570 way. Under X, the whole shape of a complex character must
5571 fit on the line or it will be completely displayed in the
5572 next line.
5574 Note that both for tabs and padding glyphs, all glyphs have
5575 the same width. */
5576 if (it->nglyphs)
5578 /* More than one glyph or glyph doesn't fit on line. All
5579 glyphs have the same width. */
5580 int single_glyph_width = it->pixel_width / it->nglyphs;
5581 int new_x;
5583 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5585 new_x = x + single_glyph_width;
5587 /* We want to leave anything reaching TO_X to the caller. */
5588 if ((op & MOVE_TO_X) && new_x > to_x)
5590 it->current_x = x;
5591 result = MOVE_X_REACHED;
5592 break;
5594 else if (/* Lines are continued. */
5595 !it->truncate_lines_p
5596 && (/* And glyph doesn't fit on the line. */
5597 new_x > it->last_visible_x
5598 /* Or it fits exactly and we're on a window
5599 system frame. */
5600 || (new_x == it->last_visible_x
5601 && FRAME_WINDOW_P (it->f))))
5603 if (/* IT->hpos == 0 means the very first glyph
5604 doesn't fit on the line, e.g. a wide image. */
5605 it->hpos == 0
5606 || (new_x == it->last_visible_x
5607 && FRAME_WINDOW_P (it->f)))
5609 ++it->hpos;
5610 it->current_x = new_x;
5611 if (i == it->nglyphs - 1)
5613 set_iterator_to_next (it, 1);
5614 #ifdef HAVE_WINDOW_SYSTEM
5615 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5617 get_next_display_element (it);
5618 if (ITERATOR_AT_END_OF_LINE_P (it))
5620 result = MOVE_NEWLINE_OR_CR;
5621 break;
5624 #endif /* HAVE_WINDOW_SYSTEM */
5627 else
5629 it->current_x = x;
5630 it->max_ascent = ascent;
5631 it->max_descent = descent;
5634 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5635 IT_CHARPOS (*it)));
5636 result = MOVE_LINE_CONTINUED;
5637 break;
5639 else if (new_x > it->first_visible_x)
5641 /* Glyph is visible. Increment number of glyphs that
5642 would be displayed. */
5643 ++it->hpos;
5645 else
5647 /* Glyph is completely off the left margin of the display
5648 area. Nothing to do. */
5652 if (result != MOVE_UNDEFINED)
5653 break;
5655 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5657 /* Stop when TO_X specified and reached. This check is
5658 necessary here because of lines consisting of a line end,
5659 only. The line end will not produce any glyphs and we
5660 would never get MOVE_X_REACHED. */
5661 xassert (it->nglyphs == 0);
5662 result = MOVE_X_REACHED;
5663 break;
5666 /* Is this a line end? If yes, we're done. */
5667 if (ITERATOR_AT_END_OF_LINE_P (it))
5669 result = MOVE_NEWLINE_OR_CR;
5670 break;
5673 /* The current display element has been consumed. Advance
5674 to the next. */
5675 set_iterator_to_next (it, 1);
5677 /* Stop if lines are truncated and IT's current x-position is
5678 past the right edge of the window now. */
5679 if (it->truncate_lines_p
5680 && it->current_x >= it->last_visible_x)
5682 #ifdef HAVE_WINDOW_SYSTEM
5683 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5685 get_next_display_element (it);
5686 if (ITERATOR_AT_END_OF_LINE_P (it))
5688 result = MOVE_NEWLINE_OR_CR;
5689 break;
5692 #endif /* HAVE_WINDOW_SYSTEM */
5693 result = MOVE_LINE_TRUNCATED;
5694 break;
5698 /* Restore the iterator settings altered at the beginning of this
5699 function. */
5700 it->glyph_row = saved_glyph_row;
5701 return result;
5705 /* Move IT forward until it satisfies one or more of the criteria in
5706 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5708 OP is a bit-mask that specifies where to stop, and in particular,
5709 which of those four position arguments makes a difference. See the
5710 description of enum move_operation_enum.
5712 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5713 screen line, this function will set IT to the next position >
5714 TO_CHARPOS. */
5716 void
5717 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5718 struct it *it;
5719 int to_charpos, to_x, to_y, to_vpos;
5720 int op;
5722 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5723 int line_height;
5724 int reached = 0;
5726 for (;;)
5728 if (op & MOVE_TO_VPOS)
5730 /* If no TO_CHARPOS and no TO_X specified, stop at the
5731 start of the line TO_VPOS. */
5732 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5734 if (it->vpos == to_vpos)
5736 reached = 1;
5737 break;
5739 else
5740 skip = move_it_in_display_line_to (it, -1, -1, 0);
5742 else
5744 /* TO_VPOS >= 0 means stop at TO_X in the line at
5745 TO_VPOS, or at TO_POS, whichever comes first. */
5746 if (it->vpos == to_vpos)
5748 reached = 2;
5749 break;
5752 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5754 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5756 reached = 3;
5757 break;
5759 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5761 /* We have reached TO_X but not in the line we want. */
5762 skip = move_it_in_display_line_to (it, to_charpos,
5763 -1, MOVE_TO_POS);
5764 if (skip == MOVE_POS_MATCH_OR_ZV)
5766 reached = 4;
5767 break;
5772 else if (op & MOVE_TO_Y)
5774 struct it it_backup;
5776 /* TO_Y specified means stop at TO_X in the line containing
5777 TO_Y---or at TO_CHARPOS if this is reached first. The
5778 problem is that we can't really tell whether the line
5779 contains TO_Y before we have completely scanned it, and
5780 this may skip past TO_X. What we do is to first scan to
5781 TO_X.
5783 If TO_X is not specified, use a TO_X of zero. The reason
5784 is to make the outcome of this function more predictable.
5785 If we didn't use TO_X == 0, we would stop at the end of
5786 the line which is probably not what a caller would expect
5787 to happen. */
5788 skip = move_it_in_display_line_to (it, to_charpos,
5789 ((op & MOVE_TO_X)
5790 ? to_x : 0),
5791 (MOVE_TO_X
5792 | (op & MOVE_TO_POS)));
5794 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5795 if (skip == MOVE_POS_MATCH_OR_ZV)
5797 reached = 5;
5798 break;
5801 /* If TO_X was reached, we would like to know whether TO_Y
5802 is in the line. This can only be said if we know the
5803 total line height which requires us to scan the rest of
5804 the line. */
5805 if (skip == MOVE_X_REACHED)
5807 it_backup = *it;
5808 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5809 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5810 op & MOVE_TO_POS);
5811 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5814 /* Now, decide whether TO_Y is in this line. */
5815 line_height = it->max_ascent + it->max_descent;
5816 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5818 if (to_y >= it->current_y
5819 && to_y < it->current_y + line_height)
5821 if (skip == MOVE_X_REACHED)
5822 /* If TO_Y is in this line and TO_X was reached above,
5823 we scanned too far. We have to restore IT's settings
5824 to the ones before skipping. */
5825 *it = it_backup;
5826 reached = 6;
5828 else if (skip == MOVE_X_REACHED)
5830 skip = skip2;
5831 if (skip == MOVE_POS_MATCH_OR_ZV)
5832 reached = 7;
5835 if (reached)
5836 break;
5838 else
5839 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5841 switch (skip)
5843 case MOVE_POS_MATCH_OR_ZV:
5844 reached = 8;
5845 goto out;
5847 case MOVE_NEWLINE_OR_CR:
5848 set_iterator_to_next (it, 1);
5849 it->continuation_lines_width = 0;
5850 break;
5852 case MOVE_LINE_TRUNCATED:
5853 it->continuation_lines_width = 0;
5854 reseat_at_next_visible_line_start (it, 0);
5855 if ((op & MOVE_TO_POS) != 0
5856 && IT_CHARPOS (*it) > to_charpos)
5858 reached = 9;
5859 goto out;
5861 break;
5863 case MOVE_LINE_CONTINUED:
5864 it->continuation_lines_width += it->current_x;
5865 break;
5867 default:
5868 abort ();
5871 /* Reset/increment for the next run. */
5872 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5873 it->current_x = it->hpos = 0;
5874 it->current_y += it->max_ascent + it->max_descent;
5875 ++it->vpos;
5876 last_height = it->max_ascent + it->max_descent;
5877 last_max_ascent = it->max_ascent;
5878 it->max_ascent = it->max_descent = 0;
5881 out:
5883 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5887 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5889 If DY > 0, move IT backward at least that many pixels. DY = 0
5890 means move IT backward to the preceding line start or BEGV. This
5891 function may move over more than DY pixels if IT->current_y - DY
5892 ends up in the middle of a line; in this case IT->current_y will be
5893 set to the top of the line moved to. */
5895 void
5896 move_it_vertically_backward (it, dy)
5897 struct it *it;
5898 int dy;
5900 int nlines, h;
5901 struct it it2, it3;
5902 int start_pos = IT_CHARPOS (*it);
5904 xassert (dy >= 0);
5906 /* Estimate how many newlines we must move back. */
5907 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5909 /* Set the iterator's position that many lines back. */
5910 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5911 back_to_previous_visible_line_start (it);
5913 /* Reseat the iterator here. When moving backward, we don't want
5914 reseat to skip forward over invisible text, set up the iterator
5915 to deliver from overlay strings at the new position etc. So,
5916 use reseat_1 here. */
5917 reseat_1 (it, it->current.pos, 1);
5919 /* We are now surely at a line start. */
5920 it->current_x = it->hpos = 0;
5921 it->continuation_lines_width = 0;
5923 /* Move forward and see what y-distance we moved. First move to the
5924 start of the next line so that we get its height. We need this
5925 height to be able to tell whether we reached the specified
5926 y-distance. */
5927 it2 = *it;
5928 it2.max_ascent = it2.max_descent = 0;
5929 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5930 MOVE_TO_POS | MOVE_TO_VPOS);
5931 xassert (IT_CHARPOS (*it) >= BEGV);
5932 it3 = it2;
5934 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5935 xassert (IT_CHARPOS (*it) >= BEGV);
5936 /* H is the actual vertical distance from the position in *IT
5937 and the starting position. */
5938 h = it2.current_y - it->current_y;
5939 /* NLINES is the distance in number of lines. */
5940 nlines = it2.vpos - it->vpos;
5942 /* Correct IT's y and vpos position
5943 so that they are relative to the starting point. */
5944 it->vpos -= nlines;
5945 it->current_y -= h;
5947 if (dy == 0)
5949 /* DY == 0 means move to the start of the screen line. The
5950 value of nlines is > 0 if continuation lines were involved. */
5951 if (nlines > 0)
5952 move_it_by_lines (it, nlines, 1);
5953 xassert (IT_CHARPOS (*it) <= start_pos);
5955 else
5957 /* The y-position we try to reach, relative to *IT.
5958 Note that H has been subtracted in front of the if-statement. */
5959 int target_y = it->current_y + h - dy;
5960 int y0 = it3.current_y;
5961 int y1 = line_bottom_y (&it3);
5962 int line_height = y1 - y0;
5964 /* If we did not reach target_y, try to move further backward if
5965 we can. If we moved too far backward, try to move forward. */
5966 if (target_y < it->current_y
5967 /* This is heuristic. In a window that's 3 lines high, with
5968 a line height of 13 pixels each, recentering with point
5969 on the bottom line will try to move -39/2 = 19 pixels
5970 backward. Try to avoid moving into the first line. */
5971 && it->current_y - target_y > line_height / 3 * 2
5972 && IT_CHARPOS (*it) > BEGV)
5974 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
5975 target_y - it->current_y));
5976 move_it_vertically (it, target_y - it->current_y);
5977 xassert (IT_CHARPOS (*it) >= BEGV);
5979 else if (target_y >= it->current_y + line_height
5980 && IT_CHARPOS (*it) < ZV)
5982 /* Should move forward by at least one line, maybe more.
5984 Note: Calling move_it_by_lines can be expensive on
5985 terminal frames, where compute_motion is used (via
5986 vmotion) to do the job, when there are very long lines
5987 and truncate-lines is nil. That's the reason for
5988 treating terminal frames specially here. */
5990 if (!FRAME_WINDOW_P (it->f))
5991 move_it_vertically (it, target_y - (it->current_y + line_height));
5992 else
5996 move_it_by_lines (it, 1, 1);
5998 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6001 xassert (IT_CHARPOS (*it) >= BEGV);
6007 /* Move IT by a specified amount of pixel lines DY. DY negative means
6008 move backwards. DY = 0 means move to start of screen line. At the
6009 end, IT will be on the start of a screen line. */
6011 void
6012 move_it_vertically (it, dy)
6013 struct it *it;
6014 int dy;
6016 if (dy <= 0)
6017 move_it_vertically_backward (it, -dy);
6018 else if (dy > 0)
6020 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6021 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6022 MOVE_TO_POS | MOVE_TO_Y);
6023 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6025 /* If buffer ends in ZV without a newline, move to the start of
6026 the line to satisfy the post-condition. */
6027 if (IT_CHARPOS (*it) == ZV
6028 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6029 move_it_by_lines (it, 0, 0);
6034 /* Move iterator IT past the end of the text line it is in. */
6036 void
6037 move_it_past_eol (it)
6038 struct it *it;
6040 enum move_it_result rc;
6042 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6043 if (rc == MOVE_NEWLINE_OR_CR)
6044 set_iterator_to_next (it, 0);
6048 #if 0 /* Currently not used. */
6050 /* Return non-zero if some text between buffer positions START_CHARPOS
6051 and END_CHARPOS is invisible. IT->window is the window for text
6052 property lookup. */
6054 static int
6055 invisible_text_between_p (it, start_charpos, end_charpos)
6056 struct it *it;
6057 int start_charpos, end_charpos;
6059 Lisp_Object prop, limit;
6060 int invisible_found_p;
6062 xassert (it != NULL && start_charpos <= end_charpos);
6064 /* Is text at START invisible? */
6065 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6066 it->window);
6067 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6068 invisible_found_p = 1;
6069 else
6071 limit = Fnext_single_char_property_change (make_number (start_charpos),
6072 Qinvisible, Qnil,
6073 make_number (end_charpos));
6074 invisible_found_p = XFASTINT (limit) < end_charpos;
6077 return invisible_found_p;
6080 #endif /* 0 */
6083 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6084 negative means move up. DVPOS == 0 means move to the start of the
6085 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6086 NEED_Y_P is zero, IT->current_y will be left unchanged.
6088 Further optimization ideas: If we would know that IT->f doesn't use
6089 a face with proportional font, we could be faster for
6090 truncate-lines nil. */
6092 void
6093 move_it_by_lines (it, dvpos, need_y_p)
6094 struct it *it;
6095 int dvpos, need_y_p;
6097 struct position pos;
6099 if (!FRAME_WINDOW_P (it->f))
6101 struct text_pos textpos;
6103 /* We can use vmotion on frames without proportional fonts. */
6104 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6105 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6106 reseat (it, textpos, 1);
6107 it->vpos += pos.vpos;
6108 it->current_y += pos.vpos;
6110 else if (dvpos == 0)
6112 /* DVPOS == 0 means move to the start of the screen line. */
6113 move_it_vertically_backward (it, 0);
6114 xassert (it->current_x == 0 && it->hpos == 0);
6116 else if (dvpos > 0)
6117 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6118 else
6120 struct it it2;
6121 int start_charpos, i;
6123 /* Start at the beginning of the screen line containing IT's
6124 position. */
6125 move_it_vertically_backward (it, 0);
6127 /* Go back -DVPOS visible lines and reseat the iterator there. */
6128 start_charpos = IT_CHARPOS (*it);
6129 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6130 back_to_previous_visible_line_start (it);
6131 reseat (it, it->current.pos, 1);
6132 it->current_x = it->hpos = 0;
6134 /* Above call may have moved too far if continuation lines
6135 are involved. Scan forward and see if it did. */
6136 it2 = *it;
6137 it2.vpos = it2.current_y = 0;
6138 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6139 it->vpos -= it2.vpos;
6140 it->current_y -= it2.current_y;
6141 it->current_x = it->hpos = 0;
6143 /* If we moved too far, move IT some lines forward. */
6144 if (it2.vpos > -dvpos)
6146 int delta = it2.vpos + dvpos;
6147 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6152 /* Return 1 if IT points into the middle of a display vector. */
6155 in_display_vector_p (it)
6156 struct it *it;
6158 return (it->method == next_element_from_display_vector
6159 && it->current.dpvec_index > 0
6160 && it->dpvec + it->current.dpvec_index != it->dpend);
6164 /***********************************************************************
6165 Messages
6166 ***********************************************************************/
6169 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6170 to *Messages*. */
6172 void
6173 add_to_log (format, arg1, arg2)
6174 char *format;
6175 Lisp_Object arg1, arg2;
6177 Lisp_Object args[3];
6178 Lisp_Object msg, fmt;
6179 char *buffer;
6180 int len;
6181 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6183 /* Do nothing if called asynchronously. Inserting text into
6184 a buffer may call after-change-functions and alike and
6185 that would means running Lisp asynchronously. */
6186 if (handling_signal)
6187 return;
6189 fmt = msg = Qnil;
6190 GCPRO4 (fmt, msg, arg1, arg2);
6192 args[0] = fmt = build_string (format);
6193 args[1] = arg1;
6194 args[2] = arg2;
6195 msg = Fformat (3, args);
6197 len = SBYTES (msg) + 1;
6198 buffer = (char *) alloca (len);
6199 bcopy (SDATA (msg), buffer, len);
6201 message_dolog (buffer, len - 1, 1, 0);
6202 UNGCPRO;
6206 /* Output a newline in the *Messages* buffer if "needs" one. */
6208 void
6209 message_log_maybe_newline ()
6211 if (message_log_need_newline)
6212 message_dolog ("", 0, 1, 0);
6216 /* Add a string M of length NBYTES to the message log, optionally
6217 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6218 nonzero, means interpret the contents of M as multibyte. This
6219 function calls low-level routines in order to bypass text property
6220 hooks, etc. which might not be safe to run. */
6222 void
6223 message_dolog (m, nbytes, nlflag, multibyte)
6224 const char *m;
6225 int nbytes, nlflag, multibyte;
6227 if (!NILP (Vmemory_full))
6228 return;
6230 if (!NILP (Vmessage_log_max))
6232 struct buffer *oldbuf;
6233 Lisp_Object oldpoint, oldbegv, oldzv;
6234 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6235 int point_at_end = 0;
6236 int zv_at_end = 0;
6237 Lisp_Object old_deactivate_mark, tem;
6238 struct gcpro gcpro1;
6240 old_deactivate_mark = Vdeactivate_mark;
6241 oldbuf = current_buffer;
6242 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6243 current_buffer->undo_list = Qt;
6245 oldpoint = message_dolog_marker1;
6246 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6247 oldbegv = message_dolog_marker2;
6248 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6249 oldzv = message_dolog_marker3;
6250 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6251 GCPRO1 (old_deactivate_mark);
6253 if (PT == Z)
6254 point_at_end = 1;
6255 if (ZV == Z)
6256 zv_at_end = 1;
6258 BEGV = BEG;
6259 BEGV_BYTE = BEG_BYTE;
6260 ZV = Z;
6261 ZV_BYTE = Z_BYTE;
6262 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6264 /* Insert the string--maybe converting multibyte to single byte
6265 or vice versa, so that all the text fits the buffer. */
6266 if (multibyte
6267 && NILP (current_buffer->enable_multibyte_characters))
6269 int i, c, char_bytes;
6270 unsigned char work[1];
6272 /* Convert a multibyte string to single-byte
6273 for the *Message* buffer. */
6274 for (i = 0; i < nbytes; i += char_bytes)
6276 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6277 work[0] = (SINGLE_BYTE_CHAR_P (c)
6279 : multibyte_char_to_unibyte (c, Qnil));
6280 insert_1_both (work, 1, 1, 1, 0, 0);
6283 else if (! multibyte
6284 && ! NILP (current_buffer->enable_multibyte_characters))
6286 int i, c, char_bytes;
6287 unsigned char *msg = (unsigned char *) m;
6288 unsigned char str[MAX_MULTIBYTE_LENGTH];
6289 /* Convert a single-byte string to multibyte
6290 for the *Message* buffer. */
6291 for (i = 0; i < nbytes; i++)
6293 c = unibyte_char_to_multibyte (msg[i]);
6294 char_bytes = CHAR_STRING (c, str);
6295 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6298 else if (nbytes)
6299 insert_1 (m, nbytes, 1, 0, 0);
6301 if (nlflag)
6303 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6304 insert_1 ("\n", 1, 1, 0, 0);
6306 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6307 this_bol = PT;
6308 this_bol_byte = PT_BYTE;
6310 /* See if this line duplicates the previous one.
6311 If so, combine duplicates. */
6312 if (this_bol > BEG)
6314 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6315 prev_bol = PT;
6316 prev_bol_byte = PT_BYTE;
6318 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6319 this_bol, this_bol_byte);
6320 if (dup)
6322 del_range_both (prev_bol, prev_bol_byte,
6323 this_bol, this_bol_byte, 0);
6324 if (dup > 1)
6326 char dupstr[40];
6327 int duplen;
6329 /* If you change this format, don't forget to also
6330 change message_log_check_duplicate. */
6331 sprintf (dupstr, " [%d times]", dup);
6332 duplen = strlen (dupstr);
6333 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6334 insert_1 (dupstr, duplen, 1, 0, 1);
6339 /* If we have more than the desired maximum number of lines
6340 in the *Messages* buffer now, delete the oldest ones.
6341 This is safe because we don't have undo in this buffer. */
6343 if (NATNUMP (Vmessage_log_max))
6345 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6346 -XFASTINT (Vmessage_log_max) - 1, 0);
6347 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6350 BEGV = XMARKER (oldbegv)->charpos;
6351 BEGV_BYTE = marker_byte_position (oldbegv);
6353 if (zv_at_end)
6355 ZV = Z;
6356 ZV_BYTE = Z_BYTE;
6358 else
6360 ZV = XMARKER (oldzv)->charpos;
6361 ZV_BYTE = marker_byte_position (oldzv);
6364 if (point_at_end)
6365 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6366 else
6367 /* We can't do Fgoto_char (oldpoint) because it will run some
6368 Lisp code. */
6369 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6370 XMARKER (oldpoint)->bytepos);
6372 UNGCPRO;
6373 unchain_marker (XMARKER (oldpoint));
6374 unchain_marker (XMARKER (oldbegv));
6375 unchain_marker (XMARKER (oldzv));
6377 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6378 set_buffer_internal (oldbuf);
6379 if (NILP (tem))
6380 windows_or_buffers_changed = old_windows_or_buffers_changed;
6381 message_log_need_newline = !nlflag;
6382 Vdeactivate_mark = old_deactivate_mark;
6387 /* We are at the end of the buffer after just having inserted a newline.
6388 (Note: We depend on the fact we won't be crossing the gap.)
6389 Check to see if the most recent message looks a lot like the previous one.
6390 Return 0 if different, 1 if the new one should just replace it, or a
6391 value N > 1 if we should also append " [N times]". */
6393 static int
6394 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6395 int prev_bol, this_bol;
6396 int prev_bol_byte, this_bol_byte;
6398 int i;
6399 int len = Z_BYTE - 1 - this_bol_byte;
6400 int seen_dots = 0;
6401 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6402 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6404 for (i = 0; i < len; i++)
6406 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6407 seen_dots = 1;
6408 if (p1[i] != p2[i])
6409 return seen_dots;
6411 p1 += len;
6412 if (*p1 == '\n')
6413 return 2;
6414 if (*p1++ == ' ' && *p1++ == '[')
6416 int n = 0;
6417 while (*p1 >= '0' && *p1 <= '9')
6418 n = n * 10 + *p1++ - '0';
6419 if (strncmp (p1, " times]\n", 8) == 0)
6420 return n+1;
6422 return 0;
6426 /* Display an echo area message M with a specified length of NBYTES
6427 bytes. The string may include null characters. If M is 0, clear
6428 out any existing message, and let the mini-buffer text show
6429 through.
6431 The buffer M must continue to exist until after the echo area gets
6432 cleared or some other message gets displayed there. This means do
6433 not pass text that is stored in a Lisp string; do not pass text in
6434 a buffer that was alloca'd. */
6436 void
6437 message2 (m, nbytes, multibyte)
6438 const char *m;
6439 int nbytes;
6440 int multibyte;
6442 /* First flush out any partial line written with print. */
6443 message_log_maybe_newline ();
6444 if (m)
6445 message_dolog (m, nbytes, 1, multibyte);
6446 message2_nolog (m, nbytes, multibyte);
6450 /* The non-logging counterpart of message2. */
6452 void
6453 message2_nolog (m, nbytes, multibyte)
6454 const char *m;
6455 int nbytes, multibyte;
6457 struct frame *sf = SELECTED_FRAME ();
6458 message_enable_multibyte = multibyte;
6460 if (noninteractive)
6462 if (noninteractive_need_newline)
6463 putc ('\n', stderr);
6464 noninteractive_need_newline = 0;
6465 if (m)
6466 fwrite (m, nbytes, 1, stderr);
6467 if (cursor_in_echo_area == 0)
6468 fprintf (stderr, "\n");
6469 fflush (stderr);
6471 /* A null message buffer means that the frame hasn't really been
6472 initialized yet. Error messages get reported properly by
6473 cmd_error, so this must be just an informative message; toss it. */
6474 else if (INTERACTIVE
6475 && sf->glyphs_initialized_p
6476 && FRAME_MESSAGE_BUF (sf))
6478 Lisp_Object mini_window;
6479 struct frame *f;
6481 /* Get the frame containing the mini-buffer
6482 that the selected frame is using. */
6483 mini_window = FRAME_MINIBUF_WINDOW (sf);
6484 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6486 FRAME_SAMPLE_VISIBILITY (f);
6487 if (FRAME_VISIBLE_P (sf)
6488 && ! FRAME_VISIBLE_P (f))
6489 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6491 if (m)
6493 set_message (m, Qnil, nbytes, multibyte);
6494 if (minibuffer_auto_raise)
6495 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6497 else
6498 clear_message (1, 1);
6500 do_pending_window_change (0);
6501 echo_area_display (1);
6502 do_pending_window_change (0);
6503 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6504 (*frame_up_to_date_hook) (f);
6509 /* Display an echo area message M with a specified length of NBYTES
6510 bytes. The string may include null characters. If M is not a
6511 string, clear out any existing message, and let the mini-buffer
6512 text show through. */
6514 void
6515 message3 (m, nbytes, multibyte)
6516 Lisp_Object m;
6517 int nbytes;
6518 int multibyte;
6520 struct gcpro gcpro1;
6522 GCPRO1 (m);
6524 /* First flush out any partial line written with print. */
6525 message_log_maybe_newline ();
6526 if (STRINGP (m))
6527 message_dolog (SDATA (m), nbytes, 1, multibyte);
6528 message3_nolog (m, nbytes, multibyte);
6530 UNGCPRO;
6534 /* The non-logging version of message3. */
6536 void
6537 message3_nolog (m, nbytes, multibyte)
6538 Lisp_Object m;
6539 int nbytes, multibyte;
6541 struct frame *sf = SELECTED_FRAME ();
6542 message_enable_multibyte = multibyte;
6544 if (noninteractive)
6546 if (noninteractive_need_newline)
6547 putc ('\n', stderr);
6548 noninteractive_need_newline = 0;
6549 if (STRINGP (m))
6550 fwrite (SDATA (m), nbytes, 1, stderr);
6551 if (cursor_in_echo_area == 0)
6552 fprintf (stderr, "\n");
6553 fflush (stderr);
6555 /* A null message buffer means that the frame hasn't really been
6556 initialized yet. Error messages get reported properly by
6557 cmd_error, so this must be just an informative message; toss it. */
6558 else if (INTERACTIVE
6559 && sf->glyphs_initialized_p
6560 && FRAME_MESSAGE_BUF (sf))
6562 Lisp_Object mini_window;
6563 Lisp_Object frame;
6564 struct frame *f;
6566 /* Get the frame containing the mini-buffer
6567 that the selected frame is using. */
6568 mini_window = FRAME_MINIBUF_WINDOW (sf);
6569 frame = XWINDOW (mini_window)->frame;
6570 f = XFRAME (frame);
6572 FRAME_SAMPLE_VISIBILITY (f);
6573 if (FRAME_VISIBLE_P (sf)
6574 && !FRAME_VISIBLE_P (f))
6575 Fmake_frame_visible (frame);
6577 if (STRINGP (m) && SCHARS (m) > 0)
6579 set_message (NULL, m, nbytes, multibyte);
6580 if (minibuffer_auto_raise)
6581 Fraise_frame (frame);
6583 else
6584 clear_message (1, 1);
6586 do_pending_window_change (0);
6587 echo_area_display (1);
6588 do_pending_window_change (0);
6589 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6590 (*frame_up_to_date_hook) (f);
6595 /* Display a null-terminated echo area message M. If M is 0, clear
6596 out any existing message, and let the mini-buffer text show through.
6598 The buffer M must continue to exist until after the echo area gets
6599 cleared or some other message gets displayed there. Do not pass
6600 text that is stored in a Lisp string. Do not pass text in a buffer
6601 that was alloca'd. */
6603 void
6604 message1 (m)
6605 char *m;
6607 message2 (m, (m ? strlen (m) : 0), 0);
6611 /* The non-logging counterpart of message1. */
6613 void
6614 message1_nolog (m)
6615 char *m;
6617 message2_nolog (m, (m ? strlen (m) : 0), 0);
6620 /* Display a message M which contains a single %s
6621 which gets replaced with STRING. */
6623 void
6624 message_with_string (m, string, log)
6625 char *m;
6626 Lisp_Object string;
6627 int log;
6629 CHECK_STRING (string);
6631 if (noninteractive)
6633 if (m)
6635 if (noninteractive_need_newline)
6636 putc ('\n', stderr);
6637 noninteractive_need_newline = 0;
6638 fprintf (stderr, m, SDATA (string));
6639 if (cursor_in_echo_area == 0)
6640 fprintf (stderr, "\n");
6641 fflush (stderr);
6644 else if (INTERACTIVE)
6646 /* The frame whose minibuffer we're going to display the message on.
6647 It may be larger than the selected frame, so we need
6648 to use its buffer, not the selected frame's buffer. */
6649 Lisp_Object mini_window;
6650 struct frame *f, *sf = SELECTED_FRAME ();
6652 /* Get the frame containing the minibuffer
6653 that the selected frame is using. */
6654 mini_window = FRAME_MINIBUF_WINDOW (sf);
6655 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6657 /* A null message buffer means that the frame hasn't really been
6658 initialized yet. Error messages get reported properly by
6659 cmd_error, so this must be just an informative message; toss it. */
6660 if (FRAME_MESSAGE_BUF (f))
6662 Lisp_Object args[2], message;
6663 struct gcpro gcpro1, gcpro2;
6665 args[0] = build_string (m);
6666 args[1] = message = string;
6667 GCPRO2 (args[0], message);
6668 gcpro1.nvars = 2;
6670 message = Fformat (2, args);
6672 if (log)
6673 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6674 else
6675 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6677 UNGCPRO;
6679 /* Print should start at the beginning of the message
6680 buffer next time. */
6681 message_buf_print = 0;
6687 /* Dump an informative message to the minibuf. If M is 0, clear out
6688 any existing message, and let the mini-buffer text show through. */
6690 /* VARARGS 1 */
6691 void
6692 message (m, a1, a2, a3)
6693 char *m;
6694 EMACS_INT a1, a2, a3;
6696 if (noninteractive)
6698 if (m)
6700 if (noninteractive_need_newline)
6701 putc ('\n', stderr);
6702 noninteractive_need_newline = 0;
6703 fprintf (stderr, m, a1, a2, a3);
6704 if (cursor_in_echo_area == 0)
6705 fprintf (stderr, "\n");
6706 fflush (stderr);
6709 else if (INTERACTIVE)
6711 /* The frame whose mini-buffer we're going to display the message
6712 on. It may be larger than the selected frame, so we need to
6713 use its buffer, not the selected frame's buffer. */
6714 Lisp_Object mini_window;
6715 struct frame *f, *sf = SELECTED_FRAME ();
6717 /* Get the frame containing the mini-buffer
6718 that the selected frame is using. */
6719 mini_window = FRAME_MINIBUF_WINDOW (sf);
6720 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6722 /* A null message buffer means that the frame hasn't really been
6723 initialized yet. Error messages get reported properly by
6724 cmd_error, so this must be just an informative message; toss
6725 it. */
6726 if (FRAME_MESSAGE_BUF (f))
6728 if (m)
6730 int len;
6731 #ifdef NO_ARG_ARRAY
6732 char *a[3];
6733 a[0] = (char *) a1;
6734 a[1] = (char *) a2;
6735 a[2] = (char *) a3;
6737 len = doprnt (FRAME_MESSAGE_BUF (f),
6738 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6739 #else
6740 len = doprnt (FRAME_MESSAGE_BUF (f),
6741 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6742 (char **) &a1);
6743 #endif /* NO_ARG_ARRAY */
6745 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6747 else
6748 message1 (0);
6750 /* Print should start at the beginning of the message
6751 buffer next time. */
6752 message_buf_print = 0;
6758 /* The non-logging version of message. */
6760 void
6761 message_nolog (m, a1, a2, a3)
6762 char *m;
6763 EMACS_INT a1, a2, a3;
6765 Lisp_Object old_log_max;
6766 old_log_max = Vmessage_log_max;
6767 Vmessage_log_max = Qnil;
6768 message (m, a1, a2, a3);
6769 Vmessage_log_max = old_log_max;
6773 /* Display the current message in the current mini-buffer. This is
6774 only called from error handlers in process.c, and is not time
6775 critical. */
6777 void
6778 update_echo_area ()
6780 if (!NILP (echo_area_buffer[0]))
6782 Lisp_Object string;
6783 string = Fcurrent_message ();
6784 message3 (string, SBYTES (string),
6785 !NILP (current_buffer->enable_multibyte_characters));
6790 /* Make sure echo area buffers in `echo_buffers' are live.
6791 If they aren't, make new ones. */
6793 static void
6794 ensure_echo_area_buffers ()
6796 int i;
6798 for (i = 0; i < 2; ++i)
6799 if (!BUFFERP (echo_buffer[i])
6800 || NILP (XBUFFER (echo_buffer[i])->name))
6802 char name[30];
6803 Lisp_Object old_buffer;
6804 int j;
6806 old_buffer = echo_buffer[i];
6807 sprintf (name, " *Echo Area %d*", i);
6808 echo_buffer[i] = Fget_buffer_create (build_string (name));
6809 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6811 for (j = 0; j < 2; ++j)
6812 if (EQ (old_buffer, echo_area_buffer[j]))
6813 echo_area_buffer[j] = echo_buffer[i];
6818 /* Call FN with args A1..A4 with either the current or last displayed
6819 echo_area_buffer as current buffer.
6821 WHICH zero means use the current message buffer
6822 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6823 from echo_buffer[] and clear it.
6825 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6826 suitable buffer from echo_buffer[] and clear it.
6828 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6829 that the current message becomes the last displayed one, make
6830 choose a suitable buffer for echo_area_buffer[0], and clear it.
6832 Value is what FN returns. */
6834 static int
6835 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6836 struct window *w;
6837 int which;
6838 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6839 EMACS_INT a1;
6840 Lisp_Object a2;
6841 EMACS_INT a3, a4;
6843 Lisp_Object buffer;
6844 int this_one, the_other, clear_buffer_p, rc;
6845 int count = SPECPDL_INDEX ();
6847 /* If buffers aren't live, make new ones. */
6848 ensure_echo_area_buffers ();
6850 clear_buffer_p = 0;
6852 if (which == 0)
6853 this_one = 0, the_other = 1;
6854 else if (which > 0)
6855 this_one = 1, the_other = 0;
6856 else
6858 this_one = 0, the_other = 1;
6859 clear_buffer_p = 1;
6861 /* We need a fresh one in case the current echo buffer equals
6862 the one containing the last displayed echo area message. */
6863 if (!NILP (echo_area_buffer[this_one])
6864 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6865 echo_area_buffer[this_one] = Qnil;
6868 /* Choose a suitable buffer from echo_buffer[] is we don't
6869 have one. */
6870 if (NILP (echo_area_buffer[this_one]))
6872 echo_area_buffer[this_one]
6873 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6874 ? echo_buffer[the_other]
6875 : echo_buffer[this_one]);
6876 clear_buffer_p = 1;
6879 buffer = echo_area_buffer[this_one];
6881 /* Don't get confused by reusing the buffer used for echoing
6882 for a different purpose. */
6883 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6884 cancel_echoing ();
6886 record_unwind_protect (unwind_with_echo_area_buffer,
6887 with_echo_area_buffer_unwind_data (w));
6889 /* Make the echo area buffer current. Note that for display
6890 purposes, it is not necessary that the displayed window's buffer
6891 == current_buffer, except for text property lookup. So, let's
6892 only set that buffer temporarily here without doing a full
6893 Fset_window_buffer. We must also change w->pointm, though,
6894 because otherwise an assertions in unshow_buffer fails, and Emacs
6895 aborts. */
6896 set_buffer_internal_1 (XBUFFER (buffer));
6897 if (w)
6899 w->buffer = buffer;
6900 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6903 current_buffer->undo_list = Qt;
6904 current_buffer->read_only = Qnil;
6905 specbind (Qinhibit_read_only, Qt);
6906 specbind (Qinhibit_modification_hooks, Qt);
6908 if (clear_buffer_p && Z > BEG)
6909 del_range (BEG, Z);
6911 xassert (BEGV >= BEG);
6912 xassert (ZV <= Z && ZV >= BEGV);
6914 rc = fn (a1, a2, a3, a4);
6916 xassert (BEGV >= BEG);
6917 xassert (ZV <= Z && ZV >= BEGV);
6919 unbind_to (count, Qnil);
6920 return rc;
6924 /* Save state that should be preserved around the call to the function
6925 FN called in with_echo_area_buffer. */
6927 static Lisp_Object
6928 with_echo_area_buffer_unwind_data (w)
6929 struct window *w;
6931 int i = 0;
6932 Lisp_Object vector;
6934 /* Reduce consing by keeping one vector in
6935 Vwith_echo_area_save_vector. */
6936 vector = Vwith_echo_area_save_vector;
6937 Vwith_echo_area_save_vector = Qnil;
6939 if (NILP (vector))
6940 vector = Fmake_vector (make_number (7), Qnil);
6942 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6943 AREF (vector, i) = Vdeactivate_mark, ++i;
6944 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6946 if (w)
6948 XSETWINDOW (AREF (vector, i), w); ++i;
6949 AREF (vector, i) = w->buffer; ++i;
6950 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6951 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6953 else
6955 int end = i + 4;
6956 for (; i < end; ++i)
6957 AREF (vector, i) = Qnil;
6960 xassert (i == ASIZE (vector));
6961 return vector;
6965 /* Restore global state from VECTOR which was created by
6966 with_echo_area_buffer_unwind_data. */
6968 static Lisp_Object
6969 unwind_with_echo_area_buffer (vector)
6970 Lisp_Object vector;
6972 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
6973 Vdeactivate_mark = AREF (vector, 1);
6974 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
6976 if (WINDOWP (AREF (vector, 3)))
6978 struct window *w;
6979 Lisp_Object buffer, charpos, bytepos;
6981 w = XWINDOW (AREF (vector, 3));
6982 buffer = AREF (vector, 4);
6983 charpos = AREF (vector, 5);
6984 bytepos = AREF (vector, 6);
6986 w->buffer = buffer;
6987 set_marker_both (w->pointm, buffer,
6988 XFASTINT (charpos), XFASTINT (bytepos));
6991 Vwith_echo_area_save_vector = vector;
6992 return Qnil;
6996 /* Set up the echo area for use by print functions. MULTIBYTE_P
6997 non-zero means we will print multibyte. */
6999 void
7000 setup_echo_area_for_printing (multibyte_p)
7001 int multibyte_p;
7003 /* If we can't find an echo area any more, exit. */
7004 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7005 Fkill_emacs (Qnil);
7007 ensure_echo_area_buffers ();
7009 if (!message_buf_print)
7011 /* A message has been output since the last time we printed.
7012 Choose a fresh echo area buffer. */
7013 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7014 echo_area_buffer[0] = echo_buffer[1];
7015 else
7016 echo_area_buffer[0] = echo_buffer[0];
7018 /* Switch to that buffer and clear it. */
7019 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7020 current_buffer->truncate_lines = Qnil;
7022 if (Z > BEG)
7024 int count = SPECPDL_INDEX ();
7025 specbind (Qinhibit_read_only, Qt);
7026 /* Note that undo recording is always disabled. */
7027 del_range (BEG, Z);
7028 unbind_to (count, Qnil);
7030 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7032 /* Set up the buffer for the multibyteness we need. */
7033 if (multibyte_p
7034 != !NILP (current_buffer->enable_multibyte_characters))
7035 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7037 /* Raise the frame containing the echo area. */
7038 if (minibuffer_auto_raise)
7040 struct frame *sf = SELECTED_FRAME ();
7041 Lisp_Object mini_window;
7042 mini_window = FRAME_MINIBUF_WINDOW (sf);
7043 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7046 message_log_maybe_newline ();
7047 message_buf_print = 1;
7049 else
7051 if (NILP (echo_area_buffer[0]))
7053 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7054 echo_area_buffer[0] = echo_buffer[1];
7055 else
7056 echo_area_buffer[0] = echo_buffer[0];
7059 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7061 /* Someone switched buffers between print requests. */
7062 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7063 current_buffer->truncate_lines = Qnil;
7069 /* Display an echo area message in window W. Value is non-zero if W's
7070 height is changed. If display_last_displayed_message_p is
7071 non-zero, display the message that was last displayed, otherwise
7072 display the current message. */
7074 static int
7075 display_echo_area (w)
7076 struct window *w;
7078 int i, no_message_p, window_height_changed_p, count;
7080 /* Temporarily disable garbage collections while displaying the echo
7081 area. This is done because a GC can print a message itself.
7082 That message would modify the echo area buffer's contents while a
7083 redisplay of the buffer is going on, and seriously confuse
7084 redisplay. */
7085 count = inhibit_garbage_collection ();
7087 /* If there is no message, we must call display_echo_area_1
7088 nevertheless because it resizes the window. But we will have to
7089 reset the echo_area_buffer in question to nil at the end because
7090 with_echo_area_buffer will sets it to an empty buffer. */
7091 i = display_last_displayed_message_p ? 1 : 0;
7092 no_message_p = NILP (echo_area_buffer[i]);
7094 window_height_changed_p
7095 = with_echo_area_buffer (w, display_last_displayed_message_p,
7096 display_echo_area_1,
7097 (EMACS_INT) w, Qnil, 0, 0);
7099 if (no_message_p)
7100 echo_area_buffer[i] = Qnil;
7102 unbind_to (count, Qnil);
7103 return window_height_changed_p;
7107 /* Helper for display_echo_area. Display the current buffer which
7108 contains the current echo area message in window W, a mini-window,
7109 a pointer to which is passed in A1. A2..A4 are currently not used.
7110 Change the height of W so that all of the message is displayed.
7111 Value is non-zero if height of W was changed. */
7113 static int
7114 display_echo_area_1 (a1, a2, a3, a4)
7115 EMACS_INT a1;
7116 Lisp_Object a2;
7117 EMACS_INT a3, a4;
7119 struct window *w = (struct window *) a1;
7120 Lisp_Object window;
7121 struct text_pos start;
7122 int window_height_changed_p = 0;
7124 /* Do this before displaying, so that we have a large enough glyph
7125 matrix for the display. */
7126 window_height_changed_p = resize_mini_window (w, 0);
7128 /* Display. */
7129 clear_glyph_matrix (w->desired_matrix);
7130 XSETWINDOW (window, w);
7131 SET_TEXT_POS (start, BEG, BEG_BYTE);
7132 try_window (window, start);
7134 return window_height_changed_p;
7138 /* Resize the echo area window to exactly the size needed for the
7139 currently displayed message, if there is one. If a mini-buffer
7140 is active, don't shrink it. */
7142 void
7143 resize_echo_area_exactly ()
7145 if (BUFFERP (echo_area_buffer[0])
7146 && WINDOWP (echo_area_window))
7148 struct window *w = XWINDOW (echo_area_window);
7149 int resized_p;
7150 Lisp_Object resize_exactly;
7152 if (minibuf_level == 0)
7153 resize_exactly = Qt;
7154 else
7155 resize_exactly = Qnil;
7157 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7158 (EMACS_INT) w, resize_exactly, 0, 0);
7159 if (resized_p)
7161 ++windows_or_buffers_changed;
7162 ++update_mode_lines;
7163 redisplay_internal (0);
7169 /* Callback function for with_echo_area_buffer, when used from
7170 resize_echo_area_exactly. A1 contains a pointer to the window to
7171 resize, EXACTLY non-nil means resize the mini-window exactly to the
7172 size of the text displayed. A3 and A4 are not used. Value is what
7173 resize_mini_window returns. */
7175 static int
7176 resize_mini_window_1 (a1, exactly, a3, a4)
7177 EMACS_INT a1;
7178 Lisp_Object exactly;
7179 EMACS_INT a3, a4;
7181 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7185 /* Resize mini-window W to fit the size of its contents. EXACT:P
7186 means size the window exactly to the size needed. Otherwise, it's
7187 only enlarged until W's buffer is empty. Value is non-zero if
7188 the window height has been changed. */
7191 resize_mini_window (w, exact_p)
7192 struct window *w;
7193 int exact_p;
7195 struct frame *f = XFRAME (w->frame);
7196 int window_height_changed_p = 0;
7198 xassert (MINI_WINDOW_P (w));
7200 /* Don't resize windows while redisplaying a window; it would
7201 confuse redisplay functions when the size of the window they are
7202 displaying changes from under them. Such a resizing can happen,
7203 for instance, when which-func prints a long message while
7204 we are running fontification-functions. We're running these
7205 functions with safe_call which binds inhibit-redisplay to t. */
7206 if (!NILP (Vinhibit_redisplay))
7207 return 0;
7209 /* Nil means don't try to resize. */
7210 if (NILP (Vresize_mini_windows)
7211 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7212 return 0;
7214 if (!FRAME_MINIBUF_ONLY_P (f))
7216 struct it it;
7217 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7218 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7219 int height, max_height;
7220 int unit = FRAME_LINE_HEIGHT (f);
7221 struct text_pos start;
7222 struct buffer *old_current_buffer = NULL;
7224 if (current_buffer != XBUFFER (w->buffer))
7226 old_current_buffer = current_buffer;
7227 set_buffer_internal (XBUFFER (w->buffer));
7230 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7232 /* Compute the max. number of lines specified by the user. */
7233 if (FLOATP (Vmax_mini_window_height))
7234 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7235 else if (INTEGERP (Vmax_mini_window_height))
7236 max_height = XINT (Vmax_mini_window_height);
7237 else
7238 max_height = total_height / 4;
7240 /* Correct that max. height if it's bogus. */
7241 max_height = max (1, max_height);
7242 max_height = min (total_height, max_height);
7244 /* Find out the height of the text in the window. */
7245 if (it.truncate_lines_p)
7246 height = 1;
7247 else
7249 last_height = 0;
7250 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7251 if (it.max_ascent == 0 && it.max_descent == 0)
7252 height = it.current_y + last_height;
7253 else
7254 height = it.current_y + it.max_ascent + it.max_descent;
7255 height -= it.extra_line_spacing;
7256 height = (height + unit - 1) / unit;
7259 /* Compute a suitable window start. */
7260 if (height > max_height)
7262 height = max_height;
7263 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7264 move_it_vertically_backward (&it, (height - 1) * unit);
7265 start = it.current.pos;
7267 else
7268 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7269 SET_MARKER_FROM_TEXT_POS (w->start, start);
7271 if (EQ (Vresize_mini_windows, Qgrow_only))
7273 /* Let it grow only, until we display an empty message, in which
7274 case the window shrinks again. */
7275 if (height > WINDOW_TOTAL_LINES (w))
7277 int old_height = WINDOW_TOTAL_LINES (w);
7278 freeze_window_starts (f, 1);
7279 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7280 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7282 else if (height < WINDOW_TOTAL_LINES (w)
7283 && (exact_p || BEGV == ZV))
7285 int old_height = WINDOW_TOTAL_LINES (w);
7286 freeze_window_starts (f, 0);
7287 shrink_mini_window (w);
7288 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7291 else
7293 /* Always resize to exact size needed. */
7294 if (height > WINDOW_TOTAL_LINES (w))
7296 int old_height = WINDOW_TOTAL_LINES (w);
7297 freeze_window_starts (f, 1);
7298 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7299 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7301 else if (height < WINDOW_TOTAL_LINES (w))
7303 int old_height = WINDOW_TOTAL_LINES (w);
7304 freeze_window_starts (f, 0);
7305 shrink_mini_window (w);
7307 if (height)
7309 freeze_window_starts (f, 1);
7310 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7313 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7317 if (old_current_buffer)
7318 set_buffer_internal (old_current_buffer);
7321 return window_height_changed_p;
7325 /* Value is the current message, a string, or nil if there is no
7326 current message. */
7328 Lisp_Object
7329 current_message ()
7331 Lisp_Object msg;
7333 if (NILP (echo_area_buffer[0]))
7334 msg = Qnil;
7335 else
7337 with_echo_area_buffer (0, 0, current_message_1,
7338 (EMACS_INT) &msg, Qnil, 0, 0);
7339 if (NILP (msg))
7340 echo_area_buffer[0] = Qnil;
7343 return msg;
7347 static int
7348 current_message_1 (a1, a2, a3, a4)
7349 EMACS_INT a1;
7350 Lisp_Object a2;
7351 EMACS_INT a3, a4;
7353 Lisp_Object *msg = (Lisp_Object *) a1;
7355 if (Z > BEG)
7356 *msg = make_buffer_string (BEG, Z, 1);
7357 else
7358 *msg = Qnil;
7359 return 0;
7363 /* Push the current message on Vmessage_stack for later restauration
7364 by restore_message. Value is non-zero if the current message isn't
7365 empty. This is a relatively infrequent operation, so it's not
7366 worth optimizing. */
7369 push_message ()
7371 Lisp_Object msg;
7372 msg = current_message ();
7373 Vmessage_stack = Fcons (msg, Vmessage_stack);
7374 return STRINGP (msg);
7378 /* Restore message display from the top of Vmessage_stack. */
7380 void
7381 restore_message ()
7383 Lisp_Object msg;
7385 xassert (CONSP (Vmessage_stack));
7386 msg = XCAR (Vmessage_stack);
7387 if (STRINGP (msg))
7388 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7389 else
7390 message3_nolog (msg, 0, 0);
7394 /* Handler for record_unwind_protect calling pop_message. */
7396 Lisp_Object
7397 pop_message_unwind (dummy)
7398 Lisp_Object dummy;
7400 pop_message ();
7401 return Qnil;
7404 /* Pop the top-most entry off Vmessage_stack. */
7406 void
7407 pop_message ()
7409 xassert (CONSP (Vmessage_stack));
7410 Vmessage_stack = XCDR (Vmessage_stack);
7414 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7415 exits. If the stack is not empty, we have a missing pop_message
7416 somewhere. */
7418 void
7419 check_message_stack ()
7421 if (!NILP (Vmessage_stack))
7422 abort ();
7426 /* Truncate to NCHARS what will be displayed in the echo area the next
7427 time we display it---but don't redisplay it now. */
7429 void
7430 truncate_echo_area (nchars)
7431 int nchars;
7433 if (nchars == 0)
7434 echo_area_buffer[0] = Qnil;
7435 /* A null message buffer means that the frame hasn't really been
7436 initialized yet. Error messages get reported properly by
7437 cmd_error, so this must be just an informative message; toss it. */
7438 else if (!noninteractive
7439 && INTERACTIVE
7440 && !NILP (echo_area_buffer[0]))
7442 struct frame *sf = SELECTED_FRAME ();
7443 if (FRAME_MESSAGE_BUF (sf))
7444 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7449 /* Helper function for truncate_echo_area. Truncate the current
7450 message to at most NCHARS characters. */
7452 static int
7453 truncate_message_1 (nchars, a2, a3, a4)
7454 EMACS_INT nchars;
7455 Lisp_Object a2;
7456 EMACS_INT a3, a4;
7458 if (BEG + nchars < Z)
7459 del_range (BEG + nchars, Z);
7460 if (Z == BEG)
7461 echo_area_buffer[0] = Qnil;
7462 return 0;
7466 /* Set the current message to a substring of S or STRING.
7468 If STRING is a Lisp string, set the message to the first NBYTES
7469 bytes from STRING. NBYTES zero means use the whole string. If
7470 STRING is multibyte, the message will be displayed multibyte.
7472 If S is not null, set the message to the first LEN bytes of S. LEN
7473 zero means use the whole string. MULTIBYTE_P non-zero means S is
7474 multibyte. Display the message multibyte in that case. */
7476 void
7477 set_message (s, string, nbytes, multibyte_p)
7478 const char *s;
7479 Lisp_Object string;
7480 int nbytes, multibyte_p;
7482 message_enable_multibyte
7483 = ((s && multibyte_p)
7484 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7486 with_echo_area_buffer (0, -1, set_message_1,
7487 (EMACS_INT) s, string, nbytes, multibyte_p);
7488 message_buf_print = 0;
7489 help_echo_showing_p = 0;
7493 /* Helper function for set_message. Arguments have the same meaning
7494 as there, with A1 corresponding to S and A2 corresponding to STRING
7495 This function is called with the echo area buffer being
7496 current. */
7498 static int
7499 set_message_1 (a1, a2, nbytes, multibyte_p)
7500 EMACS_INT a1;
7501 Lisp_Object a2;
7502 EMACS_INT nbytes, multibyte_p;
7504 const char *s = (const char *) a1;
7505 Lisp_Object string = a2;
7507 xassert (BEG == Z);
7509 /* Change multibyteness of the echo buffer appropriately. */
7510 if (message_enable_multibyte
7511 != !NILP (current_buffer->enable_multibyte_characters))
7512 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7514 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7516 /* Insert new message at BEG. */
7517 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7519 if (STRINGP (string))
7521 int nchars;
7523 if (nbytes == 0)
7524 nbytes = SBYTES (string);
7525 nchars = string_byte_to_char (string, nbytes);
7527 /* This function takes care of single/multibyte conversion. We
7528 just have to ensure that the echo area buffer has the right
7529 setting of enable_multibyte_characters. */
7530 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7532 else if (s)
7534 if (nbytes == 0)
7535 nbytes = strlen (s);
7537 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7539 /* Convert from multi-byte to single-byte. */
7540 int i, c, n;
7541 unsigned char work[1];
7543 /* Convert a multibyte string to single-byte. */
7544 for (i = 0; i < nbytes; i += n)
7546 c = string_char_and_length (s + i, nbytes - i, &n);
7547 work[0] = (SINGLE_BYTE_CHAR_P (c)
7549 : multibyte_char_to_unibyte (c, Qnil));
7550 insert_1_both (work, 1, 1, 1, 0, 0);
7553 else if (!multibyte_p
7554 && !NILP (current_buffer->enable_multibyte_characters))
7556 /* Convert from single-byte to multi-byte. */
7557 int i, c, n;
7558 const unsigned char *msg = (const unsigned char *) s;
7559 unsigned char str[MAX_MULTIBYTE_LENGTH];
7561 /* Convert a single-byte string to multibyte. */
7562 for (i = 0; i < nbytes; i++)
7564 c = unibyte_char_to_multibyte (msg[i]);
7565 n = CHAR_STRING (c, str);
7566 insert_1_both (str, 1, n, 1, 0, 0);
7569 else
7570 insert_1 (s, nbytes, 1, 0, 0);
7573 return 0;
7577 /* Clear messages. CURRENT_P non-zero means clear the current
7578 message. LAST_DISPLAYED_P non-zero means clear the message
7579 last displayed. */
7581 void
7582 clear_message (current_p, last_displayed_p)
7583 int current_p, last_displayed_p;
7585 if (current_p)
7587 echo_area_buffer[0] = Qnil;
7588 message_cleared_p = 1;
7591 if (last_displayed_p)
7592 echo_area_buffer[1] = Qnil;
7594 message_buf_print = 0;
7597 /* Clear garbaged frames.
7599 This function is used where the old redisplay called
7600 redraw_garbaged_frames which in turn called redraw_frame which in
7601 turn called clear_frame. The call to clear_frame was a source of
7602 flickering. I believe a clear_frame is not necessary. It should
7603 suffice in the new redisplay to invalidate all current matrices,
7604 and ensure a complete redisplay of all windows. */
7606 static void
7607 clear_garbaged_frames ()
7609 if (frame_garbaged)
7611 Lisp_Object tail, frame;
7612 int changed_count = 0;
7614 FOR_EACH_FRAME (tail, frame)
7616 struct frame *f = XFRAME (frame);
7618 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7620 if (f->resized_p)
7621 Fredraw_frame (frame);
7622 clear_current_matrices (f);
7623 changed_count++;
7624 f->garbaged = 0;
7625 f->resized_p = 0;
7629 frame_garbaged = 0;
7630 if (changed_count)
7631 ++windows_or_buffers_changed;
7636 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7637 is non-zero update selected_frame. Value is non-zero if the
7638 mini-windows height has been changed. */
7640 static int
7641 echo_area_display (update_frame_p)
7642 int update_frame_p;
7644 Lisp_Object mini_window;
7645 struct window *w;
7646 struct frame *f;
7647 int window_height_changed_p = 0;
7648 struct frame *sf = SELECTED_FRAME ();
7650 mini_window = FRAME_MINIBUF_WINDOW (sf);
7651 w = XWINDOW (mini_window);
7652 f = XFRAME (WINDOW_FRAME (w));
7654 /* Don't display if frame is invisible or not yet initialized. */
7655 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7656 return 0;
7658 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7659 #ifndef MAC_OS8
7660 #ifdef HAVE_WINDOW_SYSTEM
7661 /* When Emacs starts, selected_frame may be a visible terminal
7662 frame, even if we run under a window system. If we let this
7663 through, a message would be displayed on the terminal. */
7664 if (EQ (selected_frame, Vterminal_frame)
7665 && !NILP (Vwindow_system))
7666 return 0;
7667 #endif /* HAVE_WINDOW_SYSTEM */
7668 #endif
7670 /* Redraw garbaged frames. */
7671 if (frame_garbaged)
7672 clear_garbaged_frames ();
7674 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7676 echo_area_window = mini_window;
7677 window_height_changed_p = display_echo_area (w);
7678 w->must_be_updated_p = 1;
7680 /* Update the display, unless called from redisplay_internal.
7681 Also don't update the screen during redisplay itself. The
7682 update will happen at the end of redisplay, and an update
7683 here could cause confusion. */
7684 if (update_frame_p && !redisplaying_p)
7686 int n = 0;
7688 /* If the display update has been interrupted by pending
7689 input, update mode lines in the frame. Due to the
7690 pending input, it might have been that redisplay hasn't
7691 been called, so that mode lines above the echo area are
7692 garbaged. This looks odd, so we prevent it here. */
7693 if (!display_completed)
7694 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7696 if (window_height_changed_p
7697 /* Don't do this if Emacs is shutting down. Redisplay
7698 needs to run hooks. */
7699 && !NILP (Vrun_hooks))
7701 /* Must update other windows. Likewise as in other
7702 cases, don't let this update be interrupted by
7703 pending input. */
7704 int count = SPECPDL_INDEX ();
7705 specbind (Qredisplay_dont_pause, Qt);
7706 windows_or_buffers_changed = 1;
7707 redisplay_internal (0);
7708 unbind_to (count, Qnil);
7710 else if (FRAME_WINDOW_P (f) && n == 0)
7712 /* Window configuration is the same as before.
7713 Can do with a display update of the echo area,
7714 unless we displayed some mode lines. */
7715 update_single_window (w, 1);
7716 rif->flush_display (f);
7718 else
7719 update_frame (f, 1, 1);
7721 /* If cursor is in the echo area, make sure that the next
7722 redisplay displays the minibuffer, so that the cursor will
7723 be replaced with what the minibuffer wants. */
7724 if (cursor_in_echo_area)
7725 ++windows_or_buffers_changed;
7728 else if (!EQ (mini_window, selected_window))
7729 windows_or_buffers_changed++;
7731 /* Last displayed message is now the current message. */
7732 echo_area_buffer[1] = echo_area_buffer[0];
7734 /* Prevent redisplay optimization in redisplay_internal by resetting
7735 this_line_start_pos. This is done because the mini-buffer now
7736 displays the message instead of its buffer text. */
7737 if (EQ (mini_window, selected_window))
7738 CHARPOS (this_line_start_pos) = 0;
7740 return window_height_changed_p;
7745 /***********************************************************************
7746 Frame Titles
7747 ***********************************************************************/
7750 /* The frame title buffering code is also used by Fformat_mode_line.
7751 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7753 /* A buffer for constructing frame titles in it; allocated from the
7754 heap in init_xdisp and resized as needed in store_frame_title_char. */
7756 static char *frame_title_buf;
7758 /* The buffer's end, and a current output position in it. */
7760 static char *frame_title_buf_end;
7761 static char *frame_title_ptr;
7764 /* Store a single character C for the frame title in frame_title_buf.
7765 Re-allocate frame_title_buf if necessary. */
7767 static void
7768 #ifdef PROTOTYPES
7769 store_frame_title_char (char c)
7770 #else
7771 store_frame_title_char (c)
7772 char c;
7773 #endif
7775 /* If output position has reached the end of the allocated buffer,
7776 double the buffer's size. */
7777 if (frame_title_ptr == frame_title_buf_end)
7779 int len = frame_title_ptr - frame_title_buf;
7780 int new_size = 2 * len * sizeof *frame_title_buf;
7781 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7782 frame_title_buf_end = frame_title_buf + new_size;
7783 frame_title_ptr = frame_title_buf + len;
7786 *frame_title_ptr++ = c;
7790 /* Store part of a frame title in frame_title_buf, beginning at
7791 frame_title_ptr. STR is the string to store. Do not copy
7792 characters that yield more columns than PRECISION; PRECISION <= 0
7793 means copy the whole string. Pad with spaces until FIELD_WIDTH
7794 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7795 pad. Called from display_mode_element when it is used to build a
7796 frame title. */
7798 static int
7799 store_frame_title (str, field_width, precision)
7800 const unsigned char *str;
7801 int field_width, precision;
7803 int n = 0;
7804 int dummy, nbytes;
7806 /* Copy at most PRECISION chars from STR. */
7807 nbytes = strlen (str);
7808 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7809 while (nbytes--)
7810 store_frame_title_char (*str++);
7812 /* Fill up with spaces until FIELD_WIDTH reached. */
7813 while (field_width > 0
7814 && n < field_width)
7816 store_frame_title_char (' ');
7817 ++n;
7820 return n;
7823 #ifdef HAVE_WINDOW_SYSTEM
7825 /* Set the title of FRAME, if it has changed. The title format is
7826 Vicon_title_format if FRAME is iconified, otherwise it is
7827 frame_title_format. */
7829 static void
7830 x_consider_frame_title (frame)
7831 Lisp_Object frame;
7833 struct frame *f = XFRAME (frame);
7835 if (FRAME_WINDOW_P (f)
7836 || FRAME_MINIBUF_ONLY_P (f)
7837 || f->explicit_name)
7839 /* Do we have more than one visible frame on this X display? */
7840 Lisp_Object tail;
7841 Lisp_Object fmt;
7842 struct buffer *obuf;
7843 int len;
7844 struct it it;
7846 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7848 Lisp_Object other_frame = XCAR (tail);
7849 struct frame *tf = XFRAME (other_frame);
7851 if (tf != f
7852 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7853 && !FRAME_MINIBUF_ONLY_P (tf)
7854 && !EQ (other_frame, tip_frame)
7855 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7856 break;
7859 /* Set global variable indicating that multiple frames exist. */
7860 multiple_frames = CONSP (tail);
7862 /* Switch to the buffer of selected window of the frame. Set up
7863 frame_title_ptr so that display_mode_element will output into it;
7864 then display the title. */
7865 obuf = current_buffer;
7866 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7867 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7868 frame_title_ptr = frame_title_buf;
7869 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7870 NULL, DEFAULT_FACE_ID);
7871 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7872 len = frame_title_ptr - frame_title_buf;
7873 frame_title_ptr = NULL;
7874 set_buffer_internal_1 (obuf);
7876 /* Set the title only if it's changed. This avoids consing in
7877 the common case where it hasn't. (If it turns out that we've
7878 already wasted too much time by walking through the list with
7879 display_mode_element, then we might need to optimize at a
7880 higher level than this.) */
7881 if (! STRINGP (f->name)
7882 || SBYTES (f->name) != len
7883 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7884 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7888 #endif /* not HAVE_WINDOW_SYSTEM */
7893 /***********************************************************************
7894 Menu Bars
7895 ***********************************************************************/
7898 /* Prepare for redisplay by updating menu-bar item lists when
7899 appropriate. This can call eval. */
7901 void
7902 prepare_menu_bars ()
7904 int all_windows;
7905 struct gcpro gcpro1, gcpro2;
7906 struct frame *f;
7907 Lisp_Object tooltip_frame;
7909 #ifdef HAVE_WINDOW_SYSTEM
7910 tooltip_frame = tip_frame;
7911 #else
7912 tooltip_frame = Qnil;
7913 #endif
7915 /* Update all frame titles based on their buffer names, etc. We do
7916 this before the menu bars so that the buffer-menu will show the
7917 up-to-date frame titles. */
7918 #ifdef HAVE_WINDOW_SYSTEM
7919 if (windows_or_buffers_changed || update_mode_lines)
7921 Lisp_Object tail, frame;
7923 FOR_EACH_FRAME (tail, frame)
7925 f = XFRAME (frame);
7926 if (!EQ (frame, tooltip_frame)
7927 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7928 x_consider_frame_title (frame);
7931 #endif /* HAVE_WINDOW_SYSTEM */
7933 /* Update the menu bar item lists, if appropriate. This has to be
7934 done before any actual redisplay or generation of display lines. */
7935 all_windows = (update_mode_lines
7936 || buffer_shared > 1
7937 || windows_or_buffers_changed);
7938 if (all_windows)
7940 Lisp_Object tail, frame;
7941 int count = SPECPDL_INDEX ();
7943 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7945 FOR_EACH_FRAME (tail, frame)
7947 f = XFRAME (frame);
7949 /* Ignore tooltip frame. */
7950 if (EQ (frame, tooltip_frame))
7951 continue;
7953 /* If a window on this frame changed size, report that to
7954 the user and clear the size-change flag. */
7955 if (FRAME_WINDOW_SIZES_CHANGED (f))
7957 Lisp_Object functions;
7959 /* Clear flag first in case we get an error below. */
7960 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
7961 functions = Vwindow_size_change_functions;
7962 GCPRO2 (tail, functions);
7964 while (CONSP (functions))
7966 call1 (XCAR (functions), frame);
7967 functions = XCDR (functions);
7969 UNGCPRO;
7972 GCPRO1 (tail);
7973 update_menu_bar (f, 0);
7974 #ifdef HAVE_WINDOW_SYSTEM
7975 update_tool_bar (f, 0);
7976 #endif
7977 UNGCPRO;
7980 unbind_to (count, Qnil);
7982 else
7984 struct frame *sf = SELECTED_FRAME ();
7985 update_menu_bar (sf, 1);
7986 #ifdef HAVE_WINDOW_SYSTEM
7987 update_tool_bar (sf, 1);
7988 #endif
7991 /* Motif needs this. See comment in xmenu.c. Turn it off when
7992 pending_menu_activation is not defined. */
7993 #ifdef USE_X_TOOLKIT
7994 pending_menu_activation = 0;
7995 #endif
7999 /* Update the menu bar item list for frame F. This has to be done
8000 before we start to fill in any display lines, because it can call
8001 eval.
8003 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8005 static void
8006 update_menu_bar (f, save_match_data)
8007 struct frame *f;
8008 int save_match_data;
8010 Lisp_Object window;
8011 register struct window *w;
8013 /* If called recursively during a menu update, do nothing. This can
8014 happen when, for instance, an activate-menubar-hook causes a
8015 redisplay. */
8016 if (inhibit_menubar_update)
8017 return;
8019 window = FRAME_SELECTED_WINDOW (f);
8020 w = XWINDOW (window);
8022 #if 0 /* The if statement below this if statement used to include the
8023 condition !NILP (w->update_mode_line), rather than using
8024 update_mode_lines directly, and this if statement may have
8025 been added to make that condition work. Now the if
8026 statement below matches its comment, this isn't needed. */
8027 if (update_mode_lines)
8028 w->update_mode_line = Qt;
8029 #endif
8031 if (FRAME_WINDOW_P (f)
8033 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8034 || defined (USE_GTK)
8035 FRAME_EXTERNAL_MENU_BAR (f)
8036 #else
8037 FRAME_MENU_BAR_LINES (f) > 0
8038 #endif
8039 : FRAME_MENU_BAR_LINES (f) > 0)
8041 /* If the user has switched buffers or windows, we need to
8042 recompute to reflect the new bindings. But we'll
8043 recompute when update_mode_lines is set too; that means
8044 that people can use force-mode-line-update to request
8045 that the menu bar be recomputed. The adverse effect on
8046 the rest of the redisplay algorithm is about the same as
8047 windows_or_buffers_changed anyway. */
8048 if (windows_or_buffers_changed
8049 /* This used to test w->update_mode_line, but we believe
8050 there is no need to recompute the menu in that case. */
8051 || update_mode_lines
8052 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8053 < BUF_MODIFF (XBUFFER (w->buffer)))
8054 != !NILP (w->last_had_star))
8055 || ((!NILP (Vtransient_mark_mode)
8056 && !NILP (XBUFFER (w->buffer)->mark_active))
8057 != !NILP (w->region_showing)))
8059 struct buffer *prev = current_buffer;
8060 int count = SPECPDL_INDEX ();
8062 specbind (Qinhibit_menubar_update, Qt);
8064 set_buffer_internal_1 (XBUFFER (w->buffer));
8065 if (save_match_data)
8066 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8067 if (NILP (Voverriding_local_map_menu_flag))
8069 specbind (Qoverriding_terminal_local_map, Qnil);
8070 specbind (Qoverriding_local_map, Qnil);
8073 /* Run the Lucid hook. */
8074 safe_run_hooks (Qactivate_menubar_hook);
8076 /* If it has changed current-menubar from previous value,
8077 really recompute the menu-bar from the value. */
8078 if (! NILP (Vlucid_menu_bar_dirty_flag))
8079 call0 (Qrecompute_lucid_menubar);
8081 safe_run_hooks (Qmenu_bar_update_hook);
8082 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8084 /* Redisplay the menu bar in case we changed it. */
8085 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8086 || defined (USE_GTK)
8087 if (FRAME_WINDOW_P (f)
8088 #if defined (MAC_OS)
8089 /* All frames on Mac OS share the same menubar. So only the
8090 selected frame should be allowed to set it. */
8091 && f == SELECTED_FRAME ()
8092 #endif
8094 set_frame_menubar (f, 0, 0);
8095 else
8096 /* On a terminal screen, the menu bar is an ordinary screen
8097 line, and this makes it get updated. */
8098 w->update_mode_line = Qt;
8099 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8100 /* In the non-toolkit version, the menu bar is an ordinary screen
8101 line, and this makes it get updated. */
8102 w->update_mode_line = Qt;
8103 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8105 unbind_to (count, Qnil);
8106 set_buffer_internal_1 (prev);
8113 /***********************************************************************
8114 Output Cursor
8115 ***********************************************************************/
8117 #ifdef HAVE_WINDOW_SYSTEM
8119 /* EXPORT:
8120 Nominal cursor position -- where to draw output.
8121 HPOS and VPOS are window relative glyph matrix coordinates.
8122 X and Y are window relative pixel coordinates. */
8124 struct cursor_pos output_cursor;
8127 /* EXPORT:
8128 Set the global variable output_cursor to CURSOR. All cursor
8129 positions are relative to updated_window. */
8131 void
8132 set_output_cursor (cursor)
8133 struct cursor_pos *cursor;
8135 output_cursor.hpos = cursor->hpos;
8136 output_cursor.vpos = cursor->vpos;
8137 output_cursor.x = cursor->x;
8138 output_cursor.y = cursor->y;
8142 /* EXPORT for RIF:
8143 Set a nominal cursor position.
8145 HPOS and VPOS are column/row positions in a window glyph matrix. X
8146 and Y are window text area relative pixel positions.
8148 If this is done during an update, updated_window will contain the
8149 window that is being updated and the position is the future output
8150 cursor position for that window. If updated_window is null, use
8151 selected_window and display the cursor at the given position. */
8153 void
8154 x_cursor_to (vpos, hpos, y, x)
8155 int vpos, hpos, y, x;
8157 struct window *w;
8159 /* If updated_window is not set, work on selected_window. */
8160 if (updated_window)
8161 w = updated_window;
8162 else
8163 w = XWINDOW (selected_window);
8165 /* Set the output cursor. */
8166 output_cursor.hpos = hpos;
8167 output_cursor.vpos = vpos;
8168 output_cursor.x = x;
8169 output_cursor.y = y;
8171 /* If not called as part of an update, really display the cursor.
8172 This will also set the cursor position of W. */
8173 if (updated_window == NULL)
8175 BLOCK_INPUT;
8176 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8177 if (rif->flush_display_optional)
8178 rif->flush_display_optional (SELECTED_FRAME ());
8179 UNBLOCK_INPUT;
8183 #endif /* HAVE_WINDOW_SYSTEM */
8186 /***********************************************************************
8187 Tool-bars
8188 ***********************************************************************/
8190 #ifdef HAVE_WINDOW_SYSTEM
8192 /* Where the mouse was last time we reported a mouse event. */
8194 FRAME_PTR last_mouse_frame;
8196 /* Tool-bar item index of the item on which a mouse button was pressed
8197 or -1. */
8199 int last_tool_bar_item;
8202 /* Update the tool-bar item list for frame F. This has to be done
8203 before we start to fill in any display lines. Called from
8204 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8205 and restore it here. */
8207 static void
8208 update_tool_bar (f, save_match_data)
8209 struct frame *f;
8210 int save_match_data;
8212 #ifdef USE_GTK
8213 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8214 #else
8215 int do_update = WINDOWP (f->tool_bar_window)
8216 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8217 #endif
8219 if (do_update)
8221 Lisp_Object window;
8222 struct window *w;
8224 window = FRAME_SELECTED_WINDOW (f);
8225 w = XWINDOW (window);
8227 /* If the user has switched buffers or windows, we need to
8228 recompute to reflect the new bindings. But we'll
8229 recompute when update_mode_lines is set too; that means
8230 that people can use force-mode-line-update to request
8231 that the menu bar be recomputed. The adverse effect on
8232 the rest of the redisplay algorithm is about the same as
8233 windows_or_buffers_changed anyway. */
8234 if (windows_or_buffers_changed
8235 || !NILP (w->update_mode_line)
8236 || update_mode_lines
8237 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8238 < BUF_MODIFF (XBUFFER (w->buffer)))
8239 != !NILP (w->last_had_star))
8240 || ((!NILP (Vtransient_mark_mode)
8241 && !NILP (XBUFFER (w->buffer)->mark_active))
8242 != !NILP (w->region_showing)))
8244 struct buffer *prev = current_buffer;
8245 int count = SPECPDL_INDEX ();
8246 Lisp_Object old_tool_bar;
8247 struct gcpro gcpro1;
8249 /* Set current_buffer to the buffer of the selected
8250 window of the frame, so that we get the right local
8251 keymaps. */
8252 set_buffer_internal_1 (XBUFFER (w->buffer));
8254 /* Save match data, if we must. */
8255 if (save_match_data)
8256 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8258 /* Make sure that we don't accidentally use bogus keymaps. */
8259 if (NILP (Voverriding_local_map_menu_flag))
8261 specbind (Qoverriding_terminal_local_map, Qnil);
8262 specbind (Qoverriding_local_map, Qnil);
8265 old_tool_bar = f->tool_bar_items;
8266 GCPRO1 (old_tool_bar);
8268 /* Build desired tool-bar items from keymaps. */
8269 BLOCK_INPUT;
8270 f->tool_bar_items
8271 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8272 UNBLOCK_INPUT;
8274 /* Redisplay the tool-bar if we changed it. */
8275 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8276 w->update_mode_line = Qt;
8278 UNGCPRO;
8280 unbind_to (count, Qnil);
8281 set_buffer_internal_1 (prev);
8287 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8288 F's desired tool-bar contents. F->tool_bar_items must have
8289 been set up previously by calling prepare_menu_bars. */
8291 static void
8292 build_desired_tool_bar_string (f)
8293 struct frame *f;
8295 int i, size, size_needed;
8296 struct gcpro gcpro1, gcpro2, gcpro3;
8297 Lisp_Object image, plist, props;
8299 image = plist = props = Qnil;
8300 GCPRO3 (image, plist, props);
8302 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8303 Otherwise, make a new string. */
8305 /* The size of the string we might be able to reuse. */
8306 size = (STRINGP (f->desired_tool_bar_string)
8307 ? SCHARS (f->desired_tool_bar_string)
8308 : 0);
8310 /* We need one space in the string for each image. */
8311 size_needed = f->n_tool_bar_items;
8313 /* Reuse f->desired_tool_bar_string, if possible. */
8314 if (size < size_needed || NILP (f->desired_tool_bar_string))
8315 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8316 make_number (' '));
8317 else
8319 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8320 Fremove_text_properties (make_number (0), make_number (size),
8321 props, f->desired_tool_bar_string);
8324 /* Put a `display' property on the string for the images to display,
8325 put a `menu_item' property on tool-bar items with a value that
8326 is the index of the item in F's tool-bar item vector. */
8327 for (i = 0; i < f->n_tool_bar_items; ++i)
8329 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8331 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8332 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8333 int hmargin, vmargin, relief, idx, end;
8334 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8336 /* If image is a vector, choose the image according to the
8337 button state. */
8338 image = PROP (TOOL_BAR_ITEM_IMAGES);
8339 if (VECTORP (image))
8341 if (enabled_p)
8342 idx = (selected_p
8343 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8344 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8345 else
8346 idx = (selected_p
8347 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8348 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8350 xassert (ASIZE (image) >= idx);
8351 image = AREF (image, idx);
8353 else
8354 idx = -1;
8356 /* Ignore invalid image specifications. */
8357 if (!valid_image_p (image))
8358 continue;
8360 /* Display the tool-bar button pressed, or depressed. */
8361 plist = Fcopy_sequence (XCDR (image));
8363 /* Compute margin and relief to draw. */
8364 relief = (tool_bar_button_relief >= 0
8365 ? tool_bar_button_relief
8366 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8367 hmargin = vmargin = relief;
8369 if (INTEGERP (Vtool_bar_button_margin)
8370 && XINT (Vtool_bar_button_margin) > 0)
8372 hmargin += XFASTINT (Vtool_bar_button_margin);
8373 vmargin += XFASTINT (Vtool_bar_button_margin);
8375 else if (CONSP (Vtool_bar_button_margin))
8377 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8378 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8379 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8381 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8382 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8383 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8386 if (auto_raise_tool_bar_buttons_p)
8388 /* Add a `:relief' property to the image spec if the item is
8389 selected. */
8390 if (selected_p)
8392 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8393 hmargin -= relief;
8394 vmargin -= relief;
8397 else
8399 /* If image is selected, display it pressed, i.e. with a
8400 negative relief. If it's not selected, display it with a
8401 raised relief. */
8402 plist = Fplist_put (plist, QCrelief,
8403 (selected_p
8404 ? make_number (-relief)
8405 : make_number (relief)));
8406 hmargin -= relief;
8407 vmargin -= relief;
8410 /* Put a margin around the image. */
8411 if (hmargin || vmargin)
8413 if (hmargin == vmargin)
8414 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8415 else
8416 plist = Fplist_put (plist, QCmargin,
8417 Fcons (make_number (hmargin),
8418 make_number (vmargin)));
8421 /* If button is not enabled, and we don't have special images
8422 for the disabled state, make the image appear disabled by
8423 applying an appropriate algorithm to it. */
8424 if (!enabled_p && idx < 0)
8425 plist = Fplist_put (plist, QCconversion, Qdisabled);
8427 /* Put a `display' text property on the string for the image to
8428 display. Put a `menu-item' property on the string that gives
8429 the start of this item's properties in the tool-bar items
8430 vector. */
8431 image = Fcons (Qimage, plist);
8432 props = list4 (Qdisplay, image,
8433 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8435 /* Let the last image hide all remaining spaces in the tool bar
8436 string. The string can be longer than needed when we reuse a
8437 previous string. */
8438 if (i + 1 == f->n_tool_bar_items)
8439 end = SCHARS (f->desired_tool_bar_string);
8440 else
8441 end = i + 1;
8442 Fadd_text_properties (make_number (i), make_number (end),
8443 props, f->desired_tool_bar_string);
8444 #undef PROP
8447 UNGCPRO;
8451 /* Display one line of the tool-bar of frame IT->f. */
8453 static void
8454 display_tool_bar_line (it)
8455 struct it *it;
8457 struct glyph_row *row = it->glyph_row;
8458 int max_x = it->last_visible_x;
8459 struct glyph *last;
8461 prepare_desired_row (row);
8462 row->y = it->current_y;
8464 /* Note that this isn't made use of if the face hasn't a box,
8465 so there's no need to check the face here. */
8466 it->start_of_box_run_p = 1;
8468 while (it->current_x < max_x)
8470 int x_before, x, n_glyphs_before, i, nglyphs;
8472 /* Get the next display element. */
8473 if (!get_next_display_element (it))
8474 break;
8476 /* Produce glyphs. */
8477 x_before = it->current_x;
8478 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8479 PRODUCE_GLYPHS (it);
8481 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8482 i = 0;
8483 x = x_before;
8484 while (i < nglyphs)
8486 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8488 if (x + glyph->pixel_width > max_x)
8490 /* Glyph doesn't fit on line. */
8491 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8492 it->current_x = x;
8493 goto out;
8496 ++it->hpos;
8497 x += glyph->pixel_width;
8498 ++i;
8501 /* Stop at line ends. */
8502 if (ITERATOR_AT_END_OF_LINE_P (it))
8503 break;
8505 set_iterator_to_next (it, 1);
8508 out:;
8510 row->displays_text_p = row->used[TEXT_AREA] != 0;
8511 extend_face_to_end_of_line (it);
8512 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8513 last->right_box_line_p = 1;
8514 if (last == row->glyphs[TEXT_AREA])
8515 last->left_box_line_p = 1;
8516 compute_line_metrics (it);
8518 /* If line is empty, make it occupy the rest of the tool-bar. */
8519 if (!row->displays_text_p)
8521 row->height = row->phys_height = it->last_visible_y - row->y;
8522 row->ascent = row->phys_ascent = 0;
8525 row->full_width_p = 1;
8526 row->continued_p = 0;
8527 row->truncated_on_left_p = 0;
8528 row->truncated_on_right_p = 0;
8530 it->current_x = it->hpos = 0;
8531 it->current_y += row->height;
8532 ++it->vpos;
8533 ++it->glyph_row;
8537 /* Value is the number of screen lines needed to make all tool-bar
8538 items of frame F visible. */
8540 static int
8541 tool_bar_lines_needed (f)
8542 struct frame *f;
8544 struct window *w = XWINDOW (f->tool_bar_window);
8545 struct it it;
8547 /* Initialize an iterator for iteration over
8548 F->desired_tool_bar_string in the tool-bar window of frame F. */
8549 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8550 it.first_visible_x = 0;
8551 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8552 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8554 while (!ITERATOR_AT_END_P (&it))
8556 it.glyph_row = w->desired_matrix->rows;
8557 clear_glyph_row (it.glyph_row);
8558 display_tool_bar_line (&it);
8561 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8565 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8566 0, 1, 0,
8567 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8568 (frame)
8569 Lisp_Object frame;
8571 struct frame *f;
8572 struct window *w;
8573 int nlines = 0;
8575 if (NILP (frame))
8576 frame = selected_frame;
8577 else
8578 CHECK_FRAME (frame);
8579 f = XFRAME (frame);
8581 if (WINDOWP (f->tool_bar_window)
8582 || (w = XWINDOW (f->tool_bar_window),
8583 WINDOW_TOTAL_LINES (w) > 0))
8585 update_tool_bar (f, 1);
8586 if (f->n_tool_bar_items)
8588 build_desired_tool_bar_string (f);
8589 nlines = tool_bar_lines_needed (f);
8593 return make_number (nlines);
8597 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8598 height should be changed. */
8600 static int
8601 redisplay_tool_bar (f)
8602 struct frame *f;
8604 struct window *w;
8605 struct it it;
8606 struct glyph_row *row;
8607 int change_height_p = 0;
8609 #ifdef USE_GTK
8610 if (FRAME_EXTERNAL_TOOL_BAR (f))
8611 update_frame_tool_bar (f);
8612 return 0;
8613 #endif
8615 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8616 do anything. This means you must start with tool-bar-lines
8617 non-zero to get the auto-sizing effect. Or in other words, you
8618 can turn off tool-bars by specifying tool-bar-lines zero. */
8619 if (!WINDOWP (f->tool_bar_window)
8620 || (w = XWINDOW (f->tool_bar_window),
8621 WINDOW_TOTAL_LINES (w) == 0))
8622 return 0;
8624 /* Set up an iterator for the tool-bar window. */
8625 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8626 it.first_visible_x = 0;
8627 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8628 row = it.glyph_row;
8630 /* Build a string that represents the contents of the tool-bar. */
8631 build_desired_tool_bar_string (f);
8632 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8634 /* Display as many lines as needed to display all tool-bar items. */
8635 while (it.current_y < it.last_visible_y)
8636 display_tool_bar_line (&it);
8638 /* It doesn't make much sense to try scrolling in the tool-bar
8639 window, so don't do it. */
8640 w->desired_matrix->no_scrolling_p = 1;
8641 w->must_be_updated_p = 1;
8643 if (auto_resize_tool_bars_p)
8645 int nlines;
8647 /* If we couldn't display everything, change the tool-bar's
8648 height. */
8649 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8650 change_height_p = 1;
8652 /* If there are blank lines at the end, except for a partially
8653 visible blank line at the end that is smaller than
8654 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8655 row = it.glyph_row - 1;
8656 if (!row->displays_text_p
8657 && row->height >= FRAME_LINE_HEIGHT (f))
8658 change_height_p = 1;
8660 /* If row displays tool-bar items, but is partially visible,
8661 change the tool-bar's height. */
8662 if (row->displays_text_p
8663 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8664 change_height_p = 1;
8666 /* Resize windows as needed by changing the `tool-bar-lines'
8667 frame parameter. */
8668 if (change_height_p
8669 && (nlines = tool_bar_lines_needed (f),
8670 nlines != WINDOW_TOTAL_LINES (w)))
8672 extern Lisp_Object Qtool_bar_lines;
8673 Lisp_Object frame;
8674 int old_height = WINDOW_TOTAL_LINES (w);
8676 XSETFRAME (frame, f);
8677 clear_glyph_matrix (w->desired_matrix);
8678 Fmodify_frame_parameters (frame,
8679 Fcons (Fcons (Qtool_bar_lines,
8680 make_number (nlines)),
8681 Qnil));
8682 if (WINDOW_TOTAL_LINES (w) != old_height)
8683 fonts_changed_p = 1;
8687 return change_height_p;
8691 /* Get information about the tool-bar item which is displayed in GLYPH
8692 on frame F. Return in *PROP_IDX the index where tool-bar item
8693 properties start in F->tool_bar_items. Value is zero if
8694 GLYPH doesn't display a tool-bar item. */
8696 static int
8697 tool_bar_item_info (f, glyph, prop_idx)
8698 struct frame *f;
8699 struct glyph *glyph;
8700 int *prop_idx;
8702 Lisp_Object prop;
8703 int success_p;
8704 int charpos;
8706 /* This function can be called asynchronously, which means we must
8707 exclude any possibility that Fget_text_property signals an
8708 error. */
8709 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8710 charpos = max (0, charpos);
8712 /* Get the text property `menu-item' at pos. The value of that
8713 property is the start index of this item's properties in
8714 F->tool_bar_items. */
8715 prop = Fget_text_property (make_number (charpos),
8716 Qmenu_item, f->current_tool_bar_string);
8717 if (INTEGERP (prop))
8719 *prop_idx = XINT (prop);
8720 success_p = 1;
8722 else
8723 success_p = 0;
8725 return success_p;
8729 /* Get information about the tool-bar item at position X/Y on frame F.
8730 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8731 the current matrix of the tool-bar window of F, or NULL if not
8732 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8733 item in F->tool_bar_items. Value is
8735 -1 if X/Y is not on a tool-bar item
8736 0 if X/Y is on the same item that was highlighted before.
8737 1 otherwise. */
8739 static int
8740 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8741 struct frame *f;
8742 int x, y;
8743 struct glyph **glyph;
8744 int *hpos, *vpos, *prop_idx;
8746 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8747 struct window *w = XWINDOW (f->tool_bar_window);
8748 int area;
8750 /* Find the glyph under X/Y. */
8751 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8752 if (*glyph == NULL)
8753 return -1;
8755 /* Get the start of this tool-bar item's properties in
8756 f->tool_bar_items. */
8757 if (!tool_bar_item_info (f, *glyph, prop_idx))
8758 return -1;
8760 /* Is mouse on the highlighted item? */
8761 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8762 && *vpos >= dpyinfo->mouse_face_beg_row
8763 && *vpos <= dpyinfo->mouse_face_end_row
8764 && (*vpos > dpyinfo->mouse_face_beg_row
8765 || *hpos >= dpyinfo->mouse_face_beg_col)
8766 && (*vpos < dpyinfo->mouse_face_end_row
8767 || *hpos < dpyinfo->mouse_face_end_col
8768 || dpyinfo->mouse_face_past_end))
8769 return 0;
8771 return 1;
8775 /* EXPORT:
8776 Handle mouse button event on the tool-bar of frame F, at
8777 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8778 0 for button release. MODIFIERS is event modifiers for button
8779 release. */
8781 void
8782 handle_tool_bar_click (f, x, y, down_p, modifiers)
8783 struct frame *f;
8784 int x, y, down_p;
8785 unsigned int modifiers;
8787 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8788 struct window *w = XWINDOW (f->tool_bar_window);
8789 int hpos, vpos, prop_idx;
8790 struct glyph *glyph;
8791 Lisp_Object enabled_p;
8793 /* If not on the highlighted tool-bar item, return. */
8794 frame_to_window_pixel_xy (w, &x, &y);
8795 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8796 return;
8798 /* If item is disabled, do nothing. */
8799 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8800 if (NILP (enabled_p))
8801 return;
8803 if (down_p)
8805 /* Show item in pressed state. */
8806 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8807 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8808 last_tool_bar_item = prop_idx;
8810 else
8812 Lisp_Object key, frame;
8813 struct input_event event;
8814 EVENT_INIT (event);
8816 /* Show item in released state. */
8817 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8818 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8820 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8822 XSETFRAME (frame, f);
8823 event.kind = TOOL_BAR_EVENT;
8824 event.frame_or_window = frame;
8825 event.arg = frame;
8826 kbd_buffer_store_event (&event);
8828 event.kind = TOOL_BAR_EVENT;
8829 event.frame_or_window = frame;
8830 event.arg = key;
8831 event.modifiers = modifiers;
8832 kbd_buffer_store_event (&event);
8833 last_tool_bar_item = -1;
8838 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8839 tool-bar window-relative coordinates X/Y. Called from
8840 note_mouse_highlight. */
8842 static void
8843 note_tool_bar_highlight (f, x, y)
8844 struct frame *f;
8845 int x, y;
8847 Lisp_Object window = f->tool_bar_window;
8848 struct window *w = XWINDOW (window);
8849 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8850 int hpos, vpos;
8851 struct glyph *glyph;
8852 struct glyph_row *row;
8853 int i;
8854 Lisp_Object enabled_p;
8855 int prop_idx;
8856 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8857 int mouse_down_p, rc;
8859 /* Function note_mouse_highlight is called with negative x(y
8860 values when mouse moves outside of the frame. */
8861 if (x <= 0 || y <= 0)
8863 clear_mouse_face (dpyinfo);
8864 return;
8867 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8868 if (rc < 0)
8870 /* Not on tool-bar item. */
8871 clear_mouse_face (dpyinfo);
8872 return;
8874 else if (rc == 0)
8875 /* On same tool-bar item as before. */
8876 goto set_help_echo;
8878 clear_mouse_face (dpyinfo);
8880 /* Mouse is down, but on different tool-bar item? */
8881 mouse_down_p = (dpyinfo->grabbed
8882 && f == last_mouse_frame
8883 && FRAME_LIVE_P (f));
8884 if (mouse_down_p
8885 && last_tool_bar_item != prop_idx)
8886 return;
8888 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8889 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8891 /* If tool-bar item is not enabled, don't highlight it. */
8892 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8893 if (!NILP (enabled_p))
8895 /* Compute the x-position of the glyph. In front and past the
8896 image is a space. We include this in the highlighted area. */
8897 row = MATRIX_ROW (w->current_matrix, vpos);
8898 for (i = x = 0; i < hpos; ++i)
8899 x += row->glyphs[TEXT_AREA][i].pixel_width;
8901 /* Record this as the current active region. */
8902 dpyinfo->mouse_face_beg_col = hpos;
8903 dpyinfo->mouse_face_beg_row = vpos;
8904 dpyinfo->mouse_face_beg_x = x;
8905 dpyinfo->mouse_face_beg_y = row->y;
8906 dpyinfo->mouse_face_past_end = 0;
8908 dpyinfo->mouse_face_end_col = hpos + 1;
8909 dpyinfo->mouse_face_end_row = vpos;
8910 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8911 dpyinfo->mouse_face_end_y = row->y;
8912 dpyinfo->mouse_face_window = window;
8913 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8915 /* Display it as active. */
8916 show_mouse_face (dpyinfo, draw);
8917 dpyinfo->mouse_face_image_state = draw;
8920 set_help_echo:
8922 /* Set help_echo_string to a help string to display for this tool-bar item.
8923 XTread_socket does the rest. */
8924 help_echo_object = help_echo_window = Qnil;
8925 help_echo_pos = -1;
8926 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8927 if (NILP (help_echo_string))
8928 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8931 #endif /* HAVE_WINDOW_SYSTEM */
8935 /***********************************************************************
8936 Fringes
8937 ***********************************************************************/
8939 #ifdef HAVE_WINDOW_SYSTEM
8941 /* Notice that all bitmaps bits are "mirrored". */
8943 /* An arrow like this: `<-'. */
8945 ...xx...
8946 ....xx..
8947 .....xx.
8948 ..xxxxxx
8949 ..xxxxxx
8950 .....xx.
8951 ....xx..
8952 ...xx...
8954 static unsigned char left_bits[] = {
8955 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8958 /* Right truncation arrow bitmap `->'. */
8960 ...xx...
8961 ..xx....
8962 .xx.....
8963 xxxxxx..
8964 xxxxxx..
8965 .xx.....
8966 ..xx....
8967 ...xx...
8969 static unsigned char right_bits[] = {
8970 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8973 /* Up arrow bitmap. */
8975 ...xx...
8976 ..xxxx..
8977 .xxxxxx.
8978 xxxxxxxx
8979 ...xx...
8980 ...xx...
8981 ...xx...
8982 ...xx...
8984 static unsigned char up_arrow_bits[] = {
8985 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
8988 /* Down arrow bitmap. */
8990 ...xx...
8991 ...xx...
8992 ...xx...
8993 ...xx...
8994 xxxxxxxx
8995 .xxxxxx.
8996 ..xxxx..
8997 ...xx...
8999 static unsigned char down_arrow_bits[] = {
9000 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
9002 /* Marker for continued lines. */
9004 ..xxxx..
9005 .xxxxx..
9006 xx......
9007 xxx..x..
9008 xxxxxx..
9009 .xxxxx..
9010 ..xxxx..
9011 .xxxxx..
9013 static unsigned char continued_bits[] = {
9014 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
9016 /* Marker for continuation lines. */
9018 ..xxxx..
9019 ..xxxxx.
9020 ......xx
9021 ..x..xxx
9022 ..xxxxxx
9023 ..xxxxx.
9024 ..xxxx..
9025 ..xxxxx.
9027 static unsigned char continuation_bits[] = {
9028 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
9030 /* Overlay arrow bitmap. A triangular arrow. */
9032 ......xx
9033 ....xxxx
9034 ...xxxxx
9035 ..xxxxxx
9036 ..xxxxxx
9037 ...xxxxx
9038 ....xxxx
9039 ......xx
9041 static unsigned char ov_bits[] = {
9042 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
9045 /* First line bitmap. An left-up angle. */
9047 ..xxxxxx
9048 ..xxxxxx
9049 ......xx
9050 ......xx
9051 ......xx
9052 ......xx
9053 ......xx
9054 ........
9056 static unsigned char first_line_bits[] = {
9057 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
9060 /* Last line bitmap. An left-down angle. */
9062 ........
9063 xx......
9064 xx......
9065 xx......
9066 xx......
9067 xx......
9068 xxxxxx..
9069 xxxxxx..
9071 static unsigned char last_line_bits[] = {
9072 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
9074 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
9076 .xxxxxxx
9077 .xxxxxxx
9078 .xxxxxxx
9079 .xxxxxxx
9080 .xxxxxxx
9081 .xxxxxxx
9082 .xxxxxxx
9083 .xxxxxxx
9084 .xxxxxxx
9085 .xxxxxxx
9086 .xxxxxxx
9087 .xxxxxxx
9088 .xxxxxxx
9090 static unsigned char filled_box_cursor_bits[] = {
9091 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f};
9093 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
9095 .xxxxxxx
9096 .x.....x
9097 .x.....x
9098 .x.....x
9099 .x.....x
9100 .x.....x
9101 .x.....x
9102 .x.....x
9103 .x.....x
9104 .x.....x
9105 .x.....x
9106 .x.....x
9107 .xxxxxxx
9109 static unsigned char hollow_box_cursor_bits[] = {
9110 0x7f, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7f};
9112 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
9114 ......xx
9115 ......xx
9116 ......xx
9117 ......xx
9118 ......xx
9119 ......xx
9120 ......xx
9121 ......xx
9122 ......xx
9123 ......xx
9124 ......xx
9125 ......xx
9126 ......xx
9128 static unsigned char bar_cursor_bits[] = {
9129 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
9131 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
9133 .xxxxxxx
9134 .xxxxxxx
9136 static unsigned char hbar_cursor_bits[] = {
9137 0x7f, 0x7f};
9140 /* Bitmap drawn to indicate lines not displaying text if
9141 `indicate-empty-lines' is non-nil. */
9142 static unsigned char zv_bits[] = {
9143 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9144 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9145 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9146 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9147 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9148 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9149 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9150 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
9152 /* Hollow square bitmap. */
9154 .xxxxxx.
9155 .x....x.
9156 .x....x.
9157 .x....x.
9158 .x....x.
9159 .xxxxxx.
9161 static unsigned char hollow_square_bits[] = {
9162 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
9165 struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
9167 { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
9168 { 8, sizeof (left_bits), 0, left_bits },
9169 { 8, sizeof (right_bits), 0, right_bits },
9170 { 8, sizeof (up_arrow_bits), -1, up_arrow_bits },
9171 { 8, sizeof (down_arrow_bits), -2, down_arrow_bits },
9172 { 8, sizeof (continued_bits), 0, continued_bits },
9173 { 8, sizeof (continuation_bits), 0, continuation_bits },
9174 { 8, sizeof (ov_bits), 0, ov_bits },
9175 { 8, sizeof (first_line_bits), -1, first_line_bits },
9176 { 8, sizeof (last_line_bits), -2, last_line_bits },
9177 { 8, sizeof (filled_box_cursor_bits), 0, filled_box_cursor_bits },
9178 { 8, sizeof (hollow_box_cursor_bits), 0, hollow_box_cursor_bits },
9179 { 8, sizeof (bar_cursor_bits), 0, bar_cursor_bits },
9180 { 8, sizeof (hbar_cursor_bits), -2, hbar_cursor_bits },
9181 { 8, sizeof (zv_bits), 3, zv_bits },
9182 { 8, sizeof (hollow_square_bits), 0, hollow_square_bits },
9186 /* Draw the bitmap WHICH in one of the left or right fringes of
9187 window W. ROW is the glyph row for which to display the bitmap; it
9188 determines the vertical position at which the bitmap has to be
9189 drawn.
9190 LEFT_P is 1 for left fringe, 0 for right fringe.
9193 void
9194 draw_fringe_bitmap (w, row, left_p)
9195 struct window *w;
9196 struct glyph_row *row;
9197 int left_p;
9199 struct frame *f = XFRAME (WINDOW_FRAME (w));
9200 struct draw_fringe_bitmap_params p;
9201 enum fringe_bitmap_type which;
9202 int period;
9204 if (left_p)
9205 which = row->left_fringe_bitmap;
9206 else if (!row->cursor_in_fringe_p)
9207 which = row->right_fringe_bitmap;
9208 else
9209 switch (w->phys_cursor_type)
9211 case HOLLOW_BOX_CURSOR:
9212 if (row->visible_height >= sizeof(hollow_box_cursor_bits))
9213 which = HOLLOW_BOX_CURSOR_BITMAP;
9214 else
9215 which = HOLLOW_SQUARE_BITMAP;
9216 break;
9217 case FILLED_BOX_CURSOR:
9218 which = FILLED_BOX_CURSOR_BITMAP;
9219 break;
9220 case BAR_CURSOR:
9221 which = BAR_CURSOR_BITMAP;
9222 break;
9223 case HBAR_CURSOR:
9224 which = HBAR_CURSOR_BITMAP;
9225 break;
9226 case NO_CURSOR:
9227 default:
9228 w->phys_cursor_on_p = 0;
9229 row->cursor_in_fringe_p = 0;
9230 which = row->right_fringe_bitmap;
9231 break;
9234 period = fringe_bitmaps[which].period;
9236 /* Convert row to frame coordinates. */
9237 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
9239 p.which = which;
9240 p.wd = fringe_bitmaps[which].width;
9242 p.h = fringe_bitmaps[which].height;
9243 p.dh = (period > 0 ? (p.y % period) : 0);
9244 p.h -= p.dh;
9245 /* Clip bitmap if too high. */
9246 if (p.h > row->height)
9247 p.h = row->height;
9249 p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
9250 PREPARE_FACE_FOR_DISPLAY (f, p.face);
9252 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
9253 the fringe. */
9254 p.bx = -1;
9255 if (left_p)
9257 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
9258 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9259 ? LEFT_MARGIN_AREA
9260 : TEXT_AREA));
9261 if (p.wd > wd)
9262 p.wd = wd;
9263 p.x = x - p.wd - (wd - p.wd) / 2;
9265 if (p.wd < wd || row->height > p.h)
9267 /* If W has a vertical border to its left, don't draw over it. */
9268 wd -= ((!WINDOW_LEFTMOST_P (w)
9269 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
9270 ? 1 : 0);
9271 p.bx = x - wd;
9272 p.nx = wd;
9275 else
9277 int x = window_box_right (w,
9278 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9279 ? RIGHT_MARGIN_AREA
9280 : TEXT_AREA));
9281 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
9282 if (p.wd > wd)
9283 p.wd = wd;
9284 p.x = x + (wd - p.wd) / 2;
9285 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
9286 the fringe. */
9287 if (p.wd < wd || row->height > p.h)
9289 p.bx = x;
9290 p.nx = wd;
9294 if (p.bx >= 0)
9296 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
9298 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
9299 p.ny = row->visible_height;
9302 /* Adjust y to the offset in the row to start drawing the bitmap. */
9303 if (period == 0)
9304 p.y += (row->height - p.h) / 2;
9305 else if (period == -2)
9307 p.h = fringe_bitmaps[which].height;
9308 p.y += (row->visible_height - p.h);
9311 rif->draw_fringe_bitmap (w, row, &p);
9314 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
9315 function with input blocked. */
9317 void
9318 draw_row_fringe_bitmaps (w, row)
9319 struct window *w;
9320 struct glyph_row *row;
9322 xassert (interrupt_input_blocked);
9324 /* If row is completely invisible, because of vscrolling, we
9325 don't have to draw anything. */
9326 if (row->visible_height <= 0)
9327 return;
9329 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
9330 draw_fringe_bitmap (w, row, 1);
9332 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
9333 draw_fringe_bitmap (w, row, 0);
9336 /* Draw the fringes of window W. Only fringes for rows marked for
9337 update in redraw_fringe_bitmaps_p are drawn. */
9339 void
9340 draw_window_fringes (w)
9341 struct window *w;
9343 struct glyph_row *row;
9344 int yb = window_text_bottom_y (w);
9345 int nrows = w->current_matrix->nrows;
9346 int y = 0, rn;
9348 if (w->pseudo_window_p)
9349 return;
9351 for (y = 0, rn = 0, row = w->current_matrix->rows;
9352 y < yb && rn < nrows;
9353 y += row->height, ++row, ++rn)
9355 if (!row->redraw_fringe_bitmaps_p)
9356 continue;
9357 draw_row_fringe_bitmaps (w, row);
9358 row->redraw_fringe_bitmaps_p = 0;
9363 /* Compute actual fringe widths for frame F.
9365 If REDRAW is 1, redraw F if the fringe settings was actually
9366 modified and F is visible.
9368 Since the combined left and right fringe must occupy an integral
9369 number of columns, we may need to add some pixels to each fringe.
9370 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
9371 but a negative width value is taken literally (after negating it).
9373 We never make the fringes narrower than specified. It is planned
9374 to make fringe bitmaps customizable and expandable, and at that
9375 time, the user will typically specify the minimum number of pixels
9376 needed for his bitmaps, so we shouldn't select anything less than
9377 what is specified.
9380 void
9381 compute_fringe_widths (f, redraw)
9382 struct frame *f;
9383 int redraw;
9385 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
9386 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
9387 int o_cols = FRAME_FRINGE_COLS (f);
9389 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9390 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9391 int left_fringe_width, right_fringe_width;
9393 if (!NILP (left_fringe))
9394 left_fringe = Fcdr (left_fringe);
9395 if (!NILP (right_fringe))
9396 right_fringe = Fcdr (right_fringe);
9398 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9399 XINT (left_fringe));
9400 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9401 XINT (right_fringe));
9403 if (left_fringe_width || right_fringe_width)
9405 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9406 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9407 int conf_wid = left_wid + right_wid;
9408 int font_wid = FRAME_COLUMN_WIDTH (f);
9409 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9410 int real_wid = cols * font_wid;
9411 if (left_wid && right_wid)
9413 if (left_fringe_width < 0)
9415 /* Left fringe width is fixed, adjust right fringe if necessary */
9416 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
9417 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9419 else if (right_fringe_width < 0)
9421 /* Right fringe width is fixed, adjust left fringe if necessary */
9422 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9423 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
9425 else
9427 /* Adjust both fringes with an equal amount.
9428 Note that we are doing integer arithmetic here, so don't
9429 lose a pixel if the total width is an odd number. */
9430 int fill = real_wid - conf_wid;
9431 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9432 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9435 else if (left_fringe_width)
9437 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
9438 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9440 else
9442 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9443 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
9445 FRAME_FRINGE_COLS (f) = cols;
9447 else
9449 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9450 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9451 FRAME_FRINGE_COLS (f) = 0;
9454 if (redraw && FRAME_VISIBLE_P (f))
9455 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
9456 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
9457 o_cols != FRAME_FRINGE_COLS (f))
9458 redraw_frame (f);
9461 #endif /* HAVE_WINDOW_SYSTEM */
9465 /************************************************************************
9466 Horizontal scrolling
9467 ************************************************************************/
9469 static int hscroll_window_tree P_ ((Lisp_Object));
9470 static int hscroll_windows P_ ((Lisp_Object));
9472 /* For all leaf windows in the window tree rooted at WINDOW, set their
9473 hscroll value so that PT is (i) visible in the window, and (ii) so
9474 that it is not within a certain margin at the window's left and
9475 right border. Value is non-zero if any window's hscroll has been
9476 changed. */
9478 static int
9479 hscroll_window_tree (window)
9480 Lisp_Object window;
9482 int hscrolled_p = 0;
9483 int hscroll_relative_p = FLOATP (Vhscroll_step);
9484 int hscroll_step_abs = 0;
9485 double hscroll_step_rel = 0;
9487 if (hscroll_relative_p)
9489 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9490 if (hscroll_step_rel < 0)
9492 hscroll_relative_p = 0;
9493 hscroll_step_abs = 0;
9496 else if (INTEGERP (Vhscroll_step))
9498 hscroll_step_abs = XINT (Vhscroll_step);
9499 if (hscroll_step_abs < 0)
9500 hscroll_step_abs = 0;
9502 else
9503 hscroll_step_abs = 0;
9505 while (WINDOWP (window))
9507 struct window *w = XWINDOW (window);
9509 if (WINDOWP (w->hchild))
9510 hscrolled_p |= hscroll_window_tree (w->hchild);
9511 else if (WINDOWP (w->vchild))
9512 hscrolled_p |= hscroll_window_tree (w->vchild);
9513 else if (w->cursor.vpos >= 0)
9515 int h_margin;
9516 int text_area_width;
9517 struct glyph_row *current_cursor_row
9518 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9519 struct glyph_row *desired_cursor_row
9520 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9521 struct glyph_row *cursor_row
9522 = (desired_cursor_row->enabled_p
9523 ? desired_cursor_row
9524 : current_cursor_row);
9526 text_area_width = window_box_width (w, TEXT_AREA);
9528 /* Scroll when cursor is inside this scroll margin. */
9529 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9531 if ((XFASTINT (w->hscroll)
9532 && w->cursor.x <= h_margin)
9533 || (cursor_row->enabled_p
9534 && cursor_row->truncated_on_right_p
9535 && (w->cursor.x >= text_area_width - h_margin)))
9537 struct it it;
9538 int hscroll;
9539 struct buffer *saved_current_buffer;
9540 int pt;
9541 int wanted_x;
9543 /* Find point in a display of infinite width. */
9544 saved_current_buffer = current_buffer;
9545 current_buffer = XBUFFER (w->buffer);
9547 if (w == XWINDOW (selected_window))
9548 pt = BUF_PT (current_buffer);
9549 else
9551 pt = marker_position (w->pointm);
9552 pt = max (BEGV, pt);
9553 pt = min (ZV, pt);
9556 /* Move iterator to pt starting at cursor_row->start in
9557 a line with infinite width. */
9558 init_to_row_start (&it, w, cursor_row);
9559 it.last_visible_x = INFINITY;
9560 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9561 current_buffer = saved_current_buffer;
9563 /* Position cursor in window. */
9564 if (!hscroll_relative_p && hscroll_step_abs == 0)
9565 hscroll = max (0, it.current_x - text_area_width / 2)
9566 / FRAME_COLUMN_WIDTH (it.f);
9567 else if (w->cursor.x >= text_area_width - h_margin)
9569 if (hscroll_relative_p)
9570 wanted_x = text_area_width * (1 - hscroll_step_rel)
9571 - h_margin;
9572 else
9573 wanted_x = text_area_width
9574 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9575 - h_margin;
9576 hscroll
9577 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9579 else
9581 if (hscroll_relative_p)
9582 wanted_x = text_area_width * hscroll_step_rel
9583 + h_margin;
9584 else
9585 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9586 + h_margin;
9587 hscroll
9588 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9590 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9592 /* Don't call Fset_window_hscroll if value hasn't
9593 changed because it will prevent redisplay
9594 optimizations. */
9595 if (XFASTINT (w->hscroll) != hscroll)
9597 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9598 w->hscroll = make_number (hscroll);
9599 hscrolled_p = 1;
9604 window = w->next;
9607 /* Value is non-zero if hscroll of any leaf window has been changed. */
9608 return hscrolled_p;
9612 /* Set hscroll so that cursor is visible and not inside horizontal
9613 scroll margins for all windows in the tree rooted at WINDOW. See
9614 also hscroll_window_tree above. Value is non-zero if any window's
9615 hscroll has been changed. If it has, desired matrices on the frame
9616 of WINDOW are cleared. */
9618 static int
9619 hscroll_windows (window)
9620 Lisp_Object window;
9622 int hscrolled_p;
9624 if (automatic_hscrolling_p)
9626 hscrolled_p = hscroll_window_tree (window);
9627 if (hscrolled_p)
9628 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9630 else
9631 hscrolled_p = 0;
9632 return hscrolled_p;
9637 /************************************************************************
9638 Redisplay
9639 ************************************************************************/
9641 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9642 to a non-zero value. This is sometimes handy to have in a debugger
9643 session. */
9645 #if GLYPH_DEBUG
9647 /* First and last unchanged row for try_window_id. */
9649 int debug_first_unchanged_at_end_vpos;
9650 int debug_last_unchanged_at_beg_vpos;
9652 /* Delta vpos and y. */
9654 int debug_dvpos, debug_dy;
9656 /* Delta in characters and bytes for try_window_id. */
9658 int debug_delta, debug_delta_bytes;
9660 /* Values of window_end_pos and window_end_vpos at the end of
9661 try_window_id. */
9663 EMACS_INT debug_end_pos, debug_end_vpos;
9665 /* Append a string to W->desired_matrix->method. FMT is a printf
9666 format string. A1...A9 are a supplement for a variable-length
9667 argument list. If trace_redisplay_p is non-zero also printf the
9668 resulting string to stderr. */
9670 static void
9671 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9672 struct window *w;
9673 char *fmt;
9674 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9676 char buffer[512];
9677 char *method = w->desired_matrix->method;
9678 int len = strlen (method);
9679 int size = sizeof w->desired_matrix->method;
9680 int remaining = size - len - 1;
9682 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9683 if (len && remaining)
9685 method[len] = '|';
9686 --remaining, ++len;
9689 strncpy (method + len, buffer, remaining);
9691 if (trace_redisplay_p)
9692 fprintf (stderr, "%p (%s): %s\n",
9694 ((BUFFERP (w->buffer)
9695 && STRINGP (XBUFFER (w->buffer)->name))
9696 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9697 : "no buffer"),
9698 buffer);
9701 #endif /* GLYPH_DEBUG */
9704 /* Value is non-zero if all changes in window W, which displays
9705 current_buffer, are in the text between START and END. START is a
9706 buffer position, END is given as a distance from Z. Used in
9707 redisplay_internal for display optimization. */
9709 static INLINE int
9710 text_outside_line_unchanged_p (w, start, end)
9711 struct window *w;
9712 int start, end;
9714 int unchanged_p = 1;
9716 /* If text or overlays have changed, see where. */
9717 if (XFASTINT (w->last_modified) < MODIFF
9718 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9720 /* Gap in the line? */
9721 if (GPT < start || Z - GPT < end)
9722 unchanged_p = 0;
9724 /* Changes start in front of the line, or end after it? */
9725 if (unchanged_p
9726 && (BEG_UNCHANGED < start - 1
9727 || END_UNCHANGED < end))
9728 unchanged_p = 0;
9730 /* If selective display, can't optimize if changes start at the
9731 beginning of the line. */
9732 if (unchanged_p
9733 && INTEGERP (current_buffer->selective_display)
9734 && XINT (current_buffer->selective_display) > 0
9735 && (BEG_UNCHANGED < start || GPT <= start))
9736 unchanged_p = 0;
9738 /* If there are overlays at the start or end of the line, these
9739 may have overlay strings with newlines in them. A change at
9740 START, for instance, may actually concern the display of such
9741 overlay strings as well, and they are displayed on different
9742 lines. So, quickly rule out this case. (For the future, it
9743 might be desirable to implement something more telling than
9744 just BEG/END_UNCHANGED.) */
9745 if (unchanged_p)
9747 if (BEG + BEG_UNCHANGED == start
9748 && overlay_touches_p (start))
9749 unchanged_p = 0;
9750 if (END_UNCHANGED == end
9751 && overlay_touches_p (Z - end))
9752 unchanged_p = 0;
9756 return unchanged_p;
9760 /* Do a frame update, taking possible shortcuts into account. This is
9761 the main external entry point for redisplay.
9763 If the last redisplay displayed an echo area message and that message
9764 is no longer requested, we clear the echo area or bring back the
9765 mini-buffer if that is in use. */
9767 void
9768 redisplay ()
9770 redisplay_internal (0);
9774 /* Return 1 if point moved out of or into a composition. Otherwise
9775 return 0. PREV_BUF and PREV_PT are the last point buffer and
9776 position. BUF and PT are the current point buffer and position. */
9779 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9780 struct buffer *prev_buf, *buf;
9781 int prev_pt, pt;
9783 int start, end;
9784 Lisp_Object prop;
9785 Lisp_Object buffer;
9787 XSETBUFFER (buffer, buf);
9788 /* Check a composition at the last point if point moved within the
9789 same buffer. */
9790 if (prev_buf == buf)
9792 if (prev_pt == pt)
9793 /* Point didn't move. */
9794 return 0;
9796 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9797 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9798 && COMPOSITION_VALID_P (start, end, prop)
9799 && start < prev_pt && end > prev_pt)
9800 /* The last point was within the composition. Return 1 iff
9801 point moved out of the composition. */
9802 return (pt <= start || pt >= end);
9805 /* Check a composition at the current point. */
9806 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9807 && find_composition (pt, -1, &start, &end, &prop, buffer)
9808 && COMPOSITION_VALID_P (start, end, prop)
9809 && start < pt && end > pt);
9813 /* Reconsider the setting of B->clip_changed which is displayed
9814 in window W. */
9816 static INLINE void
9817 reconsider_clip_changes (w, b)
9818 struct window *w;
9819 struct buffer *b;
9821 if (b->clip_changed
9822 && !NILP (w->window_end_valid)
9823 && w->current_matrix->buffer == b
9824 && w->current_matrix->zv == BUF_ZV (b)
9825 && w->current_matrix->begv == BUF_BEGV (b))
9826 b->clip_changed = 0;
9828 /* If display wasn't paused, and W is not a tool bar window, see if
9829 point has been moved into or out of a composition. In that case,
9830 we set b->clip_changed to 1 to force updating the screen. If
9831 b->clip_changed has already been set to 1, we can skip this
9832 check. */
9833 if (!b->clip_changed
9834 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9836 int pt;
9838 if (w == XWINDOW (selected_window))
9839 pt = BUF_PT (current_buffer);
9840 else
9841 pt = marker_position (w->pointm);
9843 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9844 || pt != XINT (w->last_point))
9845 && check_point_in_composition (w->current_matrix->buffer,
9846 XINT (w->last_point),
9847 XBUFFER (w->buffer), pt))
9848 b->clip_changed = 1;
9853 /* Select FRAME to forward the values of frame-local variables into C
9854 variables so that the redisplay routines can access those values
9855 directly. */
9857 static void
9858 select_frame_for_redisplay (frame)
9859 Lisp_Object frame;
9861 Lisp_Object tail, sym, val;
9862 Lisp_Object old = selected_frame;
9864 selected_frame = frame;
9866 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9867 if (CONSP (XCAR (tail))
9868 && (sym = XCAR (XCAR (tail)),
9869 SYMBOLP (sym))
9870 && (sym = indirect_variable (sym),
9871 val = SYMBOL_VALUE (sym),
9872 (BUFFER_LOCAL_VALUEP (val)
9873 || SOME_BUFFER_LOCAL_VALUEP (val)))
9874 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9875 Fsymbol_value (sym);
9877 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9878 if (CONSP (XCAR (tail))
9879 && (sym = XCAR (XCAR (tail)),
9880 SYMBOLP (sym))
9881 && (sym = indirect_variable (sym),
9882 val = SYMBOL_VALUE (sym),
9883 (BUFFER_LOCAL_VALUEP (val)
9884 || SOME_BUFFER_LOCAL_VALUEP (val)))
9885 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9886 Fsymbol_value (sym);
9890 #define STOP_POLLING \
9891 do { if (! polling_stopped_here) stop_polling (); \
9892 polling_stopped_here = 1; } while (0)
9894 #define RESUME_POLLING \
9895 do { if (polling_stopped_here) start_polling (); \
9896 polling_stopped_here = 0; } while (0)
9899 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9900 response to any user action; therefore, we should preserve the echo
9901 area. (Actually, our caller does that job.) Perhaps in the future
9902 avoid recentering windows if it is not necessary; currently that
9903 causes some problems. */
9905 static void
9906 redisplay_internal (preserve_echo_area)
9907 int preserve_echo_area;
9909 struct window *w = XWINDOW (selected_window);
9910 struct frame *f = XFRAME (w->frame);
9911 int pause;
9912 int must_finish = 0;
9913 struct text_pos tlbufpos, tlendpos;
9914 int number_of_visible_frames;
9915 int count;
9916 struct frame *sf = SELECTED_FRAME ();
9917 int polling_stopped_here = 0;
9919 /* Non-zero means redisplay has to consider all windows on all
9920 frames. Zero means, only selected_window is considered. */
9921 int consider_all_windows_p;
9923 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9925 /* No redisplay if running in batch mode or frame is not yet fully
9926 initialized, or redisplay is explicitly turned off by setting
9927 Vinhibit_redisplay. */
9928 if (noninteractive
9929 || !NILP (Vinhibit_redisplay)
9930 || !f->glyphs_initialized_p)
9931 return;
9933 /* The flag redisplay_performed_directly_p is set by
9934 direct_output_for_insert when it already did the whole screen
9935 update necessary. */
9936 if (redisplay_performed_directly_p)
9938 redisplay_performed_directly_p = 0;
9939 if (!hscroll_windows (selected_window))
9940 return;
9943 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9944 if (popup_activated ())
9945 return;
9946 #endif
9948 /* I don't think this happens but let's be paranoid. */
9949 if (redisplaying_p)
9950 return;
9952 /* Record a function that resets redisplaying_p to its old value
9953 when we leave this function. */
9954 count = SPECPDL_INDEX ();
9955 record_unwind_protect (unwind_redisplay,
9956 Fcons (make_number (redisplaying_p), selected_frame));
9957 ++redisplaying_p;
9958 specbind (Qinhibit_free_realized_faces, Qnil);
9960 retry:
9961 pause = 0;
9962 reconsider_clip_changes (w, current_buffer);
9964 /* If new fonts have been loaded that make a glyph matrix adjustment
9965 necessary, do it. */
9966 if (fonts_changed_p)
9968 adjust_glyphs (NULL);
9969 ++windows_or_buffers_changed;
9970 fonts_changed_p = 0;
9973 /* If face_change_count is non-zero, init_iterator will free all
9974 realized faces, which includes the faces referenced from current
9975 matrices. So, we can't reuse current matrices in this case. */
9976 if (face_change_count)
9977 ++windows_or_buffers_changed;
9979 if (! FRAME_WINDOW_P (sf)
9980 && previous_terminal_frame != sf)
9982 /* Since frames on an ASCII terminal share the same display
9983 area, displaying a different frame means redisplay the whole
9984 thing. */
9985 windows_or_buffers_changed++;
9986 SET_FRAME_GARBAGED (sf);
9987 XSETFRAME (Vterminal_frame, sf);
9989 previous_terminal_frame = sf;
9991 /* Set the visible flags for all frames. Do this before checking
9992 for resized or garbaged frames; they want to know if their frames
9993 are visible. See the comment in frame.h for
9994 FRAME_SAMPLE_VISIBILITY. */
9996 Lisp_Object tail, frame;
9998 number_of_visible_frames = 0;
10000 FOR_EACH_FRAME (tail, frame)
10002 struct frame *f = XFRAME (frame);
10004 FRAME_SAMPLE_VISIBILITY (f);
10005 if (FRAME_VISIBLE_P (f))
10006 ++number_of_visible_frames;
10007 clear_desired_matrices (f);
10011 /* Notice any pending interrupt request to change frame size. */
10012 do_pending_window_change (1);
10014 /* Clear frames marked as garbaged. */
10015 if (frame_garbaged)
10016 clear_garbaged_frames ();
10018 /* Build menubar and tool-bar items. */
10019 prepare_menu_bars ();
10021 if (windows_or_buffers_changed)
10022 update_mode_lines++;
10024 /* Detect case that we need to write or remove a star in the mode line. */
10025 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10027 w->update_mode_line = Qt;
10028 if (buffer_shared > 1)
10029 update_mode_lines++;
10032 /* If %c is in the mode line, update it if needed. */
10033 if (!NILP (w->column_number_displayed)
10034 /* This alternative quickly identifies a common case
10035 where no change is needed. */
10036 && !(PT == XFASTINT (w->last_point)
10037 && XFASTINT (w->last_modified) >= MODIFF
10038 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10039 && (XFASTINT (w->column_number_displayed)
10040 != (int) current_column ())) /* iftc */
10041 w->update_mode_line = Qt;
10043 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10045 /* The variable buffer_shared is set in redisplay_window and
10046 indicates that we redisplay a buffer in different windows. See
10047 there. */
10048 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10049 || cursor_type_changed);
10051 /* If specs for an arrow have changed, do thorough redisplay
10052 to ensure we remove any arrow that should no longer exist. */
10053 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
10054 || ! EQ (Voverlay_arrow_string, last_arrow_string))
10055 consider_all_windows_p = windows_or_buffers_changed = 1;
10057 /* Normally the message* functions will have already displayed and
10058 updated the echo area, but the frame may have been trashed, or
10059 the update may have been preempted, so display the echo area
10060 again here. Checking message_cleared_p captures the case that
10061 the echo area should be cleared. */
10062 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10063 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10064 || (message_cleared_p
10065 && minibuf_level == 0
10066 /* If the mini-window is currently selected, this means the
10067 echo-area doesn't show through. */
10068 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10070 int window_height_changed_p = echo_area_display (0);
10071 must_finish = 1;
10073 /* If we don't display the current message, don't clear the
10074 message_cleared_p flag, because, if we did, we wouldn't clear
10075 the echo area in the next redisplay which doesn't preserve
10076 the echo area. */
10077 if (!display_last_displayed_message_p)
10078 message_cleared_p = 0;
10080 if (fonts_changed_p)
10081 goto retry;
10082 else if (window_height_changed_p)
10084 consider_all_windows_p = 1;
10085 ++update_mode_lines;
10086 ++windows_or_buffers_changed;
10088 /* If window configuration was changed, frames may have been
10089 marked garbaged. Clear them or we will experience
10090 surprises wrt scrolling. */
10091 if (frame_garbaged)
10092 clear_garbaged_frames ();
10095 else if (EQ (selected_window, minibuf_window)
10096 && (current_buffer->clip_changed
10097 || XFASTINT (w->last_modified) < MODIFF
10098 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10099 && resize_mini_window (w, 0))
10101 /* Resized active mini-window to fit the size of what it is
10102 showing if its contents might have changed. */
10103 must_finish = 1;
10104 consider_all_windows_p = 1;
10105 ++windows_or_buffers_changed;
10106 ++update_mode_lines;
10108 /* If window configuration was changed, frames may have been
10109 marked garbaged. Clear them or we will experience
10110 surprises wrt scrolling. */
10111 if (frame_garbaged)
10112 clear_garbaged_frames ();
10116 /* If showing the region, and mark has changed, we must redisplay
10117 the whole window. The assignment to this_line_start_pos prevents
10118 the optimization directly below this if-statement. */
10119 if (((!NILP (Vtransient_mark_mode)
10120 && !NILP (XBUFFER (w->buffer)->mark_active))
10121 != !NILP (w->region_showing))
10122 || (!NILP (w->region_showing)
10123 && !EQ (w->region_showing,
10124 Fmarker_position (XBUFFER (w->buffer)->mark))))
10125 CHARPOS (this_line_start_pos) = 0;
10127 /* Optimize the case that only the line containing the cursor in the
10128 selected window has changed. Variables starting with this_ are
10129 set in display_line and record information about the line
10130 containing the cursor. */
10131 tlbufpos = this_line_start_pos;
10132 tlendpos = this_line_end_pos;
10133 if (!consider_all_windows_p
10134 && CHARPOS (tlbufpos) > 0
10135 && NILP (w->update_mode_line)
10136 && !current_buffer->clip_changed
10137 && !current_buffer->prevent_redisplay_optimizations_p
10138 && FRAME_VISIBLE_P (XFRAME (w->frame))
10139 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10140 /* Make sure recorded data applies to current buffer, etc. */
10141 && this_line_buffer == current_buffer
10142 && current_buffer == XBUFFER (w->buffer)
10143 && NILP (w->force_start)
10144 && NILP (w->optional_new_start)
10145 /* Point must be on the line that we have info recorded about. */
10146 && PT >= CHARPOS (tlbufpos)
10147 && PT <= Z - CHARPOS (tlendpos)
10148 /* All text outside that line, including its final newline,
10149 must be unchanged */
10150 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10151 CHARPOS (tlendpos)))
10153 if (CHARPOS (tlbufpos) > BEGV
10154 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10155 && (CHARPOS (tlbufpos) == ZV
10156 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10157 /* Former continuation line has disappeared by becoming empty */
10158 goto cancel;
10159 else if (XFASTINT (w->last_modified) < MODIFF
10160 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10161 || MINI_WINDOW_P (w))
10163 /* We have to handle the case of continuation around a
10164 wide-column character (See the comment in indent.c around
10165 line 885).
10167 For instance, in the following case:
10169 -------- Insert --------
10170 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10171 J_I_ ==> J_I_ `^^' are cursors.
10172 ^^ ^^
10173 -------- --------
10175 As we have to redraw the line above, we should goto cancel. */
10177 struct it it;
10178 int line_height_before = this_line_pixel_height;
10180 /* Note that start_display will handle the case that the
10181 line starting at tlbufpos is a continuation lines. */
10182 start_display (&it, w, tlbufpos);
10184 /* Implementation note: It this still necessary? */
10185 if (it.current_x != this_line_start_x)
10186 goto cancel;
10188 TRACE ((stderr, "trying display optimization 1\n"));
10189 w->cursor.vpos = -1;
10190 overlay_arrow_seen = 0;
10191 it.vpos = this_line_vpos;
10192 it.current_y = this_line_y;
10193 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10194 display_line (&it);
10196 /* If line contains point, is not continued,
10197 and ends at same distance from eob as before, we win */
10198 if (w->cursor.vpos >= 0
10199 /* Line is not continued, otherwise this_line_start_pos
10200 would have been set to 0 in display_line. */
10201 && CHARPOS (this_line_start_pos)
10202 /* Line ends as before. */
10203 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10204 /* Line has same height as before. Otherwise other lines
10205 would have to be shifted up or down. */
10206 && this_line_pixel_height == line_height_before)
10208 /* If this is not the window's last line, we must adjust
10209 the charstarts of the lines below. */
10210 if (it.current_y < it.last_visible_y)
10212 struct glyph_row *row
10213 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10214 int delta, delta_bytes;
10216 if (Z - CHARPOS (tlendpos) == ZV)
10218 /* This line ends at end of (accessible part of)
10219 buffer. There is no newline to count. */
10220 delta = (Z
10221 - CHARPOS (tlendpos)
10222 - MATRIX_ROW_START_CHARPOS (row));
10223 delta_bytes = (Z_BYTE
10224 - BYTEPOS (tlendpos)
10225 - MATRIX_ROW_START_BYTEPOS (row));
10227 else
10229 /* This line ends in a newline. Must take
10230 account of the newline and the rest of the
10231 text that follows. */
10232 delta = (Z
10233 - CHARPOS (tlendpos)
10234 - MATRIX_ROW_START_CHARPOS (row));
10235 delta_bytes = (Z_BYTE
10236 - BYTEPOS (tlendpos)
10237 - MATRIX_ROW_START_BYTEPOS (row));
10240 increment_matrix_positions (w->current_matrix,
10241 this_line_vpos + 1,
10242 w->current_matrix->nrows,
10243 delta, delta_bytes);
10246 /* If this row displays text now but previously didn't,
10247 or vice versa, w->window_end_vpos may have to be
10248 adjusted. */
10249 if ((it.glyph_row - 1)->displays_text_p)
10251 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10252 XSETINT (w->window_end_vpos, this_line_vpos);
10254 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10255 && this_line_vpos > 0)
10256 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10257 w->window_end_valid = Qnil;
10259 /* Update hint: No need to try to scroll in update_window. */
10260 w->desired_matrix->no_scrolling_p = 1;
10262 #if GLYPH_DEBUG
10263 *w->desired_matrix->method = 0;
10264 debug_method_add (w, "optimization 1");
10265 #endif
10266 #ifdef HAVE_WINDOW_SYSTEM
10267 update_window_fringes (w, 0);
10268 #endif
10269 goto update;
10271 else
10272 goto cancel;
10274 else if (/* Cursor position hasn't changed. */
10275 PT == XFASTINT (w->last_point)
10276 /* Make sure the cursor was last displayed
10277 in this window. Otherwise we have to reposition it. */
10278 && 0 <= w->cursor.vpos
10279 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10281 if (!must_finish)
10283 do_pending_window_change (1);
10285 /* We used to always goto end_of_redisplay here, but this
10286 isn't enough if we have a blinking cursor. */
10287 if (w->cursor_off_p == w->last_cursor_off_p)
10288 goto end_of_redisplay;
10290 goto update;
10292 /* If highlighting the region, or if the cursor is in the echo area,
10293 then we can't just move the cursor. */
10294 else if (! (!NILP (Vtransient_mark_mode)
10295 && !NILP (current_buffer->mark_active))
10296 && (EQ (selected_window, current_buffer->last_selected_window)
10297 || highlight_nonselected_windows)
10298 && NILP (w->region_showing)
10299 && NILP (Vshow_trailing_whitespace)
10300 && !cursor_in_echo_area)
10302 struct it it;
10303 struct glyph_row *row;
10305 /* Skip from tlbufpos to PT and see where it is. Note that
10306 PT may be in invisible text. If so, we will end at the
10307 next visible position. */
10308 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10309 NULL, DEFAULT_FACE_ID);
10310 it.current_x = this_line_start_x;
10311 it.current_y = this_line_y;
10312 it.vpos = this_line_vpos;
10314 /* The call to move_it_to stops in front of PT, but
10315 moves over before-strings. */
10316 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10318 if (it.vpos == this_line_vpos
10319 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10320 row->enabled_p))
10322 xassert (this_line_vpos == it.vpos);
10323 xassert (this_line_y == it.current_y);
10324 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10325 #if GLYPH_DEBUG
10326 *w->desired_matrix->method = 0;
10327 debug_method_add (w, "optimization 3");
10328 #endif
10329 goto update;
10331 else
10332 goto cancel;
10335 cancel:
10336 /* Text changed drastically or point moved off of line. */
10337 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10340 CHARPOS (this_line_start_pos) = 0;
10341 consider_all_windows_p |= buffer_shared > 1;
10342 ++clear_face_cache_count;
10345 /* Build desired matrices, and update the display. If
10346 consider_all_windows_p is non-zero, do it for all windows on all
10347 frames. Otherwise do it for selected_window, only. */
10349 if (consider_all_windows_p)
10351 Lisp_Object tail, frame;
10352 int i, n = 0, size = 50;
10353 struct frame **updated
10354 = (struct frame **) alloca (size * sizeof *updated);
10356 /* Clear the face cache eventually. */
10357 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10359 clear_face_cache (0);
10360 clear_face_cache_count = 0;
10363 /* Recompute # windows showing selected buffer. This will be
10364 incremented each time such a window is displayed. */
10365 buffer_shared = 0;
10367 FOR_EACH_FRAME (tail, frame)
10369 struct frame *f = XFRAME (frame);
10371 if (FRAME_WINDOW_P (f) || f == sf)
10373 if (! EQ (frame, selected_frame))
10374 /* Select the frame, for the sake of frame-local
10375 variables. */
10376 select_frame_for_redisplay (frame);
10378 #ifdef HAVE_WINDOW_SYSTEM
10379 if (clear_face_cache_count % 50 == 0
10380 && FRAME_WINDOW_P (f))
10381 clear_image_cache (f, 0);
10382 #endif /* HAVE_WINDOW_SYSTEM */
10384 /* Mark all the scroll bars to be removed; we'll redeem
10385 the ones we want when we redisplay their windows. */
10386 if (condemn_scroll_bars_hook)
10387 condemn_scroll_bars_hook (f);
10389 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10390 redisplay_windows (FRAME_ROOT_WINDOW (f));
10392 /* Any scroll bars which redisplay_windows should have
10393 nuked should now go away. */
10394 if (judge_scroll_bars_hook)
10395 judge_scroll_bars_hook (f);
10397 /* If fonts changed, display again. */
10398 /* ??? rms: I suspect it is a mistake to jump all the way
10399 back to retry here. It should just retry this frame. */
10400 if (fonts_changed_p)
10401 goto retry;
10403 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10405 /* See if we have to hscroll. */
10406 if (hscroll_windows (f->root_window))
10407 goto retry;
10409 /* Prevent various kinds of signals during display
10410 update. stdio is not robust about handling
10411 signals, which can cause an apparent I/O
10412 error. */
10413 if (interrupt_input)
10414 unrequest_sigio ();
10415 STOP_POLLING;
10417 /* Update the display. */
10418 set_window_update_flags (XWINDOW (f->root_window), 1);
10419 pause |= update_frame (f, 0, 0);
10420 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10421 if (pause)
10422 break;
10423 #endif
10425 if (n == size)
10427 int nbytes = size * sizeof *updated;
10428 struct frame **p = (struct frame **) alloca (2 * nbytes);
10429 bcopy (updated, p, nbytes);
10430 size *= 2;
10433 updated[n++] = f;
10438 if (!pause)
10440 /* Do the mark_window_display_accurate after all windows have
10441 been redisplayed because this call resets flags in buffers
10442 which are needed for proper redisplay. */
10443 for (i = 0; i < n; ++i)
10445 struct frame *f = updated[i];
10446 mark_window_display_accurate (f->root_window, 1);
10447 if (frame_up_to_date_hook)
10448 frame_up_to_date_hook (f);
10452 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10454 Lisp_Object mini_window;
10455 struct frame *mini_frame;
10457 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10458 /* Use list_of_error, not Qerror, so that
10459 we catch only errors and don't run the debugger. */
10460 internal_condition_case_1 (redisplay_window_1, selected_window,
10461 list_of_error,
10462 redisplay_window_error);
10464 /* Compare desired and current matrices, perform output. */
10466 update:
10467 /* If fonts changed, display again. */
10468 if (fonts_changed_p)
10469 goto retry;
10471 /* Prevent various kinds of signals during display update.
10472 stdio is not robust about handling signals,
10473 which can cause an apparent I/O error. */
10474 if (interrupt_input)
10475 unrequest_sigio ();
10476 STOP_POLLING;
10478 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10480 if (hscroll_windows (selected_window))
10481 goto retry;
10483 XWINDOW (selected_window)->must_be_updated_p = 1;
10484 pause = update_frame (sf, 0, 0);
10487 /* We may have called echo_area_display at the top of this
10488 function. If the echo area is on another frame, that may
10489 have put text on a frame other than the selected one, so the
10490 above call to update_frame would not have caught it. Catch
10491 it here. */
10492 mini_window = FRAME_MINIBUF_WINDOW (sf);
10493 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10495 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10497 XWINDOW (mini_window)->must_be_updated_p = 1;
10498 pause |= update_frame (mini_frame, 0, 0);
10499 if (!pause && hscroll_windows (mini_window))
10500 goto retry;
10504 /* If display was paused because of pending input, make sure we do a
10505 thorough update the next time. */
10506 if (pause)
10508 /* Prevent the optimization at the beginning of
10509 redisplay_internal that tries a single-line update of the
10510 line containing the cursor in the selected window. */
10511 CHARPOS (this_line_start_pos) = 0;
10513 /* Let the overlay arrow be updated the next time. */
10514 if (!NILP (last_arrow_position))
10516 last_arrow_position = Qt;
10517 last_arrow_string = Qt;
10520 /* If we pause after scrolling, some rows in the current
10521 matrices of some windows are not valid. */
10522 if (!WINDOW_FULL_WIDTH_P (w)
10523 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10524 update_mode_lines = 1;
10526 else
10528 if (!consider_all_windows_p)
10530 /* This has already been done above if
10531 consider_all_windows_p is set. */
10532 mark_window_display_accurate_1 (w, 1);
10534 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10535 last_arrow_string = Voverlay_arrow_string;
10537 if (frame_up_to_date_hook != 0)
10538 frame_up_to_date_hook (sf);
10541 update_mode_lines = 0;
10542 windows_or_buffers_changed = 0;
10543 cursor_type_changed = 0;
10546 /* Start SIGIO interrupts coming again. Having them off during the
10547 code above makes it less likely one will discard output, but not
10548 impossible, since there might be stuff in the system buffer here.
10549 But it is much hairier to try to do anything about that. */
10550 if (interrupt_input)
10551 request_sigio ();
10552 RESUME_POLLING;
10554 /* If a frame has become visible which was not before, redisplay
10555 again, so that we display it. Expose events for such a frame
10556 (which it gets when becoming visible) don't call the parts of
10557 redisplay constructing glyphs, so simply exposing a frame won't
10558 display anything in this case. So, we have to display these
10559 frames here explicitly. */
10560 if (!pause)
10562 Lisp_Object tail, frame;
10563 int new_count = 0;
10565 FOR_EACH_FRAME (tail, frame)
10567 int this_is_visible = 0;
10569 if (XFRAME (frame)->visible)
10570 this_is_visible = 1;
10571 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10572 if (XFRAME (frame)->visible)
10573 this_is_visible = 1;
10575 if (this_is_visible)
10576 new_count++;
10579 if (new_count != number_of_visible_frames)
10580 windows_or_buffers_changed++;
10583 /* Change frame size now if a change is pending. */
10584 do_pending_window_change (1);
10586 /* If we just did a pending size change, or have additional
10587 visible frames, redisplay again. */
10588 if (windows_or_buffers_changed && !pause)
10589 goto retry;
10591 end_of_redisplay:
10592 unbind_to (count, Qnil);
10593 RESUME_POLLING;
10597 /* Redisplay, but leave alone any recent echo area message unless
10598 another message has been requested in its place.
10600 This is useful in situations where you need to redisplay but no
10601 user action has occurred, making it inappropriate for the message
10602 area to be cleared. See tracking_off and
10603 wait_reading_process_input for examples of these situations.
10605 FROM_WHERE is an integer saying from where this function was
10606 called. This is useful for debugging. */
10608 void
10609 redisplay_preserve_echo_area (from_where)
10610 int from_where;
10612 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10614 if (!NILP (echo_area_buffer[1]))
10616 /* We have a previously displayed message, but no current
10617 message. Redisplay the previous message. */
10618 display_last_displayed_message_p = 1;
10619 redisplay_internal (1);
10620 display_last_displayed_message_p = 0;
10622 else
10623 redisplay_internal (1);
10627 /* Function registered with record_unwind_protect in
10628 redisplay_internal. Reset redisplaying_p to the value it had
10629 before redisplay_internal was called, and clear
10630 prevent_freeing_realized_faces_p. It also selects the previously
10631 selected frame. */
10633 static Lisp_Object
10634 unwind_redisplay (val)
10635 Lisp_Object val;
10637 Lisp_Object old_redisplaying_p, old_frame;
10639 old_redisplaying_p = XCAR (val);
10640 redisplaying_p = XFASTINT (old_redisplaying_p);
10641 old_frame = XCDR (val);
10642 if (! EQ (old_frame, selected_frame))
10643 select_frame_for_redisplay (old_frame);
10644 return Qnil;
10648 /* Mark the display of window W as accurate or inaccurate. If
10649 ACCURATE_P is non-zero mark display of W as accurate. If
10650 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10651 redisplay_internal is called. */
10653 static void
10654 mark_window_display_accurate_1 (w, accurate_p)
10655 struct window *w;
10656 int accurate_p;
10658 if (BUFFERP (w->buffer))
10660 struct buffer *b = XBUFFER (w->buffer);
10662 w->last_modified
10663 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10664 w->last_overlay_modified
10665 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10666 w->last_had_star
10667 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10669 if (accurate_p)
10671 b->clip_changed = 0;
10672 b->prevent_redisplay_optimizations_p = 0;
10674 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10675 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10676 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10677 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10679 w->current_matrix->buffer = b;
10680 w->current_matrix->begv = BUF_BEGV (b);
10681 w->current_matrix->zv = BUF_ZV (b);
10683 w->last_cursor = w->cursor;
10684 w->last_cursor_off_p = w->cursor_off_p;
10686 if (w == XWINDOW (selected_window))
10687 w->last_point = make_number (BUF_PT (b));
10688 else
10689 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10693 if (accurate_p)
10695 w->window_end_valid = w->buffer;
10696 #if 0 /* This is incorrect with variable-height lines. */
10697 xassert (XINT (w->window_end_vpos)
10698 < (WINDOW_TOTAL_LINES (w)
10699 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10700 #endif
10701 w->update_mode_line = Qnil;
10706 /* Mark the display of windows in the window tree rooted at WINDOW as
10707 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10708 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10709 be redisplayed the next time redisplay_internal is called. */
10711 void
10712 mark_window_display_accurate (window, accurate_p)
10713 Lisp_Object window;
10714 int accurate_p;
10716 struct window *w;
10718 for (; !NILP (window); window = w->next)
10720 w = XWINDOW (window);
10721 mark_window_display_accurate_1 (w, accurate_p);
10723 if (!NILP (w->vchild))
10724 mark_window_display_accurate (w->vchild, accurate_p);
10725 if (!NILP (w->hchild))
10726 mark_window_display_accurate (w->hchild, accurate_p);
10729 if (accurate_p)
10731 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10732 last_arrow_string = Voverlay_arrow_string;
10734 else
10736 /* Force a thorough redisplay the next time by setting
10737 last_arrow_position and last_arrow_string to t, which is
10738 unequal to any useful value of Voverlay_arrow_... */
10739 last_arrow_position = Qt;
10740 last_arrow_string = Qt;
10745 /* Return value in display table DP (Lisp_Char_Table *) for character
10746 C. Since a display table doesn't have any parent, we don't have to
10747 follow parent. Do not call this function directly but use the
10748 macro DISP_CHAR_VECTOR. */
10750 Lisp_Object
10751 disp_char_vector (dp, c)
10752 struct Lisp_Char_Table *dp;
10753 int c;
10755 int code[4], i;
10756 Lisp_Object val;
10758 if (SINGLE_BYTE_CHAR_P (c))
10759 return (dp->contents[c]);
10761 SPLIT_CHAR (c, code[0], code[1], code[2]);
10762 if (code[1] < 32)
10763 code[1] = -1;
10764 else if (code[2] < 32)
10765 code[2] = -1;
10767 /* Here, the possible range of code[0] (== charset ID) is
10768 128..max_charset. Since the top level char table contains data
10769 for multibyte characters after 256th element, we must increment
10770 code[0] by 128 to get a correct index. */
10771 code[0] += 128;
10772 code[3] = -1; /* anchor */
10774 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10776 val = dp->contents[code[i]];
10777 if (!SUB_CHAR_TABLE_P (val))
10778 return (NILP (val) ? dp->defalt : val);
10781 /* Here, val is a sub char table. We return the default value of
10782 it. */
10783 return (dp->defalt);
10788 /***********************************************************************
10789 Window Redisplay
10790 ***********************************************************************/
10792 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10794 static void
10795 redisplay_windows (window)
10796 Lisp_Object window;
10798 while (!NILP (window))
10800 struct window *w = XWINDOW (window);
10802 if (!NILP (w->hchild))
10803 redisplay_windows (w->hchild);
10804 else if (!NILP (w->vchild))
10805 redisplay_windows (w->vchild);
10806 else
10808 displayed_buffer = XBUFFER (w->buffer);
10809 /* Use list_of_error, not Qerror, so that
10810 we catch only errors and don't run the debugger. */
10811 internal_condition_case_1 (redisplay_window_0, window,
10812 list_of_error,
10813 redisplay_window_error);
10816 window = w->next;
10820 static Lisp_Object
10821 redisplay_window_error ()
10823 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10824 return Qnil;
10827 static Lisp_Object
10828 redisplay_window_0 (window)
10829 Lisp_Object window;
10831 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10832 redisplay_window (window, 0);
10833 return Qnil;
10836 static Lisp_Object
10837 redisplay_window_1 (window)
10838 Lisp_Object window;
10840 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10841 redisplay_window (window, 1);
10842 return Qnil;
10846 /* Increment GLYPH until it reaches END or CONDITION fails while
10847 adding (GLYPH)->pixel_width to X. */
10849 #define SKIP_GLYPHS(glyph, end, x, condition) \
10850 do \
10852 (x) += (glyph)->pixel_width; \
10853 ++(glyph); \
10855 while ((glyph) < (end) && (condition))
10858 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10859 DELTA is the number of bytes by which positions recorded in ROW
10860 differ from current buffer positions. */
10862 void
10863 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10864 struct window *w;
10865 struct glyph_row *row;
10866 struct glyph_matrix *matrix;
10867 int delta, delta_bytes, dy, dvpos;
10869 struct glyph *glyph = row->glyphs[TEXT_AREA];
10870 struct glyph *end = glyph + row->used[TEXT_AREA];
10871 /* The first glyph that starts a sequence of glyphs from string. */
10872 struct glyph *string_start;
10873 /* The X coordinate of string_start. */
10874 int string_start_x;
10875 /* The last known character position. */
10876 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10877 /* The last known character position before string_start. */
10878 int string_before_pos;
10879 int x = row->x;
10880 int pt_old = PT - delta;
10882 /* Skip over glyphs not having an object at the start of the row.
10883 These are special glyphs like truncation marks on terminal
10884 frames. */
10885 if (row->displays_text_p)
10886 while (glyph < end
10887 && INTEGERP (glyph->object)
10888 && glyph->charpos < 0)
10890 x += glyph->pixel_width;
10891 ++glyph;
10894 string_start = NULL;
10895 while (glyph < end
10896 && !INTEGERP (glyph->object)
10897 && (!BUFFERP (glyph->object)
10898 || (last_pos = glyph->charpos) < pt_old))
10900 if (! STRINGP (glyph->object))
10902 string_start = NULL;
10903 x += glyph->pixel_width;
10904 ++glyph;
10906 else
10908 string_before_pos = last_pos;
10909 string_start = glyph;
10910 string_start_x = x;
10911 /* Skip all glyphs from string. */
10912 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10916 if (string_start
10917 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10919 /* We may have skipped over point because the previous glyphs
10920 are from string. As there's no easy way to know the
10921 character position of the current glyph, find the correct
10922 glyph on point by scanning from string_start again. */
10923 Lisp_Object limit;
10924 Lisp_Object string;
10925 int pos;
10927 limit = make_number (pt_old + 1);
10928 end = glyph;
10929 glyph = string_start;
10930 x = string_start_x;
10931 string = glyph->object;
10932 pos = string_buffer_position (w, string, string_before_pos);
10933 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10934 because we always put cursor after overlay strings. */
10935 while (pos == 0 && glyph < end)
10937 string = glyph->object;
10938 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10939 if (glyph < end)
10940 pos = string_buffer_position (w, glyph->object, string_before_pos);
10943 while (glyph < end)
10945 pos = XINT (Fnext_single_char_property_change
10946 (make_number (pos), Qdisplay, Qnil, limit));
10947 if (pos > pt_old)
10948 break;
10949 /* Skip glyphs from the same string. */
10950 string = glyph->object;
10951 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10952 /* Skip glyphs from an overlay. */
10953 while (glyph < end
10954 && ! string_buffer_position (w, glyph->object, pos))
10956 string = glyph->object;
10957 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10962 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10963 w->cursor.x = x;
10964 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10965 w->cursor.y = row->y + dy;
10967 if (w == XWINDOW (selected_window))
10969 if (!row->continued_p
10970 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10971 && row->x == 0)
10973 this_line_buffer = XBUFFER (w->buffer);
10975 CHARPOS (this_line_start_pos)
10976 = MATRIX_ROW_START_CHARPOS (row) + delta;
10977 BYTEPOS (this_line_start_pos)
10978 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10980 CHARPOS (this_line_end_pos)
10981 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10982 BYTEPOS (this_line_end_pos)
10983 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10985 this_line_y = w->cursor.y;
10986 this_line_pixel_height = row->height;
10987 this_line_vpos = w->cursor.vpos;
10988 this_line_start_x = row->x;
10990 else
10991 CHARPOS (this_line_start_pos) = 0;
10996 /* Run window scroll functions, if any, for WINDOW with new window
10997 start STARTP. Sets the window start of WINDOW to that position.
10999 We assume that the window's buffer is really current. */
11001 static INLINE struct text_pos
11002 run_window_scroll_functions (window, startp)
11003 Lisp_Object window;
11004 struct text_pos startp;
11006 struct window *w = XWINDOW (window);
11007 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11009 if (current_buffer != XBUFFER (w->buffer))
11010 abort ();
11012 if (!NILP (Vwindow_scroll_functions))
11014 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11015 make_number (CHARPOS (startp)));
11016 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11017 /* In case the hook functions switch buffers. */
11018 if (current_buffer != XBUFFER (w->buffer))
11019 set_buffer_internal_1 (XBUFFER (w->buffer));
11022 return startp;
11026 /* Make sure the line containing the cursor is fully visible.
11027 A value of 1 means there is nothing to be done.
11028 (Either the line is fully visible, or it cannot be made so,
11029 or we cannot tell.)
11030 A value of 0 means the caller should do scrolling
11031 as if point had gone off the screen. */
11033 static int
11034 make_cursor_line_fully_visible (w)
11035 struct window *w;
11037 struct glyph_matrix *matrix;
11038 struct glyph_row *row;
11039 int window_height;
11041 /* It's not always possible to find the cursor, e.g, when a window
11042 is full of overlay strings. Don't do anything in that case. */
11043 if (w->cursor.vpos < 0)
11044 return 1;
11046 matrix = w->desired_matrix;
11047 row = MATRIX_ROW (matrix, w->cursor.vpos);
11049 /* If the cursor row is not partially visible, there's nothing to do. */
11050 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11051 return 1;
11053 /* If the row the cursor is in is taller than the window's height,
11054 it's not clear what to do, so do nothing. */
11055 window_height = window_box_height (w);
11056 if (row->height >= window_height)
11057 return 1;
11059 return 0;
11061 #if 0
11062 /* This code used to try to scroll the window just enough to make
11063 the line visible. It returned 0 to say that the caller should
11064 allocate larger glyph matrices. */
11066 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11068 int dy = row->height - row->visible_height;
11069 w->vscroll = 0;
11070 w->cursor.y += dy;
11071 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11073 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11075 int dy = - (row->height - row->visible_height);
11076 w->vscroll = dy;
11077 w->cursor.y += dy;
11078 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11081 /* When we change the cursor y-position of the selected window,
11082 change this_line_y as well so that the display optimization for
11083 the cursor line of the selected window in redisplay_internal uses
11084 the correct y-position. */
11085 if (w == XWINDOW (selected_window))
11086 this_line_y = w->cursor.y;
11088 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11089 redisplay with larger matrices. */
11090 if (matrix->nrows < required_matrix_height (w))
11092 fonts_changed_p = 1;
11093 return 0;
11096 return 1;
11097 #endif /* 0 */
11101 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11102 non-zero means only WINDOW is redisplayed in redisplay_internal.
11103 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11104 in redisplay_window to bring a partially visible line into view in
11105 the case that only the cursor has moved.
11107 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11108 last screen line's vertical height extends past the end of the screen.
11110 Value is
11112 1 if scrolling succeeded
11114 0 if scrolling didn't find point.
11116 -1 if new fonts have been loaded so that we must interrupt
11117 redisplay, adjust glyph matrices, and try again. */
11119 enum
11121 SCROLLING_SUCCESS,
11122 SCROLLING_FAILED,
11123 SCROLLING_NEED_LARGER_MATRICES
11126 static int
11127 try_scrolling (window, just_this_one_p, scroll_conservatively,
11128 scroll_step, temp_scroll_step, last_line_misfit)
11129 Lisp_Object window;
11130 int just_this_one_p;
11131 EMACS_INT scroll_conservatively, scroll_step;
11132 int temp_scroll_step;
11133 int last_line_misfit;
11135 struct window *w = XWINDOW (window);
11136 struct frame *f = XFRAME (w->frame);
11137 struct text_pos scroll_margin_pos;
11138 struct text_pos pos;
11139 struct text_pos startp;
11140 struct it it;
11141 Lisp_Object window_end;
11142 int this_scroll_margin;
11143 int dy = 0;
11144 int scroll_max;
11145 int rc;
11146 int amount_to_scroll = 0;
11147 Lisp_Object aggressive;
11148 int height;
11149 int end_scroll_margin;
11151 #if GLYPH_DEBUG
11152 debug_method_add (w, "try_scrolling");
11153 #endif
11155 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11157 /* Compute scroll margin height in pixels. We scroll when point is
11158 within this distance from the top or bottom of the window. */
11159 if (scroll_margin > 0)
11161 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11162 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11164 else
11165 this_scroll_margin = 0;
11167 /* Compute how much we should try to scroll maximally to bring point
11168 into view. */
11169 if (scroll_step || scroll_conservatively || temp_scroll_step)
11170 scroll_max = max (scroll_step,
11171 max (scroll_conservatively, temp_scroll_step));
11172 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11173 || NUMBERP (current_buffer->scroll_up_aggressively))
11174 /* We're trying to scroll because of aggressive scrolling
11175 but no scroll_step is set. Choose an arbitrary one. Maybe
11176 there should be a variable for this. */
11177 scroll_max = 10;
11178 else
11179 scroll_max = 0;
11180 scroll_max *= FRAME_LINE_HEIGHT (f);
11182 /* Decide whether we have to scroll down. Start at the window end
11183 and move this_scroll_margin up to find the position of the scroll
11184 margin. */
11185 window_end = Fwindow_end (window, Qt);
11187 too_near_end:
11189 CHARPOS (scroll_margin_pos) = XINT (window_end);
11190 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11192 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
11193 if (end_scroll_margin)
11195 start_display (&it, w, scroll_margin_pos);
11196 move_it_vertically (&it, - end_scroll_margin);
11197 scroll_margin_pos = it.current.pos;
11200 if (PT >= CHARPOS (scroll_margin_pos))
11202 int y0;
11204 /* Point is in the scroll margin at the bottom of the window, or
11205 below. Compute a new window start that makes point visible. */
11207 /* Compute the distance from the scroll margin to PT.
11208 Give up if the distance is greater than scroll_max. */
11209 start_display (&it, w, scroll_margin_pos);
11210 y0 = it.current_y;
11211 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11212 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11214 /* To make point visible, we have to move the window start
11215 down so that the line the cursor is in is visible, which
11216 means we have to add in the height of the cursor line. */
11217 dy = line_bottom_y (&it) - y0;
11219 if (dy > scroll_max)
11220 return SCROLLING_FAILED;
11222 /* Move the window start down. If scrolling conservatively,
11223 move it just enough down to make point visible. If
11224 scroll_step is set, move it down by scroll_step. */
11225 start_display (&it, w, startp);
11227 if (scroll_conservatively)
11228 /* Set AMOUNT_TO_SCROLL to at least one line,
11229 and at most scroll_conservatively lines. */
11230 amount_to_scroll
11231 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11232 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11233 else if (scroll_step || temp_scroll_step)
11234 amount_to_scroll = scroll_max;
11235 else
11237 aggressive = current_buffer->scroll_up_aggressively;
11238 height = WINDOW_BOX_TEXT_HEIGHT (w);
11239 if (NUMBERP (aggressive))
11240 amount_to_scroll = XFLOATINT (aggressive) * height;
11243 if (amount_to_scroll <= 0)
11244 return SCROLLING_FAILED;
11246 /* If moving by amount_to_scroll leaves STARTP unchanged,
11247 move it down one screen line. */
11249 move_it_vertically (&it, amount_to_scroll);
11250 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11251 move_it_by_lines (&it, 1, 1);
11252 startp = it.current.pos;
11254 else
11256 /* See if point is inside the scroll margin at the top of the
11257 window. */
11258 scroll_margin_pos = startp;
11259 if (this_scroll_margin)
11261 start_display (&it, w, startp);
11262 move_it_vertically (&it, this_scroll_margin);
11263 scroll_margin_pos = it.current.pos;
11266 if (PT < CHARPOS (scroll_margin_pos))
11268 /* Point is in the scroll margin at the top of the window or
11269 above what is displayed in the window. */
11270 int y0;
11272 /* Compute the vertical distance from PT to the scroll
11273 margin position. Give up if distance is greater than
11274 scroll_max. */
11275 SET_TEXT_POS (pos, PT, PT_BYTE);
11276 start_display (&it, w, pos);
11277 y0 = it.current_y;
11278 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11279 it.last_visible_y, -1,
11280 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11281 dy = it.current_y - y0;
11282 if (dy > scroll_max)
11283 return SCROLLING_FAILED;
11285 /* Compute new window start. */
11286 start_display (&it, w, startp);
11288 if (scroll_conservatively)
11289 amount_to_scroll =
11290 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11291 else if (scroll_step || temp_scroll_step)
11292 amount_to_scroll = scroll_max;
11293 else
11295 aggressive = current_buffer->scroll_down_aggressively;
11296 height = WINDOW_BOX_TEXT_HEIGHT (w);
11297 if (NUMBERP (aggressive))
11298 amount_to_scroll = XFLOATINT (aggressive) * height;
11301 if (amount_to_scroll <= 0)
11302 return SCROLLING_FAILED;
11304 move_it_vertically (&it, - amount_to_scroll);
11305 startp = it.current.pos;
11309 /* Run window scroll functions. */
11310 startp = run_window_scroll_functions (window, startp);
11312 /* Display the window. Give up if new fonts are loaded, or if point
11313 doesn't appear. */
11314 if (!try_window (window, startp))
11315 rc = SCROLLING_NEED_LARGER_MATRICES;
11316 else if (w->cursor.vpos < 0)
11318 clear_glyph_matrix (w->desired_matrix);
11319 rc = SCROLLING_FAILED;
11321 else
11323 /* Maybe forget recorded base line for line number display. */
11324 if (!just_this_one_p
11325 || current_buffer->clip_changed
11326 || BEG_UNCHANGED < CHARPOS (startp))
11327 w->base_line_number = Qnil;
11329 /* If cursor ends up on a partially visible line,
11330 treat that as being off the bottom of the screen. */
11331 if (! make_cursor_line_fully_visible (w))
11333 clear_glyph_matrix (w->desired_matrix);
11334 last_line_misfit = 1;
11335 goto too_near_end;
11337 rc = SCROLLING_SUCCESS;
11340 return rc;
11344 /* Compute a suitable window start for window W if display of W starts
11345 on a continuation line. Value is non-zero if a new window start
11346 was computed.
11348 The new window start will be computed, based on W's width, starting
11349 from the start of the continued line. It is the start of the
11350 screen line with the minimum distance from the old start W->start. */
11352 static int
11353 compute_window_start_on_continuation_line (w)
11354 struct window *w;
11356 struct text_pos pos, start_pos;
11357 int window_start_changed_p = 0;
11359 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11361 /* If window start is on a continuation line... Window start may be
11362 < BEGV in case there's invisible text at the start of the
11363 buffer (M-x rmail, for example). */
11364 if (CHARPOS (start_pos) > BEGV
11365 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11367 struct it it;
11368 struct glyph_row *row;
11370 /* Handle the case that the window start is out of range. */
11371 if (CHARPOS (start_pos) < BEGV)
11372 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11373 else if (CHARPOS (start_pos) > ZV)
11374 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11376 /* Find the start of the continued line. This should be fast
11377 because scan_buffer is fast (newline cache). */
11378 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11379 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11380 row, DEFAULT_FACE_ID);
11381 reseat_at_previous_visible_line_start (&it);
11383 /* If the line start is "too far" away from the window start,
11384 say it takes too much time to compute a new window start. */
11385 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11386 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11388 int min_distance, distance;
11390 /* Move forward by display lines to find the new window
11391 start. If window width was enlarged, the new start can
11392 be expected to be > the old start. If window width was
11393 decreased, the new window start will be < the old start.
11394 So, we're looking for the display line start with the
11395 minimum distance from the old window start. */
11396 pos = it.current.pos;
11397 min_distance = INFINITY;
11398 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11399 distance < min_distance)
11401 min_distance = distance;
11402 pos = it.current.pos;
11403 move_it_by_lines (&it, 1, 0);
11406 /* Set the window start there. */
11407 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11408 window_start_changed_p = 1;
11412 return window_start_changed_p;
11416 /* Try cursor movement in case text has not changed in window WINDOW,
11417 with window start STARTP. Value is
11419 CURSOR_MOVEMENT_SUCCESS if successful
11421 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11423 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11424 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11425 we want to scroll as if scroll-step were set to 1. See the code.
11427 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11428 which case we have to abort this redisplay, and adjust matrices
11429 first. */
11431 enum
11433 CURSOR_MOVEMENT_SUCCESS,
11434 CURSOR_MOVEMENT_CANNOT_BE_USED,
11435 CURSOR_MOVEMENT_MUST_SCROLL,
11436 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11439 static int
11440 try_cursor_movement (window, startp, scroll_step)
11441 Lisp_Object window;
11442 struct text_pos startp;
11443 int *scroll_step;
11445 struct window *w = XWINDOW (window);
11446 struct frame *f = XFRAME (w->frame);
11447 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11449 #if GLYPH_DEBUG
11450 if (inhibit_try_cursor_movement)
11451 return rc;
11452 #endif
11454 /* Handle case where text has not changed, only point, and it has
11455 not moved off the frame. */
11456 if (/* Point may be in this window. */
11457 PT >= CHARPOS (startp)
11458 /* Selective display hasn't changed. */
11459 && !current_buffer->clip_changed
11460 /* Function force-mode-line-update is used to force a thorough
11461 redisplay. It sets either windows_or_buffers_changed or
11462 update_mode_lines. So don't take a shortcut here for these
11463 cases. */
11464 && !update_mode_lines
11465 && !windows_or_buffers_changed
11466 && !cursor_type_changed
11467 /* Can't use this case if highlighting a region. When a
11468 region exists, cursor movement has to do more than just
11469 set the cursor. */
11470 && !(!NILP (Vtransient_mark_mode)
11471 && !NILP (current_buffer->mark_active))
11472 && NILP (w->region_showing)
11473 && NILP (Vshow_trailing_whitespace)
11474 /* Right after splitting windows, last_point may be nil. */
11475 && INTEGERP (w->last_point)
11476 /* This code is not used for mini-buffer for the sake of the case
11477 of redisplaying to replace an echo area message; since in
11478 that case the mini-buffer contents per se are usually
11479 unchanged. This code is of no real use in the mini-buffer
11480 since the handling of this_line_start_pos, etc., in redisplay
11481 handles the same cases. */
11482 && !EQ (window, minibuf_window)
11483 /* When splitting windows or for new windows, it happens that
11484 redisplay is called with a nil window_end_vpos or one being
11485 larger than the window. This should really be fixed in
11486 window.c. I don't have this on my list, now, so we do
11487 approximately the same as the old redisplay code. --gerd. */
11488 && INTEGERP (w->window_end_vpos)
11489 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11490 && (FRAME_WINDOW_P (f)
11491 || !MARKERP (Voverlay_arrow_position)
11492 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11494 int this_scroll_margin;
11495 struct glyph_row *row = NULL;
11497 #if GLYPH_DEBUG
11498 debug_method_add (w, "cursor movement");
11499 #endif
11501 /* Scroll if point within this distance from the top or bottom
11502 of the window. This is a pixel value. */
11503 this_scroll_margin = max (0, scroll_margin);
11504 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11505 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11507 /* Start with the row the cursor was displayed during the last
11508 not paused redisplay. Give up if that row is not valid. */
11509 if (w->last_cursor.vpos < 0
11510 || w->last_cursor.vpos >= w->current_matrix->nrows)
11511 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11512 else
11514 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11515 if (row->mode_line_p)
11516 ++row;
11517 if (!row->enabled_p)
11518 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11521 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11523 int scroll_p = 0;
11524 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11526 if (PT > XFASTINT (w->last_point))
11528 /* Point has moved forward. */
11529 while (MATRIX_ROW_END_CHARPOS (row) < PT
11530 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11532 xassert (row->enabled_p);
11533 ++row;
11536 /* The end position of a row equals the start position
11537 of the next row. If PT is there, we would rather
11538 display it in the next line. */
11539 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11540 && MATRIX_ROW_END_CHARPOS (row) == PT
11541 && !cursor_row_p (w, row))
11542 ++row;
11544 /* If within the scroll margin, scroll. Note that
11545 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11546 the next line would be drawn, and that
11547 this_scroll_margin can be zero. */
11548 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11549 || PT > MATRIX_ROW_END_CHARPOS (row)
11550 /* Line is completely visible last line in window
11551 and PT is to be set in the next line. */
11552 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11553 && PT == MATRIX_ROW_END_CHARPOS (row)
11554 && !row->ends_at_zv_p
11555 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11556 scroll_p = 1;
11558 else if (PT < XFASTINT (w->last_point))
11560 /* Cursor has to be moved backward. Note that PT >=
11561 CHARPOS (startp) because of the outer
11562 if-statement. */
11563 while (!row->mode_line_p
11564 && (MATRIX_ROW_START_CHARPOS (row) > PT
11565 || (MATRIX_ROW_START_CHARPOS (row) == PT
11566 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11567 && (row->y > this_scroll_margin
11568 || CHARPOS (startp) == BEGV))
11570 xassert (row->enabled_p);
11571 --row;
11574 /* Consider the following case: Window starts at BEGV,
11575 there is invisible, intangible text at BEGV, so that
11576 display starts at some point START > BEGV. It can
11577 happen that we are called with PT somewhere between
11578 BEGV and START. Try to handle that case. */
11579 if (row < w->current_matrix->rows
11580 || row->mode_line_p)
11582 row = w->current_matrix->rows;
11583 if (row->mode_line_p)
11584 ++row;
11587 /* Due to newlines in overlay strings, we may have to
11588 skip forward over overlay strings. */
11589 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11590 && MATRIX_ROW_END_CHARPOS (row) == PT
11591 && !cursor_row_p (w, row))
11592 ++row;
11594 /* If within the scroll margin, scroll. */
11595 if (row->y < this_scroll_margin
11596 && CHARPOS (startp) != BEGV)
11597 scroll_p = 1;
11600 if (PT < MATRIX_ROW_START_CHARPOS (row)
11601 || PT > MATRIX_ROW_END_CHARPOS (row))
11603 /* if PT is not in the glyph row, give up. */
11604 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11606 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11608 if (PT == MATRIX_ROW_END_CHARPOS (row)
11609 && !row->ends_at_zv_p
11610 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11611 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11612 else if (row->height > window_box_height (w))
11614 /* If we end up in a partially visible line, let's
11615 make it fully visible, except when it's taller
11616 than the window, in which case we can't do much
11617 about it. */
11618 *scroll_step = 1;
11619 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11621 else
11623 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11624 if (!make_cursor_line_fully_visible (w))
11625 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11626 else
11627 rc = CURSOR_MOVEMENT_SUCCESS;
11630 else if (scroll_p)
11631 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11632 else
11634 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11635 rc = CURSOR_MOVEMENT_SUCCESS;
11640 return rc;
11643 void
11644 set_vertical_scroll_bar (w)
11645 struct window *w;
11647 int start, end, whole;
11649 /* Calculate the start and end positions for the current window.
11650 At some point, it would be nice to choose between scrollbars
11651 which reflect the whole buffer size, with special markers
11652 indicating narrowing, and scrollbars which reflect only the
11653 visible region.
11655 Note that mini-buffers sometimes aren't displaying any text. */
11656 if (!MINI_WINDOW_P (w)
11657 || (w == XWINDOW (minibuf_window)
11658 && NILP (echo_area_buffer[0])))
11660 struct buffer *buf = XBUFFER (w->buffer);
11661 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11662 start = marker_position (w->start) - BUF_BEGV (buf);
11663 /* I don't think this is guaranteed to be right. For the
11664 moment, we'll pretend it is. */
11665 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11667 if (end < start)
11668 end = start;
11669 if (whole < (end - start))
11670 whole = end - start;
11672 else
11673 start = end = whole = 0;
11675 /* Indicate what this scroll bar ought to be displaying now. */
11676 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11679 #ifdef HAVE_WINDOW_SYSTEM
11681 /* Recalculate the bitmaps to show in the fringes of window W.
11682 If FORCE_P is 0, only mark rows with modified bitmaps for update in
11683 redraw_fringe_bitmaps_p; else mark all rows for update. */
11686 update_window_fringes (w, force_p)
11687 struct window *w;
11688 int force_p;
11690 struct glyph_row *row, *cur = 0;
11691 int yb = window_text_bottom_y (w);
11692 int rn, nrows = w->current_matrix->nrows;
11693 int y;
11694 int redraw_p = 0;
11695 Lisp_Object ind;
11697 if (w->pseudo_window_p)
11698 return 0;
11700 if (!MINI_WINDOW_P (w)
11701 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
11703 int do_eob = 1, do_bob = 1;
11705 for (y = 0, rn = 0;
11706 y < yb && rn < nrows;
11707 y += row->height, ++rn)
11709 unsigned indicate_bob_p, indicate_top_line_p;
11710 unsigned indicate_eob_p, indicate_bottom_line_p;
11712 row = w->desired_matrix->rows + rn;
11713 if (!row->enabled_p)
11714 row = w->current_matrix->rows + rn;
11716 indicate_bob_p = row->indicate_bob_p;
11717 indicate_top_line_p = row->indicate_top_line_p;
11718 indicate_eob_p = row->indicate_eob_p;
11719 indicate_bottom_line_p = row->indicate_bottom_line_p;
11721 row->indicate_bob_p = row->indicate_top_line_p = 0;
11722 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
11724 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
11725 row->indicate_bob_p = do_bob, do_bob = 0;
11726 else if (EQ (ind, Qt)
11727 && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn)
11728 row->indicate_top_line_p = 1;
11730 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
11731 row->indicate_eob_p = do_eob, do_eob = 0;
11732 else if (EQ (ind, Qt)
11733 && y + row->height >= yb)
11734 row->indicate_bottom_line_p = 1;
11736 if (indicate_bob_p != row->indicate_bob_p
11737 || indicate_top_line_p != row->indicate_top_line_p
11738 || indicate_eob_p != row->indicate_eob_p
11739 || indicate_bottom_line_p != row->indicate_bottom_line_p)
11740 row->redraw_fringe_bitmaps_p = 1;
11744 for (y = 0, rn = 0;
11745 y < yb && rn < nrows;
11746 y += row->height, rn++)
11748 enum fringe_bitmap_type left, right;
11750 row = w->desired_matrix->rows + rn;
11751 cur = w->current_matrix->rows + rn;
11752 if (!row->enabled_p)
11753 row = cur;
11755 /* Decide which bitmap to draw in the left fringe. */
11756 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
11757 left = NO_FRINGE_BITMAP;
11758 else if (row->overlay_arrow_p)
11759 left = OVERLAY_ARROW_BITMAP;
11760 else if (row->truncated_on_left_p)
11761 left = LEFT_TRUNCATION_BITMAP;
11762 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
11763 left = CONTINUATION_LINE_BITMAP;
11764 else if (row->indicate_empty_line_p)
11765 left = ZV_LINE_BITMAP;
11766 else if (row->indicate_bob_p)
11767 left = FIRST_LINE_BITMAP;
11768 else
11769 left = NO_FRINGE_BITMAP;
11771 /* Decide which bitmap to draw in the right fringe. */
11772 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
11773 right = NO_FRINGE_BITMAP;
11774 else if (row->truncated_on_right_p)
11775 right = RIGHT_TRUNCATION_BITMAP;
11776 else if (row->continued_p)
11777 right = CONTINUED_LINE_BITMAP;
11778 else if (row->indicate_eob_p)
11779 right = LAST_LINE_BITMAP;
11780 else if (row->indicate_top_line_p)
11781 right = UP_ARROW_BITMAP;
11782 else if (row->indicate_bottom_line_p)
11783 right = DOWN_ARROW_BITMAP;
11784 else if (row->indicate_empty_line_p && WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
11785 right = ZV_LINE_BITMAP;
11786 else
11787 right = NO_FRINGE_BITMAP;
11789 if (force_p
11790 || row->y != cur->y
11791 || row->visible_height != cur->visible_height
11792 || left != cur->left_fringe_bitmap
11793 || right != cur->right_fringe_bitmap
11794 || cur->redraw_fringe_bitmaps_p)
11796 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
11797 cur->left_fringe_bitmap = left;
11798 cur->right_fringe_bitmap = right;
11801 row->left_fringe_bitmap = left;
11802 row->right_fringe_bitmap = right;
11805 return redraw_p;
11808 #endif /* HAVE_WINDOW_SYSTEM */
11810 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11811 selected_window is redisplayed.
11813 We can return without actually redisplaying the window if
11814 fonts_changed_p is nonzero. In that case, redisplay_internal will
11815 retry. */
11817 static void
11818 redisplay_window (window, just_this_one_p)
11819 Lisp_Object window;
11820 int just_this_one_p;
11822 struct window *w = XWINDOW (window);
11823 struct frame *f = XFRAME (w->frame);
11824 struct buffer *buffer = XBUFFER (w->buffer);
11825 struct buffer *old = current_buffer;
11826 struct text_pos lpoint, opoint, startp;
11827 int update_mode_line;
11828 int tem;
11829 struct it it;
11830 /* Record it now because it's overwritten. */
11831 int current_matrix_up_to_date_p = 0;
11832 int used_current_matrix_p = 0;
11833 /* This is less strict than current_matrix_up_to_date_p.
11834 It indictes that the buffer contents and narrowing are unchanged. */
11835 int buffer_unchanged_p = 0;
11836 int temp_scroll_step = 0;
11837 int count = SPECPDL_INDEX ();
11838 int rc;
11839 int centering_position;
11840 int last_line_misfit = 0;
11842 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11843 opoint = lpoint;
11845 /* W must be a leaf window here. */
11846 xassert (!NILP (w->buffer));
11847 #if GLYPH_DEBUG
11848 *w->desired_matrix->method = 0;
11849 #endif
11851 specbind (Qinhibit_point_motion_hooks, Qt);
11853 reconsider_clip_changes (w, buffer);
11855 /* Has the mode line to be updated? */
11856 update_mode_line = (!NILP (w->update_mode_line)
11857 || update_mode_lines
11858 || buffer->clip_changed
11859 || buffer->prevent_redisplay_optimizations_p);
11861 if (MINI_WINDOW_P (w))
11863 if (w == XWINDOW (echo_area_window)
11864 && !NILP (echo_area_buffer[0]))
11866 if (update_mode_line)
11867 /* We may have to update a tty frame's menu bar or a
11868 tool-bar. Example `M-x C-h C-h C-g'. */
11869 goto finish_menu_bars;
11870 else
11871 /* We've already displayed the echo area glyphs in this window. */
11872 goto finish_scroll_bars;
11874 else if ((w != XWINDOW (minibuf_window)
11875 || minibuf_level == 0)
11876 /* When buffer is nonempty, redisplay window normally. */
11877 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11878 /* Quail displays non-mini buffers in minibuffer window.
11879 In that case, redisplay the window normally. */
11880 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11882 /* W is a mini-buffer window, but it's not active, so clear
11883 it. */
11884 int yb = window_text_bottom_y (w);
11885 struct glyph_row *row;
11886 int y;
11888 for (y = 0, row = w->desired_matrix->rows;
11889 y < yb;
11890 y += row->height, ++row)
11891 blank_row (w, row, y);
11892 goto finish_scroll_bars;
11895 clear_glyph_matrix (w->desired_matrix);
11898 /* Otherwise set up data on this window; select its buffer and point
11899 value. */
11900 /* Really select the buffer, for the sake of buffer-local
11901 variables. */
11902 set_buffer_internal_1 (XBUFFER (w->buffer));
11903 SET_TEXT_POS (opoint, PT, PT_BYTE);
11905 current_matrix_up_to_date_p
11906 = (!NILP (w->window_end_valid)
11907 && !current_buffer->clip_changed
11908 && !current_buffer->prevent_redisplay_optimizations_p
11909 && XFASTINT (w->last_modified) >= MODIFF
11910 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11912 buffer_unchanged_p
11913 = (!NILP (w->window_end_valid)
11914 && !current_buffer->clip_changed
11915 && XFASTINT (w->last_modified) >= MODIFF
11916 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11918 /* When windows_or_buffers_changed is non-zero, we can't rely on
11919 the window end being valid, so set it to nil there. */
11920 if (windows_or_buffers_changed)
11922 /* If window starts on a continuation line, maybe adjust the
11923 window start in case the window's width changed. */
11924 if (XMARKER (w->start)->buffer == current_buffer)
11925 compute_window_start_on_continuation_line (w);
11927 w->window_end_valid = Qnil;
11930 /* Some sanity checks. */
11931 CHECK_WINDOW_END (w);
11932 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11933 abort ();
11934 if (BYTEPOS (opoint) < CHARPOS (opoint))
11935 abort ();
11937 /* If %c is in mode line, update it if needed. */
11938 if (!NILP (w->column_number_displayed)
11939 /* This alternative quickly identifies a common case
11940 where no change is needed. */
11941 && !(PT == XFASTINT (w->last_point)
11942 && XFASTINT (w->last_modified) >= MODIFF
11943 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11944 && (XFASTINT (w->column_number_displayed)
11945 != (int) current_column ())) /* iftc */
11946 update_mode_line = 1;
11948 /* Count number of windows showing the selected buffer. An indirect
11949 buffer counts as its base buffer. */
11950 if (!just_this_one_p)
11952 struct buffer *current_base, *window_base;
11953 current_base = current_buffer;
11954 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11955 if (current_base->base_buffer)
11956 current_base = current_base->base_buffer;
11957 if (window_base->base_buffer)
11958 window_base = window_base->base_buffer;
11959 if (current_base == window_base)
11960 buffer_shared++;
11963 /* Point refers normally to the selected window. For any other
11964 window, set up appropriate value. */
11965 if (!EQ (window, selected_window))
11967 int new_pt = XMARKER (w->pointm)->charpos;
11968 int new_pt_byte = marker_byte_position (w->pointm);
11969 if (new_pt < BEGV)
11971 new_pt = BEGV;
11972 new_pt_byte = BEGV_BYTE;
11973 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11975 else if (new_pt > (ZV - 1))
11977 new_pt = ZV;
11978 new_pt_byte = ZV_BYTE;
11979 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11982 /* We don't use SET_PT so that the point-motion hooks don't run. */
11983 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11986 /* If any of the character widths specified in the display table
11987 have changed, invalidate the width run cache. It's true that
11988 this may be a bit late to catch such changes, but the rest of
11989 redisplay goes (non-fatally) haywire when the display table is
11990 changed, so why should we worry about doing any better? */
11991 if (current_buffer->width_run_cache)
11993 struct Lisp_Char_Table *disptab = buffer_display_table ();
11995 if (! disptab_matches_widthtab (disptab,
11996 XVECTOR (current_buffer->width_table)))
11998 invalidate_region_cache (current_buffer,
11999 current_buffer->width_run_cache,
12000 BEG, Z);
12001 recompute_width_table (current_buffer, disptab);
12005 /* If window-start is screwed up, choose a new one. */
12006 if (XMARKER (w->start)->buffer != current_buffer)
12007 goto recenter;
12009 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12011 /* If someone specified a new starting point but did not insist,
12012 check whether it can be used. */
12013 if (!NILP (w->optional_new_start)
12014 && CHARPOS (startp) >= BEGV
12015 && CHARPOS (startp) <= ZV)
12017 w->optional_new_start = Qnil;
12018 start_display (&it, w, startp);
12019 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12020 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12021 if (IT_CHARPOS (it) == PT)
12022 w->force_start = Qt;
12023 /* IT may overshoot PT if text at PT is invisible. */
12024 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12025 w->force_start = Qt;
12030 /* Handle case where place to start displaying has been specified,
12031 unless the specified location is outside the accessible range. */
12032 if (!NILP (w->force_start)
12033 || w->frozen_window_start_p)
12035 /* We set this later on if we have to adjust point. */
12036 int new_vpos = -1;
12038 w->force_start = Qnil;
12039 w->vscroll = 0;
12040 w->window_end_valid = Qnil;
12042 /* Forget any recorded base line for line number display. */
12043 if (!buffer_unchanged_p)
12044 w->base_line_number = Qnil;
12046 /* Redisplay the mode line. Select the buffer properly for that.
12047 Also, run the hook window-scroll-functions
12048 because we have scrolled. */
12049 /* Note, we do this after clearing force_start because
12050 if there's an error, it is better to forget about force_start
12051 than to get into an infinite loop calling the hook functions
12052 and having them get more errors. */
12053 if (!update_mode_line
12054 || ! NILP (Vwindow_scroll_functions))
12056 update_mode_line = 1;
12057 w->update_mode_line = Qt;
12058 startp = run_window_scroll_functions (window, startp);
12061 w->last_modified = make_number (0);
12062 w->last_overlay_modified = make_number (0);
12063 if (CHARPOS (startp) < BEGV)
12064 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12065 else if (CHARPOS (startp) > ZV)
12066 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12068 /* Redisplay, then check if cursor has been set during the
12069 redisplay. Give up if new fonts were loaded. */
12070 if (!try_window (window, startp))
12072 w->force_start = Qt;
12073 clear_glyph_matrix (w->desired_matrix);
12074 goto need_larger_matrices;
12077 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12079 /* If point does not appear, try to move point so it does
12080 appear. The desired matrix has been built above, so we
12081 can use it here. */
12082 new_vpos = window_box_height (w) / 2;
12085 if (!make_cursor_line_fully_visible (w))
12087 /* Point does appear, but on a line partly visible at end of window.
12088 Move it back to a fully-visible line. */
12089 new_vpos = window_box_height (w);
12092 /* If we need to move point for either of the above reasons,
12093 now actually do it. */
12094 if (new_vpos >= 0)
12096 struct glyph_row *row;
12098 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12099 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12100 ++row;
12102 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12103 MATRIX_ROW_START_BYTEPOS (row));
12105 if (w != XWINDOW (selected_window))
12106 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12107 else if (current_buffer == old)
12108 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12110 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12112 /* If we are highlighting the region, then we just changed
12113 the region, so redisplay to show it. */
12114 if (!NILP (Vtransient_mark_mode)
12115 && !NILP (current_buffer->mark_active))
12117 clear_glyph_matrix (w->desired_matrix);
12118 if (!try_window (window, startp))
12119 goto need_larger_matrices;
12123 #if GLYPH_DEBUG
12124 debug_method_add (w, "forced window start");
12125 #endif
12126 goto done;
12129 /* Handle case where text has not changed, only point, and it has
12130 not moved off the frame, and we are not retrying after hscroll.
12131 (current_matrix_up_to_date_p is nonzero when retrying.) */
12132 if (current_matrix_up_to_date_p
12133 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12134 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12136 switch (rc)
12138 case CURSOR_MOVEMENT_SUCCESS:
12139 used_current_matrix_p = 1;
12140 goto done;
12142 #if 0 /* try_cursor_movement never returns this value. */
12143 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12144 goto need_larger_matrices;
12145 #endif
12147 case CURSOR_MOVEMENT_MUST_SCROLL:
12148 goto try_to_scroll;
12150 default:
12151 abort ();
12154 /* If current starting point was originally the beginning of a line
12155 but no longer is, find a new starting point. */
12156 else if (!NILP (w->start_at_line_beg)
12157 && !(CHARPOS (startp) <= BEGV
12158 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12160 #if GLYPH_DEBUG
12161 debug_method_add (w, "recenter 1");
12162 #endif
12163 goto recenter;
12166 /* Try scrolling with try_window_id. Value is > 0 if update has
12167 been done, it is -1 if we know that the same window start will
12168 not work. It is 0 if unsuccessful for some other reason. */
12169 else if ((tem = try_window_id (w)) != 0)
12171 #if GLYPH_DEBUG
12172 debug_method_add (w, "try_window_id %d", tem);
12173 #endif
12175 if (fonts_changed_p)
12176 goto need_larger_matrices;
12177 if (tem > 0)
12178 goto done;
12180 /* Otherwise try_window_id has returned -1 which means that we
12181 don't want the alternative below this comment to execute. */
12183 else if (CHARPOS (startp) >= BEGV
12184 && CHARPOS (startp) <= ZV
12185 && PT >= CHARPOS (startp)
12186 && (CHARPOS (startp) < ZV
12187 /* Avoid starting at end of buffer. */
12188 || CHARPOS (startp) == BEGV
12189 || (XFASTINT (w->last_modified) >= MODIFF
12190 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12192 #if GLYPH_DEBUG
12193 debug_method_add (w, "same window start");
12194 #endif
12196 /* Try to redisplay starting at same place as before.
12197 If point has not moved off frame, accept the results. */
12198 if (!current_matrix_up_to_date_p
12199 /* Don't use try_window_reusing_current_matrix in this case
12200 because a window scroll function can have changed the
12201 buffer. */
12202 || !NILP (Vwindow_scroll_functions)
12203 || MINI_WINDOW_P (w)
12204 || !(used_current_matrix_p =
12205 try_window_reusing_current_matrix (w)))
12207 IF_DEBUG (debug_method_add (w, "1"));
12208 try_window (window, startp);
12211 if (fonts_changed_p)
12212 goto need_larger_matrices;
12214 if (w->cursor.vpos >= 0)
12216 if (!just_this_one_p
12217 || current_buffer->clip_changed
12218 || BEG_UNCHANGED < CHARPOS (startp))
12219 /* Forget any recorded base line for line number display. */
12220 w->base_line_number = Qnil;
12222 if (!make_cursor_line_fully_visible (w))
12224 clear_glyph_matrix (w->desired_matrix);
12225 last_line_misfit = 1;
12227 /* Drop through and scroll. */
12228 else
12229 goto done;
12231 else
12232 clear_glyph_matrix (w->desired_matrix);
12235 try_to_scroll:
12237 w->last_modified = make_number (0);
12238 w->last_overlay_modified = make_number (0);
12240 /* Redisplay the mode line. Select the buffer properly for that. */
12241 if (!update_mode_line)
12243 update_mode_line = 1;
12244 w->update_mode_line = Qt;
12247 /* Try to scroll by specified few lines. */
12248 if ((scroll_conservatively
12249 || scroll_step
12250 || temp_scroll_step
12251 || NUMBERP (current_buffer->scroll_up_aggressively)
12252 || NUMBERP (current_buffer->scroll_down_aggressively))
12253 && !current_buffer->clip_changed
12254 && CHARPOS (startp) >= BEGV
12255 && CHARPOS (startp) <= ZV)
12257 /* The function returns -1 if new fonts were loaded, 1 if
12258 successful, 0 if not successful. */
12259 int rc = try_scrolling (window, just_this_one_p,
12260 scroll_conservatively,
12261 scroll_step,
12262 temp_scroll_step, last_line_misfit);
12263 switch (rc)
12265 case SCROLLING_SUCCESS:
12266 goto done;
12268 case SCROLLING_NEED_LARGER_MATRICES:
12269 goto need_larger_matrices;
12271 case SCROLLING_FAILED:
12272 break;
12274 default:
12275 abort ();
12279 /* Finally, just choose place to start which centers point */
12281 recenter:
12282 centering_position = window_box_height (w) / 2;
12284 point_at_top:
12285 /* Jump here with centering_position already set to 0. */
12287 #if GLYPH_DEBUG
12288 debug_method_add (w, "recenter");
12289 #endif
12291 /* w->vscroll = 0; */
12293 /* Forget any previously recorded base line for line number display. */
12294 if (!buffer_unchanged_p)
12295 w->base_line_number = Qnil;
12297 /* Move backward half the height of the window. */
12298 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12299 it.current_y = it.last_visible_y;
12300 move_it_vertically_backward (&it, centering_position);
12301 xassert (IT_CHARPOS (it) >= BEGV);
12303 /* The function move_it_vertically_backward may move over more
12304 than the specified y-distance. If it->w is small, e.g. a
12305 mini-buffer window, we may end up in front of the window's
12306 display area. Start displaying at the start of the line
12307 containing PT in this case. */
12308 if (it.current_y <= 0)
12310 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12311 move_it_vertically (&it, 0);
12312 xassert (IT_CHARPOS (it) <= PT);
12313 it.current_y = 0;
12316 it.current_x = it.hpos = 0;
12318 /* Set startp here explicitly in case that helps avoid an infinite loop
12319 in case the window-scroll-functions functions get errors. */
12320 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12322 /* Run scroll hooks. */
12323 startp = run_window_scroll_functions (window, it.current.pos);
12325 /* Redisplay the window. */
12326 if (!current_matrix_up_to_date_p
12327 || windows_or_buffers_changed
12328 || cursor_type_changed
12329 /* Don't use try_window_reusing_current_matrix in this case
12330 because it can have changed the buffer. */
12331 || !NILP (Vwindow_scroll_functions)
12332 || !just_this_one_p
12333 || MINI_WINDOW_P (w)
12334 || !(used_current_matrix_p =
12335 try_window_reusing_current_matrix (w)))
12336 try_window (window, startp);
12338 /* If new fonts have been loaded (due to fontsets), give up. We
12339 have to start a new redisplay since we need to re-adjust glyph
12340 matrices. */
12341 if (fonts_changed_p)
12342 goto need_larger_matrices;
12344 /* If cursor did not appear assume that the middle of the window is
12345 in the first line of the window. Do it again with the next line.
12346 (Imagine a window of height 100, displaying two lines of height
12347 60. Moving back 50 from it->last_visible_y will end in the first
12348 line.) */
12349 if (w->cursor.vpos < 0)
12351 if (!NILP (w->window_end_valid)
12352 && PT >= Z - XFASTINT (w->window_end_pos))
12354 clear_glyph_matrix (w->desired_matrix);
12355 move_it_by_lines (&it, 1, 0);
12356 try_window (window, it.current.pos);
12358 else if (PT < IT_CHARPOS (it))
12360 clear_glyph_matrix (w->desired_matrix);
12361 move_it_by_lines (&it, -1, 0);
12362 try_window (window, it.current.pos);
12364 else
12366 /* Not much we can do about it. */
12370 /* Consider the following case: Window starts at BEGV, there is
12371 invisible, intangible text at BEGV, so that display starts at
12372 some point START > BEGV. It can happen that we are called with
12373 PT somewhere between BEGV and START. Try to handle that case. */
12374 if (w->cursor.vpos < 0)
12376 struct glyph_row *row = w->current_matrix->rows;
12377 if (row->mode_line_p)
12378 ++row;
12379 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12382 if (!make_cursor_line_fully_visible (w))
12384 /* If vscroll is enabled, disable it and try again. */
12385 if (w->vscroll)
12387 w->vscroll = 0;
12388 clear_glyph_matrix (w->desired_matrix);
12389 goto recenter;
12392 /* If centering point failed to make the whole line visible,
12393 put point at the top instead. That has to make the whole line
12394 visible, if it can be done. */
12395 centering_position = 0;
12396 goto point_at_top;
12399 done:
12401 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12402 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12403 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12404 ? Qt : Qnil);
12406 /* Display the mode line, if we must. */
12407 if ((update_mode_line
12408 /* If window not full width, must redo its mode line
12409 if (a) the window to its side is being redone and
12410 (b) we do a frame-based redisplay. This is a consequence
12411 of how inverted lines are drawn in frame-based redisplay. */
12412 || (!just_this_one_p
12413 && !FRAME_WINDOW_P (f)
12414 && !WINDOW_FULL_WIDTH_P (w))
12415 /* Line number to display. */
12416 || INTEGERP (w->base_line_pos)
12417 /* Column number is displayed and different from the one displayed. */
12418 || (!NILP (w->column_number_displayed)
12419 && (XFASTINT (w->column_number_displayed)
12420 != (int) current_column ()))) /* iftc */
12421 /* This means that the window has a mode line. */
12422 && (WINDOW_WANTS_MODELINE_P (w)
12423 || WINDOW_WANTS_HEADER_LINE_P (w)))
12425 display_mode_lines (w);
12427 /* If mode line height has changed, arrange for a thorough
12428 immediate redisplay using the correct mode line height. */
12429 if (WINDOW_WANTS_MODELINE_P (w)
12430 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12432 fonts_changed_p = 1;
12433 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12434 = DESIRED_MODE_LINE_HEIGHT (w);
12437 /* If top line height has changed, arrange for a thorough
12438 immediate redisplay using the correct mode line height. */
12439 if (WINDOW_WANTS_HEADER_LINE_P (w)
12440 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12442 fonts_changed_p = 1;
12443 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12444 = DESIRED_HEADER_LINE_HEIGHT (w);
12447 if (fonts_changed_p)
12448 goto need_larger_matrices;
12451 if (!line_number_displayed
12452 && !BUFFERP (w->base_line_pos))
12454 w->base_line_pos = Qnil;
12455 w->base_line_number = Qnil;
12458 finish_menu_bars:
12460 /* When we reach a frame's selected window, redo the frame's menu bar. */
12461 if (update_mode_line
12462 && EQ (FRAME_SELECTED_WINDOW (f), window))
12464 int redisplay_menu_p = 0;
12465 int redisplay_tool_bar_p = 0;
12467 if (FRAME_WINDOW_P (f))
12469 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12470 || defined (USE_GTK)
12471 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12472 #else
12473 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12474 #endif
12476 else
12477 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12479 if (redisplay_menu_p)
12480 display_menu_bar (w);
12482 #ifdef HAVE_WINDOW_SYSTEM
12483 #ifdef USE_GTK
12484 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12485 #else
12486 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12487 && (FRAME_TOOL_BAR_LINES (f) > 0
12488 || auto_resize_tool_bars_p);
12490 #endif
12492 if (redisplay_tool_bar_p)
12493 redisplay_tool_bar (f);
12494 #endif
12497 #ifdef HAVE_WINDOW_SYSTEM
12498 if (update_window_fringes (w, 0)
12499 && (used_current_matrix_p || overlay_arrow_seen)
12500 && !w->pseudo_window_p)
12502 update_begin (f);
12503 BLOCK_INPUT;
12504 draw_window_fringes (w);
12505 UNBLOCK_INPUT;
12506 update_end (f);
12508 #endif /* HAVE_WINDOW_SYSTEM */
12510 /* We go to this label, with fonts_changed_p nonzero,
12511 if it is necessary to try again using larger glyph matrices.
12512 We have to redeem the scroll bar even in this case,
12513 because the loop in redisplay_internal expects that. */
12514 need_larger_matrices:
12516 finish_scroll_bars:
12518 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12520 /* Set the thumb's position and size. */
12521 set_vertical_scroll_bar (w);
12523 /* Note that we actually used the scroll bar attached to this
12524 window, so it shouldn't be deleted at the end of redisplay. */
12525 redeem_scroll_bar_hook (w);
12528 /* Restore current_buffer and value of point in it. */
12529 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12530 set_buffer_internal_1 (old);
12531 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12533 unbind_to (count, Qnil);
12537 /* Build the complete desired matrix of WINDOW with a window start
12538 buffer position POS. Value is non-zero if successful. It is zero
12539 if fonts were loaded during redisplay which makes re-adjusting
12540 glyph matrices necessary. */
12543 try_window (window, pos)
12544 Lisp_Object window;
12545 struct text_pos pos;
12547 struct window *w = XWINDOW (window);
12548 struct it it;
12549 struct glyph_row *last_text_row = NULL;
12551 /* Make POS the new window start. */
12552 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12554 /* Mark cursor position as unknown. No overlay arrow seen. */
12555 w->cursor.vpos = -1;
12556 overlay_arrow_seen = 0;
12558 /* Initialize iterator and info to start at POS. */
12559 start_display (&it, w, pos);
12561 /* Display all lines of W. */
12562 while (it.current_y < it.last_visible_y)
12564 if (display_line (&it))
12565 last_text_row = it.glyph_row - 1;
12566 if (fonts_changed_p)
12567 return 0;
12570 /* If bottom moved off end of frame, change mode line percentage. */
12571 if (XFASTINT (w->window_end_pos) <= 0
12572 && Z != IT_CHARPOS (it))
12573 w->update_mode_line = Qt;
12575 /* Set window_end_pos to the offset of the last character displayed
12576 on the window from the end of current_buffer. Set
12577 window_end_vpos to its row number. */
12578 if (last_text_row)
12580 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12581 w->window_end_bytepos
12582 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12583 w->window_end_pos
12584 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12585 w->window_end_vpos
12586 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12587 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12588 ->displays_text_p);
12590 else
12592 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12593 w->window_end_pos = make_number (Z - ZV);
12594 w->window_end_vpos = make_number (0);
12597 /* But that is not valid info until redisplay finishes. */
12598 w->window_end_valid = Qnil;
12599 return 1;
12604 /************************************************************************
12605 Window redisplay reusing current matrix when buffer has not changed
12606 ************************************************************************/
12608 /* Try redisplay of window W showing an unchanged buffer with a
12609 different window start than the last time it was displayed by
12610 reusing its current matrix. Value is non-zero if successful.
12611 W->start is the new window start. */
12613 static int
12614 try_window_reusing_current_matrix (w)
12615 struct window *w;
12617 struct frame *f = XFRAME (w->frame);
12618 struct glyph_row *row, *bottom_row;
12619 struct it it;
12620 struct run run;
12621 struct text_pos start, new_start;
12622 int nrows_scrolled, i;
12623 struct glyph_row *last_text_row;
12624 struct glyph_row *last_reused_text_row;
12625 struct glyph_row *start_row;
12626 int start_vpos, min_y, max_y;
12628 #if GLYPH_DEBUG
12629 if (inhibit_try_window_reusing)
12630 return 0;
12631 #endif
12633 if (/* This function doesn't handle terminal frames. */
12634 !FRAME_WINDOW_P (f)
12635 /* Don't try to reuse the display if windows have been split
12636 or such. */
12637 || windows_or_buffers_changed
12638 || cursor_type_changed)
12639 return 0;
12641 /* Can't do this if region may have changed. */
12642 if ((!NILP (Vtransient_mark_mode)
12643 && !NILP (current_buffer->mark_active))
12644 || !NILP (w->region_showing)
12645 || !NILP (Vshow_trailing_whitespace))
12646 return 0;
12648 /* If top-line visibility has changed, give up. */
12649 if (WINDOW_WANTS_HEADER_LINE_P (w)
12650 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12651 return 0;
12653 /* Give up if old or new display is scrolled vertically. We could
12654 make this function handle this, but right now it doesn't. */
12655 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12656 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12657 return 0;
12659 /* The variable new_start now holds the new window start. The old
12660 start `start' can be determined from the current matrix. */
12661 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12662 start = start_row->start.pos;
12663 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12665 /* Clear the desired matrix for the display below. */
12666 clear_glyph_matrix (w->desired_matrix);
12668 if (CHARPOS (new_start) <= CHARPOS (start))
12670 int first_row_y;
12672 /* Don't use this method if the display starts with an ellipsis
12673 displayed for invisible text. It's not easy to handle that case
12674 below, and it's certainly not worth the effort since this is
12675 not a frequent case. */
12676 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12677 return 0;
12679 IF_DEBUG (debug_method_add (w, "twu1"));
12681 /* Display up to a row that can be reused. The variable
12682 last_text_row is set to the last row displayed that displays
12683 text. Note that it.vpos == 0 if or if not there is a
12684 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12685 start_display (&it, w, new_start);
12686 first_row_y = it.current_y;
12687 w->cursor.vpos = -1;
12688 last_text_row = last_reused_text_row = NULL;
12690 while (it.current_y < it.last_visible_y
12691 && IT_CHARPOS (it) < CHARPOS (start)
12692 && !fonts_changed_p)
12693 if (display_line (&it))
12694 last_text_row = it.glyph_row - 1;
12696 /* A value of current_y < last_visible_y means that we stopped
12697 at the previous window start, which in turn means that we
12698 have at least one reusable row. */
12699 if (it.current_y < it.last_visible_y)
12701 /* IT.vpos always starts from 0; it counts text lines. */
12702 nrows_scrolled = it.vpos;
12704 /* Find PT if not already found in the lines displayed. */
12705 if (w->cursor.vpos < 0)
12707 int dy = it.current_y - first_row_y;
12709 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12710 row = row_containing_pos (w, PT, row, NULL, dy);
12711 if (row)
12712 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12713 dy, nrows_scrolled);
12714 else
12716 clear_glyph_matrix (w->desired_matrix);
12717 return 0;
12721 /* Scroll the display. Do it before the current matrix is
12722 changed. The problem here is that update has not yet
12723 run, i.e. part of the current matrix is not up to date.
12724 scroll_run_hook will clear the cursor, and use the
12725 current matrix to get the height of the row the cursor is
12726 in. */
12727 run.current_y = first_row_y;
12728 run.desired_y = it.current_y;
12729 run.height = it.last_visible_y - it.current_y;
12731 if (run.height > 0 && run.current_y != run.desired_y)
12733 update_begin (f);
12734 rif->update_window_begin_hook (w);
12735 rif->clear_window_mouse_face (w);
12736 rif->scroll_run_hook (w, &run);
12737 rif->update_window_end_hook (w, 0, 0);
12738 update_end (f);
12741 /* Shift current matrix down by nrows_scrolled lines. */
12742 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12743 rotate_matrix (w->current_matrix,
12744 start_vpos,
12745 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12746 nrows_scrolled);
12748 /* Disable lines that must be updated. */
12749 for (i = 0; i < it.vpos; ++i)
12750 (start_row + i)->enabled_p = 0;
12752 /* Re-compute Y positions. */
12753 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12754 max_y = it.last_visible_y;
12755 for (row = start_row + nrows_scrolled;
12756 row < bottom_row;
12757 ++row)
12759 row->y = it.current_y;
12760 row->visible_height = row->height;
12762 if (row->y < min_y)
12763 row->visible_height -= min_y - row->y;
12764 if (row->y + row->height > max_y)
12765 row->visible_height -= row->y + row->height - max_y;
12766 row->redraw_fringe_bitmaps_p = 1;
12768 it.current_y += row->height;
12770 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12771 last_reused_text_row = row;
12772 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12773 break;
12776 /* Disable lines in the current matrix which are now
12777 below the window. */
12778 for (++row; row < bottom_row; ++row)
12779 row->enabled_p = 0;
12782 /* Update window_end_pos etc.; last_reused_text_row is the last
12783 reused row from the current matrix containing text, if any.
12784 The value of last_text_row is the last displayed line
12785 containing text. */
12786 if (last_reused_text_row)
12788 w->window_end_bytepos
12789 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12790 w->window_end_pos
12791 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12792 w->window_end_vpos
12793 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12794 w->current_matrix));
12796 else if (last_text_row)
12798 w->window_end_bytepos
12799 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12800 w->window_end_pos
12801 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12802 w->window_end_vpos
12803 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12805 else
12807 /* This window must be completely empty. */
12808 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12809 w->window_end_pos = make_number (Z - ZV);
12810 w->window_end_vpos = make_number (0);
12812 w->window_end_valid = Qnil;
12814 /* Update hint: don't try scrolling again in update_window. */
12815 w->desired_matrix->no_scrolling_p = 1;
12817 #if GLYPH_DEBUG
12818 debug_method_add (w, "try_window_reusing_current_matrix 1");
12819 #endif
12820 return 1;
12822 else if (CHARPOS (new_start) > CHARPOS (start))
12824 struct glyph_row *pt_row, *row;
12825 struct glyph_row *first_reusable_row;
12826 struct glyph_row *first_row_to_display;
12827 int dy;
12828 int yb = window_text_bottom_y (w);
12830 /* Find the row starting at new_start, if there is one. Don't
12831 reuse a partially visible line at the end. */
12832 first_reusable_row = start_row;
12833 while (first_reusable_row->enabled_p
12834 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12835 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12836 < CHARPOS (new_start)))
12837 ++first_reusable_row;
12839 /* Give up if there is no row to reuse. */
12840 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12841 || !first_reusable_row->enabled_p
12842 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12843 != CHARPOS (new_start)))
12844 return 0;
12846 /* We can reuse fully visible rows beginning with
12847 first_reusable_row to the end of the window. Set
12848 first_row_to_display to the first row that cannot be reused.
12849 Set pt_row to the row containing point, if there is any. */
12850 pt_row = NULL;
12851 for (first_row_to_display = first_reusable_row;
12852 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12853 ++first_row_to_display)
12855 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12856 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12857 pt_row = first_row_to_display;
12860 /* Start displaying at the start of first_row_to_display. */
12861 xassert (first_row_to_display->y < yb);
12862 init_to_row_start (&it, w, first_row_to_display);
12864 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12865 - start_vpos);
12866 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12867 - nrows_scrolled);
12868 it.current_y = (first_row_to_display->y - first_reusable_row->y
12869 + WINDOW_HEADER_LINE_HEIGHT (w));
12871 /* Display lines beginning with first_row_to_display in the
12872 desired matrix. Set last_text_row to the last row displayed
12873 that displays text. */
12874 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12875 if (pt_row == NULL)
12876 w->cursor.vpos = -1;
12877 last_text_row = NULL;
12878 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12879 if (display_line (&it))
12880 last_text_row = it.glyph_row - 1;
12882 /* Give up If point isn't in a row displayed or reused. */
12883 if (w->cursor.vpos < 0)
12885 clear_glyph_matrix (w->desired_matrix);
12886 return 0;
12889 /* If point is in a reused row, adjust y and vpos of the cursor
12890 position. */
12891 if (pt_row)
12893 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12894 w->current_matrix);
12895 w->cursor.y -= first_reusable_row->y;
12898 /* Scroll the display. */
12899 run.current_y = first_reusable_row->y;
12900 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12901 run.height = it.last_visible_y - run.current_y;
12902 dy = run.current_y - run.desired_y;
12904 if (run.height)
12906 update_begin (f);
12907 rif->update_window_begin_hook (w);
12908 rif->clear_window_mouse_face (w);
12909 rif->scroll_run_hook (w, &run);
12910 rif->update_window_end_hook (w, 0, 0);
12911 update_end (f);
12914 /* Adjust Y positions of reused rows. */
12915 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12916 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12917 max_y = it.last_visible_y;
12918 for (row = first_reusable_row; row < first_row_to_display; ++row)
12920 row->y -= dy;
12921 row->visible_height = row->height;
12922 if (row->y < min_y)
12923 row->visible_height -= min_y - row->y;
12924 if (row->y + row->height > max_y)
12925 row->visible_height -= row->y + row->height - max_y;
12926 row->redraw_fringe_bitmaps_p = 1;
12929 /* Scroll the current matrix. */
12930 xassert (nrows_scrolled > 0);
12931 rotate_matrix (w->current_matrix,
12932 start_vpos,
12933 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12934 -nrows_scrolled);
12936 /* Disable rows not reused. */
12937 for (row -= nrows_scrolled; row < bottom_row; ++row)
12938 row->enabled_p = 0;
12940 /* Adjust window end. A null value of last_text_row means that
12941 the window end is in reused rows which in turn means that
12942 only its vpos can have changed. */
12943 if (last_text_row)
12945 w->window_end_bytepos
12946 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12947 w->window_end_pos
12948 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12949 w->window_end_vpos
12950 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12952 else
12954 w->window_end_vpos
12955 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12958 w->window_end_valid = Qnil;
12959 w->desired_matrix->no_scrolling_p = 1;
12961 #if GLYPH_DEBUG
12962 debug_method_add (w, "try_window_reusing_current_matrix 2");
12963 #endif
12964 return 1;
12967 return 0;
12972 /************************************************************************
12973 Window redisplay reusing current matrix when buffer has changed
12974 ************************************************************************/
12976 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12977 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12978 int *, int *));
12979 static struct glyph_row *
12980 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12981 struct glyph_row *));
12984 /* Return the last row in MATRIX displaying text. If row START is
12985 non-null, start searching with that row. IT gives the dimensions
12986 of the display. Value is null if matrix is empty; otherwise it is
12987 a pointer to the row found. */
12989 static struct glyph_row *
12990 find_last_row_displaying_text (matrix, it, start)
12991 struct glyph_matrix *matrix;
12992 struct it *it;
12993 struct glyph_row *start;
12995 struct glyph_row *row, *row_found;
12997 /* Set row_found to the last row in IT->w's current matrix
12998 displaying text. The loop looks funny but think of partially
12999 visible lines. */
13000 row_found = NULL;
13001 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13002 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13004 xassert (row->enabled_p);
13005 row_found = row;
13006 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13007 break;
13008 ++row;
13011 return row_found;
13015 /* Return the last row in the current matrix of W that is not affected
13016 by changes at the start of current_buffer that occurred since W's
13017 current matrix was built. Value is null if no such row exists.
13019 BEG_UNCHANGED us the number of characters unchanged at the start of
13020 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13021 first changed character in current_buffer. Characters at positions <
13022 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13023 when the current matrix was built. */
13025 static struct glyph_row *
13026 find_last_unchanged_at_beg_row (w)
13027 struct window *w;
13029 int first_changed_pos = BEG + BEG_UNCHANGED;
13030 struct glyph_row *row;
13031 struct glyph_row *row_found = NULL;
13032 int yb = window_text_bottom_y (w);
13034 /* Find the last row displaying unchanged text. */
13035 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13036 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13037 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13039 if (/* If row ends before first_changed_pos, it is unchanged,
13040 except in some case. */
13041 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13042 /* When row ends in ZV and we write at ZV it is not
13043 unchanged. */
13044 && !row->ends_at_zv_p
13045 /* When first_changed_pos is the end of a continued line,
13046 row is not unchanged because it may be no longer
13047 continued. */
13048 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13049 && (row->continued_p
13050 || row->exact_window_width_line_p)))
13051 row_found = row;
13053 /* Stop if last visible row. */
13054 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13055 break;
13057 ++row;
13060 return row_found;
13064 /* Find the first glyph row in the current matrix of W that is not
13065 affected by changes at the end of current_buffer since the
13066 time W's current matrix was built.
13068 Return in *DELTA the number of chars by which buffer positions in
13069 unchanged text at the end of current_buffer must be adjusted.
13071 Return in *DELTA_BYTES the corresponding number of bytes.
13073 Value is null if no such row exists, i.e. all rows are affected by
13074 changes. */
13076 static struct glyph_row *
13077 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13078 struct window *w;
13079 int *delta, *delta_bytes;
13081 struct glyph_row *row;
13082 struct glyph_row *row_found = NULL;
13084 *delta = *delta_bytes = 0;
13086 /* Display must not have been paused, otherwise the current matrix
13087 is not up to date. */
13088 if (NILP (w->window_end_valid))
13089 abort ();
13091 /* A value of window_end_pos >= END_UNCHANGED means that the window
13092 end is in the range of changed text. If so, there is no
13093 unchanged row at the end of W's current matrix. */
13094 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13095 return NULL;
13097 /* Set row to the last row in W's current matrix displaying text. */
13098 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13100 /* If matrix is entirely empty, no unchanged row exists. */
13101 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13103 /* The value of row is the last glyph row in the matrix having a
13104 meaningful buffer position in it. The end position of row
13105 corresponds to window_end_pos. This allows us to translate
13106 buffer positions in the current matrix to current buffer
13107 positions for characters not in changed text. */
13108 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13109 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13110 int last_unchanged_pos, last_unchanged_pos_old;
13111 struct glyph_row *first_text_row
13112 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13114 *delta = Z - Z_old;
13115 *delta_bytes = Z_BYTE - Z_BYTE_old;
13117 /* Set last_unchanged_pos to the buffer position of the last
13118 character in the buffer that has not been changed. Z is the
13119 index + 1 of the last character in current_buffer, i.e. by
13120 subtracting END_UNCHANGED we get the index of the last
13121 unchanged character, and we have to add BEG to get its buffer
13122 position. */
13123 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13124 last_unchanged_pos_old = last_unchanged_pos - *delta;
13126 /* Search backward from ROW for a row displaying a line that
13127 starts at a minimum position >= last_unchanged_pos_old. */
13128 for (; row > first_text_row; --row)
13130 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13131 abort ();
13133 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13134 row_found = row;
13138 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13139 abort ();
13141 return row_found;
13145 /* Make sure that glyph rows in the current matrix of window W
13146 reference the same glyph memory as corresponding rows in the
13147 frame's frame matrix. This function is called after scrolling W's
13148 current matrix on a terminal frame in try_window_id and
13149 try_window_reusing_current_matrix. */
13151 static void
13152 sync_frame_with_window_matrix_rows (w)
13153 struct window *w;
13155 struct frame *f = XFRAME (w->frame);
13156 struct glyph_row *window_row, *window_row_end, *frame_row;
13158 /* Preconditions: W must be a leaf window and full-width. Its frame
13159 must have a frame matrix. */
13160 xassert (NILP (w->hchild) && NILP (w->vchild));
13161 xassert (WINDOW_FULL_WIDTH_P (w));
13162 xassert (!FRAME_WINDOW_P (f));
13164 /* If W is a full-width window, glyph pointers in W's current matrix
13165 have, by definition, to be the same as glyph pointers in the
13166 corresponding frame matrix. Note that frame matrices have no
13167 marginal areas (see build_frame_matrix). */
13168 window_row = w->current_matrix->rows;
13169 window_row_end = window_row + w->current_matrix->nrows;
13170 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13171 while (window_row < window_row_end)
13173 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13174 struct glyph *end = window_row->glyphs[LAST_AREA];
13176 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13177 frame_row->glyphs[TEXT_AREA] = start;
13178 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13179 frame_row->glyphs[LAST_AREA] = end;
13181 /* Disable frame rows whose corresponding window rows have
13182 been disabled in try_window_id. */
13183 if (!window_row->enabled_p)
13184 frame_row->enabled_p = 0;
13186 ++window_row, ++frame_row;
13191 /* Find the glyph row in window W containing CHARPOS. Consider all
13192 rows between START and END (not inclusive). END null means search
13193 all rows to the end of the display area of W. Value is the row
13194 containing CHARPOS or null. */
13196 struct glyph_row *
13197 row_containing_pos (w, charpos, start, end, dy)
13198 struct window *w;
13199 int charpos;
13200 struct glyph_row *start, *end;
13201 int dy;
13203 struct glyph_row *row = start;
13204 int last_y;
13206 /* If we happen to start on a header-line, skip that. */
13207 if (row->mode_line_p)
13208 ++row;
13210 if ((end && row >= end) || !row->enabled_p)
13211 return NULL;
13213 last_y = window_text_bottom_y (w) - dy;
13215 while (1)
13217 /* Give up if we have gone too far. */
13218 if (end && row >= end)
13219 return NULL;
13220 /* This formerly returned if they were equal.
13221 I think that both quantities are of a "last plus one" type;
13222 if so, when they are equal, the row is within the screen. -- rms. */
13223 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13224 return NULL;
13226 /* If it is in this row, return this row. */
13227 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13228 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13229 /* The end position of a row equals the start
13230 position of the next row. If CHARPOS is there, we
13231 would rather display it in the next line, except
13232 when this line ends in ZV. */
13233 && !row->ends_at_zv_p
13234 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13235 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13236 return row;
13237 ++row;
13242 /* Try to redisplay window W by reusing its existing display. W's
13243 current matrix must be up to date when this function is called,
13244 i.e. window_end_valid must not be nil.
13246 Value is
13248 1 if display has been updated
13249 0 if otherwise unsuccessful
13250 -1 if redisplay with same window start is known not to succeed
13252 The following steps are performed:
13254 1. Find the last row in the current matrix of W that is not
13255 affected by changes at the start of current_buffer. If no such row
13256 is found, give up.
13258 2. Find the first row in W's current matrix that is not affected by
13259 changes at the end of current_buffer. Maybe there is no such row.
13261 3. Display lines beginning with the row + 1 found in step 1 to the
13262 row found in step 2 or, if step 2 didn't find a row, to the end of
13263 the window.
13265 4. If cursor is not known to appear on the window, give up.
13267 5. If display stopped at the row found in step 2, scroll the
13268 display and current matrix as needed.
13270 6. Maybe display some lines at the end of W, if we must. This can
13271 happen under various circumstances, like a partially visible line
13272 becoming fully visible, or because newly displayed lines are displayed
13273 in smaller font sizes.
13275 7. Update W's window end information. */
13277 static int
13278 try_window_id (w)
13279 struct window *w;
13281 struct frame *f = XFRAME (w->frame);
13282 struct glyph_matrix *current_matrix = w->current_matrix;
13283 struct glyph_matrix *desired_matrix = w->desired_matrix;
13284 struct glyph_row *last_unchanged_at_beg_row;
13285 struct glyph_row *first_unchanged_at_end_row;
13286 struct glyph_row *row;
13287 struct glyph_row *bottom_row;
13288 int bottom_vpos;
13289 struct it it;
13290 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13291 struct text_pos start_pos;
13292 struct run run;
13293 int first_unchanged_at_end_vpos = 0;
13294 struct glyph_row *last_text_row, *last_text_row_at_end;
13295 struct text_pos start;
13296 int first_changed_charpos, last_changed_charpos;
13298 #if GLYPH_DEBUG
13299 if (inhibit_try_window_id)
13300 return 0;
13301 #endif
13303 /* This is handy for debugging. */
13304 #if 0
13305 #define GIVE_UP(X) \
13306 do { \
13307 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13308 return 0; \
13309 } while (0)
13310 #else
13311 #define GIVE_UP(X) return 0
13312 #endif
13314 SET_TEXT_POS_FROM_MARKER (start, w->start);
13316 /* Don't use this for mini-windows because these can show
13317 messages and mini-buffers, and we don't handle that here. */
13318 if (MINI_WINDOW_P (w))
13319 GIVE_UP (1);
13321 /* This flag is used to prevent redisplay optimizations. */
13322 if (windows_or_buffers_changed || cursor_type_changed)
13323 GIVE_UP (2);
13325 /* Verify that narrowing has not changed.
13326 Also verify that we were not told to prevent redisplay optimizations.
13327 It would be nice to further
13328 reduce the number of cases where this prevents try_window_id. */
13329 if (current_buffer->clip_changed
13330 || current_buffer->prevent_redisplay_optimizations_p)
13331 GIVE_UP (3);
13333 /* Window must either use window-based redisplay or be full width. */
13334 if (!FRAME_WINDOW_P (f)
13335 && (!line_ins_del_ok
13336 || !WINDOW_FULL_WIDTH_P (w)))
13337 GIVE_UP (4);
13339 /* Give up if point is not known NOT to appear in W. */
13340 if (PT < CHARPOS (start))
13341 GIVE_UP (5);
13343 /* Another way to prevent redisplay optimizations. */
13344 if (XFASTINT (w->last_modified) == 0)
13345 GIVE_UP (6);
13347 /* Verify that window is not hscrolled. */
13348 if (XFASTINT (w->hscroll) != 0)
13349 GIVE_UP (7);
13351 /* Verify that display wasn't paused. */
13352 if (NILP (w->window_end_valid))
13353 GIVE_UP (8);
13355 /* Can't use this if highlighting a region because a cursor movement
13356 will do more than just set the cursor. */
13357 if (!NILP (Vtransient_mark_mode)
13358 && !NILP (current_buffer->mark_active))
13359 GIVE_UP (9);
13361 /* Likewise if highlighting trailing whitespace. */
13362 if (!NILP (Vshow_trailing_whitespace))
13363 GIVE_UP (11);
13365 /* Likewise if showing a region. */
13366 if (!NILP (w->region_showing))
13367 GIVE_UP (10);
13369 /* Can use this if overlay arrow position and or string have changed. */
13370 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
13371 || !EQ (last_arrow_string, Voverlay_arrow_string))
13372 GIVE_UP (12);
13375 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13376 only if buffer has really changed. The reason is that the gap is
13377 initially at Z for freshly visited files. The code below would
13378 set end_unchanged to 0 in that case. */
13379 if (MODIFF > SAVE_MODIFF
13380 /* This seems to happen sometimes after saving a buffer. */
13381 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13383 if (GPT - BEG < BEG_UNCHANGED)
13384 BEG_UNCHANGED = GPT - BEG;
13385 if (Z - GPT < END_UNCHANGED)
13386 END_UNCHANGED = Z - GPT;
13389 /* The position of the first and last character that has been changed. */
13390 first_changed_charpos = BEG + BEG_UNCHANGED;
13391 last_changed_charpos = Z - END_UNCHANGED;
13393 /* If window starts after a line end, and the last change is in
13394 front of that newline, then changes don't affect the display.
13395 This case happens with stealth-fontification. Note that although
13396 the display is unchanged, glyph positions in the matrix have to
13397 be adjusted, of course. */
13398 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13399 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13400 && ((last_changed_charpos < CHARPOS (start)
13401 && CHARPOS (start) == BEGV)
13402 || (last_changed_charpos < CHARPOS (start) - 1
13403 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13405 int Z_old, delta, Z_BYTE_old, delta_bytes;
13406 struct glyph_row *r0;
13408 /* Compute how many chars/bytes have been added to or removed
13409 from the buffer. */
13410 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13411 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13412 delta = Z - Z_old;
13413 delta_bytes = Z_BYTE - Z_BYTE_old;
13415 /* Give up if PT is not in the window. Note that it already has
13416 been checked at the start of try_window_id that PT is not in
13417 front of the window start. */
13418 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13419 GIVE_UP (13);
13421 /* If window start is unchanged, we can reuse the whole matrix
13422 as is, after adjusting glyph positions. No need to compute
13423 the window end again, since its offset from Z hasn't changed. */
13424 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13425 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13426 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13427 /* PT must not be in a partially visible line. */
13428 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13429 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13431 /* Adjust positions in the glyph matrix. */
13432 if (delta || delta_bytes)
13434 struct glyph_row *r1
13435 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13436 increment_matrix_positions (w->current_matrix,
13437 MATRIX_ROW_VPOS (r0, current_matrix),
13438 MATRIX_ROW_VPOS (r1, current_matrix),
13439 delta, delta_bytes);
13442 /* Set the cursor. */
13443 row = row_containing_pos (w, PT, r0, NULL, 0);
13444 if (row)
13445 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13446 else
13447 abort ();
13448 return 1;
13452 /* Handle the case that changes are all below what is displayed in
13453 the window, and that PT is in the window. This shortcut cannot
13454 be taken if ZV is visible in the window, and text has been added
13455 there that is visible in the window. */
13456 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13457 /* ZV is not visible in the window, or there are no
13458 changes at ZV, actually. */
13459 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13460 || first_changed_charpos == last_changed_charpos))
13462 struct glyph_row *r0;
13464 /* Give up if PT is not in the window. Note that it already has
13465 been checked at the start of try_window_id that PT is not in
13466 front of the window start. */
13467 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13468 GIVE_UP (14);
13470 /* If window start is unchanged, we can reuse the whole matrix
13471 as is, without changing glyph positions since no text has
13472 been added/removed in front of the window end. */
13473 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13474 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13475 /* PT must not be in a partially visible line. */
13476 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13477 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13479 /* We have to compute the window end anew since text
13480 can have been added/removed after it. */
13481 w->window_end_pos
13482 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13483 w->window_end_bytepos
13484 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13486 /* Set the cursor. */
13487 row = row_containing_pos (w, PT, r0, NULL, 0);
13488 if (row)
13489 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13490 else
13491 abort ();
13492 return 2;
13496 /* Give up if window start is in the changed area.
13498 The condition used to read
13500 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13502 but why that was tested escapes me at the moment. */
13503 if (CHARPOS (start) >= first_changed_charpos
13504 && CHARPOS (start) <= last_changed_charpos)
13505 GIVE_UP (15);
13507 /* Check that window start agrees with the start of the first glyph
13508 row in its current matrix. Check this after we know the window
13509 start is not in changed text, otherwise positions would not be
13510 comparable. */
13511 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13512 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13513 GIVE_UP (16);
13515 /* Give up if the window ends in strings. Overlay strings
13516 at the end are difficult to handle, so don't try. */
13517 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13518 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13519 GIVE_UP (20);
13521 /* Compute the position at which we have to start displaying new
13522 lines. Some of the lines at the top of the window might be
13523 reusable because they are not displaying changed text. Find the
13524 last row in W's current matrix not affected by changes at the
13525 start of current_buffer. Value is null if changes start in the
13526 first line of window. */
13527 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13528 if (last_unchanged_at_beg_row)
13530 /* Avoid starting to display in the moddle of a character, a TAB
13531 for instance. This is easier than to set up the iterator
13532 exactly, and it's not a frequent case, so the additional
13533 effort wouldn't really pay off. */
13534 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13535 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13536 && last_unchanged_at_beg_row > w->current_matrix->rows)
13537 --last_unchanged_at_beg_row;
13539 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13540 GIVE_UP (17);
13542 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13543 GIVE_UP (18);
13544 start_pos = it.current.pos;
13546 /* Start displaying new lines in the desired matrix at the same
13547 vpos we would use in the current matrix, i.e. below
13548 last_unchanged_at_beg_row. */
13549 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13550 current_matrix);
13551 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13552 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13554 xassert (it.hpos == 0 && it.current_x == 0);
13556 else
13558 /* There are no reusable lines at the start of the window.
13559 Start displaying in the first text line. */
13560 start_display (&it, w, start);
13561 it.vpos = it.first_vpos;
13562 start_pos = it.current.pos;
13565 /* Find the first row that is not affected by changes at the end of
13566 the buffer. Value will be null if there is no unchanged row, in
13567 which case we must redisplay to the end of the window. delta
13568 will be set to the value by which buffer positions beginning with
13569 first_unchanged_at_end_row have to be adjusted due to text
13570 changes. */
13571 first_unchanged_at_end_row
13572 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13573 IF_DEBUG (debug_delta = delta);
13574 IF_DEBUG (debug_delta_bytes = delta_bytes);
13576 /* Set stop_pos to the buffer position up to which we will have to
13577 display new lines. If first_unchanged_at_end_row != NULL, this
13578 is the buffer position of the start of the line displayed in that
13579 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13580 that we don't stop at a buffer position. */
13581 stop_pos = 0;
13582 if (first_unchanged_at_end_row)
13584 xassert (last_unchanged_at_beg_row == NULL
13585 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13587 /* If this is a continuation line, move forward to the next one
13588 that isn't. Changes in lines above affect this line.
13589 Caution: this may move first_unchanged_at_end_row to a row
13590 not displaying text. */
13591 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13592 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13593 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13594 < it.last_visible_y))
13595 ++first_unchanged_at_end_row;
13597 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13598 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13599 >= it.last_visible_y))
13600 first_unchanged_at_end_row = NULL;
13601 else
13603 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13604 + delta);
13605 first_unchanged_at_end_vpos
13606 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13607 xassert (stop_pos >= Z - END_UNCHANGED);
13610 else if (last_unchanged_at_beg_row == NULL)
13611 GIVE_UP (19);
13614 #if GLYPH_DEBUG
13616 /* Either there is no unchanged row at the end, or the one we have
13617 now displays text. This is a necessary condition for the window
13618 end pos calculation at the end of this function. */
13619 xassert (first_unchanged_at_end_row == NULL
13620 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13622 debug_last_unchanged_at_beg_vpos
13623 = (last_unchanged_at_beg_row
13624 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13625 : -1);
13626 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13628 #endif /* GLYPH_DEBUG != 0 */
13631 /* Display new lines. Set last_text_row to the last new line
13632 displayed which has text on it, i.e. might end up as being the
13633 line where the window_end_vpos is. */
13634 w->cursor.vpos = -1;
13635 last_text_row = NULL;
13636 overlay_arrow_seen = 0;
13637 while (it.current_y < it.last_visible_y
13638 && !fonts_changed_p
13639 && (first_unchanged_at_end_row == NULL
13640 || IT_CHARPOS (it) < stop_pos))
13642 if (display_line (&it))
13643 last_text_row = it.glyph_row - 1;
13646 if (fonts_changed_p)
13647 return -1;
13650 /* Compute differences in buffer positions, y-positions etc. for
13651 lines reused at the bottom of the window. Compute what we can
13652 scroll. */
13653 if (first_unchanged_at_end_row
13654 /* No lines reused because we displayed everything up to the
13655 bottom of the window. */
13656 && it.current_y < it.last_visible_y)
13658 dvpos = (it.vpos
13659 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13660 current_matrix));
13661 dy = it.current_y - first_unchanged_at_end_row->y;
13662 run.current_y = first_unchanged_at_end_row->y;
13663 run.desired_y = run.current_y + dy;
13664 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13666 else
13668 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13669 first_unchanged_at_end_row = NULL;
13671 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13674 /* Find the cursor if not already found. We have to decide whether
13675 PT will appear on this window (it sometimes doesn't, but this is
13676 not a very frequent case.) This decision has to be made before
13677 the current matrix is altered. A value of cursor.vpos < 0 means
13678 that PT is either in one of the lines beginning at
13679 first_unchanged_at_end_row or below the window. Don't care for
13680 lines that might be displayed later at the window end; as
13681 mentioned, this is not a frequent case. */
13682 if (w->cursor.vpos < 0)
13684 /* Cursor in unchanged rows at the top? */
13685 if (PT < CHARPOS (start_pos)
13686 && last_unchanged_at_beg_row)
13688 row = row_containing_pos (w, PT,
13689 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13690 last_unchanged_at_beg_row + 1, 0);
13691 if (row)
13692 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13695 /* Start from first_unchanged_at_end_row looking for PT. */
13696 else if (first_unchanged_at_end_row)
13698 row = row_containing_pos (w, PT - delta,
13699 first_unchanged_at_end_row, NULL, 0);
13700 if (row)
13701 set_cursor_from_row (w, row, w->current_matrix, delta,
13702 delta_bytes, dy, dvpos);
13705 /* Give up if cursor was not found. */
13706 if (w->cursor.vpos < 0)
13708 clear_glyph_matrix (w->desired_matrix);
13709 return -1;
13713 /* Don't let the cursor end in the scroll margins. */
13715 int this_scroll_margin, cursor_height;
13717 this_scroll_margin = max (0, scroll_margin);
13718 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13719 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13720 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13722 if ((w->cursor.y < this_scroll_margin
13723 && CHARPOS (start) > BEGV)
13724 /* Don't take scroll margin into account at the bottom because
13725 old redisplay didn't do it either. */
13726 || w->cursor.y + cursor_height > it.last_visible_y)
13728 w->cursor.vpos = -1;
13729 clear_glyph_matrix (w->desired_matrix);
13730 return -1;
13734 /* Scroll the display. Do it before changing the current matrix so
13735 that xterm.c doesn't get confused about where the cursor glyph is
13736 found. */
13737 if (dy && run.height)
13739 update_begin (f);
13741 if (FRAME_WINDOW_P (f))
13743 rif->update_window_begin_hook (w);
13744 rif->clear_window_mouse_face (w);
13745 rif->scroll_run_hook (w, &run);
13746 rif->update_window_end_hook (w, 0, 0);
13748 else
13750 /* Terminal frame. In this case, dvpos gives the number of
13751 lines to scroll by; dvpos < 0 means scroll up. */
13752 int first_unchanged_at_end_vpos
13753 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13754 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13755 int end = (WINDOW_TOP_EDGE_LINE (w)
13756 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13757 + window_internal_height (w));
13759 /* Perform the operation on the screen. */
13760 if (dvpos > 0)
13762 /* Scroll last_unchanged_at_beg_row to the end of the
13763 window down dvpos lines. */
13764 set_terminal_window (end);
13766 /* On dumb terminals delete dvpos lines at the end
13767 before inserting dvpos empty lines. */
13768 if (!scroll_region_ok)
13769 ins_del_lines (end - dvpos, -dvpos);
13771 /* Insert dvpos empty lines in front of
13772 last_unchanged_at_beg_row. */
13773 ins_del_lines (from, dvpos);
13775 else if (dvpos < 0)
13777 /* Scroll up last_unchanged_at_beg_vpos to the end of
13778 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13779 set_terminal_window (end);
13781 /* Delete dvpos lines in front of
13782 last_unchanged_at_beg_vpos. ins_del_lines will set
13783 the cursor to the given vpos and emit |dvpos| delete
13784 line sequences. */
13785 ins_del_lines (from + dvpos, dvpos);
13787 /* On a dumb terminal insert dvpos empty lines at the
13788 end. */
13789 if (!scroll_region_ok)
13790 ins_del_lines (end + dvpos, -dvpos);
13793 set_terminal_window (0);
13796 update_end (f);
13799 /* Shift reused rows of the current matrix to the right position.
13800 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13801 text. */
13802 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13803 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13804 if (dvpos < 0)
13806 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13807 bottom_vpos, dvpos);
13808 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13809 bottom_vpos, 0);
13811 else if (dvpos > 0)
13813 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13814 bottom_vpos, dvpos);
13815 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13816 first_unchanged_at_end_vpos + dvpos, 0);
13819 /* For frame-based redisplay, make sure that current frame and window
13820 matrix are in sync with respect to glyph memory. */
13821 if (!FRAME_WINDOW_P (f))
13822 sync_frame_with_window_matrix_rows (w);
13824 /* Adjust buffer positions in reused rows. */
13825 if (delta)
13826 increment_matrix_positions (current_matrix,
13827 first_unchanged_at_end_vpos + dvpos,
13828 bottom_vpos, delta, delta_bytes);
13830 /* Adjust Y positions. */
13831 if (dy)
13832 shift_glyph_matrix (w, current_matrix,
13833 first_unchanged_at_end_vpos + dvpos,
13834 bottom_vpos, dy);
13836 if (first_unchanged_at_end_row)
13837 first_unchanged_at_end_row += dvpos;
13839 /* If scrolling up, there may be some lines to display at the end of
13840 the window. */
13841 last_text_row_at_end = NULL;
13842 if (dy < 0)
13844 /* Scrolling up can leave for example a partially visible line
13845 at the end of the window to be redisplayed. */
13846 /* Set last_row to the glyph row in the current matrix where the
13847 window end line is found. It has been moved up or down in
13848 the matrix by dvpos. */
13849 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13850 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13852 /* If last_row is the window end line, it should display text. */
13853 xassert (last_row->displays_text_p);
13855 /* If window end line was partially visible before, begin
13856 displaying at that line. Otherwise begin displaying with the
13857 line following it. */
13858 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13860 init_to_row_start (&it, w, last_row);
13861 it.vpos = last_vpos;
13862 it.current_y = last_row->y;
13864 else
13866 init_to_row_end (&it, w, last_row);
13867 it.vpos = 1 + last_vpos;
13868 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13869 ++last_row;
13872 /* We may start in a continuation line. If so, we have to
13873 get the right continuation_lines_width and current_x. */
13874 it.continuation_lines_width = last_row->continuation_lines_width;
13875 it.hpos = it.current_x = 0;
13877 /* Display the rest of the lines at the window end. */
13878 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13879 while (it.current_y < it.last_visible_y
13880 && !fonts_changed_p)
13882 /* Is it always sure that the display agrees with lines in
13883 the current matrix? I don't think so, so we mark rows
13884 displayed invalid in the current matrix by setting their
13885 enabled_p flag to zero. */
13886 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13887 if (display_line (&it))
13888 last_text_row_at_end = it.glyph_row - 1;
13892 /* Update window_end_pos and window_end_vpos. */
13893 if (first_unchanged_at_end_row
13894 && first_unchanged_at_end_row->y < it.last_visible_y
13895 && !last_text_row_at_end)
13897 /* Window end line if one of the preserved rows from the current
13898 matrix. Set row to the last row displaying text in current
13899 matrix starting at first_unchanged_at_end_row, after
13900 scrolling. */
13901 xassert (first_unchanged_at_end_row->displays_text_p);
13902 row = find_last_row_displaying_text (w->current_matrix, &it,
13903 first_unchanged_at_end_row);
13904 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13906 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13907 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13908 w->window_end_vpos
13909 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13910 xassert (w->window_end_bytepos >= 0);
13911 IF_DEBUG (debug_method_add (w, "A"));
13913 else if (last_text_row_at_end)
13915 w->window_end_pos
13916 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13917 w->window_end_bytepos
13918 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13919 w->window_end_vpos
13920 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13921 xassert (w->window_end_bytepos >= 0);
13922 IF_DEBUG (debug_method_add (w, "B"));
13924 else if (last_text_row)
13926 /* We have displayed either to the end of the window or at the
13927 end of the window, i.e. the last row with text is to be found
13928 in the desired matrix. */
13929 w->window_end_pos
13930 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13931 w->window_end_bytepos
13932 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13933 w->window_end_vpos
13934 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13935 xassert (w->window_end_bytepos >= 0);
13937 else if (first_unchanged_at_end_row == NULL
13938 && last_text_row == NULL
13939 && last_text_row_at_end == NULL)
13941 /* Displayed to end of window, but no line containing text was
13942 displayed. Lines were deleted at the end of the window. */
13943 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13944 int vpos = XFASTINT (w->window_end_vpos);
13945 struct glyph_row *current_row = current_matrix->rows + vpos;
13946 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13948 for (row = NULL;
13949 row == NULL && vpos >= first_vpos;
13950 --vpos, --current_row, --desired_row)
13952 if (desired_row->enabled_p)
13954 if (desired_row->displays_text_p)
13955 row = desired_row;
13957 else if (current_row->displays_text_p)
13958 row = current_row;
13961 xassert (row != NULL);
13962 w->window_end_vpos = make_number (vpos + 1);
13963 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13964 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13965 xassert (w->window_end_bytepos >= 0);
13966 IF_DEBUG (debug_method_add (w, "C"));
13968 else
13969 abort ();
13971 #if 0 /* This leads to problems, for instance when the cursor is
13972 at ZV, and the cursor line displays no text. */
13973 /* Disable rows below what's displayed in the window. This makes
13974 debugging easier. */
13975 enable_glyph_matrix_rows (current_matrix,
13976 XFASTINT (w->window_end_vpos) + 1,
13977 bottom_vpos, 0);
13978 #endif
13980 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13981 debug_end_vpos = XFASTINT (w->window_end_vpos));
13983 /* Record that display has not been completed. */
13984 w->window_end_valid = Qnil;
13985 w->desired_matrix->no_scrolling_p = 1;
13986 return 3;
13988 #undef GIVE_UP
13993 /***********************************************************************
13994 More debugging support
13995 ***********************************************************************/
13997 #if GLYPH_DEBUG
13999 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14000 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14001 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14004 /* Dump the contents of glyph matrix MATRIX on stderr.
14006 GLYPHS 0 means don't show glyph contents.
14007 GLYPHS 1 means show glyphs in short form
14008 GLYPHS > 1 means show glyphs in long form. */
14010 void
14011 dump_glyph_matrix (matrix, glyphs)
14012 struct glyph_matrix *matrix;
14013 int glyphs;
14015 int i;
14016 for (i = 0; i < matrix->nrows; ++i)
14017 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14021 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14022 the glyph row and area where the glyph comes from. */
14024 void
14025 dump_glyph (row, glyph, area)
14026 struct glyph_row *row;
14027 struct glyph *glyph;
14028 int area;
14030 if (glyph->type == CHAR_GLYPH)
14032 fprintf (stderr,
14033 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14034 glyph - row->glyphs[TEXT_AREA],
14035 'C',
14036 glyph->charpos,
14037 (BUFFERP (glyph->object)
14038 ? 'B'
14039 : (STRINGP (glyph->object)
14040 ? 'S'
14041 : '-')),
14042 glyph->pixel_width,
14043 glyph->u.ch,
14044 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14045 ? glyph->u.ch
14046 : '.'),
14047 glyph->face_id,
14048 glyph->left_box_line_p,
14049 glyph->right_box_line_p);
14051 else if (glyph->type == STRETCH_GLYPH)
14053 fprintf (stderr,
14054 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14055 glyph - row->glyphs[TEXT_AREA],
14056 'S',
14057 glyph->charpos,
14058 (BUFFERP (glyph->object)
14059 ? 'B'
14060 : (STRINGP (glyph->object)
14061 ? 'S'
14062 : '-')),
14063 glyph->pixel_width,
14065 '.',
14066 glyph->face_id,
14067 glyph->left_box_line_p,
14068 glyph->right_box_line_p);
14070 else if (glyph->type == IMAGE_GLYPH)
14072 fprintf (stderr,
14073 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14074 glyph - row->glyphs[TEXT_AREA],
14075 'I',
14076 glyph->charpos,
14077 (BUFFERP (glyph->object)
14078 ? 'B'
14079 : (STRINGP (glyph->object)
14080 ? 'S'
14081 : '-')),
14082 glyph->pixel_width,
14083 glyph->u.img_id,
14084 '.',
14085 glyph->face_id,
14086 glyph->left_box_line_p,
14087 glyph->right_box_line_p);
14092 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14093 GLYPHS 0 means don't show glyph contents.
14094 GLYPHS 1 means show glyphs in short form
14095 GLYPHS > 1 means show glyphs in long form. */
14097 void
14098 dump_glyph_row (row, vpos, glyphs)
14099 struct glyph_row *row;
14100 int vpos, glyphs;
14102 if (glyphs != 1)
14104 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
14105 fprintf (stderr, "=======================================================================\n");
14107 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
14108 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14109 vpos,
14110 MATRIX_ROW_START_CHARPOS (row),
14111 MATRIX_ROW_END_CHARPOS (row),
14112 row->used[TEXT_AREA],
14113 row->contains_overlapping_glyphs_p,
14114 row->enabled_p,
14115 row->truncated_on_left_p,
14116 row->truncated_on_right_p,
14117 row->overlay_arrow_p,
14118 row->continued_p,
14119 MATRIX_ROW_CONTINUATION_LINE_P (row),
14120 row->displays_text_p,
14121 row->ends_at_zv_p,
14122 row->fill_line_p,
14123 row->ends_in_middle_of_char_p,
14124 row->starts_in_middle_of_char_p,
14125 row->mouse_face_p,
14126 row->x,
14127 row->y,
14128 row->pixel_width,
14129 row->height,
14130 row->visible_height,
14131 row->ascent,
14132 row->phys_ascent);
14133 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14134 row->end.overlay_string_index,
14135 row->continuation_lines_width);
14136 fprintf (stderr, "%9d %5d\n",
14137 CHARPOS (row->start.string_pos),
14138 CHARPOS (row->end.string_pos));
14139 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14140 row->end.dpvec_index);
14143 if (glyphs > 1)
14145 int area;
14147 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14149 struct glyph *glyph = row->glyphs[area];
14150 struct glyph *glyph_end = glyph + row->used[area];
14152 /* Glyph for a line end in text. */
14153 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14154 ++glyph_end;
14156 if (glyph < glyph_end)
14157 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14159 for (; glyph < glyph_end; ++glyph)
14160 dump_glyph (row, glyph, area);
14163 else if (glyphs == 1)
14165 int area;
14167 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14169 char *s = (char *) alloca (row->used[area] + 1);
14170 int i;
14172 for (i = 0; i < row->used[area]; ++i)
14174 struct glyph *glyph = row->glyphs[area] + i;
14175 if (glyph->type == CHAR_GLYPH
14176 && glyph->u.ch < 0x80
14177 && glyph->u.ch >= ' ')
14178 s[i] = glyph->u.ch;
14179 else
14180 s[i] = '.';
14183 s[i] = '\0';
14184 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14190 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14191 Sdump_glyph_matrix, 0, 1, "p",
14192 doc: /* Dump the current matrix of the selected window to stderr.
14193 Shows contents of glyph row structures. With non-nil
14194 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14195 glyphs in short form, otherwise show glyphs in long form. */)
14196 (glyphs)
14197 Lisp_Object glyphs;
14199 struct window *w = XWINDOW (selected_window);
14200 struct buffer *buffer = XBUFFER (w->buffer);
14202 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14203 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14204 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14205 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14206 fprintf (stderr, "=============================================\n");
14207 dump_glyph_matrix (w->current_matrix,
14208 NILP (glyphs) ? 0 : XINT (glyphs));
14209 return Qnil;
14213 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14214 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14217 struct frame *f = XFRAME (selected_frame);
14218 dump_glyph_matrix (f->current_matrix, 1);
14219 return Qnil;
14223 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14224 doc: /* Dump glyph row ROW to stderr.
14225 GLYPH 0 means don't dump glyphs.
14226 GLYPH 1 means dump glyphs in short form.
14227 GLYPH > 1 or omitted means dump glyphs in long form. */)
14228 (row, glyphs)
14229 Lisp_Object row, glyphs;
14231 struct glyph_matrix *matrix;
14232 int vpos;
14234 CHECK_NUMBER (row);
14235 matrix = XWINDOW (selected_window)->current_matrix;
14236 vpos = XINT (row);
14237 if (vpos >= 0 && vpos < matrix->nrows)
14238 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14239 vpos,
14240 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14241 return Qnil;
14245 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14246 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14247 GLYPH 0 means don't dump glyphs.
14248 GLYPH 1 means dump glyphs in short form.
14249 GLYPH > 1 or omitted means dump glyphs in long form. */)
14250 (row, glyphs)
14251 Lisp_Object row, glyphs;
14253 struct frame *sf = SELECTED_FRAME ();
14254 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14255 int vpos;
14257 CHECK_NUMBER (row);
14258 vpos = XINT (row);
14259 if (vpos >= 0 && vpos < m->nrows)
14260 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14261 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14262 return Qnil;
14266 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14267 doc: /* Toggle tracing of redisplay.
14268 With ARG, turn tracing on if and only if ARG is positive. */)
14269 (arg)
14270 Lisp_Object arg;
14272 if (NILP (arg))
14273 trace_redisplay_p = !trace_redisplay_p;
14274 else
14276 arg = Fprefix_numeric_value (arg);
14277 trace_redisplay_p = XINT (arg) > 0;
14280 return Qnil;
14284 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14285 doc: /* Like `format', but print result to stderr.
14286 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14287 (nargs, args)
14288 int nargs;
14289 Lisp_Object *args;
14291 Lisp_Object s = Fformat (nargs, args);
14292 fprintf (stderr, "%s", SDATA (s));
14293 return Qnil;
14296 #endif /* GLYPH_DEBUG */
14300 /***********************************************************************
14301 Building Desired Matrix Rows
14302 ***********************************************************************/
14304 /* Return a temporary glyph row holding the glyphs of an overlay
14305 arrow. Only used for non-window-redisplay windows. */
14307 static struct glyph_row *
14308 get_overlay_arrow_glyph_row (w)
14309 struct window *w;
14311 struct frame *f = XFRAME (WINDOW_FRAME (w));
14312 struct buffer *buffer = XBUFFER (w->buffer);
14313 struct buffer *old = current_buffer;
14314 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
14315 int arrow_len = SCHARS (Voverlay_arrow_string);
14316 const unsigned char *arrow_end = arrow_string + arrow_len;
14317 const unsigned char *p;
14318 struct it it;
14319 int multibyte_p;
14320 int n_glyphs_before;
14322 set_buffer_temp (buffer);
14323 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14324 it.glyph_row->used[TEXT_AREA] = 0;
14325 SET_TEXT_POS (it.position, 0, 0);
14327 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14328 p = arrow_string;
14329 while (p < arrow_end)
14331 Lisp_Object face, ilisp;
14333 /* Get the next character. */
14334 if (multibyte_p)
14335 it.c = string_char_and_length (p, arrow_len, &it.len);
14336 else
14337 it.c = *p, it.len = 1;
14338 p += it.len;
14340 /* Get its face. */
14341 ilisp = make_number (p - arrow_string);
14342 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
14343 it.face_id = compute_char_face (f, it.c, face);
14345 /* Compute its width, get its glyphs. */
14346 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14347 SET_TEXT_POS (it.position, -1, -1);
14348 PRODUCE_GLYPHS (&it);
14350 /* If this character doesn't fit any more in the line, we have
14351 to remove some glyphs. */
14352 if (it.current_x > it.last_visible_x)
14354 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14355 break;
14359 set_buffer_temp (old);
14360 return it.glyph_row;
14364 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14365 glyphs are only inserted for terminal frames since we can't really
14366 win with truncation glyphs when partially visible glyphs are
14367 involved. Which glyphs to insert is determined by
14368 produce_special_glyphs. */
14370 static void
14371 insert_left_trunc_glyphs (it)
14372 struct it *it;
14374 struct it truncate_it;
14375 struct glyph *from, *end, *to, *toend;
14377 xassert (!FRAME_WINDOW_P (it->f));
14379 /* Get the truncation glyphs. */
14380 truncate_it = *it;
14381 truncate_it.current_x = 0;
14382 truncate_it.face_id = DEFAULT_FACE_ID;
14383 truncate_it.glyph_row = &scratch_glyph_row;
14384 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14385 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14386 truncate_it.object = make_number (0);
14387 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14389 /* Overwrite glyphs from IT with truncation glyphs. */
14390 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14391 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14392 to = it->glyph_row->glyphs[TEXT_AREA];
14393 toend = to + it->glyph_row->used[TEXT_AREA];
14395 while (from < end)
14396 *to++ = *from++;
14398 /* There may be padding glyphs left over. Overwrite them too. */
14399 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14401 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14402 while (from < end)
14403 *to++ = *from++;
14406 if (to > toend)
14407 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14411 /* Compute the pixel height and width of IT->glyph_row.
14413 Most of the time, ascent and height of a display line will be equal
14414 to the max_ascent and max_height values of the display iterator
14415 structure. This is not the case if
14417 1. We hit ZV without displaying anything. In this case, max_ascent
14418 and max_height will be zero.
14420 2. We have some glyphs that don't contribute to the line height.
14421 (The glyph row flag contributes_to_line_height_p is for future
14422 pixmap extensions).
14424 The first case is easily covered by using default values because in
14425 these cases, the line height does not really matter, except that it
14426 must not be zero. */
14428 static void
14429 compute_line_metrics (it)
14430 struct it *it;
14432 struct glyph_row *row = it->glyph_row;
14433 int area, i;
14435 if (FRAME_WINDOW_P (it->f))
14437 int i, min_y, max_y;
14439 /* The line may consist of one space only, that was added to
14440 place the cursor on it. If so, the row's height hasn't been
14441 computed yet. */
14442 if (row->height == 0)
14444 if (it->max_ascent + it->max_descent == 0)
14445 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14446 row->ascent = it->max_ascent;
14447 row->height = it->max_ascent + it->max_descent;
14448 row->phys_ascent = it->max_phys_ascent;
14449 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14452 /* Compute the width of this line. */
14453 row->pixel_width = row->x;
14454 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14455 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14457 xassert (row->pixel_width >= 0);
14458 xassert (row->ascent >= 0 && row->height > 0);
14460 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14461 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14463 /* If first line's physical ascent is larger than its logical
14464 ascent, use the physical ascent, and make the row taller.
14465 This makes accented characters fully visible. */
14466 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14467 && row->phys_ascent > row->ascent)
14469 row->height += row->phys_ascent - row->ascent;
14470 row->ascent = row->phys_ascent;
14473 /* Compute how much of the line is visible. */
14474 row->visible_height = row->height;
14476 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14477 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14479 if (row->y < min_y)
14480 row->visible_height -= min_y - row->y;
14481 if (row->y + row->height > max_y)
14482 row->visible_height -= row->y + row->height - max_y;
14484 else
14486 row->pixel_width = row->used[TEXT_AREA];
14487 if (row->continued_p)
14488 row->pixel_width -= it->continuation_pixel_width;
14489 else if (row->truncated_on_right_p)
14490 row->pixel_width -= it->truncation_pixel_width;
14491 row->ascent = row->phys_ascent = 0;
14492 row->height = row->phys_height = row->visible_height = 1;
14495 /* Compute a hash code for this row. */
14496 row->hash = 0;
14497 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14498 for (i = 0; i < row->used[area]; ++i)
14499 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14500 + row->glyphs[area][i].u.val
14501 + row->glyphs[area][i].face_id
14502 + row->glyphs[area][i].padding_p
14503 + (row->glyphs[area][i].type << 2));
14505 it->max_ascent = it->max_descent = 0;
14506 it->max_phys_ascent = it->max_phys_descent = 0;
14510 /* Append one space to the glyph row of iterator IT if doing a
14511 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14512 space have the default face, otherwise let it have the same face as
14513 IT->face_id. Value is non-zero if a space was added.
14515 This function is called to make sure that there is always one glyph
14516 at the end of a glyph row that the cursor can be set on under
14517 window-systems. (If there weren't such a glyph we would not know
14518 how wide and tall a box cursor should be displayed).
14520 At the same time this space let's a nicely handle clearing to the
14521 end of the line if the row ends in italic text. */
14523 static int
14524 append_space (it, default_face_p)
14525 struct it *it;
14526 int default_face_p;
14528 if (FRAME_WINDOW_P (it->f))
14530 int n = it->glyph_row->used[TEXT_AREA];
14532 if (it->glyph_row->glyphs[TEXT_AREA] + n
14533 < it->glyph_row->glyphs[1 + TEXT_AREA])
14535 /* Save some values that must not be changed.
14536 Must save IT->c and IT->len because otherwise
14537 ITERATOR_AT_END_P wouldn't work anymore after
14538 append_space has been called. */
14539 enum display_element_type saved_what = it->what;
14540 int saved_c = it->c, saved_len = it->len;
14541 int saved_x = it->current_x;
14542 int saved_face_id = it->face_id;
14543 struct text_pos saved_pos;
14544 Lisp_Object saved_object;
14545 struct face *face;
14547 saved_object = it->object;
14548 saved_pos = it->position;
14550 it->what = IT_CHARACTER;
14551 bzero (&it->position, sizeof it->position);
14552 it->object = make_number (0);
14553 it->c = ' ';
14554 it->len = 1;
14556 if (default_face_p)
14557 it->face_id = DEFAULT_FACE_ID;
14558 else if (it->face_before_selective_p)
14559 it->face_id = it->saved_face_id;
14560 face = FACE_FROM_ID (it->f, it->face_id);
14561 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14563 PRODUCE_GLYPHS (it);
14565 it->current_x = saved_x;
14566 it->object = saved_object;
14567 it->position = saved_pos;
14568 it->what = saved_what;
14569 it->face_id = saved_face_id;
14570 it->len = saved_len;
14571 it->c = saved_c;
14572 return 1;
14576 return 0;
14580 /* Extend the face of the last glyph in the text area of IT->glyph_row
14581 to the end of the display line. Called from display_line.
14582 If the glyph row is empty, add a space glyph to it so that we
14583 know the face to draw. Set the glyph row flag fill_line_p. */
14585 static void
14586 extend_face_to_end_of_line (it)
14587 struct it *it;
14589 struct face *face;
14590 struct frame *f = it->f;
14592 /* If line is already filled, do nothing. */
14593 if (it->current_x >= it->last_visible_x)
14594 return;
14596 /* Face extension extends the background and box of IT->face_id
14597 to the end of the line. If the background equals the background
14598 of the frame, we don't have to do anything. */
14599 if (it->face_before_selective_p)
14600 face = FACE_FROM_ID (it->f, it->saved_face_id);
14601 else
14602 face = FACE_FROM_ID (f, it->face_id);
14604 if (FRAME_WINDOW_P (f)
14605 && face->box == FACE_NO_BOX
14606 && face->background == FRAME_BACKGROUND_PIXEL (f)
14607 && !face->stipple)
14608 return;
14610 /* Set the glyph row flag indicating that the face of the last glyph
14611 in the text area has to be drawn to the end of the text area. */
14612 it->glyph_row->fill_line_p = 1;
14614 /* If current character of IT is not ASCII, make sure we have the
14615 ASCII face. This will be automatically undone the next time
14616 get_next_display_element returns a multibyte character. Note
14617 that the character will always be single byte in unibyte text. */
14618 if (!SINGLE_BYTE_CHAR_P (it->c))
14620 it->face_id = FACE_FOR_CHAR (f, face, 0);
14623 if (FRAME_WINDOW_P (f))
14625 /* If the row is empty, add a space with the current face of IT,
14626 so that we know which face to draw. */
14627 if (it->glyph_row->used[TEXT_AREA] == 0)
14629 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14630 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14631 it->glyph_row->used[TEXT_AREA] = 1;
14634 else
14636 /* Save some values that must not be changed. */
14637 int saved_x = it->current_x;
14638 struct text_pos saved_pos;
14639 Lisp_Object saved_object;
14640 enum display_element_type saved_what = it->what;
14641 int saved_face_id = it->face_id;
14643 saved_object = it->object;
14644 saved_pos = it->position;
14646 it->what = IT_CHARACTER;
14647 bzero (&it->position, sizeof it->position);
14648 it->object = make_number (0);
14649 it->c = ' ';
14650 it->len = 1;
14651 it->face_id = face->id;
14653 PRODUCE_GLYPHS (it);
14655 while (it->current_x <= it->last_visible_x)
14656 PRODUCE_GLYPHS (it);
14658 /* Don't count these blanks really. It would let us insert a left
14659 truncation glyph below and make us set the cursor on them, maybe. */
14660 it->current_x = saved_x;
14661 it->object = saved_object;
14662 it->position = saved_pos;
14663 it->what = saved_what;
14664 it->face_id = saved_face_id;
14669 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14670 trailing whitespace. */
14672 static int
14673 trailing_whitespace_p (charpos)
14674 int charpos;
14676 int bytepos = CHAR_TO_BYTE (charpos);
14677 int c = 0;
14679 while (bytepos < ZV_BYTE
14680 && (c = FETCH_CHAR (bytepos),
14681 c == ' ' || c == '\t'))
14682 ++bytepos;
14684 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14686 if (bytepos != PT_BYTE)
14687 return 1;
14689 return 0;
14693 /* Highlight trailing whitespace, if any, in ROW. */
14695 void
14696 highlight_trailing_whitespace (f, row)
14697 struct frame *f;
14698 struct glyph_row *row;
14700 int used = row->used[TEXT_AREA];
14702 if (used)
14704 struct glyph *start = row->glyphs[TEXT_AREA];
14705 struct glyph *glyph = start + used - 1;
14707 /* Skip over glyphs inserted to display the cursor at the
14708 end of a line, for extending the face of the last glyph
14709 to the end of the line on terminals, and for truncation
14710 and continuation glyphs. */
14711 while (glyph >= start
14712 && glyph->type == CHAR_GLYPH
14713 && INTEGERP (glyph->object))
14714 --glyph;
14716 /* If last glyph is a space or stretch, and it's trailing
14717 whitespace, set the face of all trailing whitespace glyphs in
14718 IT->glyph_row to `trailing-whitespace'. */
14719 if (glyph >= start
14720 && BUFFERP (glyph->object)
14721 && (glyph->type == STRETCH_GLYPH
14722 || (glyph->type == CHAR_GLYPH
14723 && glyph->u.ch == ' '))
14724 && trailing_whitespace_p (glyph->charpos))
14726 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14728 while (glyph >= start
14729 && BUFFERP (glyph->object)
14730 && (glyph->type == STRETCH_GLYPH
14731 || (glyph->type == CHAR_GLYPH
14732 && glyph->u.ch == ' ')))
14733 (glyph--)->face_id = face_id;
14739 /* Value is non-zero if glyph row ROW in window W should be
14740 used to hold the cursor. */
14742 static int
14743 cursor_row_p (w, row)
14744 struct window *w;
14745 struct glyph_row *row;
14747 int cursor_row_p = 1;
14749 if (PT == MATRIX_ROW_END_CHARPOS (row))
14751 /* If the row ends with a newline from a string, we don't want
14752 the cursor there (if the row is continued it doesn't end in a
14753 newline). */
14754 if (CHARPOS (row->end.string_pos) >= 0
14755 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14756 cursor_row_p = row->continued_p;
14758 /* If the row ends at ZV, display the cursor at the end of that
14759 row instead of at the start of the row below. */
14760 else if (row->ends_at_zv_p)
14761 cursor_row_p = 1;
14762 else
14763 cursor_row_p = 0;
14766 return cursor_row_p;
14770 /* Construct the glyph row IT->glyph_row in the desired matrix of
14771 IT->w from text at the current position of IT. See dispextern.h
14772 for an overview of struct it. Value is non-zero if
14773 IT->glyph_row displays text, as opposed to a line displaying ZV
14774 only. */
14776 static int
14777 display_line (it)
14778 struct it *it;
14780 struct glyph_row *row = it->glyph_row;
14782 /* We always start displaying at hpos zero even if hscrolled. */
14783 xassert (it->hpos == 0 && it->current_x == 0);
14785 /* We must not display in a row that's not a text row. */
14786 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14787 < it->w->desired_matrix->nrows);
14789 /* Is IT->w showing the region? */
14790 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14792 /* Clear the result glyph row and enable it. */
14793 prepare_desired_row (row);
14795 row->y = it->current_y;
14796 row->start = it->start;
14797 row->continuation_lines_width = it->continuation_lines_width;
14798 row->displays_text_p = 1;
14799 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14800 it->starts_in_middle_of_char_p = 0;
14802 /* Arrange the overlays nicely for our purposes. Usually, we call
14803 display_line on only one line at a time, in which case this
14804 can't really hurt too much, or we call it on lines which appear
14805 one after another in the buffer, in which case all calls to
14806 recenter_overlay_lists but the first will be pretty cheap. */
14807 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14809 /* Move over display elements that are not visible because we are
14810 hscrolled. This may stop at an x-position < IT->first_visible_x
14811 if the first glyph is partially visible or if we hit a line end. */
14812 if (it->current_x < it->first_visible_x)
14813 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14814 MOVE_TO_POS | MOVE_TO_X);
14816 /* Get the initial row height. This is either the height of the
14817 text hscrolled, if there is any, or zero. */
14818 row->ascent = it->max_ascent;
14819 row->height = it->max_ascent + it->max_descent;
14820 row->phys_ascent = it->max_phys_ascent;
14821 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14823 /* Loop generating characters. The loop is left with IT on the next
14824 character to display. */
14825 while (1)
14827 int n_glyphs_before, hpos_before, x_before;
14828 int x, i, nglyphs;
14829 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14831 /* Retrieve the next thing to display. Value is zero if end of
14832 buffer reached. */
14833 if (!get_next_display_element (it))
14835 /* Maybe add a space at the end of this line that is used to
14836 display the cursor there under X. Set the charpos of the
14837 first glyph of blank lines not corresponding to any text
14838 to -1. */
14839 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14840 || row->used[TEXT_AREA] == 0)
14842 row->glyphs[TEXT_AREA]->charpos = -1;
14843 row->displays_text_p = 0;
14845 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14846 && (!MINI_WINDOW_P (it->w)
14847 || (minibuf_level && EQ (it->window, minibuf_window))))
14848 row->indicate_empty_line_p = 1;
14851 it->continuation_lines_width = 0;
14852 row->ends_at_zv_p = 1;
14853 break;
14856 /* Now, get the metrics of what we want to display. This also
14857 generates glyphs in `row' (which is IT->glyph_row). */
14858 n_glyphs_before = row->used[TEXT_AREA];
14859 x = it->current_x;
14861 /* Remember the line height so far in case the next element doesn't
14862 fit on the line. */
14863 if (!it->truncate_lines_p)
14865 ascent = it->max_ascent;
14866 descent = it->max_descent;
14867 phys_ascent = it->max_phys_ascent;
14868 phys_descent = it->max_phys_descent;
14871 PRODUCE_GLYPHS (it);
14873 /* If this display element was in marginal areas, continue with
14874 the next one. */
14875 if (it->area != TEXT_AREA)
14877 row->ascent = max (row->ascent, it->max_ascent);
14878 row->height = max (row->height, it->max_ascent + it->max_descent);
14879 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14880 row->phys_height = max (row->phys_height,
14881 it->max_phys_ascent + it->max_phys_descent);
14882 set_iterator_to_next (it, 1);
14883 continue;
14886 /* Does the display element fit on the line? If we truncate
14887 lines, we should draw past the right edge of the window. If
14888 we don't truncate, we want to stop so that we can display the
14889 continuation glyph before the right margin. If lines are
14890 continued, there are two possible strategies for characters
14891 resulting in more than 1 glyph (e.g. tabs): Display as many
14892 glyphs as possible in this line and leave the rest for the
14893 continuation line, or display the whole element in the next
14894 line. Original redisplay did the former, so we do it also. */
14895 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14896 hpos_before = it->hpos;
14897 x_before = x;
14899 if (/* Not a newline. */
14900 nglyphs > 0
14901 /* Glyphs produced fit entirely in the line. */
14902 && it->current_x < it->last_visible_x)
14904 it->hpos += nglyphs;
14905 row->ascent = max (row->ascent, it->max_ascent);
14906 row->height = max (row->height, it->max_ascent + it->max_descent);
14907 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14908 row->phys_height = max (row->phys_height,
14909 it->max_phys_ascent + it->max_phys_descent);
14910 if (it->current_x - it->pixel_width < it->first_visible_x)
14911 row->x = x - it->first_visible_x;
14913 else
14915 int new_x;
14916 struct glyph *glyph;
14918 for (i = 0; i < nglyphs; ++i, x = new_x)
14920 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14921 new_x = x + glyph->pixel_width;
14923 if (/* Lines are continued. */
14924 !it->truncate_lines_p
14925 && (/* Glyph doesn't fit on the line. */
14926 new_x > it->last_visible_x
14927 /* Or it fits exactly on a window system frame. */
14928 || (new_x == it->last_visible_x
14929 && FRAME_WINDOW_P (it->f))))
14931 /* End of a continued line. */
14933 if (it->hpos == 0
14934 || (new_x == it->last_visible_x
14935 && FRAME_WINDOW_P (it->f)))
14937 /* Current glyph is the only one on the line or
14938 fits exactly on the line. We must continue
14939 the line because we can't draw the cursor
14940 after the glyph. */
14941 row->continued_p = 1;
14942 it->current_x = new_x;
14943 it->continuation_lines_width += new_x;
14944 ++it->hpos;
14945 if (i == nglyphs - 1)
14947 set_iterator_to_next (it, 1);
14948 #ifdef HAVE_WINDOW_SYSTEM
14949 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14951 get_next_display_element (it);
14952 if (ITERATOR_AT_END_OF_LINE_P (it))
14954 row->continued_p = 0;
14955 row->exact_window_width_line_p = 1;
14958 #endif /* HAVE_WINDOW_SYSTEM */
14961 else if (CHAR_GLYPH_PADDING_P (*glyph)
14962 && !FRAME_WINDOW_P (it->f))
14964 /* A padding glyph that doesn't fit on this line.
14965 This means the whole character doesn't fit
14966 on the line. */
14967 row->used[TEXT_AREA] = n_glyphs_before;
14969 /* Fill the rest of the row with continuation
14970 glyphs like in 20.x. */
14971 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14972 < row->glyphs[1 + TEXT_AREA])
14973 produce_special_glyphs (it, IT_CONTINUATION);
14975 row->continued_p = 1;
14976 it->current_x = x_before;
14977 it->continuation_lines_width += x_before;
14979 /* Restore the height to what it was before the
14980 element not fitting on the line. */
14981 it->max_ascent = ascent;
14982 it->max_descent = descent;
14983 it->max_phys_ascent = phys_ascent;
14984 it->max_phys_descent = phys_descent;
14986 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14988 /* A TAB that extends past the right edge of the
14989 window. This produces a single glyph on
14990 window system frames. We leave the glyph in
14991 this row and let it fill the row, but don't
14992 consume the TAB. */
14993 it->continuation_lines_width += it->last_visible_x;
14994 row->ends_in_middle_of_char_p = 1;
14995 row->continued_p = 1;
14996 glyph->pixel_width = it->last_visible_x - x;
14997 it->starts_in_middle_of_char_p = 1;
14999 else
15001 /* Something other than a TAB that draws past
15002 the right edge of the window. Restore
15003 positions to values before the element. */
15004 row->used[TEXT_AREA] = n_glyphs_before + i;
15006 /* Display continuation glyphs. */
15007 if (!FRAME_WINDOW_P (it->f))
15008 produce_special_glyphs (it, IT_CONTINUATION);
15009 row->continued_p = 1;
15011 it->continuation_lines_width += x;
15013 if (nglyphs > 1 && i > 0)
15015 row->ends_in_middle_of_char_p = 1;
15016 it->starts_in_middle_of_char_p = 1;
15019 /* Restore the height to what it was before the
15020 element not fitting on the line. */
15021 it->max_ascent = ascent;
15022 it->max_descent = descent;
15023 it->max_phys_ascent = phys_ascent;
15024 it->max_phys_descent = phys_descent;
15027 break;
15029 else if (new_x > it->first_visible_x)
15031 /* Increment number of glyphs actually displayed. */
15032 ++it->hpos;
15034 if (x < it->first_visible_x)
15035 /* Glyph is partially visible, i.e. row starts at
15036 negative X position. */
15037 row->x = x - it->first_visible_x;
15039 else
15041 /* Glyph is completely off the left margin of the
15042 window. This should not happen because of the
15043 move_it_in_display_line at the start of this
15044 function, unless the text display area of the
15045 window is empty. */
15046 xassert (it->first_visible_x <= it->last_visible_x);
15050 row->ascent = max (row->ascent, it->max_ascent);
15051 row->height = max (row->height, it->max_ascent + it->max_descent);
15052 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15053 row->phys_height = max (row->phys_height,
15054 it->max_phys_ascent + it->max_phys_descent);
15056 /* End of this display line if row is continued. */
15057 if (row->continued_p)
15058 break;
15061 at_end_of_line:
15062 /* Is this a line end? If yes, we're also done, after making
15063 sure that a non-default face is extended up to the right
15064 margin of the window. */
15065 if (ITERATOR_AT_END_OF_LINE_P (it))
15067 int used_before = row->used[TEXT_AREA];
15069 row->ends_in_newline_from_string_p = STRINGP (it->object);
15071 #ifdef HAVE_WINDOW_SYSTEM
15072 /* Add a space at the end of the line that is used to
15073 display the cursor there. */
15074 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15075 append_space (it, 0);
15076 #endif /* HAVE_WINDOW_SYSTEM */
15078 /* Extend the face to the end of the line. */
15079 extend_face_to_end_of_line (it);
15081 /* Make sure we have the position. */
15082 if (used_before == 0)
15083 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15085 /* Consume the line end. This skips over invisible lines. */
15086 set_iterator_to_next (it, 1);
15087 it->continuation_lines_width = 0;
15088 break;
15091 /* Proceed with next display element. Note that this skips
15092 over lines invisible because of selective display. */
15093 set_iterator_to_next (it, 1);
15095 /* If we truncate lines, we are done when the last displayed
15096 glyphs reach past the right margin of the window. */
15097 if (it->truncate_lines_p
15098 && (FRAME_WINDOW_P (it->f)
15099 ? (it->current_x >= it->last_visible_x)
15100 : (it->current_x > it->last_visible_x)))
15102 /* Maybe add truncation glyphs. */
15103 if (!FRAME_WINDOW_P (it->f))
15105 int i, n;
15107 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15108 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15109 break;
15111 for (n = row->used[TEXT_AREA]; i < n; ++i)
15113 row->used[TEXT_AREA] = i;
15114 produce_special_glyphs (it, IT_TRUNCATION);
15117 #ifdef HAVE_WINDOW_SYSTEM
15118 else
15120 /* Don't truncate if we can overflow newline into fringe. */
15121 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15123 get_next_display_element (it);
15124 if (ITERATOR_AT_END_OF_LINE_P (it))
15126 row->exact_window_width_line_p = 1;
15127 goto at_end_of_line;
15131 #endif /* HAVE_WINDOW_SYSTEM */
15133 row->truncated_on_right_p = 1;
15134 it->continuation_lines_width = 0;
15135 reseat_at_next_visible_line_start (it, 0);
15136 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15137 it->hpos = hpos_before;
15138 it->current_x = x_before;
15139 break;
15143 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15144 at the left window margin. */
15145 if (it->first_visible_x
15146 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15148 if (!FRAME_WINDOW_P (it->f))
15149 insert_left_trunc_glyphs (it);
15150 row->truncated_on_left_p = 1;
15153 /* If the start of this line is the overlay arrow-position, then
15154 mark this glyph row as the one containing the overlay arrow.
15155 This is clearly a mess with variable size fonts. It would be
15156 better to let it be displayed like cursors under X. */
15157 if (MARKERP (Voverlay_arrow_position)
15158 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
15159 && (MATRIX_ROW_START_CHARPOS (row)
15160 == marker_position (Voverlay_arrow_position))
15161 && STRINGP (Voverlay_arrow_string)
15162 && ! overlay_arrow_seen)
15164 /* Overlay arrow in window redisplay is a fringe bitmap. */
15165 if (!FRAME_WINDOW_P (it->f))
15167 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
15168 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15169 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15170 struct glyph *p = row->glyphs[TEXT_AREA];
15171 struct glyph *p2, *end;
15173 /* Copy the arrow glyphs. */
15174 while (glyph < arrow_end)
15175 *p++ = *glyph++;
15177 /* Throw away padding glyphs. */
15178 p2 = p;
15179 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15180 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15181 ++p2;
15182 if (p2 > p)
15184 while (p2 < end)
15185 *p++ = *p2++;
15186 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15190 overlay_arrow_seen = 1;
15191 row->overlay_arrow_p = 1;
15194 /* Compute pixel dimensions of this line. */
15195 compute_line_metrics (it);
15197 /* Remember the position at which this line ends. */
15198 row->end = it->current;
15200 /* Maybe set the cursor. */
15201 if (it->w->cursor.vpos < 0
15202 && PT >= MATRIX_ROW_START_CHARPOS (row)
15203 && PT <= MATRIX_ROW_END_CHARPOS (row)
15204 && cursor_row_p (it->w, row))
15205 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15207 /* Highlight trailing whitespace. */
15208 if (!NILP (Vshow_trailing_whitespace))
15209 highlight_trailing_whitespace (it->f, it->glyph_row);
15211 /* Prepare for the next line. This line starts horizontally at (X
15212 HPOS) = (0 0). Vertical positions are incremented. As a
15213 convenience for the caller, IT->glyph_row is set to the next
15214 row to be used. */
15215 it->current_x = it->hpos = 0;
15216 it->current_y += row->height;
15217 ++it->vpos;
15218 ++it->glyph_row;
15219 it->start = it->current;
15220 return row->displays_text_p;
15225 /***********************************************************************
15226 Menu Bar
15227 ***********************************************************************/
15229 /* Redisplay the menu bar in the frame for window W.
15231 The menu bar of X frames that don't have X toolkit support is
15232 displayed in a special window W->frame->menu_bar_window.
15234 The menu bar of terminal frames is treated specially as far as
15235 glyph matrices are concerned. Menu bar lines are not part of
15236 windows, so the update is done directly on the frame matrix rows
15237 for the menu bar. */
15239 static void
15240 display_menu_bar (w)
15241 struct window *w;
15243 struct frame *f = XFRAME (WINDOW_FRAME (w));
15244 struct it it;
15245 Lisp_Object items;
15246 int i;
15248 /* Don't do all this for graphical frames. */
15249 #ifdef HAVE_NTGUI
15250 if (!NILP (Vwindow_system))
15251 return;
15252 #endif
15253 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15254 if (FRAME_X_P (f))
15255 return;
15256 #endif
15257 #ifdef MAC_OS
15258 if (FRAME_MAC_P (f))
15259 return;
15260 #endif
15262 #ifdef USE_X_TOOLKIT
15263 xassert (!FRAME_WINDOW_P (f));
15264 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15265 it.first_visible_x = 0;
15266 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15267 #else /* not USE_X_TOOLKIT */
15268 if (FRAME_WINDOW_P (f))
15270 /* Menu bar lines are displayed in the desired matrix of the
15271 dummy window menu_bar_window. */
15272 struct window *menu_w;
15273 xassert (WINDOWP (f->menu_bar_window));
15274 menu_w = XWINDOW (f->menu_bar_window);
15275 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15276 MENU_FACE_ID);
15277 it.first_visible_x = 0;
15278 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15280 else
15282 /* This is a TTY frame, i.e. character hpos/vpos are used as
15283 pixel x/y. */
15284 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15285 MENU_FACE_ID);
15286 it.first_visible_x = 0;
15287 it.last_visible_x = FRAME_COLS (f);
15289 #endif /* not USE_X_TOOLKIT */
15291 if (! mode_line_inverse_video)
15292 /* Force the menu-bar to be displayed in the default face. */
15293 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15295 /* Clear all rows of the menu bar. */
15296 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15298 struct glyph_row *row = it.glyph_row + i;
15299 clear_glyph_row (row);
15300 row->enabled_p = 1;
15301 row->full_width_p = 1;
15304 /* Display all items of the menu bar. */
15305 items = FRAME_MENU_BAR_ITEMS (it.f);
15306 for (i = 0; i < XVECTOR (items)->size; i += 4)
15308 Lisp_Object string;
15310 /* Stop at nil string. */
15311 string = AREF (items, i + 1);
15312 if (NILP (string))
15313 break;
15315 /* Remember where item was displayed. */
15316 AREF (items, i + 3) = make_number (it.hpos);
15318 /* Display the item, pad with one space. */
15319 if (it.current_x < it.last_visible_x)
15320 display_string (NULL, string, Qnil, 0, 0, &it,
15321 SCHARS (string) + 1, 0, 0, -1);
15324 /* Fill out the line with spaces. */
15325 if (it.current_x < it.last_visible_x)
15326 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15328 /* Compute the total height of the lines. */
15329 compute_line_metrics (&it);
15334 /***********************************************************************
15335 Mode Line
15336 ***********************************************************************/
15338 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15339 FORCE is non-zero, redisplay mode lines unconditionally.
15340 Otherwise, redisplay only mode lines that are garbaged. Value is
15341 the number of windows whose mode lines were redisplayed. */
15343 static int
15344 redisplay_mode_lines (window, force)
15345 Lisp_Object window;
15346 int force;
15348 int nwindows = 0;
15350 while (!NILP (window))
15352 struct window *w = XWINDOW (window);
15354 if (WINDOWP (w->hchild))
15355 nwindows += redisplay_mode_lines (w->hchild, force);
15356 else if (WINDOWP (w->vchild))
15357 nwindows += redisplay_mode_lines (w->vchild, force);
15358 else if (force
15359 || FRAME_GARBAGED_P (XFRAME (w->frame))
15360 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15362 struct text_pos lpoint;
15363 struct buffer *old = current_buffer;
15365 /* Set the window's buffer for the mode line display. */
15366 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15367 set_buffer_internal_1 (XBUFFER (w->buffer));
15369 /* Point refers normally to the selected window. For any
15370 other window, set up appropriate value. */
15371 if (!EQ (window, selected_window))
15373 struct text_pos pt;
15375 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15376 if (CHARPOS (pt) < BEGV)
15377 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15378 else if (CHARPOS (pt) > (ZV - 1))
15379 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15380 else
15381 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15384 /* Display mode lines. */
15385 clear_glyph_matrix (w->desired_matrix);
15386 if (display_mode_lines (w))
15388 ++nwindows;
15389 w->must_be_updated_p = 1;
15392 /* Restore old settings. */
15393 set_buffer_internal_1 (old);
15394 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15397 window = w->next;
15400 return nwindows;
15404 /* Display the mode and/or top line of window W. Value is the number
15405 of mode lines displayed. */
15407 static int
15408 display_mode_lines (w)
15409 struct window *w;
15411 Lisp_Object old_selected_window, old_selected_frame;
15412 int n = 0;
15414 old_selected_frame = selected_frame;
15415 selected_frame = w->frame;
15416 old_selected_window = selected_window;
15417 XSETWINDOW (selected_window, w);
15419 /* These will be set while the mode line specs are processed. */
15420 line_number_displayed = 0;
15421 w->column_number_displayed = Qnil;
15423 if (WINDOW_WANTS_MODELINE_P (w))
15425 struct window *sel_w = XWINDOW (old_selected_window);
15427 /* Select mode line face based on the real selected window. */
15428 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15429 current_buffer->mode_line_format);
15430 ++n;
15433 if (WINDOW_WANTS_HEADER_LINE_P (w))
15435 display_mode_line (w, HEADER_LINE_FACE_ID,
15436 current_buffer->header_line_format);
15437 ++n;
15440 selected_frame = old_selected_frame;
15441 selected_window = old_selected_window;
15442 return n;
15446 /* Display mode or top line of window W. FACE_ID specifies which line
15447 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15448 FORMAT is the mode line format to display. Value is the pixel
15449 height of the mode line displayed. */
15451 static int
15452 display_mode_line (w, face_id, format)
15453 struct window *w;
15454 enum face_id face_id;
15455 Lisp_Object format;
15457 struct it it;
15458 struct face *face;
15460 init_iterator (&it, w, -1, -1, NULL, face_id);
15461 prepare_desired_row (it.glyph_row);
15463 if (! mode_line_inverse_video)
15464 /* Force the mode-line to be displayed in the default face. */
15465 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15467 /* Temporarily make frame's keyboard the current kboard so that
15468 kboard-local variables in the mode_line_format will get the right
15469 values. */
15470 push_frame_kboard (it.f);
15471 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15472 pop_frame_kboard ();
15474 /* Fill up with spaces. */
15475 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15477 compute_line_metrics (&it);
15478 it.glyph_row->full_width_p = 1;
15479 it.glyph_row->mode_line_p = 1;
15480 it.glyph_row->continued_p = 0;
15481 it.glyph_row->truncated_on_left_p = 0;
15482 it.glyph_row->truncated_on_right_p = 0;
15484 /* Make a 3D mode-line have a shadow at its right end. */
15485 face = FACE_FROM_ID (it.f, face_id);
15486 extend_face_to_end_of_line (&it);
15487 if (face->box != FACE_NO_BOX)
15489 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15490 + it.glyph_row->used[TEXT_AREA] - 1);
15491 last->right_box_line_p = 1;
15494 return it.glyph_row->height;
15497 /* Alist that caches the results of :propertize.
15498 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15499 Lisp_Object mode_line_proptrans_alist;
15501 /* List of strings making up the mode-line. */
15502 Lisp_Object mode_line_string_list;
15504 /* Base face property when building propertized mode line string. */
15505 static Lisp_Object mode_line_string_face;
15506 static Lisp_Object mode_line_string_face_prop;
15509 /* Contribute ELT to the mode line for window IT->w. How it
15510 translates into text depends on its data type.
15512 IT describes the display environment in which we display, as usual.
15514 DEPTH is the depth in recursion. It is used to prevent
15515 infinite recursion here.
15517 FIELD_WIDTH is the number of characters the display of ELT should
15518 occupy in the mode line, and PRECISION is the maximum number of
15519 characters to display from ELT's representation. See
15520 display_string for details.
15522 Returns the hpos of the end of the text generated by ELT.
15524 PROPS is a property list to add to any string we encounter.
15526 If RISKY is nonzero, remove (disregard) any properties in any string
15527 we encounter, and ignore :eval and :propertize.
15529 If the global variable `frame_title_ptr' is non-NULL, then the output
15530 is passed to `store_frame_title' instead of `display_string'. */
15532 static int
15533 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15534 struct it *it;
15535 int depth;
15536 int field_width, precision;
15537 Lisp_Object elt, props;
15538 int risky;
15540 int n = 0, field, prec;
15541 int literal = 0;
15543 tail_recurse:
15544 if (depth > 100)
15545 elt = build_string ("*too-deep*");
15547 depth++;
15549 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15551 case Lisp_String:
15553 /* A string: output it and check for %-constructs within it. */
15554 unsigned char c;
15555 const unsigned char *this, *lisp_string;
15557 if (!NILP (props) || risky)
15559 Lisp_Object oprops, aelt;
15560 oprops = Ftext_properties_at (make_number (0), elt);
15562 if (NILP (Fequal (props, oprops)) || risky)
15564 /* If the starting string has properties,
15565 merge the specified ones onto the existing ones. */
15566 if (! NILP (oprops) && !risky)
15568 Lisp_Object tem;
15570 oprops = Fcopy_sequence (oprops);
15571 tem = props;
15572 while (CONSP (tem))
15574 oprops = Fplist_put (oprops, XCAR (tem),
15575 XCAR (XCDR (tem)));
15576 tem = XCDR (XCDR (tem));
15578 props = oprops;
15581 aelt = Fassoc (elt, mode_line_proptrans_alist);
15582 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15584 mode_line_proptrans_alist
15585 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15586 elt = XCAR (aelt);
15588 else
15590 Lisp_Object tem;
15592 elt = Fcopy_sequence (elt);
15593 Fset_text_properties (make_number (0), Flength (elt),
15594 props, elt);
15595 /* Add this item to mode_line_proptrans_alist. */
15596 mode_line_proptrans_alist
15597 = Fcons (Fcons (elt, props),
15598 mode_line_proptrans_alist);
15599 /* Truncate mode_line_proptrans_alist
15600 to at most 50 elements. */
15601 tem = Fnthcdr (make_number (50),
15602 mode_line_proptrans_alist);
15603 if (! NILP (tem))
15604 XSETCDR (tem, Qnil);
15609 this = SDATA (elt);
15610 lisp_string = this;
15612 if (literal)
15614 prec = precision - n;
15615 if (frame_title_ptr)
15616 n += store_frame_title (SDATA (elt), -1, prec);
15617 else if (!NILP (mode_line_string_list))
15618 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15619 else
15620 n += display_string (NULL, elt, Qnil, 0, 0, it,
15621 0, prec, 0, STRING_MULTIBYTE (elt));
15623 break;
15626 while ((precision <= 0 || n < precision)
15627 && *this
15628 && (frame_title_ptr
15629 || !NILP (mode_line_string_list)
15630 || it->current_x < it->last_visible_x))
15632 const unsigned char *last = this;
15634 /* Advance to end of string or next format specifier. */
15635 while ((c = *this++) != '\0' && c != '%')
15638 if (this - 1 != last)
15640 /* Output to end of string or up to '%'. Field width
15641 is length of string. Don't output more than
15642 PRECISION allows us. */
15643 --this;
15645 prec = chars_in_text (last, this - last);
15646 if (precision > 0 && prec > precision - n)
15647 prec = precision - n;
15649 if (frame_title_ptr)
15650 n += store_frame_title (last, 0, prec);
15651 else if (!NILP (mode_line_string_list))
15653 int bytepos = last - lisp_string;
15654 int charpos = string_byte_to_char (elt, bytepos);
15655 n += store_mode_line_string (NULL,
15656 Fsubstring (elt, make_number (charpos),
15657 make_number (charpos + prec)),
15658 0, 0, 0, Qnil);
15660 else
15662 int bytepos = last - lisp_string;
15663 int charpos = string_byte_to_char (elt, bytepos);
15664 n += display_string (NULL, elt, Qnil, 0, charpos,
15665 it, 0, prec, 0,
15666 STRING_MULTIBYTE (elt));
15669 else /* c == '%' */
15671 const unsigned char *percent_position = this;
15673 /* Get the specified minimum width. Zero means
15674 don't pad. */
15675 field = 0;
15676 while ((c = *this++) >= '0' && c <= '9')
15677 field = field * 10 + c - '0';
15679 /* Don't pad beyond the total padding allowed. */
15680 if (field_width - n > 0 && field > field_width - n)
15681 field = field_width - n;
15683 /* Note that either PRECISION <= 0 or N < PRECISION. */
15684 prec = precision - n;
15686 if (c == 'M')
15687 n += display_mode_element (it, depth, field, prec,
15688 Vglobal_mode_string, props,
15689 risky);
15690 else if (c != 0)
15692 int multibyte;
15693 int bytepos, charpos;
15694 unsigned char *spec;
15696 bytepos = percent_position - lisp_string;
15697 charpos = (STRING_MULTIBYTE (elt)
15698 ? string_byte_to_char (elt, bytepos)
15699 : bytepos);
15701 spec
15702 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15704 if (frame_title_ptr)
15705 n += store_frame_title (spec, field, prec);
15706 else if (!NILP (mode_line_string_list))
15708 int len = strlen (spec);
15709 Lisp_Object tem = make_string (spec, len);
15710 props = Ftext_properties_at (make_number (charpos), elt);
15711 /* Should only keep face property in props */
15712 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15714 else
15716 int nglyphs_before, nwritten;
15718 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15719 nwritten = display_string (spec, Qnil, elt,
15720 charpos, 0, it,
15721 field, prec, 0,
15722 multibyte);
15724 /* Assign to the glyphs written above the
15725 string where the `%x' came from, position
15726 of the `%'. */
15727 if (nwritten > 0)
15729 struct glyph *glyph
15730 = (it->glyph_row->glyphs[TEXT_AREA]
15731 + nglyphs_before);
15732 int i;
15734 for (i = 0; i < nwritten; ++i)
15736 glyph[i].object = elt;
15737 glyph[i].charpos = charpos;
15740 n += nwritten;
15744 else /* c == 0 */
15745 break;
15749 break;
15751 case Lisp_Symbol:
15752 /* A symbol: process the value of the symbol recursively
15753 as if it appeared here directly. Avoid error if symbol void.
15754 Special case: if value of symbol is a string, output the string
15755 literally. */
15757 register Lisp_Object tem;
15759 /* If the variable is not marked as risky to set
15760 then its contents are risky to use. */
15761 if (NILP (Fget (elt, Qrisky_local_variable)))
15762 risky = 1;
15764 tem = Fboundp (elt);
15765 if (!NILP (tem))
15767 tem = Fsymbol_value (elt);
15768 /* If value is a string, output that string literally:
15769 don't check for % within it. */
15770 if (STRINGP (tem))
15771 literal = 1;
15773 if (!EQ (tem, elt))
15775 /* Give up right away for nil or t. */
15776 elt = tem;
15777 goto tail_recurse;
15781 break;
15783 case Lisp_Cons:
15785 register Lisp_Object car, tem;
15787 /* A cons cell: five distinct cases.
15788 If first element is :eval or :propertize, do something special.
15789 If first element is a string or a cons, process all the elements
15790 and effectively concatenate them.
15791 If first element is a negative number, truncate displaying cdr to
15792 at most that many characters. If positive, pad (with spaces)
15793 to at least that many characters.
15794 If first element is a symbol, process the cadr or caddr recursively
15795 according to whether the symbol's value is non-nil or nil. */
15796 car = XCAR (elt);
15797 if (EQ (car, QCeval))
15799 /* An element of the form (:eval FORM) means evaluate FORM
15800 and use the result as mode line elements. */
15802 if (risky)
15803 break;
15805 if (CONSP (XCDR (elt)))
15807 Lisp_Object spec;
15808 spec = safe_eval (XCAR (XCDR (elt)));
15809 n += display_mode_element (it, depth, field_width - n,
15810 precision - n, spec, props,
15811 risky);
15814 else if (EQ (car, QCpropertize))
15816 /* An element of the form (:propertize ELT PROPS...)
15817 means display ELT but applying properties PROPS. */
15819 if (risky)
15820 break;
15822 if (CONSP (XCDR (elt)))
15823 n += display_mode_element (it, depth, field_width - n,
15824 precision - n, XCAR (XCDR (elt)),
15825 XCDR (XCDR (elt)), risky);
15827 else if (SYMBOLP (car))
15829 tem = Fboundp (car);
15830 elt = XCDR (elt);
15831 if (!CONSP (elt))
15832 goto invalid;
15833 /* elt is now the cdr, and we know it is a cons cell.
15834 Use its car if CAR has a non-nil value. */
15835 if (!NILP (tem))
15837 tem = Fsymbol_value (car);
15838 if (!NILP (tem))
15840 elt = XCAR (elt);
15841 goto tail_recurse;
15844 /* Symbol's value is nil (or symbol is unbound)
15845 Get the cddr of the original list
15846 and if possible find the caddr and use that. */
15847 elt = XCDR (elt);
15848 if (NILP (elt))
15849 break;
15850 else if (!CONSP (elt))
15851 goto invalid;
15852 elt = XCAR (elt);
15853 goto tail_recurse;
15855 else if (INTEGERP (car))
15857 register int lim = XINT (car);
15858 elt = XCDR (elt);
15859 if (lim < 0)
15861 /* Negative int means reduce maximum width. */
15862 if (precision <= 0)
15863 precision = -lim;
15864 else
15865 precision = min (precision, -lim);
15867 else if (lim > 0)
15869 /* Padding specified. Don't let it be more than
15870 current maximum. */
15871 if (precision > 0)
15872 lim = min (precision, lim);
15874 /* If that's more padding than already wanted, queue it.
15875 But don't reduce padding already specified even if
15876 that is beyond the current truncation point. */
15877 field_width = max (lim, field_width);
15879 goto tail_recurse;
15881 else if (STRINGP (car) || CONSP (car))
15883 register int limit = 50;
15884 /* Limit is to protect against circular lists. */
15885 while (CONSP (elt)
15886 && --limit > 0
15887 && (precision <= 0 || n < precision))
15889 n += display_mode_element (it, depth, field_width - n,
15890 precision - n, XCAR (elt),
15891 props, risky);
15892 elt = XCDR (elt);
15896 break;
15898 default:
15899 invalid:
15900 elt = build_string ("*invalid*");
15901 goto tail_recurse;
15904 /* Pad to FIELD_WIDTH. */
15905 if (field_width > 0 && n < field_width)
15907 if (frame_title_ptr)
15908 n += store_frame_title ("", field_width - n, 0);
15909 else if (!NILP (mode_line_string_list))
15910 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15911 else
15912 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15913 0, 0, 0);
15916 return n;
15919 /* Store a mode-line string element in mode_line_string_list.
15921 If STRING is non-null, display that C string. Otherwise, the Lisp
15922 string LISP_STRING is displayed.
15924 FIELD_WIDTH is the minimum number of output glyphs to produce.
15925 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15926 with spaces. FIELD_WIDTH <= 0 means don't pad.
15928 PRECISION is the maximum number of characters to output from
15929 STRING. PRECISION <= 0 means don't truncate the string.
15931 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15932 properties to the string.
15934 PROPS are the properties to add to the string.
15935 The mode_line_string_face face property is always added to the string.
15938 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15939 char *string;
15940 Lisp_Object lisp_string;
15941 int copy_string;
15942 int field_width;
15943 int precision;
15944 Lisp_Object props;
15946 int len;
15947 int n = 0;
15949 if (string != NULL)
15951 len = strlen (string);
15952 if (precision > 0 && len > precision)
15953 len = precision;
15954 lisp_string = make_string (string, len);
15955 if (NILP (props))
15956 props = mode_line_string_face_prop;
15957 else if (!NILP (mode_line_string_face))
15959 Lisp_Object face = Fplist_get (props, Qface);
15960 props = Fcopy_sequence (props);
15961 if (NILP (face))
15962 face = mode_line_string_face;
15963 else
15964 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15965 props = Fplist_put (props, Qface, face);
15967 Fadd_text_properties (make_number (0), make_number (len),
15968 props, lisp_string);
15970 else
15972 len = XFASTINT (Flength (lisp_string));
15973 if (precision > 0 && len > precision)
15975 len = precision;
15976 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15977 precision = -1;
15979 if (!NILP (mode_line_string_face))
15981 Lisp_Object face;
15982 if (NILP (props))
15983 props = Ftext_properties_at (make_number (0), lisp_string);
15984 face = Fplist_get (props, Qface);
15985 if (NILP (face))
15986 face = mode_line_string_face;
15987 else
15988 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15989 props = Fcons (Qface, Fcons (face, Qnil));
15990 if (copy_string)
15991 lisp_string = Fcopy_sequence (lisp_string);
15993 if (!NILP (props))
15994 Fadd_text_properties (make_number (0), make_number (len),
15995 props, lisp_string);
15998 if (len > 0)
16000 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16001 n += len;
16004 if (field_width > len)
16006 field_width -= len;
16007 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16008 if (!NILP (props))
16009 Fadd_text_properties (make_number (0), make_number (field_width),
16010 props, lisp_string);
16011 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16012 n += field_width;
16015 return n;
16019 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16020 0, 3, 0,
16021 doc: /* Return the mode-line of selected window as a string.
16022 First optional arg FORMAT specifies a different format string (see
16023 `mode-line-format' for details) to use. If FORMAT is t, return
16024 the buffer's header-line. Second optional arg WINDOW specifies a
16025 different window to use as the context for the formatting.
16026 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
16027 (format, window, no_props)
16028 Lisp_Object format, window, no_props;
16030 struct it it;
16031 int len;
16032 struct window *w;
16033 struct buffer *old_buffer = NULL;
16034 enum face_id face_id = DEFAULT_FACE_ID;
16036 if (NILP (window))
16037 window = selected_window;
16038 CHECK_WINDOW (window);
16039 w = XWINDOW (window);
16040 CHECK_BUFFER (w->buffer);
16042 if (XBUFFER (w->buffer) != current_buffer)
16044 old_buffer = current_buffer;
16045 set_buffer_internal_1 (XBUFFER (w->buffer));
16048 if (NILP (format) || EQ (format, Qt))
16050 face_id = NILP (format)
16051 ? CURRENT_MODE_LINE_FACE_ID (w) :
16052 HEADER_LINE_FACE_ID;
16053 format = NILP (format)
16054 ? current_buffer->mode_line_format
16055 : current_buffer->header_line_format;
16058 init_iterator (&it, w, -1, -1, NULL, face_id);
16060 if (NILP (no_props))
16062 mode_line_string_face =
16063 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
16064 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
16065 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
16067 mode_line_string_face_prop =
16068 NILP (mode_line_string_face) ? Qnil :
16069 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
16071 /* We need a dummy last element in mode_line_string_list to
16072 indicate we are building the propertized mode-line string.
16073 Using mode_line_string_face_prop here GC protects it. */
16074 mode_line_string_list =
16075 Fcons (mode_line_string_face_prop, Qnil);
16076 frame_title_ptr = NULL;
16078 else
16080 mode_line_string_face_prop = Qnil;
16081 mode_line_string_list = Qnil;
16082 frame_title_ptr = frame_title_buf;
16085 push_frame_kboard (it.f);
16086 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16087 pop_frame_kboard ();
16089 if (old_buffer)
16090 set_buffer_internal_1 (old_buffer);
16092 if (NILP (no_props))
16094 Lisp_Object str;
16095 mode_line_string_list = Fnreverse (mode_line_string_list);
16096 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16097 make_string ("", 0));
16098 mode_line_string_face_prop = Qnil;
16099 mode_line_string_list = Qnil;
16100 return str;
16103 len = frame_title_ptr - frame_title_buf;
16104 if (len > 0 && frame_title_ptr[-1] == '-')
16106 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16107 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16109 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16110 if (len > frame_title_ptr - frame_title_buf)
16111 len = frame_title_ptr - frame_title_buf;
16114 frame_title_ptr = NULL;
16115 return make_string (frame_title_buf, len);
16118 /* Write a null-terminated, right justified decimal representation of
16119 the positive integer D to BUF using a minimal field width WIDTH. */
16121 static void
16122 pint2str (buf, width, d)
16123 register char *buf;
16124 register int width;
16125 register int d;
16127 register char *p = buf;
16129 if (d <= 0)
16130 *p++ = '0';
16131 else
16133 while (d > 0)
16135 *p++ = d % 10 + '0';
16136 d /= 10;
16140 for (width -= (int) (p - buf); width > 0; --width)
16141 *p++ = ' ';
16142 *p-- = '\0';
16143 while (p > buf)
16145 d = *buf;
16146 *buf++ = *p;
16147 *p-- = d;
16151 /* Write a null-terminated, right justified decimal and "human
16152 readable" representation of the nonnegative integer D to BUF using
16153 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16155 static const char power_letter[] =
16157 0, /* not used */
16158 'k', /* kilo */
16159 'M', /* mega */
16160 'G', /* giga */
16161 'T', /* tera */
16162 'P', /* peta */
16163 'E', /* exa */
16164 'Z', /* zetta */
16165 'Y' /* yotta */
16168 static void
16169 pint2hrstr (buf, width, d)
16170 char *buf;
16171 int width;
16172 int d;
16174 /* We aim to represent the nonnegative integer D as
16175 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16176 int quotient = d;
16177 int remainder = 0;
16178 /* -1 means: do not use TENTHS. */
16179 int tenths = -1;
16180 int exponent = 0;
16182 /* Length of QUOTIENT.TENTHS as a string. */
16183 int length;
16185 char * psuffix;
16186 char * p;
16188 if (1000 <= quotient)
16190 /* Scale to the appropriate EXPONENT. */
16193 remainder = quotient % 1000;
16194 quotient /= 1000;
16195 exponent++;
16197 while (1000 <= quotient);
16199 /* Round to nearest and decide whether to use TENTHS or not. */
16200 if (quotient <= 9)
16202 tenths = remainder / 100;
16203 if (50 <= remainder % 100)
16204 if (tenths < 9)
16205 tenths++;
16206 else
16208 quotient++;
16209 if (quotient == 10)
16210 tenths = -1;
16211 else
16212 tenths = 0;
16215 else
16216 if (500 <= remainder)
16217 if (quotient < 999)
16218 quotient++;
16219 else
16221 quotient = 1;
16222 exponent++;
16223 tenths = 0;
16227 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16228 if (tenths == -1 && quotient <= 99)
16229 if (quotient <= 9)
16230 length = 1;
16231 else
16232 length = 2;
16233 else
16234 length = 3;
16235 p = psuffix = buf + max (width, length);
16237 /* Print EXPONENT. */
16238 if (exponent)
16239 *psuffix++ = power_letter[exponent];
16240 *psuffix = '\0';
16242 /* Print TENTHS. */
16243 if (tenths >= 0)
16245 *--p = '0' + tenths;
16246 *--p = '.';
16249 /* Print QUOTIENT. */
16252 int digit = quotient % 10;
16253 *--p = '0' + digit;
16255 while ((quotient /= 10) != 0);
16257 /* Print leading spaces. */
16258 while (buf < p)
16259 *--p = ' ';
16262 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16263 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16264 type of CODING_SYSTEM. Return updated pointer into BUF. */
16266 static unsigned char invalid_eol_type[] = "(*invalid*)";
16268 static char *
16269 decode_mode_spec_coding (coding_system, buf, eol_flag)
16270 Lisp_Object coding_system;
16271 register char *buf;
16272 int eol_flag;
16274 Lisp_Object val;
16275 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16276 const unsigned char *eol_str;
16277 int eol_str_len;
16278 /* The EOL conversion we are using. */
16279 Lisp_Object eoltype;
16281 val = Fget (coding_system, Qcoding_system);
16282 eoltype = Qnil;
16284 if (!VECTORP (val)) /* Not yet decided. */
16286 if (multibyte)
16287 *buf++ = '-';
16288 if (eol_flag)
16289 eoltype = eol_mnemonic_undecided;
16290 /* Don't mention EOL conversion if it isn't decided. */
16292 else
16294 Lisp_Object eolvalue;
16296 eolvalue = Fget (coding_system, Qeol_type);
16298 if (multibyte)
16299 *buf++ = XFASTINT (AREF (val, 1));
16301 if (eol_flag)
16303 /* The EOL conversion that is normal on this system. */
16305 if (NILP (eolvalue)) /* Not yet decided. */
16306 eoltype = eol_mnemonic_undecided;
16307 else if (VECTORP (eolvalue)) /* Not yet decided. */
16308 eoltype = eol_mnemonic_undecided;
16309 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16310 eoltype = (XFASTINT (eolvalue) == 0
16311 ? eol_mnemonic_unix
16312 : (XFASTINT (eolvalue) == 1
16313 ? eol_mnemonic_dos : eol_mnemonic_mac));
16317 if (eol_flag)
16319 /* Mention the EOL conversion if it is not the usual one. */
16320 if (STRINGP (eoltype))
16322 eol_str = SDATA (eoltype);
16323 eol_str_len = SBYTES (eoltype);
16325 else if (INTEGERP (eoltype)
16326 && CHAR_VALID_P (XINT (eoltype), 0))
16328 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16329 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16330 eol_str = tmp;
16332 else
16334 eol_str = invalid_eol_type;
16335 eol_str_len = sizeof (invalid_eol_type) - 1;
16337 bcopy (eol_str, buf, eol_str_len);
16338 buf += eol_str_len;
16341 return buf;
16344 /* Return a string for the output of a mode line %-spec for window W,
16345 generated by character C. PRECISION >= 0 means don't return a
16346 string longer than that value. FIELD_WIDTH > 0 means pad the
16347 string returned with spaces to that value. Return 1 in *MULTIBYTE
16348 if the result is multibyte text. */
16350 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16352 static char *
16353 decode_mode_spec (w, c, field_width, precision, multibyte)
16354 struct window *w;
16355 register int c;
16356 int field_width, precision;
16357 int *multibyte;
16359 Lisp_Object obj;
16360 struct frame *f = XFRAME (WINDOW_FRAME (w));
16361 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16362 struct buffer *b = XBUFFER (w->buffer);
16364 obj = Qnil;
16365 *multibyte = 0;
16367 switch (c)
16369 case '*':
16370 if (!NILP (b->read_only))
16371 return "%";
16372 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16373 return "*";
16374 return "-";
16376 case '+':
16377 /* This differs from %* only for a modified read-only buffer. */
16378 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16379 return "*";
16380 if (!NILP (b->read_only))
16381 return "%";
16382 return "-";
16384 case '&':
16385 /* This differs from %* in ignoring read-only-ness. */
16386 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16387 return "*";
16388 return "-";
16390 case '%':
16391 return "%";
16393 case '[':
16395 int i;
16396 char *p;
16398 if (command_loop_level > 5)
16399 return "[[[... ";
16400 p = decode_mode_spec_buf;
16401 for (i = 0; i < command_loop_level; i++)
16402 *p++ = '[';
16403 *p = 0;
16404 return decode_mode_spec_buf;
16407 case ']':
16409 int i;
16410 char *p;
16412 if (command_loop_level > 5)
16413 return " ...]]]";
16414 p = decode_mode_spec_buf;
16415 for (i = 0; i < command_loop_level; i++)
16416 *p++ = ']';
16417 *p = 0;
16418 return decode_mode_spec_buf;
16421 case '-':
16423 register int i;
16425 /* Let lots_of_dashes be a string of infinite length. */
16426 if (!NILP (mode_line_string_list))
16427 return "--";
16428 if (field_width <= 0
16429 || field_width > sizeof (lots_of_dashes))
16431 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16432 decode_mode_spec_buf[i] = '-';
16433 decode_mode_spec_buf[i] = '\0';
16434 return decode_mode_spec_buf;
16436 else
16437 return lots_of_dashes;
16440 case 'b':
16441 obj = b->name;
16442 break;
16444 case 'c':
16446 int col = (int) current_column (); /* iftc */
16447 w->column_number_displayed = make_number (col);
16448 pint2str (decode_mode_spec_buf, field_width, col);
16449 return decode_mode_spec_buf;
16452 case 'F':
16453 /* %F displays the frame name. */
16454 if (!NILP (f->title))
16455 return (char *) SDATA (f->title);
16456 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16457 return (char *) SDATA (f->name);
16458 return "Emacs";
16460 case 'f':
16461 obj = b->filename;
16462 break;
16464 case 'i':
16466 int size = ZV - BEGV;
16467 pint2str (decode_mode_spec_buf, field_width, size);
16468 return decode_mode_spec_buf;
16471 case 'I':
16473 int size = ZV - BEGV;
16474 pint2hrstr (decode_mode_spec_buf, field_width, size);
16475 return decode_mode_spec_buf;
16478 case 'l':
16480 int startpos = XMARKER (w->start)->charpos;
16481 int startpos_byte = marker_byte_position (w->start);
16482 int line, linepos, linepos_byte, topline;
16483 int nlines, junk;
16484 int height = WINDOW_TOTAL_LINES (w);
16486 /* If we decided that this buffer isn't suitable for line numbers,
16487 don't forget that too fast. */
16488 if (EQ (w->base_line_pos, w->buffer))
16489 goto no_value;
16490 /* But do forget it, if the window shows a different buffer now. */
16491 else if (BUFFERP (w->base_line_pos))
16492 w->base_line_pos = Qnil;
16494 /* If the buffer is very big, don't waste time. */
16495 if (INTEGERP (Vline_number_display_limit)
16496 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16498 w->base_line_pos = Qnil;
16499 w->base_line_number = Qnil;
16500 goto no_value;
16503 if (!NILP (w->base_line_number)
16504 && !NILP (w->base_line_pos)
16505 && XFASTINT (w->base_line_pos) <= startpos)
16507 line = XFASTINT (w->base_line_number);
16508 linepos = XFASTINT (w->base_line_pos);
16509 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16511 else
16513 line = 1;
16514 linepos = BUF_BEGV (b);
16515 linepos_byte = BUF_BEGV_BYTE (b);
16518 /* Count lines from base line to window start position. */
16519 nlines = display_count_lines (linepos, linepos_byte,
16520 startpos_byte,
16521 startpos, &junk);
16523 topline = nlines + line;
16525 /* Determine a new base line, if the old one is too close
16526 or too far away, or if we did not have one.
16527 "Too close" means it's plausible a scroll-down would
16528 go back past it. */
16529 if (startpos == BUF_BEGV (b))
16531 w->base_line_number = make_number (topline);
16532 w->base_line_pos = make_number (BUF_BEGV (b));
16534 else if (nlines < height + 25 || nlines > height * 3 + 50
16535 || linepos == BUF_BEGV (b))
16537 int limit = BUF_BEGV (b);
16538 int limit_byte = BUF_BEGV_BYTE (b);
16539 int position;
16540 int distance = (height * 2 + 30) * line_number_display_limit_width;
16542 if (startpos - distance > limit)
16544 limit = startpos - distance;
16545 limit_byte = CHAR_TO_BYTE (limit);
16548 nlines = display_count_lines (startpos, startpos_byte,
16549 limit_byte,
16550 - (height * 2 + 30),
16551 &position);
16552 /* If we couldn't find the lines we wanted within
16553 line_number_display_limit_width chars per line,
16554 give up on line numbers for this window. */
16555 if (position == limit_byte && limit == startpos - distance)
16557 w->base_line_pos = w->buffer;
16558 w->base_line_number = Qnil;
16559 goto no_value;
16562 w->base_line_number = make_number (topline - nlines);
16563 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16566 /* Now count lines from the start pos to point. */
16567 nlines = display_count_lines (startpos, startpos_byte,
16568 PT_BYTE, PT, &junk);
16570 /* Record that we did display the line number. */
16571 line_number_displayed = 1;
16573 /* Make the string to show. */
16574 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16575 return decode_mode_spec_buf;
16576 no_value:
16578 char* p = decode_mode_spec_buf;
16579 int pad = field_width - 2;
16580 while (pad-- > 0)
16581 *p++ = ' ';
16582 *p++ = '?';
16583 *p++ = '?';
16584 *p = '\0';
16585 return decode_mode_spec_buf;
16588 break;
16590 case 'm':
16591 obj = b->mode_name;
16592 break;
16594 case 'n':
16595 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16596 return " Narrow";
16597 break;
16599 case 'p':
16601 int pos = marker_position (w->start);
16602 int total = BUF_ZV (b) - BUF_BEGV (b);
16604 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16606 if (pos <= BUF_BEGV (b))
16607 return "All";
16608 else
16609 return "Bottom";
16611 else if (pos <= BUF_BEGV (b))
16612 return "Top";
16613 else
16615 if (total > 1000000)
16616 /* Do it differently for a large value, to avoid overflow. */
16617 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16618 else
16619 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16620 /* We can't normally display a 3-digit number,
16621 so get us a 2-digit number that is close. */
16622 if (total == 100)
16623 total = 99;
16624 sprintf (decode_mode_spec_buf, "%2d%%", total);
16625 return decode_mode_spec_buf;
16629 /* Display percentage of size above the bottom of the screen. */
16630 case 'P':
16632 int toppos = marker_position (w->start);
16633 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16634 int total = BUF_ZV (b) - BUF_BEGV (b);
16636 if (botpos >= BUF_ZV (b))
16638 if (toppos <= BUF_BEGV (b))
16639 return "All";
16640 else
16641 return "Bottom";
16643 else
16645 if (total > 1000000)
16646 /* Do it differently for a large value, to avoid overflow. */
16647 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16648 else
16649 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16650 /* We can't normally display a 3-digit number,
16651 so get us a 2-digit number that is close. */
16652 if (total == 100)
16653 total = 99;
16654 if (toppos <= BUF_BEGV (b))
16655 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16656 else
16657 sprintf (decode_mode_spec_buf, "%2d%%", total);
16658 return decode_mode_spec_buf;
16662 case 's':
16663 /* status of process */
16664 obj = Fget_buffer_process (w->buffer);
16665 if (NILP (obj))
16666 return "no process";
16667 #ifdef subprocesses
16668 obj = Fsymbol_name (Fprocess_status (obj));
16669 #endif
16670 break;
16672 case 't': /* indicate TEXT or BINARY */
16673 #ifdef MODE_LINE_BINARY_TEXT
16674 return MODE_LINE_BINARY_TEXT (b);
16675 #else
16676 return "T";
16677 #endif
16679 case 'z':
16680 /* coding-system (not including end-of-line format) */
16681 case 'Z':
16682 /* coding-system (including end-of-line type) */
16684 int eol_flag = (c == 'Z');
16685 char *p = decode_mode_spec_buf;
16687 if (! FRAME_WINDOW_P (f))
16689 /* No need to mention EOL here--the terminal never needs
16690 to do EOL conversion. */
16691 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16692 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16694 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16695 p, eol_flag);
16697 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16698 #ifdef subprocesses
16699 obj = Fget_buffer_process (Fcurrent_buffer ());
16700 if (PROCESSP (obj))
16702 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16703 p, eol_flag);
16704 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16705 p, eol_flag);
16707 #endif /* subprocesses */
16708 #endif /* 0 */
16709 *p = 0;
16710 return decode_mode_spec_buf;
16714 if (STRINGP (obj))
16716 *multibyte = STRING_MULTIBYTE (obj);
16717 return (char *) SDATA (obj);
16719 else
16720 return "";
16724 /* Count up to COUNT lines starting from START / START_BYTE.
16725 But don't go beyond LIMIT_BYTE.
16726 Return the number of lines thus found (always nonnegative).
16728 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16730 static int
16731 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16732 int start, start_byte, limit_byte, count;
16733 int *byte_pos_ptr;
16735 register unsigned char *cursor;
16736 unsigned char *base;
16738 register int ceiling;
16739 register unsigned char *ceiling_addr;
16740 int orig_count = count;
16742 /* If we are not in selective display mode,
16743 check only for newlines. */
16744 int selective_display = (!NILP (current_buffer->selective_display)
16745 && !INTEGERP (current_buffer->selective_display));
16747 if (count > 0)
16749 while (start_byte < limit_byte)
16751 ceiling = BUFFER_CEILING_OF (start_byte);
16752 ceiling = min (limit_byte - 1, ceiling);
16753 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16754 base = (cursor = BYTE_POS_ADDR (start_byte));
16755 while (1)
16757 if (selective_display)
16758 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16760 else
16761 while (*cursor != '\n' && ++cursor != ceiling_addr)
16764 if (cursor != ceiling_addr)
16766 if (--count == 0)
16768 start_byte += cursor - base + 1;
16769 *byte_pos_ptr = start_byte;
16770 return orig_count;
16772 else
16773 if (++cursor == ceiling_addr)
16774 break;
16776 else
16777 break;
16779 start_byte += cursor - base;
16782 else
16784 while (start_byte > limit_byte)
16786 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16787 ceiling = max (limit_byte, ceiling);
16788 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16789 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16790 while (1)
16792 if (selective_display)
16793 while (--cursor != ceiling_addr
16794 && *cursor != '\n' && *cursor != 015)
16796 else
16797 while (--cursor != ceiling_addr && *cursor != '\n')
16800 if (cursor != ceiling_addr)
16802 if (++count == 0)
16804 start_byte += cursor - base + 1;
16805 *byte_pos_ptr = start_byte;
16806 /* When scanning backwards, we should
16807 not count the newline posterior to which we stop. */
16808 return - orig_count - 1;
16811 else
16812 break;
16814 /* Here we add 1 to compensate for the last decrement
16815 of CURSOR, which took it past the valid range. */
16816 start_byte += cursor - base + 1;
16820 *byte_pos_ptr = limit_byte;
16822 if (count < 0)
16823 return - orig_count + count;
16824 return orig_count - count;
16830 /***********************************************************************
16831 Displaying strings
16832 ***********************************************************************/
16834 /* Display a NUL-terminated string, starting with index START.
16836 If STRING is non-null, display that C string. Otherwise, the Lisp
16837 string LISP_STRING is displayed.
16839 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16840 FACE_STRING. Display STRING or LISP_STRING with the face at
16841 FACE_STRING_POS in FACE_STRING:
16843 Display the string in the environment given by IT, but use the
16844 standard display table, temporarily.
16846 FIELD_WIDTH is the minimum number of output glyphs to produce.
16847 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16848 with spaces. If STRING has more characters, more than FIELD_WIDTH
16849 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16851 PRECISION is the maximum number of characters to output from
16852 STRING. PRECISION < 0 means don't truncate the string.
16854 This is roughly equivalent to printf format specifiers:
16856 FIELD_WIDTH PRECISION PRINTF
16857 ----------------------------------------
16858 -1 -1 %s
16859 -1 10 %.10s
16860 10 -1 %10s
16861 20 10 %20.10s
16863 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16864 display them, and < 0 means obey the current buffer's value of
16865 enable_multibyte_characters.
16867 Value is the number of glyphs produced. */
16869 static int
16870 display_string (string, lisp_string, face_string, face_string_pos,
16871 start, it, field_width, precision, max_x, multibyte)
16872 unsigned char *string;
16873 Lisp_Object lisp_string;
16874 Lisp_Object face_string;
16875 int face_string_pos;
16876 int start;
16877 struct it *it;
16878 int field_width, precision, max_x;
16879 int multibyte;
16881 int hpos_at_start = it->hpos;
16882 int saved_face_id = it->face_id;
16883 struct glyph_row *row = it->glyph_row;
16885 /* Initialize the iterator IT for iteration over STRING beginning
16886 with index START. */
16887 reseat_to_string (it, string, lisp_string, start,
16888 precision, field_width, multibyte);
16890 /* If displaying STRING, set up the face of the iterator
16891 from LISP_STRING, if that's given. */
16892 if (STRINGP (face_string))
16894 int endptr;
16895 struct face *face;
16897 it->face_id
16898 = face_at_string_position (it->w, face_string, face_string_pos,
16899 0, it->region_beg_charpos,
16900 it->region_end_charpos,
16901 &endptr, it->base_face_id, 0);
16902 face = FACE_FROM_ID (it->f, it->face_id);
16903 it->face_box_p = face->box != FACE_NO_BOX;
16906 /* Set max_x to the maximum allowed X position. Don't let it go
16907 beyond the right edge of the window. */
16908 if (max_x <= 0)
16909 max_x = it->last_visible_x;
16910 else
16911 max_x = min (max_x, it->last_visible_x);
16913 /* Skip over display elements that are not visible. because IT->w is
16914 hscrolled. */
16915 if (it->current_x < it->first_visible_x)
16916 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16917 MOVE_TO_POS | MOVE_TO_X);
16919 row->ascent = it->max_ascent;
16920 row->height = it->max_ascent + it->max_descent;
16921 row->phys_ascent = it->max_phys_ascent;
16922 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16924 /* This condition is for the case that we are called with current_x
16925 past last_visible_x. */
16926 while (it->current_x < max_x)
16928 int x_before, x, n_glyphs_before, i, nglyphs;
16930 /* Get the next display element. */
16931 if (!get_next_display_element (it))
16932 break;
16934 /* Produce glyphs. */
16935 x_before = it->current_x;
16936 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16937 PRODUCE_GLYPHS (it);
16939 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16940 i = 0;
16941 x = x_before;
16942 while (i < nglyphs)
16944 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16946 if (!it->truncate_lines_p
16947 && x + glyph->pixel_width > max_x)
16949 /* End of continued line or max_x reached. */
16950 if (CHAR_GLYPH_PADDING_P (*glyph))
16952 /* A wide character is unbreakable. */
16953 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16954 it->current_x = x_before;
16956 else
16958 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16959 it->current_x = x;
16961 break;
16963 else if (x + glyph->pixel_width > it->first_visible_x)
16965 /* Glyph is at least partially visible. */
16966 ++it->hpos;
16967 if (x < it->first_visible_x)
16968 it->glyph_row->x = x - it->first_visible_x;
16970 else
16972 /* Glyph is off the left margin of the display area.
16973 Should not happen. */
16974 abort ();
16977 row->ascent = max (row->ascent, it->max_ascent);
16978 row->height = max (row->height, it->max_ascent + it->max_descent);
16979 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16980 row->phys_height = max (row->phys_height,
16981 it->max_phys_ascent + it->max_phys_descent);
16982 x += glyph->pixel_width;
16983 ++i;
16986 /* Stop if max_x reached. */
16987 if (i < nglyphs)
16988 break;
16990 /* Stop at line ends. */
16991 if (ITERATOR_AT_END_OF_LINE_P (it))
16993 it->continuation_lines_width = 0;
16994 break;
16997 set_iterator_to_next (it, 1);
16999 /* Stop if truncating at the right edge. */
17000 if (it->truncate_lines_p
17001 && it->current_x >= it->last_visible_x)
17003 /* Add truncation mark, but don't do it if the line is
17004 truncated at a padding space. */
17005 if (IT_CHARPOS (*it) < it->string_nchars)
17007 if (!FRAME_WINDOW_P (it->f))
17009 int i, n;
17011 if (it->current_x > it->last_visible_x)
17013 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17014 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17015 break;
17016 for (n = row->used[TEXT_AREA]; i < n; ++i)
17018 row->used[TEXT_AREA] = i;
17019 produce_special_glyphs (it, IT_TRUNCATION);
17022 produce_special_glyphs (it, IT_TRUNCATION);
17024 it->glyph_row->truncated_on_right_p = 1;
17026 break;
17030 /* Maybe insert a truncation at the left. */
17031 if (it->first_visible_x
17032 && IT_CHARPOS (*it) > 0)
17034 if (!FRAME_WINDOW_P (it->f))
17035 insert_left_trunc_glyphs (it);
17036 it->glyph_row->truncated_on_left_p = 1;
17039 it->face_id = saved_face_id;
17041 /* Value is number of columns displayed. */
17042 return it->hpos - hpos_at_start;
17047 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17048 appears as an element of LIST or as the car of an element of LIST.
17049 If PROPVAL is a list, compare each element against LIST in that
17050 way, and return 1/2 if any element of PROPVAL is found in LIST.
17051 Otherwise return 0. This function cannot quit.
17052 The return value is 2 if the text is invisible but with an ellipsis
17053 and 1 if it's invisible and without an ellipsis. */
17056 invisible_p (propval, list)
17057 register Lisp_Object propval;
17058 Lisp_Object list;
17060 register Lisp_Object tail, proptail;
17062 for (tail = list; CONSP (tail); tail = XCDR (tail))
17064 register Lisp_Object tem;
17065 tem = XCAR (tail);
17066 if (EQ (propval, tem))
17067 return 1;
17068 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17069 return NILP (XCDR (tem)) ? 1 : 2;
17072 if (CONSP (propval))
17074 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17076 Lisp_Object propelt;
17077 propelt = XCAR (proptail);
17078 for (tail = list; CONSP (tail); tail = XCDR (tail))
17080 register Lisp_Object tem;
17081 tem = XCAR (tail);
17082 if (EQ (propelt, tem))
17083 return 1;
17084 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17085 return NILP (XCDR (tem)) ? 1 : 2;
17090 return 0;
17094 /***********************************************************************
17095 Glyph Display
17096 ***********************************************************************/
17098 #ifdef HAVE_WINDOW_SYSTEM
17100 #if GLYPH_DEBUG
17102 void
17103 dump_glyph_string (s)
17104 struct glyph_string *s;
17106 fprintf (stderr, "glyph string\n");
17107 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17108 s->x, s->y, s->width, s->height);
17109 fprintf (stderr, " ybase = %d\n", s->ybase);
17110 fprintf (stderr, " hl = %d\n", s->hl);
17111 fprintf (stderr, " left overhang = %d, right = %d\n",
17112 s->left_overhang, s->right_overhang);
17113 fprintf (stderr, " nchars = %d\n", s->nchars);
17114 fprintf (stderr, " extends to end of line = %d\n",
17115 s->extends_to_end_of_line_p);
17116 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17117 fprintf (stderr, " bg width = %d\n", s->background_width);
17120 #endif /* GLYPH_DEBUG */
17122 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17123 of XChar2b structures for S; it can't be allocated in
17124 init_glyph_string because it must be allocated via `alloca'. W
17125 is the window on which S is drawn. ROW and AREA are the glyph row
17126 and area within the row from which S is constructed. START is the
17127 index of the first glyph structure covered by S. HL is a
17128 face-override for drawing S. */
17130 #ifdef HAVE_NTGUI
17131 #define OPTIONAL_HDC(hdc) hdc,
17132 #define DECLARE_HDC(hdc) HDC hdc;
17133 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17134 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17135 #endif
17137 #ifndef OPTIONAL_HDC
17138 #define OPTIONAL_HDC(hdc)
17139 #define DECLARE_HDC(hdc)
17140 #define ALLOCATE_HDC(hdc, f)
17141 #define RELEASE_HDC(hdc, f)
17142 #endif
17144 static void
17145 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17146 struct glyph_string *s;
17147 DECLARE_HDC (hdc)
17148 XChar2b *char2b;
17149 struct window *w;
17150 struct glyph_row *row;
17151 enum glyph_row_area area;
17152 int start;
17153 enum draw_glyphs_face hl;
17155 bzero (s, sizeof *s);
17156 s->w = w;
17157 s->f = XFRAME (w->frame);
17158 #ifdef HAVE_NTGUI
17159 s->hdc = hdc;
17160 #endif
17161 s->display = FRAME_X_DISPLAY (s->f);
17162 s->window = FRAME_X_WINDOW (s->f);
17163 s->char2b = char2b;
17164 s->hl = hl;
17165 s->row = row;
17166 s->area = area;
17167 s->first_glyph = row->glyphs[area] + start;
17168 s->height = row->height;
17169 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17171 /* Display the internal border below the tool-bar window. */
17172 if (s->w == XWINDOW (s->f->tool_bar_window))
17173 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17175 s->ybase = s->y + row->ascent;
17179 /* Append the list of glyph strings with head H and tail T to the list
17180 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17182 static INLINE void
17183 append_glyph_string_lists (head, tail, h, t)
17184 struct glyph_string **head, **tail;
17185 struct glyph_string *h, *t;
17187 if (h)
17189 if (*head)
17190 (*tail)->next = h;
17191 else
17192 *head = h;
17193 h->prev = *tail;
17194 *tail = t;
17199 /* Prepend the list of glyph strings with head H and tail T to the
17200 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17201 result. */
17203 static INLINE void
17204 prepend_glyph_string_lists (head, tail, h, t)
17205 struct glyph_string **head, **tail;
17206 struct glyph_string *h, *t;
17208 if (h)
17210 if (*head)
17211 (*head)->prev = t;
17212 else
17213 *tail = t;
17214 t->next = *head;
17215 *head = h;
17220 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17221 Set *HEAD and *TAIL to the resulting list. */
17223 static INLINE void
17224 append_glyph_string (head, tail, s)
17225 struct glyph_string **head, **tail;
17226 struct glyph_string *s;
17228 s->next = s->prev = NULL;
17229 append_glyph_string_lists (head, tail, s, s);
17233 /* Get face and two-byte form of character glyph GLYPH on frame F.
17234 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17235 a pointer to a realized face that is ready for display. */
17237 static INLINE struct face *
17238 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17239 struct frame *f;
17240 struct glyph *glyph;
17241 XChar2b *char2b;
17242 int *two_byte_p;
17244 struct face *face;
17246 xassert (glyph->type == CHAR_GLYPH);
17247 face = FACE_FROM_ID (f, glyph->face_id);
17249 if (two_byte_p)
17250 *two_byte_p = 0;
17252 if (!glyph->multibyte_p)
17254 /* Unibyte case. We don't have to encode, but we have to make
17255 sure to use a face suitable for unibyte. */
17256 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17258 else if (glyph->u.ch < 128
17259 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17261 /* Case of ASCII in a face known to fit ASCII. */
17262 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17264 else
17266 int c1, c2, charset;
17268 /* Split characters into bytes. If c2 is -1 afterwards, C is
17269 really a one-byte character so that byte1 is zero. */
17270 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17271 if (c2 > 0)
17272 STORE_XCHAR2B (char2b, c1, c2);
17273 else
17274 STORE_XCHAR2B (char2b, 0, c1);
17276 /* Maybe encode the character in *CHAR2B. */
17277 if (charset != CHARSET_ASCII)
17279 struct font_info *font_info
17280 = FONT_INFO_FROM_ID (f, face->font_info_id);
17281 if (font_info)
17282 glyph->font_type
17283 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17287 /* Make sure X resources of the face are allocated. */
17288 xassert (face != NULL);
17289 PREPARE_FACE_FOR_DISPLAY (f, face);
17290 return face;
17294 /* Fill glyph string S with composition components specified by S->cmp.
17296 FACES is an array of faces for all components of this composition.
17297 S->gidx is the index of the first component for S.
17298 OVERLAPS_P non-zero means S should draw the foreground only, and
17299 use its physical height for clipping.
17301 Value is the index of a component not in S. */
17303 static int
17304 fill_composite_glyph_string (s, faces, overlaps_p)
17305 struct glyph_string *s;
17306 struct face **faces;
17307 int overlaps_p;
17309 int i;
17311 xassert (s);
17313 s->for_overlaps_p = overlaps_p;
17315 s->face = faces[s->gidx];
17316 s->font = s->face->font;
17317 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17319 /* For all glyphs of this composition, starting at the offset
17320 S->gidx, until we reach the end of the definition or encounter a
17321 glyph that requires the different face, add it to S. */
17322 ++s->nchars;
17323 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17324 ++s->nchars;
17326 /* All glyph strings for the same composition has the same width,
17327 i.e. the width set for the first component of the composition. */
17329 s->width = s->first_glyph->pixel_width;
17331 /* If the specified font could not be loaded, use the frame's
17332 default font, but record the fact that we couldn't load it in
17333 the glyph string so that we can draw rectangles for the
17334 characters of the glyph string. */
17335 if (s->font == NULL)
17337 s->font_not_found_p = 1;
17338 s->font = FRAME_FONT (s->f);
17341 /* Adjust base line for subscript/superscript text. */
17342 s->ybase += s->first_glyph->voffset;
17344 xassert (s->face && s->face->gc);
17346 /* This glyph string must always be drawn with 16-bit functions. */
17347 s->two_byte_p = 1;
17349 return s->gidx + s->nchars;
17353 /* Fill glyph string S from a sequence of character glyphs.
17355 FACE_ID is the face id of the string. START is the index of the
17356 first glyph to consider, END is the index of the last + 1.
17357 OVERLAPS_P non-zero means S should draw the foreground only, and
17358 use its physical height for clipping.
17360 Value is the index of the first glyph not in S. */
17362 static int
17363 fill_glyph_string (s, face_id, start, end, overlaps_p)
17364 struct glyph_string *s;
17365 int face_id;
17366 int start, end, overlaps_p;
17368 struct glyph *glyph, *last;
17369 int voffset;
17370 int glyph_not_available_p;
17372 xassert (s->f == XFRAME (s->w->frame));
17373 xassert (s->nchars == 0);
17374 xassert (start >= 0 && end > start);
17376 s->for_overlaps_p = overlaps_p,
17377 glyph = s->row->glyphs[s->area] + start;
17378 last = s->row->glyphs[s->area] + end;
17379 voffset = glyph->voffset;
17381 glyph_not_available_p = glyph->glyph_not_available_p;
17383 while (glyph < last
17384 && glyph->type == CHAR_GLYPH
17385 && glyph->voffset == voffset
17386 /* Same face id implies same font, nowadays. */
17387 && glyph->face_id == face_id
17388 && glyph->glyph_not_available_p == glyph_not_available_p)
17390 int two_byte_p;
17392 s->face = get_glyph_face_and_encoding (s->f, glyph,
17393 s->char2b + s->nchars,
17394 &two_byte_p);
17395 s->two_byte_p = two_byte_p;
17396 ++s->nchars;
17397 xassert (s->nchars <= end - start);
17398 s->width += glyph->pixel_width;
17399 ++glyph;
17402 s->font = s->face->font;
17403 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17405 /* If the specified font could not be loaded, use the frame's font,
17406 but record the fact that we couldn't load it in
17407 S->font_not_found_p so that we can draw rectangles for the
17408 characters of the glyph string. */
17409 if (s->font == NULL || glyph_not_available_p)
17411 s->font_not_found_p = 1;
17412 s->font = FRAME_FONT (s->f);
17415 /* Adjust base line for subscript/superscript text. */
17416 s->ybase += voffset;
17418 xassert (s->face && s->face->gc);
17419 return glyph - s->row->glyphs[s->area];
17423 /* Fill glyph string S from image glyph S->first_glyph. */
17425 static void
17426 fill_image_glyph_string (s)
17427 struct glyph_string *s;
17429 xassert (s->first_glyph->type == IMAGE_GLYPH);
17430 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17431 xassert (s->img);
17432 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17433 s->font = s->face->font;
17434 s->width = s->first_glyph->pixel_width;
17436 /* Adjust base line for subscript/superscript text. */
17437 s->ybase += s->first_glyph->voffset;
17441 /* Fill glyph string S from a sequence of stretch glyphs.
17443 ROW is the glyph row in which the glyphs are found, AREA is the
17444 area within the row. START is the index of the first glyph to
17445 consider, END is the index of the last + 1.
17447 Value is the index of the first glyph not in S. */
17449 static int
17450 fill_stretch_glyph_string (s, row, area, start, end)
17451 struct glyph_string *s;
17452 struct glyph_row *row;
17453 enum glyph_row_area area;
17454 int start, end;
17456 struct glyph *glyph, *last;
17457 int voffset, face_id;
17459 xassert (s->first_glyph->type == STRETCH_GLYPH);
17461 glyph = s->row->glyphs[s->area] + start;
17462 last = s->row->glyphs[s->area] + end;
17463 face_id = glyph->face_id;
17464 s->face = FACE_FROM_ID (s->f, face_id);
17465 s->font = s->face->font;
17466 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17467 s->width = glyph->pixel_width;
17468 voffset = glyph->voffset;
17470 for (++glyph;
17471 (glyph < last
17472 && glyph->type == STRETCH_GLYPH
17473 && glyph->voffset == voffset
17474 && glyph->face_id == face_id);
17475 ++glyph)
17476 s->width += glyph->pixel_width;
17478 /* Adjust base line for subscript/superscript text. */
17479 s->ybase += voffset;
17481 /* The case that face->gc == 0 is handled when drawing the glyph
17482 string by calling PREPARE_FACE_FOR_DISPLAY. */
17483 xassert (s->face);
17484 return glyph - s->row->glyphs[s->area];
17488 /* EXPORT for RIF:
17489 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17490 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17491 assumed to be zero. */
17493 void
17494 x_get_glyph_overhangs (glyph, f, left, right)
17495 struct glyph *glyph;
17496 struct frame *f;
17497 int *left, *right;
17499 *left = *right = 0;
17501 if (glyph->type == CHAR_GLYPH)
17503 XFontStruct *font;
17504 struct face *face;
17505 struct font_info *font_info;
17506 XChar2b char2b;
17507 XCharStruct *pcm;
17509 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17510 font = face->font;
17511 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17512 if (font /* ++KFS: Should this be font_info ? */
17513 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17515 if (pcm->rbearing > pcm->width)
17516 *right = pcm->rbearing - pcm->width;
17517 if (pcm->lbearing < 0)
17518 *left = -pcm->lbearing;
17524 /* Return the index of the first glyph preceding glyph string S that
17525 is overwritten by S because of S's left overhang. Value is -1
17526 if no glyphs are overwritten. */
17528 static int
17529 left_overwritten (s)
17530 struct glyph_string *s;
17532 int k;
17534 if (s->left_overhang)
17536 int x = 0, i;
17537 struct glyph *glyphs = s->row->glyphs[s->area];
17538 int first = s->first_glyph - glyphs;
17540 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17541 x -= glyphs[i].pixel_width;
17543 k = i + 1;
17545 else
17546 k = -1;
17548 return k;
17552 /* Return the index of the first glyph preceding glyph string S that
17553 is overwriting S because of its right overhang. Value is -1 if no
17554 glyph in front of S overwrites S. */
17556 static int
17557 left_overwriting (s)
17558 struct glyph_string *s;
17560 int i, k, x;
17561 struct glyph *glyphs = s->row->glyphs[s->area];
17562 int first = s->first_glyph - glyphs;
17564 k = -1;
17565 x = 0;
17566 for (i = first - 1; i >= 0; --i)
17568 int left, right;
17569 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17570 if (x + right > 0)
17571 k = i;
17572 x -= glyphs[i].pixel_width;
17575 return k;
17579 /* Return the index of the last glyph following glyph string S that is
17580 not overwritten by S because of S's right overhang. Value is -1 if
17581 no such glyph is found. */
17583 static int
17584 right_overwritten (s)
17585 struct glyph_string *s;
17587 int k = -1;
17589 if (s->right_overhang)
17591 int x = 0, i;
17592 struct glyph *glyphs = s->row->glyphs[s->area];
17593 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17594 int end = s->row->used[s->area];
17596 for (i = first; i < end && s->right_overhang > x; ++i)
17597 x += glyphs[i].pixel_width;
17599 k = i;
17602 return k;
17606 /* Return the index of the last glyph following glyph string S that
17607 overwrites S because of its left overhang. Value is negative
17608 if no such glyph is found. */
17610 static int
17611 right_overwriting (s)
17612 struct glyph_string *s;
17614 int i, k, x;
17615 int end = s->row->used[s->area];
17616 struct glyph *glyphs = s->row->glyphs[s->area];
17617 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17619 k = -1;
17620 x = 0;
17621 for (i = first; i < end; ++i)
17623 int left, right;
17624 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17625 if (x - left < 0)
17626 k = i;
17627 x += glyphs[i].pixel_width;
17630 return k;
17634 /* Get face and two-byte form of character C in face FACE_ID on frame
17635 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17636 means we want to display multibyte text. DISPLAY_P non-zero means
17637 make sure that X resources for the face returned are allocated.
17638 Value is a pointer to a realized face that is ready for display if
17639 DISPLAY_P is non-zero. */
17641 static INLINE struct face *
17642 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17643 struct frame *f;
17644 int c, face_id;
17645 XChar2b *char2b;
17646 int multibyte_p, display_p;
17648 struct face *face = FACE_FROM_ID (f, face_id);
17650 if (!multibyte_p)
17652 /* Unibyte case. We don't have to encode, but we have to make
17653 sure to use a face suitable for unibyte. */
17654 STORE_XCHAR2B (char2b, 0, c);
17655 face_id = FACE_FOR_CHAR (f, face, c);
17656 face = FACE_FROM_ID (f, face_id);
17658 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17660 /* Case of ASCII in a face known to fit ASCII. */
17661 STORE_XCHAR2B (char2b, 0, c);
17663 else
17665 int c1, c2, charset;
17667 /* Split characters into bytes. If c2 is -1 afterwards, C is
17668 really a one-byte character so that byte1 is zero. */
17669 SPLIT_CHAR (c, charset, c1, c2);
17670 if (c2 > 0)
17671 STORE_XCHAR2B (char2b, c1, c2);
17672 else
17673 STORE_XCHAR2B (char2b, 0, c1);
17675 /* Maybe encode the character in *CHAR2B. */
17676 if (face->font != NULL)
17678 struct font_info *font_info
17679 = FONT_INFO_FROM_ID (f, face->font_info_id);
17680 if (font_info)
17681 rif->encode_char (c, char2b, font_info, 0);
17685 /* Make sure X resources of the face are allocated. */
17686 #ifdef HAVE_X_WINDOWS
17687 if (display_p)
17688 #endif
17690 xassert (face != NULL);
17691 PREPARE_FACE_FOR_DISPLAY (f, face);
17694 return face;
17698 /* Set background width of glyph string S. START is the index of the
17699 first glyph following S. LAST_X is the right-most x-position + 1
17700 in the drawing area. */
17702 static INLINE void
17703 set_glyph_string_background_width (s, start, last_x)
17704 struct glyph_string *s;
17705 int start;
17706 int last_x;
17708 /* If the face of this glyph string has to be drawn to the end of
17709 the drawing area, set S->extends_to_end_of_line_p. */
17710 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17712 if (start == s->row->used[s->area]
17713 && s->area == TEXT_AREA
17714 && ((s->hl == DRAW_NORMAL_TEXT
17715 && (s->row->fill_line_p
17716 || s->face->background != default_face->background
17717 || s->face->stipple != default_face->stipple
17718 || s->row->mouse_face_p))
17719 || s->hl == DRAW_MOUSE_FACE
17720 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17721 && s->row->fill_line_p)))
17722 s->extends_to_end_of_line_p = 1;
17724 /* If S extends its face to the end of the line, set its
17725 background_width to the distance to the right edge of the drawing
17726 area. */
17727 if (s->extends_to_end_of_line_p)
17728 s->background_width = last_x - s->x + 1;
17729 else
17730 s->background_width = s->width;
17734 /* Compute overhangs and x-positions for glyph string S and its
17735 predecessors, or successors. X is the starting x-position for S.
17736 BACKWARD_P non-zero means process predecessors. */
17738 static void
17739 compute_overhangs_and_x (s, x, backward_p)
17740 struct glyph_string *s;
17741 int x;
17742 int backward_p;
17744 if (backward_p)
17746 while (s)
17748 if (rif->compute_glyph_string_overhangs)
17749 rif->compute_glyph_string_overhangs (s);
17750 x -= s->width;
17751 s->x = x;
17752 s = s->prev;
17755 else
17757 while (s)
17759 if (rif->compute_glyph_string_overhangs)
17760 rif->compute_glyph_string_overhangs (s);
17761 s->x = x;
17762 x += s->width;
17763 s = s->next;
17770 /* The following macros are only called from draw_glyphs below.
17771 They reference the following parameters of that function directly:
17772 `w', `row', `area', and `overlap_p'
17773 as well as the following local variables:
17774 `s', `f', and `hdc' (in W32) */
17776 #ifdef HAVE_NTGUI
17777 /* On W32, silently add local `hdc' variable to argument list of
17778 init_glyph_string. */
17779 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17780 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17781 #else
17782 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17783 init_glyph_string (s, char2b, w, row, area, start, hl)
17784 #endif
17786 /* Add a glyph string for a stretch glyph to the list of strings
17787 between HEAD and TAIL. START is the index of the stretch glyph in
17788 row area AREA of glyph row ROW. END is the index of the last glyph
17789 in that glyph row area. X is the current output position assigned
17790 to the new glyph string constructed. HL overrides that face of the
17791 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17792 is the right-most x-position of the drawing area. */
17794 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17795 and below -- keep them on one line. */
17796 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17797 do \
17799 s = (struct glyph_string *) alloca (sizeof *s); \
17800 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17801 START = fill_stretch_glyph_string (s, row, area, START, END); \
17802 append_glyph_string (&HEAD, &TAIL, s); \
17803 s->x = (X); \
17805 while (0)
17808 /* Add a glyph string for an image glyph to the list of strings
17809 between HEAD and TAIL. START is the index of the image glyph in
17810 row area AREA of glyph row ROW. END is the index of the last glyph
17811 in that glyph row area. X is the current output position assigned
17812 to the new glyph string constructed. HL overrides that face of the
17813 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17814 is the right-most x-position of the drawing area. */
17816 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17817 do \
17819 s = (struct glyph_string *) alloca (sizeof *s); \
17820 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17821 fill_image_glyph_string (s); \
17822 append_glyph_string (&HEAD, &TAIL, s); \
17823 ++START; \
17824 s->x = (X); \
17826 while (0)
17829 /* Add a glyph string for a sequence of character glyphs to the list
17830 of strings between HEAD and TAIL. START is the index of the first
17831 glyph in row area AREA of glyph row ROW that is part of the new
17832 glyph string. END is the index of the last glyph in that glyph row
17833 area. X is the current output position assigned to the new glyph
17834 string constructed. HL overrides that face of the glyph; e.g. it
17835 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17836 right-most x-position of the drawing area. */
17838 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17839 do \
17841 int c, face_id; \
17842 XChar2b *char2b; \
17844 c = (row)->glyphs[area][START].u.ch; \
17845 face_id = (row)->glyphs[area][START].face_id; \
17847 s = (struct glyph_string *) alloca (sizeof *s); \
17848 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17849 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17850 append_glyph_string (&HEAD, &TAIL, s); \
17851 s->x = (X); \
17852 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17854 while (0)
17857 /* Add a glyph string for a composite sequence to the list of strings
17858 between HEAD and TAIL. START is the index of the first glyph in
17859 row area AREA of glyph row ROW that is part of the new glyph
17860 string. END is the index of the last glyph in that glyph row area.
17861 X is the current output position assigned to the new glyph string
17862 constructed. HL overrides that face of the glyph; e.g. it is
17863 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17864 x-position of the drawing area. */
17866 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17867 do { \
17868 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17869 int face_id = (row)->glyphs[area][START].face_id; \
17870 struct face *base_face = FACE_FROM_ID (f, face_id); \
17871 struct composition *cmp = composition_table[cmp_id]; \
17872 int glyph_len = cmp->glyph_len; \
17873 XChar2b *char2b; \
17874 struct face **faces; \
17875 struct glyph_string *first_s = NULL; \
17876 int n; \
17878 base_face = base_face->ascii_face; \
17879 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17880 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17881 /* At first, fill in `char2b' and `faces'. */ \
17882 for (n = 0; n < glyph_len; n++) \
17884 int c = COMPOSITION_GLYPH (cmp, n); \
17885 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17886 faces[n] = FACE_FROM_ID (f, this_face_id); \
17887 get_char_face_and_encoding (f, c, this_face_id, \
17888 char2b + n, 1, 1); \
17891 /* Make glyph_strings for each glyph sequence that is drawable by \
17892 the same face, and append them to HEAD/TAIL. */ \
17893 for (n = 0; n < cmp->glyph_len;) \
17895 s = (struct glyph_string *) alloca (sizeof *s); \
17896 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17897 append_glyph_string (&(HEAD), &(TAIL), s); \
17898 s->cmp = cmp; \
17899 s->gidx = n; \
17900 s->x = (X); \
17902 if (n == 0) \
17903 first_s = s; \
17905 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17908 ++START; \
17909 s = first_s; \
17910 } while (0)
17913 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17914 of AREA of glyph row ROW on window W between indices START and END.
17915 HL overrides the face for drawing glyph strings, e.g. it is
17916 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17917 x-positions of the drawing area.
17919 This is an ugly monster macro construct because we must use alloca
17920 to allocate glyph strings (because draw_glyphs can be called
17921 asynchronously). */
17923 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17924 do \
17926 HEAD = TAIL = NULL; \
17927 while (START < END) \
17929 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17930 switch (first_glyph->type) \
17932 case CHAR_GLYPH: \
17933 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17934 HL, X, LAST_X); \
17935 break; \
17937 case COMPOSITE_GLYPH: \
17938 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17939 HL, X, LAST_X); \
17940 break; \
17942 case STRETCH_GLYPH: \
17943 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17944 HL, X, LAST_X); \
17945 break; \
17947 case IMAGE_GLYPH: \
17948 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17949 HL, X, LAST_X); \
17950 break; \
17952 default: \
17953 abort (); \
17956 set_glyph_string_background_width (s, START, LAST_X); \
17957 (X) += s->width; \
17960 while (0)
17963 /* Draw glyphs between START and END in AREA of ROW on window W,
17964 starting at x-position X. X is relative to AREA in W. HL is a
17965 face-override with the following meaning:
17967 DRAW_NORMAL_TEXT draw normally
17968 DRAW_CURSOR draw in cursor face
17969 DRAW_MOUSE_FACE draw in mouse face.
17970 DRAW_INVERSE_VIDEO draw in mode line face
17971 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17972 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17974 If OVERLAPS_P is non-zero, draw only the foreground of characters
17975 and clip to the physical height of ROW.
17977 Value is the x-position reached, relative to AREA of W. */
17979 static int
17980 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17981 struct window *w;
17982 int x;
17983 struct glyph_row *row;
17984 enum glyph_row_area area;
17985 int start, end;
17986 enum draw_glyphs_face hl;
17987 int overlaps_p;
17989 struct glyph_string *head, *tail;
17990 struct glyph_string *s;
17991 int last_x, area_width;
17992 int x_reached;
17993 int i, j;
17994 struct frame *f = XFRAME (WINDOW_FRAME (w));
17995 DECLARE_HDC (hdc);
17997 ALLOCATE_HDC (hdc, f);
17999 /* Let's rather be paranoid than getting a SEGV. */
18000 end = min (end, row->used[area]);
18001 start = max (0, start);
18002 start = min (end, start);
18004 /* Translate X to frame coordinates. Set last_x to the right
18005 end of the drawing area. */
18006 if (row->full_width_p)
18008 /* X is relative to the left edge of W, without scroll bars
18009 or fringes. */
18010 x += WINDOW_LEFT_EDGE_X (w);
18011 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18013 else
18015 int area_left = window_box_left (w, area);
18016 x += area_left;
18017 area_width = window_box_width (w, area);
18018 last_x = area_left + area_width;
18021 /* Build a doubly-linked list of glyph_string structures between
18022 head and tail from what we have to draw. Note that the macro
18023 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18024 the reason we use a separate variable `i'. */
18025 i = start;
18026 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18027 if (tail)
18028 x_reached = tail->x + tail->background_width;
18029 else
18030 x_reached = x;
18032 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18033 the row, redraw some glyphs in front or following the glyph
18034 strings built above. */
18035 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18037 int dummy_x = 0;
18038 struct glyph_string *h, *t;
18040 /* Compute overhangs for all glyph strings. */
18041 if (rif->compute_glyph_string_overhangs)
18042 for (s = head; s; s = s->next)
18043 rif->compute_glyph_string_overhangs (s);
18045 /* Prepend glyph strings for glyphs in front of the first glyph
18046 string that are overwritten because of the first glyph
18047 string's left overhang. The background of all strings
18048 prepended must be drawn because the first glyph string
18049 draws over it. */
18050 i = left_overwritten (head);
18051 if (i >= 0)
18053 j = i;
18054 BUILD_GLYPH_STRINGS (j, start, h, t,
18055 DRAW_NORMAL_TEXT, dummy_x, last_x);
18056 start = i;
18057 compute_overhangs_and_x (t, head->x, 1);
18058 prepend_glyph_string_lists (&head, &tail, h, t);
18061 /* Prepend glyph strings for glyphs in front of the first glyph
18062 string that overwrite that glyph string because of their
18063 right overhang. For these strings, only the foreground must
18064 be drawn, because it draws over the glyph string at `head'.
18065 The background must not be drawn because this would overwrite
18066 right overhangs of preceding glyphs for which no glyph
18067 strings exist. */
18068 i = left_overwriting (head);
18069 if (i >= 0)
18071 BUILD_GLYPH_STRINGS (i, start, h, t,
18072 DRAW_NORMAL_TEXT, dummy_x, last_x);
18073 for (s = h; s; s = s->next)
18074 s->background_filled_p = 1;
18075 compute_overhangs_and_x (t, head->x, 1);
18076 prepend_glyph_string_lists (&head, &tail, h, t);
18079 /* Append glyphs strings for glyphs following the last glyph
18080 string tail that are overwritten by tail. The background of
18081 these strings has to be drawn because tail's foreground draws
18082 over it. */
18083 i = right_overwritten (tail);
18084 if (i >= 0)
18086 BUILD_GLYPH_STRINGS (end, i, h, t,
18087 DRAW_NORMAL_TEXT, x, last_x);
18088 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18089 append_glyph_string_lists (&head, &tail, h, t);
18092 /* Append glyph strings for glyphs following the last glyph
18093 string tail that overwrite tail. The foreground of such
18094 glyphs has to be drawn because it writes into the background
18095 of tail. The background must not be drawn because it could
18096 paint over the foreground of following glyphs. */
18097 i = right_overwriting (tail);
18098 if (i >= 0)
18100 BUILD_GLYPH_STRINGS (end, i, h, t,
18101 DRAW_NORMAL_TEXT, x, last_x);
18102 for (s = h; s; s = s->next)
18103 s->background_filled_p = 1;
18104 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18105 append_glyph_string_lists (&head, &tail, h, t);
18109 /* Draw all strings. */
18110 for (s = head; s; s = s->next)
18111 rif->draw_glyph_string (s);
18113 if (area == TEXT_AREA
18114 && !row->full_width_p
18115 /* When drawing overlapping rows, only the glyph strings'
18116 foreground is drawn, which doesn't erase a cursor
18117 completely. */
18118 && !overlaps_p)
18120 int x0 = head ? head->x : x;
18121 int x1 = tail ? tail->x + tail->background_width : x;
18123 int text_left = window_box_left (w, TEXT_AREA);
18124 x0 -= text_left;
18125 x1 -= text_left;
18127 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18128 row->y, MATRIX_ROW_BOTTOM_Y (row));
18131 /* Value is the x-position up to which drawn, relative to AREA of W.
18132 This doesn't include parts drawn because of overhangs. */
18133 if (row->full_width_p)
18134 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18135 else
18136 x_reached -= window_box_left (w, area);
18138 RELEASE_HDC (hdc, f);
18140 return x_reached;
18144 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18145 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18147 static INLINE void
18148 append_glyph (it)
18149 struct it *it;
18151 struct glyph *glyph;
18152 enum glyph_row_area area = it->area;
18154 xassert (it->glyph_row);
18155 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18157 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18158 if (glyph < it->glyph_row->glyphs[area + 1])
18160 glyph->charpos = CHARPOS (it->position);
18161 glyph->object = it->object;
18162 glyph->pixel_width = it->pixel_width;
18163 glyph->ascent = it->ascent;
18164 glyph->descent = it->descent;
18165 glyph->voffset = it->voffset;
18166 glyph->type = CHAR_GLYPH;
18167 glyph->multibyte_p = it->multibyte_p;
18168 glyph->left_box_line_p = it->start_of_box_run_p;
18169 glyph->right_box_line_p = it->end_of_box_run_p;
18170 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18171 || it->phys_descent > it->descent);
18172 glyph->padding_p = 0;
18173 glyph->glyph_not_available_p = it->glyph_not_available_p;
18174 glyph->face_id = it->face_id;
18175 glyph->u.ch = it->char_to_display;
18176 glyph->font_type = FONT_TYPE_UNKNOWN;
18177 ++it->glyph_row->used[area];
18181 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18182 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18184 static INLINE void
18185 append_composite_glyph (it)
18186 struct it *it;
18188 struct glyph *glyph;
18189 enum glyph_row_area area = it->area;
18191 xassert (it->glyph_row);
18193 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18194 if (glyph < it->glyph_row->glyphs[area + 1])
18196 glyph->charpos = CHARPOS (it->position);
18197 glyph->object = it->object;
18198 glyph->pixel_width = it->pixel_width;
18199 glyph->ascent = it->ascent;
18200 glyph->descent = it->descent;
18201 glyph->voffset = it->voffset;
18202 glyph->type = COMPOSITE_GLYPH;
18203 glyph->multibyte_p = it->multibyte_p;
18204 glyph->left_box_line_p = it->start_of_box_run_p;
18205 glyph->right_box_line_p = it->end_of_box_run_p;
18206 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18207 || it->phys_descent > it->descent);
18208 glyph->padding_p = 0;
18209 glyph->glyph_not_available_p = 0;
18210 glyph->face_id = it->face_id;
18211 glyph->u.cmp_id = it->cmp_id;
18212 glyph->font_type = FONT_TYPE_UNKNOWN;
18213 ++it->glyph_row->used[area];
18218 /* Change IT->ascent and IT->height according to the setting of
18219 IT->voffset. */
18221 static INLINE void
18222 take_vertical_position_into_account (it)
18223 struct it *it;
18225 if (it->voffset)
18227 if (it->voffset < 0)
18228 /* Increase the ascent so that we can display the text higher
18229 in the line. */
18230 it->ascent += abs (it->voffset);
18231 else
18232 /* Increase the descent so that we can display the text lower
18233 in the line. */
18234 it->descent += it->voffset;
18239 /* Produce glyphs/get display metrics for the image IT is loaded with.
18240 See the description of struct display_iterator in dispextern.h for
18241 an overview of struct display_iterator. */
18243 static void
18244 produce_image_glyph (it)
18245 struct it *it;
18247 struct image *img;
18248 struct face *face;
18249 int face_ascent, glyph_ascent;
18251 xassert (it->what == IT_IMAGE);
18253 face = FACE_FROM_ID (it->f, it->face_id);
18254 img = IMAGE_FROM_ID (it->f, it->image_id);
18255 xassert (img);
18257 /* Make sure X resources of the face and image are loaded. */
18258 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18259 prepare_image_for_display (it->f, img);
18261 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
18262 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
18263 it->pixel_width = img->width + 2 * img->hmargin;
18265 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18266 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18267 if (face_ascent > it->ascent)
18268 it->ascent = it->phys_ascent = face_ascent;
18270 it->nglyphs = 1;
18272 if (face->box != FACE_NO_BOX)
18274 if (face->box_line_width > 0)
18276 it->ascent += face->box_line_width;
18277 it->descent += face->box_line_width;
18280 if (it->start_of_box_run_p)
18281 it->pixel_width += abs (face->box_line_width);
18282 if (it->end_of_box_run_p)
18283 it->pixel_width += abs (face->box_line_width);
18286 take_vertical_position_into_account (it);
18288 if (it->glyph_row)
18290 struct glyph *glyph;
18291 enum glyph_row_area area = it->area;
18293 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18294 if (glyph < it->glyph_row->glyphs[area + 1])
18296 glyph->charpos = CHARPOS (it->position);
18297 glyph->object = it->object;
18298 glyph->pixel_width = it->pixel_width;
18299 glyph->ascent = glyph_ascent;
18300 glyph->descent = it->descent;
18301 glyph->voffset = it->voffset;
18302 glyph->type = IMAGE_GLYPH;
18303 glyph->multibyte_p = it->multibyte_p;
18304 glyph->left_box_line_p = it->start_of_box_run_p;
18305 glyph->right_box_line_p = it->end_of_box_run_p;
18306 glyph->overlaps_vertically_p = 0;
18307 glyph->padding_p = 0;
18308 glyph->glyph_not_available_p = 0;
18309 glyph->face_id = it->face_id;
18310 glyph->u.img_id = img->id;
18311 glyph->font_type = FONT_TYPE_UNKNOWN;
18312 ++it->glyph_row->used[area];
18318 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18319 of the glyph, WIDTH and HEIGHT are the width and height of the
18320 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18322 static void
18323 append_stretch_glyph (it, object, width, height, ascent)
18324 struct it *it;
18325 Lisp_Object object;
18326 int width, height;
18327 int ascent;
18329 struct glyph *glyph;
18330 enum glyph_row_area area = it->area;
18332 xassert (ascent >= 0 && ascent <= height);
18334 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18335 if (glyph < it->glyph_row->glyphs[area + 1])
18337 glyph->charpos = CHARPOS (it->position);
18338 glyph->object = object;
18339 glyph->pixel_width = width;
18340 glyph->ascent = ascent;
18341 glyph->descent = height - ascent;
18342 glyph->voffset = it->voffset;
18343 glyph->type = STRETCH_GLYPH;
18344 glyph->multibyte_p = it->multibyte_p;
18345 glyph->left_box_line_p = it->start_of_box_run_p;
18346 glyph->right_box_line_p = it->end_of_box_run_p;
18347 glyph->overlaps_vertically_p = 0;
18348 glyph->padding_p = 0;
18349 glyph->glyph_not_available_p = 0;
18350 glyph->face_id = it->face_id;
18351 glyph->u.stretch.ascent = ascent;
18352 glyph->u.stretch.height = height;
18353 glyph->font_type = FONT_TYPE_UNKNOWN;
18354 ++it->glyph_row->used[area];
18359 /* Calculate a width or height in pixels from a specification using
18360 the following elements:
18362 SPEC ::=
18363 NUM - a (fractional) multiple of the default font width/height
18364 (NUM) - specifies exactly NUM pixels
18365 UNIT - a fixed number of pixels, see below.
18366 ELEMENT - size of a display element in pixels, see below.
18367 (NUM . SPEC) - equals NUM * SPEC
18368 (+ SPEC SPEC ...) - add pixel values
18369 (- SPEC SPEC ...) - subtract pixel values
18370 (- SPEC) - negate pixel value
18372 NUM ::=
18373 INT or FLOAT - a number constant
18374 SYMBOL - use symbol's (buffer local) variable binding.
18376 UNIT ::=
18377 in - pixels per inch *)
18378 mm - pixels per 1/1000 meter *)
18379 cm - pixels per 1/100 meter *)
18380 width - width of current font in pixels.
18381 height - height of current font in pixels.
18383 *) using the ratio(s) defined in display-pixels-per-inch.
18385 ELEMENT ::=
18387 left-fringe - left fringe width in pixels
18388 (left-fringe . nil) - left fringe width if inside margins, else 0
18389 (left-fringe . t) - left fringe width if outside margins, else 0
18391 right-fringe - right fringe width in pixels
18392 (right-fringe . nil) - right fringe width if inside margins, else 0
18393 (right-fringe . t) - right fringe width if outside margins, else 0
18395 left-margin - left margin width in pixels
18396 right-margin - right margin width in pixels
18398 scroll-bar - scroll-bar area width in pixels
18399 (scroll-bar . left) - scroll-bar width if on left, else 0
18400 (scroll-bar . right) - scroll-bar width if on right, else 0
18402 Examples:
18404 Pixels corresponding to 5 inches:
18405 (5 . in)
18407 Total width of non-text areas on left side of window:
18408 (+ left-fringe left-margin (scroll-bar . left))
18410 Total width of fringes if inside display margins:
18411 (+ (left-fringe) (right-fringe))
18413 Width of left margin minus width of 1 character in the default font:
18414 (- left-margin 1)
18416 Width of left margin minus width of 2 characters in the current font:
18417 (- left-margin (2 . width))
18419 Width of left fringe plus left margin minus one pixel:
18420 (- (+ left-fringe left-margin) (1))
18421 (+ left-fringe left-margin (- (1)))
18422 (+ left-fringe left-margin (-1))
18426 #define NUMVAL(X) \
18427 ((INTEGERP (X) || FLOATP (X)) \
18428 ? XFLOATINT (X) \
18429 : - 1)
18431 static int
18432 calc_pixel_width_or_height (res, it, prop, font, width_p)
18433 double *res;
18434 struct it *it;
18435 Lisp_Object prop;
18436 XFontStruct *font;
18437 int width_p;
18439 double pixels;
18441 #define OK_PIXELS(val) ((*res = (val)), 1)
18443 if (SYMBOLP (prop))
18445 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18447 char *unit = SDATA (SYMBOL_NAME (prop));
18449 if (unit[0] == 'i' && unit[1] == 'n')
18450 pixels = 1.0;
18451 else if (unit[0] == 'm' && unit[1] == 'm')
18452 pixels = 25.4;
18453 else if (unit[0] == 'c' && unit[1] == 'm')
18454 pixels = 2.54;
18455 else
18456 pixels = 0;
18457 if (pixels > 0)
18459 double ppi;
18460 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18461 || (CONSP (Vdisplay_pixels_per_inch)
18462 && (ppi = (width_p
18463 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18464 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18465 ppi > 0)))
18466 return OK_PIXELS (ppi / pixels);
18468 return 0;
18472 if (EQ (prop, Qheight))
18473 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
18474 if (EQ (prop, Qwidth))
18475 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
18476 if (EQ (prop, Qleft_fringe))
18477 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18478 if (EQ (prop, Qright_fringe))
18479 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18480 if (EQ (prop, Qleft_margin))
18481 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18482 if (EQ (prop, Qright_margin))
18483 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18484 if (EQ (prop, Qscroll_bar))
18485 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18487 prop = Fbuffer_local_value (prop, it->w->buffer);
18490 if (INTEGERP (prop) || FLOATP (prop))
18492 int base_unit = (width_p
18493 ? FRAME_COLUMN_WIDTH (it->f)
18494 : FRAME_LINE_HEIGHT (it->f));
18495 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18498 if (CONSP (prop))
18500 Lisp_Object car = XCAR (prop);
18501 Lisp_Object cdr = XCDR (prop);
18503 if (SYMBOLP (car))
18505 if (EQ (car, Qplus) || EQ (car, Qminus))
18507 int first = 1;
18508 double px;
18510 pixels = 0;
18511 while (CONSP (cdr))
18513 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
18514 return 0;
18515 if (first)
18516 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18517 else
18518 pixels += px;
18519 cdr = XCDR (cdr);
18521 if (EQ (car, Qminus))
18522 pixels = -pixels;
18523 return OK_PIXELS (pixels);
18526 if (EQ (car, Qleft_fringe))
18527 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18528 == !NILP (cdr))
18529 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
18530 : 0);
18531 if (EQ (car, Qright_fringe))
18532 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18533 == !NILP (cdr))
18534 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18535 : 0);
18536 if (EQ (car, Qscroll_bar))
18537 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18538 == EQ (cdr, Qleft))
18539 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
18540 : 0);
18542 car = Fbuffer_local_value (car, it->w->buffer);
18545 if (INTEGERP (car) || FLOATP (car))
18547 double fact;
18548 pixels = XFLOATINT (car);
18549 if (NILP (cdr))
18550 return OK_PIXELS (pixels);
18551 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
18552 return OK_PIXELS (pixels * fact);
18553 return 0;
18556 return 0;
18559 return 0;
18562 /* Produce a stretch glyph for iterator IT. IT->object is the value
18563 of the glyph property displayed. The value must be a list
18564 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18565 being recognized:
18567 1. `:width WIDTH' specifies that the space should be WIDTH *
18568 canonical char width wide. WIDTH may be an integer or floating
18569 point number.
18571 2. `:relative-width FACTOR' specifies that the width of the stretch
18572 should be computed from the width of the first character having the
18573 `glyph' property, and should be FACTOR times that width.
18575 3. `:align-to HPOS' specifies that the space should be wide enough
18576 to reach HPOS, a value in canonical character units.
18578 Exactly one of the above pairs must be present.
18580 4. `:height HEIGHT' specifies that the height of the stretch produced
18581 should be HEIGHT, measured in canonical character units.
18583 5. `:relative-height FACTOR' specifies that the height of the
18584 stretch should be FACTOR times the height of the characters having
18585 the glyph property.
18587 Either none or exactly one of 4 or 5 must be present.
18589 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18590 of the stretch should be used for the ascent of the stretch.
18591 ASCENT must be in the range 0 <= ASCENT <= 100. */
18593 static void
18594 produce_stretch_glyph (it)
18595 struct it *it;
18597 /* (space :width WIDTH :height HEIGHT ...) */
18598 Lisp_Object prop, plist;
18599 int width = 0, height = 0;
18600 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18601 int ascent = 0;
18602 double tem;
18603 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18604 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18606 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18608 /* List should start with `space'. */
18609 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18610 plist = XCDR (it->object);
18612 /* Compute the width of the stretch. */
18613 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18614 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18616 /* Absolute width `:width WIDTH' specified and valid. */
18617 zero_width_ok_p = 1;
18618 width = (int)tem;
18620 else if (prop = Fplist_get (plist, QCrelative_width),
18621 NUMVAL (prop) > 0)
18623 /* Relative width `:relative-width FACTOR' specified and valid.
18624 Compute the width of the characters having the `glyph'
18625 property. */
18626 struct it it2;
18627 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18629 it2 = *it;
18630 if (it->multibyte_p)
18632 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18633 - IT_BYTEPOS (*it));
18634 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18636 else
18637 it2.c = *p, it2.len = 1;
18639 it2.glyph_row = NULL;
18640 it2.what = IT_CHARACTER;
18641 x_produce_glyphs (&it2);
18642 width = NUMVAL (prop) * it2.pixel_width;
18644 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18645 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18647 width = max (0, (int)tem - it->current_x);
18648 zero_width_ok_p = 1;
18650 else
18651 /* Nothing specified -> width defaults to canonical char width. */
18652 width = FRAME_COLUMN_WIDTH (it->f);
18654 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18655 width = 1;
18657 /* Compute height. */
18658 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18659 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18661 height = (int)tem;
18662 zero_height_ok_p = 1;
18664 else if (prop = Fplist_get (plist, QCrelative_height),
18665 NUMVAL (prop) > 0)
18666 height = FONT_HEIGHT (font) * NUMVAL (prop);
18667 else
18668 height = FONT_HEIGHT (font);
18670 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18671 height = 1;
18673 /* Compute percentage of height used for ascent. If
18674 `:ascent ASCENT' is present and valid, use that. Otherwise,
18675 derive the ascent from the font in use. */
18676 if (prop = Fplist_get (plist, QCascent),
18677 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18678 ascent = height * NUMVAL (prop) / 100.0;
18679 else if (!NILP (prop)
18680 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18681 ascent = min (max (0, (int)tem), height);
18682 else
18683 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18685 if (width > 0 && height > 0 && it->glyph_row)
18687 Lisp_Object object = it->stack[it->sp - 1].string;
18688 if (!STRINGP (object))
18689 object = it->w->buffer;
18690 append_stretch_glyph (it, object, width, height, ascent);
18693 it->pixel_width = width;
18694 it->ascent = it->phys_ascent = ascent;
18695 it->descent = it->phys_descent = height - it->ascent;
18696 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18698 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18700 if (face->box_line_width > 0)
18702 it->ascent += face->box_line_width;
18703 it->descent += face->box_line_width;
18706 if (it->start_of_box_run_p)
18707 it->pixel_width += abs (face->box_line_width);
18708 if (it->end_of_box_run_p)
18709 it->pixel_width += abs (face->box_line_width);
18712 take_vertical_position_into_account (it);
18715 /* RIF:
18716 Produce glyphs/get display metrics for the display element IT is
18717 loaded with. See the description of struct display_iterator in
18718 dispextern.h for an overview of struct display_iterator. */
18720 void
18721 x_produce_glyphs (it)
18722 struct it *it;
18724 it->glyph_not_available_p = 0;
18726 if (it->what == IT_CHARACTER)
18728 XChar2b char2b;
18729 XFontStruct *font;
18730 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18731 XCharStruct *pcm;
18732 int font_not_found_p;
18733 struct font_info *font_info;
18734 int boff; /* baseline offset */
18735 /* We may change it->multibyte_p upon unibyte<->multibyte
18736 conversion. So, save the current value now and restore it
18737 later.
18739 Note: It seems that we don't have to record multibyte_p in
18740 struct glyph because the character code itself tells if or
18741 not the character is multibyte. Thus, in the future, we must
18742 consider eliminating the field `multibyte_p' in the struct
18743 glyph. */
18744 int saved_multibyte_p = it->multibyte_p;
18746 /* Maybe translate single-byte characters to multibyte, or the
18747 other way. */
18748 it->char_to_display = it->c;
18749 if (!ASCII_BYTE_P (it->c))
18751 if (unibyte_display_via_language_environment
18752 && SINGLE_BYTE_CHAR_P (it->c)
18753 && (it->c >= 0240
18754 || !NILP (Vnonascii_translation_table)))
18756 it->char_to_display = unibyte_char_to_multibyte (it->c);
18757 it->multibyte_p = 1;
18758 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18759 face = FACE_FROM_ID (it->f, it->face_id);
18761 else if (!SINGLE_BYTE_CHAR_P (it->c)
18762 && !it->multibyte_p)
18764 it->multibyte_p = 1;
18765 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18766 face = FACE_FROM_ID (it->f, it->face_id);
18770 /* Get font to use. Encode IT->char_to_display. */
18771 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18772 &char2b, it->multibyte_p, 0);
18773 font = face->font;
18775 /* When no suitable font found, use the default font. */
18776 font_not_found_p = font == NULL;
18777 if (font_not_found_p)
18779 font = FRAME_FONT (it->f);
18780 boff = FRAME_BASELINE_OFFSET (it->f);
18781 font_info = NULL;
18783 else
18785 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18786 boff = font_info->baseline_offset;
18787 if (font_info->vertical_centering)
18788 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18791 if (it->char_to_display >= ' '
18792 && (!it->multibyte_p || it->char_to_display < 128))
18794 /* Either unibyte or ASCII. */
18795 int stretched_p;
18797 it->nglyphs = 1;
18799 pcm = rif->per_char_metric (font, &char2b,
18800 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18801 it->ascent = FONT_BASE (font) + boff;
18802 it->descent = FONT_DESCENT (font) - boff;
18804 if (pcm)
18806 it->phys_ascent = pcm->ascent + boff;
18807 it->phys_descent = pcm->descent - boff;
18808 it->pixel_width = pcm->width;
18810 else
18812 it->glyph_not_available_p = 1;
18813 it->phys_ascent = FONT_BASE (font) + boff;
18814 it->phys_descent = FONT_DESCENT (font) - boff;
18815 it->pixel_width = FONT_WIDTH (font);
18818 /* If this is a space inside a region of text with
18819 `space-width' property, change its width. */
18820 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18821 if (stretched_p)
18822 it->pixel_width *= XFLOATINT (it->space_width);
18824 /* If face has a box, add the box thickness to the character
18825 height. If character has a box line to the left and/or
18826 right, add the box line width to the character's width. */
18827 if (face->box != FACE_NO_BOX)
18829 int thick = face->box_line_width;
18831 if (thick > 0)
18833 it->ascent += thick;
18834 it->descent += thick;
18836 else
18837 thick = -thick;
18839 if (it->start_of_box_run_p)
18840 it->pixel_width += thick;
18841 if (it->end_of_box_run_p)
18842 it->pixel_width += thick;
18845 /* If face has an overline, add the height of the overline
18846 (1 pixel) and a 1 pixel margin to the character height. */
18847 if (face->overline_p)
18848 it->ascent += 2;
18850 take_vertical_position_into_account (it);
18852 /* If we have to actually produce glyphs, do it. */
18853 if (it->glyph_row)
18855 if (stretched_p)
18857 /* Translate a space with a `space-width' property
18858 into a stretch glyph. */
18859 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18860 / FONT_HEIGHT (font));
18861 append_stretch_glyph (it, it->object, it->pixel_width,
18862 it->ascent + it->descent, ascent);
18864 else
18865 append_glyph (it);
18867 /* If characters with lbearing or rbearing are displayed
18868 in this line, record that fact in a flag of the
18869 glyph row. This is used to optimize X output code. */
18870 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18871 it->glyph_row->contains_overlapping_glyphs_p = 1;
18874 else if (it->char_to_display == '\n')
18876 /* A newline has no width but we need the height of the line. */
18877 it->pixel_width = 0;
18878 it->nglyphs = 0;
18879 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18880 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18882 if (face->box != FACE_NO_BOX
18883 && face->box_line_width > 0)
18885 it->ascent += face->box_line_width;
18886 it->descent += face->box_line_width;
18889 else if (it->char_to_display == '\t')
18891 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18892 int x = it->current_x + it->continuation_lines_width;
18893 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18895 /* If the distance from the current position to the next tab
18896 stop is less than a canonical character width, use the
18897 tab stop after that. */
18898 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18899 next_tab_x += tab_width;
18901 it->pixel_width = next_tab_x - x;
18902 it->nglyphs = 1;
18903 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18904 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18906 if (it->glyph_row)
18908 append_stretch_glyph (it, it->object, it->pixel_width,
18909 it->ascent + it->descent, it->ascent);
18912 else
18914 /* A multi-byte character. Assume that the display width of the
18915 character is the width of the character multiplied by the
18916 width of the font. */
18918 /* If we found a font, this font should give us the right
18919 metrics. If we didn't find a font, use the frame's
18920 default font and calculate the width of the character
18921 from the charset width; this is what old redisplay code
18922 did. */
18924 pcm = rif->per_char_metric (font, &char2b,
18925 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18927 if (font_not_found_p || !pcm)
18929 int charset = CHAR_CHARSET (it->char_to_display);
18931 it->glyph_not_available_p = 1;
18932 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18933 * CHARSET_WIDTH (charset));
18934 it->phys_ascent = FONT_BASE (font) + boff;
18935 it->phys_descent = FONT_DESCENT (font) - boff;
18937 else
18939 it->pixel_width = pcm->width;
18940 it->phys_ascent = pcm->ascent + boff;
18941 it->phys_descent = pcm->descent - boff;
18942 if (it->glyph_row
18943 && (pcm->lbearing < 0
18944 || pcm->rbearing > pcm->width))
18945 it->glyph_row->contains_overlapping_glyphs_p = 1;
18947 it->nglyphs = 1;
18948 it->ascent = FONT_BASE (font) + boff;
18949 it->descent = FONT_DESCENT (font) - boff;
18950 if (face->box != FACE_NO_BOX)
18952 int thick = face->box_line_width;
18954 if (thick > 0)
18956 it->ascent += thick;
18957 it->descent += thick;
18959 else
18960 thick = - thick;
18962 if (it->start_of_box_run_p)
18963 it->pixel_width += thick;
18964 if (it->end_of_box_run_p)
18965 it->pixel_width += thick;
18968 /* If face has an overline, add the height of the overline
18969 (1 pixel) and a 1 pixel margin to the character height. */
18970 if (face->overline_p)
18971 it->ascent += 2;
18973 take_vertical_position_into_account (it);
18975 if (it->glyph_row)
18976 append_glyph (it);
18978 it->multibyte_p = saved_multibyte_p;
18980 else if (it->what == IT_COMPOSITION)
18982 /* Note: A composition is represented as one glyph in the
18983 glyph matrix. There are no padding glyphs. */
18984 XChar2b char2b;
18985 XFontStruct *font;
18986 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18987 XCharStruct *pcm;
18988 int font_not_found_p;
18989 struct font_info *font_info;
18990 int boff; /* baseline offset */
18991 struct composition *cmp = composition_table[it->cmp_id];
18993 /* Maybe translate single-byte characters to multibyte. */
18994 it->char_to_display = it->c;
18995 if (unibyte_display_via_language_environment
18996 && SINGLE_BYTE_CHAR_P (it->c)
18997 && (it->c >= 0240
18998 || (it->c >= 0200
18999 && !NILP (Vnonascii_translation_table))))
19001 it->char_to_display = unibyte_char_to_multibyte (it->c);
19004 /* Get face and font to use. Encode IT->char_to_display. */
19005 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19006 face = FACE_FROM_ID (it->f, it->face_id);
19007 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19008 &char2b, it->multibyte_p, 0);
19009 font = face->font;
19011 /* When no suitable font found, use the default font. */
19012 font_not_found_p = font == NULL;
19013 if (font_not_found_p)
19015 font = FRAME_FONT (it->f);
19016 boff = FRAME_BASELINE_OFFSET (it->f);
19017 font_info = NULL;
19019 else
19021 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19022 boff = font_info->baseline_offset;
19023 if (font_info->vertical_centering)
19024 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19027 /* There are no padding glyphs, so there is only one glyph to
19028 produce for the composition. Important is that pixel_width,
19029 ascent and descent are the values of what is drawn by
19030 draw_glyphs (i.e. the values of the overall glyphs composed). */
19031 it->nglyphs = 1;
19033 /* If we have not yet calculated pixel size data of glyphs of
19034 the composition for the current face font, calculate them
19035 now. Theoretically, we have to check all fonts for the
19036 glyphs, but that requires much time and memory space. So,
19037 here we check only the font of the first glyph. This leads
19038 to incorrect display very rarely, and C-l (recenter) can
19039 correct the display anyway. */
19040 if (cmp->font != (void *) font)
19042 /* Ascent and descent of the font of the first character of
19043 this composition (adjusted by baseline offset). Ascent
19044 and descent of overall glyphs should not be less than
19045 them respectively. */
19046 int font_ascent = FONT_BASE (font) + boff;
19047 int font_descent = FONT_DESCENT (font) - boff;
19048 /* Bounding box of the overall glyphs. */
19049 int leftmost, rightmost, lowest, highest;
19050 int i, width, ascent, descent;
19052 cmp->font = (void *) font;
19054 /* Initialize the bounding box. */
19055 if (font_info
19056 && (pcm = rif->per_char_metric (font, &char2b,
19057 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19059 width = pcm->width;
19060 ascent = pcm->ascent;
19061 descent = pcm->descent;
19063 else
19065 width = FONT_WIDTH (font);
19066 ascent = FONT_BASE (font);
19067 descent = FONT_DESCENT (font);
19070 rightmost = width;
19071 lowest = - descent + boff;
19072 highest = ascent + boff;
19073 leftmost = 0;
19075 if (font_info
19076 && font_info->default_ascent
19077 && CHAR_TABLE_P (Vuse_default_ascent)
19078 && !NILP (Faref (Vuse_default_ascent,
19079 make_number (it->char_to_display))))
19080 highest = font_info->default_ascent + boff;
19082 /* Draw the first glyph at the normal position. It may be
19083 shifted to right later if some other glyphs are drawn at
19084 the left. */
19085 cmp->offsets[0] = 0;
19086 cmp->offsets[1] = boff;
19088 /* Set cmp->offsets for the remaining glyphs. */
19089 for (i = 1; i < cmp->glyph_len; i++)
19091 int left, right, btm, top;
19092 int ch = COMPOSITION_GLYPH (cmp, i);
19093 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19095 face = FACE_FROM_ID (it->f, face_id);
19096 get_char_face_and_encoding (it->f, ch, face->id,
19097 &char2b, it->multibyte_p, 0);
19098 font = face->font;
19099 if (font == NULL)
19101 font = FRAME_FONT (it->f);
19102 boff = FRAME_BASELINE_OFFSET (it->f);
19103 font_info = NULL;
19105 else
19107 font_info
19108 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19109 boff = font_info->baseline_offset;
19110 if (font_info->vertical_centering)
19111 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19114 if (font_info
19115 && (pcm = rif->per_char_metric (font, &char2b,
19116 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19118 width = pcm->width;
19119 ascent = pcm->ascent;
19120 descent = pcm->descent;
19122 else
19124 width = FONT_WIDTH (font);
19125 ascent = 1;
19126 descent = 0;
19129 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19131 /* Relative composition with or without
19132 alternate chars. */
19133 left = (leftmost + rightmost - width) / 2;
19134 btm = - descent + boff;
19135 if (font_info && font_info->relative_compose
19136 && (! CHAR_TABLE_P (Vignore_relative_composition)
19137 || NILP (Faref (Vignore_relative_composition,
19138 make_number (ch)))))
19141 if (- descent >= font_info->relative_compose)
19142 /* One extra pixel between two glyphs. */
19143 btm = highest + 1;
19144 else if (ascent <= 0)
19145 /* One extra pixel between two glyphs. */
19146 btm = lowest - 1 - ascent - descent;
19149 else
19151 /* A composition rule is specified by an integer
19152 value that encodes global and new reference
19153 points (GREF and NREF). GREF and NREF are
19154 specified by numbers as below:
19156 0---1---2 -- ascent
19160 9--10--11 -- center
19162 ---3---4---5--- baseline
19164 6---7---8 -- descent
19166 int rule = COMPOSITION_RULE (cmp, i);
19167 int gref, nref, grefx, grefy, nrefx, nrefy;
19169 COMPOSITION_DECODE_RULE (rule, gref, nref);
19170 grefx = gref % 3, nrefx = nref % 3;
19171 grefy = gref / 3, nrefy = nref / 3;
19173 left = (leftmost
19174 + grefx * (rightmost - leftmost) / 2
19175 - nrefx * width / 2);
19176 btm = ((grefy == 0 ? highest
19177 : grefy == 1 ? 0
19178 : grefy == 2 ? lowest
19179 : (highest + lowest) / 2)
19180 - (nrefy == 0 ? ascent + descent
19181 : nrefy == 1 ? descent - boff
19182 : nrefy == 2 ? 0
19183 : (ascent + descent) / 2));
19186 cmp->offsets[i * 2] = left;
19187 cmp->offsets[i * 2 + 1] = btm + descent;
19189 /* Update the bounding box of the overall glyphs. */
19190 right = left + width;
19191 top = btm + descent + ascent;
19192 if (left < leftmost)
19193 leftmost = left;
19194 if (right > rightmost)
19195 rightmost = right;
19196 if (top > highest)
19197 highest = top;
19198 if (btm < lowest)
19199 lowest = btm;
19202 /* If there are glyphs whose x-offsets are negative,
19203 shift all glyphs to the right and make all x-offsets
19204 non-negative. */
19205 if (leftmost < 0)
19207 for (i = 0; i < cmp->glyph_len; i++)
19208 cmp->offsets[i * 2] -= leftmost;
19209 rightmost -= leftmost;
19212 cmp->pixel_width = rightmost;
19213 cmp->ascent = highest;
19214 cmp->descent = - lowest;
19215 if (cmp->ascent < font_ascent)
19216 cmp->ascent = font_ascent;
19217 if (cmp->descent < font_descent)
19218 cmp->descent = font_descent;
19221 it->pixel_width = cmp->pixel_width;
19222 it->ascent = it->phys_ascent = cmp->ascent;
19223 it->descent = it->phys_descent = cmp->descent;
19225 if (face->box != FACE_NO_BOX)
19227 int thick = face->box_line_width;
19229 if (thick > 0)
19231 it->ascent += thick;
19232 it->descent += thick;
19234 else
19235 thick = - thick;
19237 if (it->start_of_box_run_p)
19238 it->pixel_width += thick;
19239 if (it->end_of_box_run_p)
19240 it->pixel_width += thick;
19243 /* If face has an overline, add the height of the overline
19244 (1 pixel) and a 1 pixel margin to the character height. */
19245 if (face->overline_p)
19246 it->ascent += 2;
19248 take_vertical_position_into_account (it);
19250 if (it->glyph_row)
19251 append_composite_glyph (it);
19253 else if (it->what == IT_IMAGE)
19254 produce_image_glyph (it);
19255 else if (it->what == IT_STRETCH)
19256 produce_stretch_glyph (it);
19258 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19259 because this isn't true for images with `:ascent 100'. */
19260 xassert (it->ascent >= 0 && it->descent >= 0);
19261 if (it->area == TEXT_AREA)
19262 it->current_x += it->pixel_width;
19264 it->descent += it->extra_line_spacing;
19266 it->max_ascent = max (it->max_ascent, it->ascent);
19267 it->max_descent = max (it->max_descent, it->descent);
19268 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19269 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19272 /* EXPORT for RIF:
19273 Output LEN glyphs starting at START at the nominal cursor position.
19274 Advance the nominal cursor over the text. The global variable
19275 updated_window contains the window being updated, updated_row is
19276 the glyph row being updated, and updated_area is the area of that
19277 row being updated. */
19279 void
19280 x_write_glyphs (start, len)
19281 struct glyph *start;
19282 int len;
19284 int x, hpos;
19286 xassert (updated_window && updated_row);
19287 BLOCK_INPUT;
19289 /* Write glyphs. */
19291 hpos = start - updated_row->glyphs[updated_area];
19292 x = draw_glyphs (updated_window, output_cursor.x,
19293 updated_row, updated_area,
19294 hpos, hpos + len,
19295 DRAW_NORMAL_TEXT, 0);
19297 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19298 if (updated_area == TEXT_AREA
19299 && updated_window->phys_cursor_on_p
19300 && updated_window->phys_cursor.vpos == output_cursor.vpos
19301 && updated_window->phys_cursor.hpos >= hpos
19302 && updated_window->phys_cursor.hpos < hpos + len)
19303 updated_window->phys_cursor_on_p = 0;
19305 UNBLOCK_INPUT;
19307 /* Advance the output cursor. */
19308 output_cursor.hpos += len;
19309 output_cursor.x = x;
19313 /* EXPORT for RIF:
19314 Insert LEN glyphs from START at the nominal cursor position. */
19316 void
19317 x_insert_glyphs (start, len)
19318 struct glyph *start;
19319 int len;
19321 struct frame *f;
19322 struct window *w;
19323 int line_height, shift_by_width, shifted_region_width;
19324 struct glyph_row *row;
19325 struct glyph *glyph;
19326 int frame_x, frame_y, hpos;
19328 xassert (updated_window && updated_row);
19329 BLOCK_INPUT;
19330 w = updated_window;
19331 f = XFRAME (WINDOW_FRAME (w));
19333 /* Get the height of the line we are in. */
19334 row = updated_row;
19335 line_height = row->height;
19337 /* Get the width of the glyphs to insert. */
19338 shift_by_width = 0;
19339 for (glyph = start; glyph < start + len; ++glyph)
19340 shift_by_width += glyph->pixel_width;
19342 /* Get the width of the region to shift right. */
19343 shifted_region_width = (window_box_width (w, updated_area)
19344 - output_cursor.x
19345 - shift_by_width);
19347 /* Shift right. */
19348 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19349 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19351 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19352 line_height, shift_by_width);
19354 /* Write the glyphs. */
19355 hpos = start - row->glyphs[updated_area];
19356 draw_glyphs (w, output_cursor.x, row, updated_area,
19357 hpos, hpos + len,
19358 DRAW_NORMAL_TEXT, 0);
19360 /* Advance the output cursor. */
19361 output_cursor.hpos += len;
19362 output_cursor.x += shift_by_width;
19363 UNBLOCK_INPUT;
19367 /* EXPORT for RIF:
19368 Erase the current text line from the nominal cursor position
19369 (inclusive) to pixel column TO_X (exclusive). The idea is that
19370 everything from TO_X onward is already erased.
19372 TO_X is a pixel position relative to updated_area of
19373 updated_window. TO_X == -1 means clear to the end of this area. */
19375 void
19376 x_clear_end_of_line (to_x)
19377 int to_x;
19379 struct frame *f;
19380 struct window *w = updated_window;
19381 int max_x, min_y, max_y;
19382 int from_x, from_y, to_y;
19384 xassert (updated_window && updated_row);
19385 f = XFRAME (w->frame);
19387 if (updated_row->full_width_p)
19388 max_x = WINDOW_TOTAL_WIDTH (w);
19389 else
19390 max_x = window_box_width (w, updated_area);
19391 max_y = window_text_bottom_y (w);
19393 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19394 of window. For TO_X > 0, truncate to end of drawing area. */
19395 if (to_x == 0)
19396 return;
19397 else if (to_x < 0)
19398 to_x = max_x;
19399 else
19400 to_x = min (to_x, max_x);
19402 to_y = min (max_y, output_cursor.y + updated_row->height);
19404 /* Notice if the cursor will be cleared by this operation. */
19405 if (!updated_row->full_width_p)
19406 notice_overwritten_cursor (w, updated_area,
19407 output_cursor.x, -1,
19408 updated_row->y,
19409 MATRIX_ROW_BOTTOM_Y (updated_row));
19411 from_x = output_cursor.x;
19413 /* Translate to frame coordinates. */
19414 if (updated_row->full_width_p)
19416 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19417 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19419 else
19421 int area_left = window_box_left (w, updated_area);
19422 from_x += area_left;
19423 to_x += area_left;
19426 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19427 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19428 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19430 /* Prevent inadvertently clearing to end of the X window. */
19431 if (to_x > from_x && to_y > from_y)
19433 BLOCK_INPUT;
19434 rif->clear_frame_area (f, from_x, from_y,
19435 to_x - from_x, to_y - from_y);
19436 UNBLOCK_INPUT;
19440 #endif /* HAVE_WINDOW_SYSTEM */
19444 /***********************************************************************
19445 Cursor types
19446 ***********************************************************************/
19448 /* Value is the internal representation of the specified cursor type
19449 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19450 of the bar cursor. */
19452 static enum text_cursor_kinds
19453 get_specified_cursor_type (arg, width)
19454 Lisp_Object arg;
19455 int *width;
19457 enum text_cursor_kinds type;
19459 if (NILP (arg))
19460 return NO_CURSOR;
19462 if (EQ (arg, Qbox))
19463 return FILLED_BOX_CURSOR;
19465 if (EQ (arg, Qhollow))
19466 return HOLLOW_BOX_CURSOR;
19468 if (EQ (arg, Qbar))
19470 *width = 2;
19471 return BAR_CURSOR;
19474 if (CONSP (arg)
19475 && EQ (XCAR (arg), Qbar)
19476 && INTEGERP (XCDR (arg))
19477 && XINT (XCDR (arg)) >= 0)
19479 *width = XINT (XCDR (arg));
19480 return BAR_CURSOR;
19483 if (EQ (arg, Qhbar))
19485 *width = 2;
19486 return HBAR_CURSOR;
19489 if (CONSP (arg)
19490 && EQ (XCAR (arg), Qhbar)
19491 && INTEGERP (XCDR (arg))
19492 && XINT (XCDR (arg)) >= 0)
19494 *width = XINT (XCDR (arg));
19495 return HBAR_CURSOR;
19498 /* Treat anything unknown as "hollow box cursor".
19499 It was bad to signal an error; people have trouble fixing
19500 .Xdefaults with Emacs, when it has something bad in it. */
19501 type = HOLLOW_BOX_CURSOR;
19503 return type;
19506 /* Set the default cursor types for specified frame. */
19507 void
19508 set_frame_cursor_types (f, arg)
19509 struct frame *f;
19510 Lisp_Object arg;
19512 int width;
19513 Lisp_Object tem;
19515 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19516 FRAME_CURSOR_WIDTH (f) = width;
19518 /* By default, set up the blink-off state depending on the on-state. */
19520 tem = Fassoc (arg, Vblink_cursor_alist);
19521 if (!NILP (tem))
19523 FRAME_BLINK_OFF_CURSOR (f)
19524 = get_specified_cursor_type (XCDR (tem), &width);
19525 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19527 else
19528 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19532 /* Return the cursor we want to be displayed in window W. Return
19533 width of bar/hbar cursor through WIDTH arg. Return with
19534 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19535 (i.e. if the `system caret' should track this cursor).
19537 In a mini-buffer window, we want the cursor only to appear if we
19538 are reading input from this window. For the selected window, we
19539 want the cursor type given by the frame parameter or buffer local
19540 setting of cursor-type. If explicitly marked off, draw no cursor.
19541 In all other cases, we want a hollow box cursor. */
19543 static enum text_cursor_kinds
19544 get_window_cursor_type (w, glyph, width, active_cursor)
19545 struct window *w;
19546 struct glyph *glyph;
19547 int *width;
19548 int *active_cursor;
19550 struct frame *f = XFRAME (w->frame);
19551 struct buffer *b = XBUFFER (w->buffer);
19552 int cursor_type = DEFAULT_CURSOR;
19553 Lisp_Object alt_cursor;
19554 int non_selected = 0;
19556 *active_cursor = 1;
19558 /* Echo area */
19559 if (cursor_in_echo_area
19560 && FRAME_HAS_MINIBUF_P (f)
19561 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19563 if (w == XWINDOW (echo_area_window))
19565 *width = FRAME_CURSOR_WIDTH (f);
19566 return FRAME_DESIRED_CURSOR (f);
19569 *active_cursor = 0;
19570 non_selected = 1;
19573 /* Nonselected window or nonselected frame. */
19574 else if (w != XWINDOW (f->selected_window)
19575 #ifdef HAVE_WINDOW_SYSTEM
19576 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19577 #endif
19580 *active_cursor = 0;
19582 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19583 return NO_CURSOR;
19585 non_selected = 1;
19588 /* Never display a cursor in a window in which cursor-type is nil. */
19589 if (NILP (b->cursor_type))
19590 return NO_CURSOR;
19592 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19593 if (non_selected)
19595 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19596 return get_specified_cursor_type (alt_cursor, width);
19599 /* Get the normal cursor type for this window. */
19600 if (EQ (b->cursor_type, Qt))
19602 cursor_type = FRAME_DESIRED_CURSOR (f);
19603 *width = FRAME_CURSOR_WIDTH (f);
19605 else
19606 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19608 /* Use normal cursor if not blinked off. */
19609 if (!w->cursor_off_p)
19611 if (glyph->type == IMAGE_GLYPH) {
19612 if (cursor_type == FILLED_BOX_CURSOR)
19613 cursor_type = HOLLOW_BOX_CURSOR;
19615 return cursor_type;
19618 /* Cursor is blinked off, so determine how to "toggle" it. */
19620 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19621 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19622 return get_specified_cursor_type (XCDR (alt_cursor), width);
19624 /* Then see if frame has specified a specific blink off cursor type. */
19625 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19627 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19628 return FRAME_BLINK_OFF_CURSOR (f);
19631 #if 0
19632 /* Some people liked having a permanently visible blinking cursor,
19633 while others had very strong opinions against it. So it was
19634 decided to remove it. KFS 2003-09-03 */
19636 /* Finally perform built-in cursor blinking:
19637 filled box <-> hollow box
19638 wide [h]bar <-> narrow [h]bar
19639 narrow [h]bar <-> no cursor
19640 other type <-> no cursor */
19642 if (cursor_type == FILLED_BOX_CURSOR)
19643 return HOLLOW_BOX_CURSOR;
19645 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19647 *width = 1;
19648 return cursor_type;
19650 #endif
19652 return NO_CURSOR;
19656 #ifdef HAVE_WINDOW_SYSTEM
19658 /* Notice when the text cursor of window W has been completely
19659 overwritten by a drawing operation that outputs glyphs in AREA
19660 starting at X0 and ending at X1 in the line starting at Y0 and
19661 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19662 the rest of the line after X0 has been written. Y coordinates
19663 are window-relative. */
19665 static void
19666 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19667 struct window *w;
19668 enum glyph_row_area area;
19669 int x0, y0, x1, y1;
19671 int cx0, cx1, cy0, cy1;
19672 struct glyph_row *row;
19674 if (!w->phys_cursor_on_p)
19675 return;
19676 if (area != TEXT_AREA)
19677 return;
19679 row = w->current_matrix->rows + w->phys_cursor.vpos;
19680 if (!row->displays_text_p)
19681 return;
19683 if (row->cursor_in_fringe_p)
19685 row->cursor_in_fringe_p = 0;
19686 draw_fringe_bitmap (w, row, 0);
19687 w->phys_cursor_on_p = 0;
19688 return;
19691 cx0 = w->phys_cursor.x;
19692 cx1 = cx0 + w->phys_cursor_width;
19693 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19694 return;
19696 /* The cursor image will be completely removed from the
19697 screen if the output area intersects the cursor area in
19698 y-direction. When we draw in [y0 y1[, and some part of
19699 the cursor is at y < y0, that part must have been drawn
19700 before. When scrolling, the cursor is erased before
19701 actually scrolling, so we don't come here. When not
19702 scrolling, the rows above the old cursor row must have
19703 changed, and in this case these rows must have written
19704 over the cursor image.
19706 Likewise if part of the cursor is below y1, with the
19707 exception of the cursor being in the first blank row at
19708 the buffer and window end because update_text_area
19709 doesn't draw that row. (Except when it does, but
19710 that's handled in update_text_area.) */
19712 cy0 = w->phys_cursor.y;
19713 cy1 = cy0 + w->phys_cursor_height;
19714 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19715 return;
19717 w->phys_cursor_on_p = 0;
19720 #endif /* HAVE_WINDOW_SYSTEM */
19723 /************************************************************************
19724 Mouse Face
19725 ************************************************************************/
19727 #ifdef HAVE_WINDOW_SYSTEM
19729 /* EXPORT for RIF:
19730 Fix the display of area AREA of overlapping row ROW in window W. */
19732 void
19733 x_fix_overlapping_area (w, row, area)
19734 struct window *w;
19735 struct glyph_row *row;
19736 enum glyph_row_area area;
19738 int i, x;
19740 BLOCK_INPUT;
19742 x = 0;
19743 for (i = 0; i < row->used[area];)
19745 if (row->glyphs[area][i].overlaps_vertically_p)
19747 int start = i, start_x = x;
19751 x += row->glyphs[area][i].pixel_width;
19752 ++i;
19754 while (i < row->used[area]
19755 && row->glyphs[area][i].overlaps_vertically_p);
19757 draw_glyphs (w, start_x, row, area,
19758 start, i,
19759 DRAW_NORMAL_TEXT, 1);
19761 else
19763 x += row->glyphs[area][i].pixel_width;
19764 ++i;
19768 UNBLOCK_INPUT;
19772 /* EXPORT:
19773 Draw the cursor glyph of window W in glyph row ROW. See the
19774 comment of draw_glyphs for the meaning of HL. */
19776 void
19777 draw_phys_cursor_glyph (w, row, hl)
19778 struct window *w;
19779 struct glyph_row *row;
19780 enum draw_glyphs_face hl;
19782 /* If cursor hpos is out of bounds, don't draw garbage. This can
19783 happen in mini-buffer windows when switching between echo area
19784 glyphs and mini-buffer. */
19785 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19787 int on_p = w->phys_cursor_on_p;
19788 int x1;
19789 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19790 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19791 hl, 0);
19792 w->phys_cursor_on_p = on_p;
19794 if (hl == DRAW_CURSOR)
19795 w->phys_cursor_width = x1 - w->phys_cursor.x;
19796 /* When we erase the cursor, and ROW is overlapped by other
19797 rows, make sure that these overlapping parts of other rows
19798 are redrawn. */
19799 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19801 if (row > w->current_matrix->rows
19802 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19803 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19805 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19806 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19807 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19813 /* EXPORT:
19814 Erase the image of a cursor of window W from the screen. */
19816 void
19817 erase_phys_cursor (w)
19818 struct window *w;
19820 struct frame *f = XFRAME (w->frame);
19821 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19822 int hpos = w->phys_cursor.hpos;
19823 int vpos = w->phys_cursor.vpos;
19824 int mouse_face_here_p = 0;
19825 struct glyph_matrix *active_glyphs = w->current_matrix;
19826 struct glyph_row *cursor_row;
19827 struct glyph *cursor_glyph;
19828 enum draw_glyphs_face hl;
19830 /* No cursor displayed or row invalidated => nothing to do on the
19831 screen. */
19832 if (w->phys_cursor_type == NO_CURSOR)
19833 goto mark_cursor_off;
19835 /* VPOS >= active_glyphs->nrows means that window has been resized.
19836 Don't bother to erase the cursor. */
19837 if (vpos >= active_glyphs->nrows)
19838 goto mark_cursor_off;
19840 /* If row containing cursor is marked invalid, there is nothing we
19841 can do. */
19842 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19843 if (!cursor_row->enabled_p)
19844 goto mark_cursor_off;
19846 /* If row is completely invisible, don't attempt to delete a cursor which
19847 isn't there. This can happen if cursor is at top of a window, and
19848 we switch to a buffer with a header line in that window. */
19849 if (cursor_row->visible_height <= 0)
19850 goto mark_cursor_off;
19852 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19853 if (cursor_row->cursor_in_fringe_p)
19855 cursor_row->cursor_in_fringe_p = 0;
19856 draw_fringe_bitmap (w, cursor_row, 0);
19857 goto mark_cursor_off;
19860 /* This can happen when the new row is shorter than the old one.
19861 In this case, either draw_glyphs or clear_end_of_line
19862 should have cleared the cursor. Note that we wouldn't be
19863 able to erase the cursor in this case because we don't have a
19864 cursor glyph at hand. */
19865 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19866 goto mark_cursor_off;
19868 /* If the cursor is in the mouse face area, redisplay that when
19869 we clear the cursor. */
19870 if (! NILP (dpyinfo->mouse_face_window)
19871 && w == XWINDOW (dpyinfo->mouse_face_window)
19872 && (vpos > dpyinfo->mouse_face_beg_row
19873 || (vpos == dpyinfo->mouse_face_beg_row
19874 && hpos >= dpyinfo->mouse_face_beg_col))
19875 && (vpos < dpyinfo->mouse_face_end_row
19876 || (vpos == dpyinfo->mouse_face_end_row
19877 && hpos < dpyinfo->mouse_face_end_col))
19878 /* Don't redraw the cursor's spot in mouse face if it is at the
19879 end of a line (on a newline). The cursor appears there, but
19880 mouse highlighting does not. */
19881 && cursor_row->used[TEXT_AREA] > hpos)
19882 mouse_face_here_p = 1;
19884 /* Maybe clear the display under the cursor. */
19885 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19887 int x, y;
19888 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19890 cursor_glyph = get_phys_cursor_glyph (w);
19891 if (cursor_glyph == NULL)
19892 goto mark_cursor_off;
19894 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19895 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19897 rif->clear_frame_area (f, x, y,
19898 cursor_glyph->pixel_width, cursor_row->visible_height);
19901 /* Erase the cursor by redrawing the character underneath it. */
19902 if (mouse_face_here_p)
19903 hl = DRAW_MOUSE_FACE;
19904 else
19905 hl = DRAW_NORMAL_TEXT;
19906 draw_phys_cursor_glyph (w, cursor_row, hl);
19908 mark_cursor_off:
19909 w->phys_cursor_on_p = 0;
19910 w->phys_cursor_type = NO_CURSOR;
19914 /* EXPORT:
19915 Display or clear cursor of window W. If ON is zero, clear the
19916 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19917 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19919 void
19920 display_and_set_cursor (w, on, hpos, vpos, x, y)
19921 struct window *w;
19922 int on, hpos, vpos, x, y;
19924 struct frame *f = XFRAME (w->frame);
19925 int new_cursor_type;
19926 int new_cursor_width;
19927 int active_cursor;
19928 struct glyph_matrix *current_glyphs;
19929 struct glyph_row *glyph_row;
19930 struct glyph *glyph;
19932 /* This is pointless on invisible frames, and dangerous on garbaged
19933 windows and frames; in the latter case, the frame or window may
19934 be in the midst of changing its size, and x and y may be off the
19935 window. */
19936 if (! FRAME_VISIBLE_P (f)
19937 || FRAME_GARBAGED_P (f)
19938 || vpos >= w->current_matrix->nrows
19939 || hpos >= w->current_matrix->matrix_w)
19940 return;
19942 /* If cursor is off and we want it off, return quickly. */
19943 if (!on && !w->phys_cursor_on_p)
19944 return;
19946 current_glyphs = w->current_matrix;
19947 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19948 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19950 /* If cursor row is not enabled, we don't really know where to
19951 display the cursor. */
19952 if (!glyph_row->enabled_p)
19954 w->phys_cursor_on_p = 0;
19955 return;
19958 xassert (interrupt_input_blocked);
19960 /* Set new_cursor_type to the cursor we want to be displayed. */
19961 new_cursor_type = get_window_cursor_type (w, glyph,
19962 &new_cursor_width, &active_cursor);
19964 /* If cursor is currently being shown and we don't want it to be or
19965 it is in the wrong place, or the cursor type is not what we want,
19966 erase it. */
19967 if (w->phys_cursor_on_p
19968 && (!on
19969 || w->phys_cursor.x != x
19970 || w->phys_cursor.y != y
19971 || new_cursor_type != w->phys_cursor_type
19972 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19973 && new_cursor_width != w->phys_cursor_width)))
19974 erase_phys_cursor (w);
19976 /* Don't check phys_cursor_on_p here because that flag is only set
19977 to zero in some cases where we know that the cursor has been
19978 completely erased, to avoid the extra work of erasing the cursor
19979 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19980 still not be visible, or it has only been partly erased. */
19981 if (on)
19983 w->phys_cursor_ascent = glyph_row->ascent;
19984 w->phys_cursor_height = glyph_row->height;
19986 /* Set phys_cursor_.* before x_draw_.* is called because some
19987 of them may need the information. */
19988 w->phys_cursor.x = x;
19989 w->phys_cursor.y = glyph_row->y;
19990 w->phys_cursor.hpos = hpos;
19991 w->phys_cursor.vpos = vpos;
19994 rif->draw_window_cursor (w, glyph_row, x, y,
19995 new_cursor_type, new_cursor_width,
19996 on, active_cursor);
20000 /* Switch the display of W's cursor on or off, according to the value
20001 of ON. */
20003 static void
20004 update_window_cursor (w, on)
20005 struct window *w;
20006 int on;
20008 /* Don't update cursor in windows whose frame is in the process
20009 of being deleted. */
20010 if (w->current_matrix)
20012 BLOCK_INPUT;
20013 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20014 w->phys_cursor.x, w->phys_cursor.y);
20015 UNBLOCK_INPUT;
20020 /* Call update_window_cursor with parameter ON_P on all leaf windows
20021 in the window tree rooted at W. */
20023 static void
20024 update_cursor_in_window_tree (w, on_p)
20025 struct window *w;
20026 int on_p;
20028 while (w)
20030 if (!NILP (w->hchild))
20031 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20032 else if (!NILP (w->vchild))
20033 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20034 else
20035 update_window_cursor (w, on_p);
20037 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20042 /* EXPORT:
20043 Display the cursor on window W, or clear it, according to ON_P.
20044 Don't change the cursor's position. */
20046 void
20047 x_update_cursor (f, on_p)
20048 struct frame *f;
20049 int on_p;
20051 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20055 /* EXPORT:
20056 Clear the cursor of window W to background color, and mark the
20057 cursor as not shown. This is used when the text where the cursor
20058 is is about to be rewritten. */
20060 void
20061 x_clear_cursor (w)
20062 struct window *w;
20064 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20065 update_window_cursor (w, 0);
20069 /* EXPORT:
20070 Display the active region described by mouse_face_* according to DRAW. */
20072 void
20073 show_mouse_face (dpyinfo, draw)
20074 Display_Info *dpyinfo;
20075 enum draw_glyphs_face draw;
20077 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20078 struct frame *f = XFRAME (WINDOW_FRAME (w));
20080 if (/* If window is in the process of being destroyed, don't bother
20081 to do anything. */
20082 w->current_matrix != NULL
20083 /* Don't update mouse highlight if hidden */
20084 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20085 /* Recognize when we are called to operate on rows that don't exist
20086 anymore. This can happen when a window is split. */
20087 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20089 int phys_cursor_on_p = w->phys_cursor_on_p;
20090 struct glyph_row *row, *first, *last;
20092 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20093 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20095 for (row = first; row <= last && row->enabled_p; ++row)
20097 int start_hpos, end_hpos, start_x;
20099 /* For all but the first row, the highlight starts at column 0. */
20100 if (row == first)
20102 start_hpos = dpyinfo->mouse_face_beg_col;
20103 start_x = dpyinfo->mouse_face_beg_x;
20105 else
20107 start_hpos = 0;
20108 start_x = 0;
20111 if (row == last)
20112 end_hpos = dpyinfo->mouse_face_end_col;
20113 else
20114 end_hpos = row->used[TEXT_AREA];
20116 if (end_hpos > start_hpos)
20118 draw_glyphs (w, start_x, row, TEXT_AREA,
20119 start_hpos, end_hpos,
20120 draw, 0);
20122 row->mouse_face_p
20123 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20127 /* When we've written over the cursor, arrange for it to
20128 be displayed again. */
20129 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20131 BLOCK_INPUT;
20132 display_and_set_cursor (w, 1,
20133 w->phys_cursor.hpos, w->phys_cursor.vpos,
20134 w->phys_cursor.x, w->phys_cursor.y);
20135 UNBLOCK_INPUT;
20139 /* Change the mouse cursor. */
20140 if (draw == DRAW_NORMAL_TEXT)
20141 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20142 else if (draw == DRAW_MOUSE_FACE)
20143 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20144 else
20145 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20148 /* EXPORT:
20149 Clear out the mouse-highlighted active region.
20150 Redraw it un-highlighted first. Value is non-zero if mouse
20151 face was actually drawn unhighlighted. */
20154 clear_mouse_face (dpyinfo)
20155 Display_Info *dpyinfo;
20157 int cleared = 0;
20159 if (!NILP (dpyinfo->mouse_face_window))
20161 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20162 cleared = 1;
20165 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20166 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20167 dpyinfo->mouse_face_window = Qnil;
20168 dpyinfo->mouse_face_overlay = Qnil;
20169 return cleared;
20173 /* EXPORT:
20174 Non-zero if physical cursor of window W is within mouse face. */
20177 cursor_in_mouse_face_p (w)
20178 struct window *w;
20180 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20181 int in_mouse_face = 0;
20183 if (WINDOWP (dpyinfo->mouse_face_window)
20184 && XWINDOW (dpyinfo->mouse_face_window) == w)
20186 int hpos = w->phys_cursor.hpos;
20187 int vpos = w->phys_cursor.vpos;
20189 if (vpos >= dpyinfo->mouse_face_beg_row
20190 && vpos <= dpyinfo->mouse_face_end_row
20191 && (vpos > dpyinfo->mouse_face_beg_row
20192 || hpos >= dpyinfo->mouse_face_beg_col)
20193 && (vpos < dpyinfo->mouse_face_end_row
20194 || hpos < dpyinfo->mouse_face_end_col
20195 || dpyinfo->mouse_face_past_end))
20196 in_mouse_face = 1;
20199 return in_mouse_face;
20205 /* Find the glyph matrix position of buffer position CHARPOS in window
20206 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20207 current glyphs must be up to date. If CHARPOS is above window
20208 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20209 of last line in W. In the row containing CHARPOS, stop before glyphs
20210 having STOP as object. */
20212 #if 1 /* This is a version of fast_find_position that's more correct
20213 in the presence of hscrolling, for example. I didn't install
20214 it right away because the problem fixed is minor, it failed
20215 in 20.x as well, and I think it's too risky to install
20216 so near the release of 21.1. 2001-09-25 gerd. */
20218 static int
20219 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20220 struct window *w;
20221 int charpos;
20222 int *hpos, *vpos, *x, *y;
20223 Lisp_Object stop;
20225 struct glyph_row *row, *first;
20226 struct glyph *glyph, *end;
20227 int past_end = 0;
20229 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20230 row = row_containing_pos (w, charpos, first, NULL, 0);
20231 if (row == NULL)
20233 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20235 *x = *y = *hpos = *vpos = 0;
20236 return 0;
20238 else
20240 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20241 past_end = 1;
20245 *x = row->x;
20246 *y = row->y;
20247 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20249 glyph = row->glyphs[TEXT_AREA];
20250 end = glyph + row->used[TEXT_AREA];
20252 /* Skip over glyphs not having an object at the start of the row.
20253 These are special glyphs like truncation marks on terminal
20254 frames. */
20255 if (row->displays_text_p)
20256 while (glyph < end
20257 && INTEGERP (glyph->object)
20258 && !EQ (stop, glyph->object)
20259 && glyph->charpos < 0)
20261 *x += glyph->pixel_width;
20262 ++glyph;
20265 while (glyph < end
20266 && !INTEGERP (glyph->object)
20267 && !EQ (stop, glyph->object)
20268 && (!BUFFERP (glyph->object)
20269 || glyph->charpos < charpos))
20271 *x += glyph->pixel_width;
20272 ++glyph;
20275 *hpos = glyph - row->glyphs[TEXT_AREA];
20276 return past_end;
20279 #else /* not 1 */
20281 static int
20282 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20283 struct window *w;
20284 int pos;
20285 int *hpos, *vpos, *x, *y;
20286 Lisp_Object stop;
20288 int i;
20289 int lastcol;
20290 int maybe_next_line_p = 0;
20291 int line_start_position;
20292 int yb = window_text_bottom_y (w);
20293 struct glyph_row *row, *best_row;
20294 int row_vpos, best_row_vpos;
20295 int current_x;
20297 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20298 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20300 while (row->y < yb)
20302 if (row->used[TEXT_AREA])
20303 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20304 else
20305 line_start_position = 0;
20307 if (line_start_position > pos)
20308 break;
20309 /* If the position sought is the end of the buffer,
20310 don't include the blank lines at the bottom of the window. */
20311 else if (line_start_position == pos
20312 && pos == BUF_ZV (XBUFFER (w->buffer)))
20314 maybe_next_line_p = 1;
20315 break;
20317 else if (line_start_position > 0)
20319 best_row = row;
20320 best_row_vpos = row_vpos;
20323 if (row->y + row->height >= yb)
20324 break;
20326 ++row;
20327 ++row_vpos;
20330 /* Find the right column within BEST_ROW. */
20331 lastcol = 0;
20332 current_x = best_row->x;
20333 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20335 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20336 int charpos = glyph->charpos;
20338 if (BUFFERP (glyph->object))
20340 if (charpos == pos)
20342 *hpos = i;
20343 *vpos = best_row_vpos;
20344 *x = current_x;
20345 *y = best_row->y;
20346 return 1;
20348 else if (charpos > pos)
20349 break;
20351 else if (EQ (glyph->object, stop))
20352 break;
20354 if (charpos > 0)
20355 lastcol = i;
20356 current_x += glyph->pixel_width;
20359 /* If we're looking for the end of the buffer,
20360 and we didn't find it in the line we scanned,
20361 use the start of the following line. */
20362 if (maybe_next_line_p)
20364 ++best_row;
20365 ++best_row_vpos;
20366 lastcol = 0;
20367 current_x = best_row->x;
20370 *vpos = best_row_vpos;
20371 *hpos = lastcol + 1;
20372 *x = current_x;
20373 *y = best_row->y;
20374 return 0;
20377 #endif /* not 1 */
20380 /* Find the position of the glyph for position POS in OBJECT in
20381 window W's current matrix, and return in *X, *Y the pixel
20382 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20384 RIGHT_P non-zero means return the position of the right edge of the
20385 glyph, RIGHT_P zero means return the left edge position.
20387 If no glyph for POS exists in the matrix, return the position of
20388 the glyph with the next smaller position that is in the matrix, if
20389 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20390 exists in the matrix, return the position of the glyph with the
20391 next larger position in OBJECT.
20393 Value is non-zero if a glyph was found. */
20395 static int
20396 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20397 struct window *w;
20398 int pos;
20399 Lisp_Object object;
20400 int *hpos, *vpos, *x, *y;
20401 int right_p;
20403 int yb = window_text_bottom_y (w);
20404 struct glyph_row *r;
20405 struct glyph *best_glyph = NULL;
20406 struct glyph_row *best_row = NULL;
20407 int best_x = 0;
20409 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20410 r->enabled_p && r->y < yb;
20411 ++r)
20413 struct glyph *g = r->glyphs[TEXT_AREA];
20414 struct glyph *e = g + r->used[TEXT_AREA];
20415 int gx;
20417 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20418 if (EQ (g->object, object))
20420 if (g->charpos == pos)
20422 best_glyph = g;
20423 best_x = gx;
20424 best_row = r;
20425 goto found;
20427 else if (best_glyph == NULL
20428 || ((abs (g->charpos - pos)
20429 < abs (best_glyph->charpos - pos))
20430 && (right_p
20431 ? g->charpos < pos
20432 : g->charpos > pos)))
20434 best_glyph = g;
20435 best_x = gx;
20436 best_row = r;
20441 found:
20443 if (best_glyph)
20445 *x = best_x;
20446 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20448 if (right_p)
20450 *x += best_glyph->pixel_width;
20451 ++*hpos;
20454 *y = best_row->y;
20455 *vpos = best_row - w->current_matrix->rows;
20458 return best_glyph != NULL;
20462 /* See if position X, Y is within a hot-spot of an image. */
20464 static int
20465 on_hot_spot_p (hot_spot, x, y)
20466 Lisp_Object hot_spot;
20467 int x, y;
20469 if (!CONSP (hot_spot))
20470 return 0;
20472 if (EQ (XCAR (hot_spot), Qrect))
20474 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20475 Lisp_Object rect = XCDR (hot_spot);
20476 Lisp_Object tem;
20477 if (!CONSP (rect))
20478 return 0;
20479 if (!CONSP (XCAR (rect)))
20480 return 0;
20481 if (!CONSP (XCDR (rect)))
20482 return 0;
20483 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20484 return 0;
20485 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20486 return 0;
20487 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20488 return 0;
20489 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20490 return 0;
20491 return 1;
20493 else if (EQ (XCAR (hot_spot), Qcircle))
20495 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20496 Lisp_Object circ = XCDR (hot_spot);
20497 Lisp_Object lr, lx0, ly0;
20498 if (CONSP (circ)
20499 && CONSP (XCAR (circ))
20500 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20501 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20502 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20504 double r = XFLOATINT (lr);
20505 double dx = XINT (lx0) - x;
20506 double dy = XINT (ly0) - y;
20507 return (dx * dx + dy * dy <= r * r);
20510 else if (EQ (XCAR (hot_spot), Qpoly))
20512 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20513 if (VECTORP (XCDR (hot_spot)))
20515 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20516 Lisp_Object *poly = v->contents;
20517 int n = v->size;
20518 int i;
20519 int inside = 0;
20520 Lisp_Object lx, ly;
20521 int x0, y0;
20523 /* Need an even number of coordinates, and at least 3 edges. */
20524 if (n < 6 || n & 1)
20525 return 0;
20527 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20528 If count is odd, we are inside polygon. Pixels on edges
20529 may or may not be included depending on actual geometry of the
20530 polygon. */
20531 if ((lx = poly[n-2], !INTEGERP (lx))
20532 || (ly = poly[n-1], !INTEGERP (lx)))
20533 return 0;
20534 x0 = XINT (lx), y0 = XINT (ly);
20535 for (i = 0; i < n; i += 2)
20537 int x1 = x0, y1 = y0;
20538 if ((lx = poly[i], !INTEGERP (lx))
20539 || (ly = poly[i+1], !INTEGERP (ly)))
20540 return 0;
20541 x0 = XINT (lx), y0 = XINT (ly);
20543 /* Does this segment cross the X line? */
20544 if (x0 >= x)
20546 if (x1 >= x)
20547 continue;
20549 else if (x1 < x)
20550 continue;
20551 if (y > y0 && y > y1)
20552 continue;
20553 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20554 inside = !inside;
20556 return inside;
20559 else
20560 return 0;
20563 Lisp_Object
20564 find_hot_spot (map, x, y)
20565 Lisp_Object map;
20566 int x, y;
20568 while (CONSP (map))
20570 if (CONSP (XCAR (map))
20571 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20572 return XCAR (map);
20573 map = XCDR (map);
20576 return Qnil;
20579 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20580 3, 3, 0,
20581 doc: /* Lookup in image map MAP coordinates X and Y.
20582 An image map is an alist where each element has the format (AREA ID PLIST).
20583 An AREA is specified as either a rectangle, a circle, or a polygon:
20584 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20585 pixel coordinates of the upper left and bottom right corners.
20586 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20587 and the radius of the circle; r may be a float or integer.
20588 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20589 vector describes one corner in the polygon.
20590 Returns the alist element for the first matching AREA in MAP. */)
20591 (map, x, y)
20592 Lisp_Object map;
20593 Lisp_Object x, y;
20595 int ix, iy;
20596 if (NILP (map))
20597 return Qnil;
20599 if (!INTEGERP (x))
20600 wrong_type_argument (Qintegerp, x);
20601 if (!INTEGERP (y))
20602 wrong_type_argument (Qintegerp, y);
20604 return find_hot_spot (map, XINT (x), XINT (y));
20608 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20609 static void
20610 define_frame_cursor1 (f, cursor, pointer)
20611 struct frame *f;
20612 Cursor cursor;
20613 Lisp_Object pointer;
20615 if (!NILP (pointer))
20617 if (EQ (pointer, Qarrow))
20618 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20619 else if (EQ (pointer, Qhand))
20620 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20621 else if (EQ (pointer, Qtext))
20622 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20623 else if (EQ (pointer, intern ("hdrag")))
20624 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20625 #ifdef HAVE_X_WINDOWS
20626 else if (EQ (pointer, intern ("vdrag")))
20627 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20628 #endif
20629 else if (EQ (pointer, intern ("hourglass")))
20630 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20631 else if (EQ (pointer, Qmodeline))
20632 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20633 else
20634 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20637 #ifndef HAVE_CARBON
20638 if (cursor != No_Cursor)
20639 #else
20640 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20641 #endif
20642 rif->define_frame_cursor (f, cursor);
20645 /* Take proper action when mouse has moved to the mode or header line
20646 or marginal area AREA of window W, x-position X and y-position Y.
20647 X is relative to the start of the text display area of W, so the
20648 width of bitmap areas and scroll bars must be subtracted to get a
20649 position relative to the start of the mode line. */
20651 static void
20652 note_mode_line_or_margin_highlight (w, x, y, area)
20653 struct window *w;
20654 int x, y;
20655 enum window_part area;
20657 struct frame *f = XFRAME (w->frame);
20658 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20659 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20660 Lisp_Object pointer = Qnil;
20661 int charpos, dx, dy, width, height;
20662 Lisp_Object string, object = Qnil;
20663 Lisp_Object pos, help, image;
20665 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20666 string = mode_line_string (w, area, &x, &y, &charpos,
20667 &object, &dx, &dy, &width, &height);
20668 else
20670 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20671 string = marginal_area_string (w, area, &x, &y, &charpos,
20672 &object, &dx, &dy, &width, &height);
20675 help = Qnil;
20677 if (IMAGEP (object))
20679 Lisp_Object image_map, hotspot;
20680 if ((image_map = Fplist_get (XCDR (object), QCmap),
20681 !NILP (image_map))
20682 && (hotspot = find_hot_spot (image_map, dx, dy),
20683 CONSP (hotspot))
20684 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20686 Lisp_Object area_id, plist;
20688 area_id = XCAR (hotspot);
20689 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20690 If so, we could look for mouse-enter, mouse-leave
20691 properties in PLIST (and do something...). */
20692 if ((plist = XCDR (hotspot), CONSP (plist)))
20694 pointer = Fplist_get (plist, Qpointer);
20695 if (NILP (pointer))
20696 pointer = Qhand;
20697 help = Fplist_get (plist, Qhelp_echo);
20698 if (!NILP (help))
20700 help_echo_string = help;
20701 /* Is this correct? ++kfs */
20702 XSETWINDOW (help_echo_window, w);
20703 help_echo_object = w->buffer;
20704 help_echo_pos = charpos;
20707 if (NILP (pointer))
20708 pointer = Fplist_get (XCDR (object), QCpointer);
20712 if (STRINGP (string))
20714 pos = make_number (charpos);
20715 /* If we're on a string with `help-echo' text property, arrange
20716 for the help to be displayed. This is done by setting the
20717 global variable help_echo_string to the help string. */
20718 help = Fget_text_property (pos, Qhelp_echo, string);
20719 if (!NILP (help))
20721 help_echo_string = help;
20722 XSETWINDOW (help_echo_window, w);
20723 help_echo_object = string;
20724 help_echo_pos = charpos;
20727 if (NILP (pointer))
20728 pointer = Fget_text_property (pos, Qpointer, string);
20730 /* Change the mouse pointer according to what is under X/Y. */
20731 if (NILP (pointer) && area == ON_MODE_LINE)
20733 Lisp_Object map;
20734 map = Fget_text_property (pos, Qlocal_map, string);
20735 if (!KEYMAPP (map))
20736 map = Fget_text_property (pos, Qkeymap, string);
20737 if (!KEYMAPP (map))
20738 cursor = dpyinfo->vertical_scroll_bar_cursor;
20742 define_frame_cursor1 (f, cursor, pointer);
20746 /* EXPORT:
20747 Take proper action when the mouse has moved to position X, Y on
20748 frame F as regards highlighting characters that have mouse-face
20749 properties. Also de-highlighting chars where the mouse was before.
20750 X and Y can be negative or out of range. */
20752 void
20753 note_mouse_highlight (f, x, y)
20754 struct frame *f;
20755 int x, y;
20757 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20758 enum window_part part;
20759 Lisp_Object window;
20760 struct window *w;
20761 Cursor cursor = No_Cursor;
20762 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20763 struct buffer *b;
20765 /* When a menu is active, don't highlight because this looks odd. */
20766 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20767 if (popup_activated ())
20768 return;
20769 #endif
20771 if (NILP (Vmouse_highlight)
20772 || !f->glyphs_initialized_p)
20773 return;
20775 dpyinfo->mouse_face_mouse_x = x;
20776 dpyinfo->mouse_face_mouse_y = y;
20777 dpyinfo->mouse_face_mouse_frame = f;
20779 if (dpyinfo->mouse_face_defer)
20780 return;
20782 if (gc_in_progress)
20784 dpyinfo->mouse_face_deferred_gc = 1;
20785 return;
20788 /* Which window is that in? */
20789 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20791 /* If we were displaying active text in another window, clear that. */
20792 if (! EQ (window, dpyinfo->mouse_face_window))
20793 clear_mouse_face (dpyinfo);
20795 /* Not on a window -> return. */
20796 if (!WINDOWP (window))
20797 return;
20799 /* Reset help_echo_string. It will get recomputed below. */
20800 help_echo_string = Qnil;
20802 /* Convert to window-relative pixel coordinates. */
20803 w = XWINDOW (window);
20804 frame_to_window_pixel_xy (w, &x, &y);
20806 /* Handle tool-bar window differently since it doesn't display a
20807 buffer. */
20808 if (EQ (window, f->tool_bar_window))
20810 note_tool_bar_highlight (f, x, y);
20811 return;
20814 /* Mouse is on the mode, header line or margin? */
20815 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20816 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20818 note_mode_line_or_margin_highlight (w, x, y, part);
20819 return;
20822 if (part == ON_VERTICAL_BORDER)
20823 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20824 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20825 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20826 else
20827 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20829 /* Are we in a window whose display is up to date?
20830 And verify the buffer's text has not changed. */
20831 b = XBUFFER (w->buffer);
20832 if (part == ON_TEXT
20833 && EQ (w->window_end_valid, w->buffer)
20834 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20835 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20837 int hpos, vpos, pos, i, dx, dy, area;
20838 struct glyph *glyph;
20839 Lisp_Object object;
20840 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20841 Lisp_Object *overlay_vec = NULL;
20842 int len, noverlays;
20843 struct buffer *obuf;
20844 int obegv, ozv, same_region;
20846 /* Find the glyph under X/Y. */
20847 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20849 /* Look for :pointer property on image. */
20850 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20852 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20853 if (img != NULL && IMAGEP (img->spec))
20855 Lisp_Object image_map, hotspot;
20856 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20857 !NILP (image_map))
20858 && (hotspot = find_hot_spot (image_map, dx, dy),
20859 CONSP (hotspot))
20860 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20862 Lisp_Object area_id, plist;
20864 area_id = XCAR (hotspot);
20865 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20866 If so, we could look for mouse-enter, mouse-leave
20867 properties in PLIST (and do something...). */
20868 if ((plist = XCDR (hotspot), CONSP (plist)))
20870 pointer = Fplist_get (plist, Qpointer);
20871 if (NILP (pointer))
20872 pointer = Qhand;
20873 help_echo_string = Fplist_get (plist, Qhelp_echo);
20874 if (!NILP (help_echo_string))
20876 help_echo_window = window;
20877 help_echo_object = glyph->object;
20878 help_echo_pos = glyph->charpos;
20882 if (NILP (pointer))
20883 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20887 /* Clear mouse face if X/Y not over text. */
20888 if (glyph == NULL
20889 || area != TEXT_AREA
20890 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20892 if (clear_mouse_face (dpyinfo))
20893 cursor = No_Cursor;
20894 if (NILP (pointer))
20896 if (area != TEXT_AREA)
20897 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20898 else
20899 pointer = Vvoid_text_area_pointer;
20901 goto set_cursor;
20904 pos = glyph->charpos;
20905 object = glyph->object;
20906 if (!STRINGP (object) && !BUFFERP (object))
20907 goto set_cursor;
20909 /* If we get an out-of-range value, return now; avoid an error. */
20910 if (BUFFERP (object) && pos > BUF_Z (b))
20911 goto set_cursor;
20913 /* Make the window's buffer temporarily current for
20914 overlays_at and compute_char_face. */
20915 obuf = current_buffer;
20916 current_buffer = b;
20917 obegv = BEGV;
20918 ozv = ZV;
20919 BEGV = BEG;
20920 ZV = Z;
20922 /* Is this char mouse-active or does it have help-echo? */
20923 position = make_number (pos);
20925 if (BUFFERP (object))
20927 /* Put all the overlays we want in a vector in overlay_vec.
20928 Store the length in len. If there are more than 10, make
20929 enough space for all, and try again. */
20930 len = 10;
20931 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20932 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20933 if (noverlays > len)
20935 len = noverlays;
20936 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20937 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20940 /* Sort overlays into increasing priority order. */
20941 noverlays = sort_overlays (overlay_vec, noverlays, w);
20943 else
20944 noverlays = 0;
20946 same_region = (EQ (window, dpyinfo->mouse_face_window)
20947 && vpos >= dpyinfo->mouse_face_beg_row
20948 && vpos <= dpyinfo->mouse_face_end_row
20949 && (vpos > dpyinfo->mouse_face_beg_row
20950 || hpos >= dpyinfo->mouse_face_beg_col)
20951 && (vpos < dpyinfo->mouse_face_end_row
20952 || hpos < dpyinfo->mouse_face_end_col
20953 || dpyinfo->mouse_face_past_end));
20955 if (same_region)
20956 cursor = No_Cursor;
20958 /* Check mouse-face highlighting. */
20959 if (! same_region
20960 /* If there exists an overlay with mouse-face overlapping
20961 the one we are currently highlighting, we have to
20962 check if we enter the overlapping overlay, and then
20963 highlight only that. */
20964 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20965 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20967 /* Find the highest priority overlay that has a mouse-face
20968 property. */
20969 overlay = Qnil;
20970 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20972 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20973 if (!NILP (mouse_face))
20974 overlay = overlay_vec[i];
20977 /* If we're actually highlighting the same overlay as
20978 before, there's no need to do that again. */
20979 if (!NILP (overlay)
20980 && EQ (overlay, dpyinfo->mouse_face_overlay))
20981 goto check_help_echo;
20983 dpyinfo->mouse_face_overlay = overlay;
20985 /* Clear the display of the old active region, if any. */
20986 if (clear_mouse_face (dpyinfo))
20987 cursor = No_Cursor;
20989 /* If no overlay applies, get a text property. */
20990 if (NILP (overlay))
20991 mouse_face = Fget_text_property (position, Qmouse_face, object);
20993 /* Handle the overlay case. */
20994 if (!NILP (overlay))
20996 /* Find the range of text around this char that
20997 should be active. */
20998 Lisp_Object before, after;
20999 int ignore;
21001 before = Foverlay_start (overlay);
21002 after = Foverlay_end (overlay);
21003 /* Record this as the current active region. */
21004 fast_find_position (w, XFASTINT (before),
21005 &dpyinfo->mouse_face_beg_col,
21006 &dpyinfo->mouse_face_beg_row,
21007 &dpyinfo->mouse_face_beg_x,
21008 &dpyinfo->mouse_face_beg_y, Qnil);
21010 dpyinfo->mouse_face_past_end
21011 = !fast_find_position (w, XFASTINT (after),
21012 &dpyinfo->mouse_face_end_col,
21013 &dpyinfo->mouse_face_end_row,
21014 &dpyinfo->mouse_face_end_x,
21015 &dpyinfo->mouse_face_end_y, Qnil);
21016 dpyinfo->mouse_face_window = window;
21018 dpyinfo->mouse_face_face_id
21019 = face_at_buffer_position (w, pos, 0, 0,
21020 &ignore, pos + 1,
21021 !dpyinfo->mouse_face_hidden);
21023 /* Display it as active. */
21024 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21025 cursor = No_Cursor;
21027 /* Handle the text property case. */
21028 else if (!NILP (mouse_face) && BUFFERP (object))
21030 /* Find the range of text around this char that
21031 should be active. */
21032 Lisp_Object before, after, beginning, end;
21033 int ignore;
21035 beginning = Fmarker_position (w->start);
21036 end = make_number (BUF_Z (XBUFFER (object))
21037 - XFASTINT (w->window_end_pos));
21038 before
21039 = Fprevious_single_property_change (make_number (pos + 1),
21040 Qmouse_face,
21041 object, beginning);
21042 after
21043 = Fnext_single_property_change (position, Qmouse_face,
21044 object, end);
21046 /* Record this as the current active region. */
21047 fast_find_position (w, XFASTINT (before),
21048 &dpyinfo->mouse_face_beg_col,
21049 &dpyinfo->mouse_face_beg_row,
21050 &dpyinfo->mouse_face_beg_x,
21051 &dpyinfo->mouse_face_beg_y, Qnil);
21052 dpyinfo->mouse_face_past_end
21053 = !fast_find_position (w, XFASTINT (after),
21054 &dpyinfo->mouse_face_end_col,
21055 &dpyinfo->mouse_face_end_row,
21056 &dpyinfo->mouse_face_end_x,
21057 &dpyinfo->mouse_face_end_y, Qnil);
21058 dpyinfo->mouse_face_window = window;
21060 if (BUFFERP (object))
21061 dpyinfo->mouse_face_face_id
21062 = face_at_buffer_position (w, pos, 0, 0,
21063 &ignore, pos + 1,
21064 !dpyinfo->mouse_face_hidden);
21066 /* Display it as active. */
21067 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21068 cursor = No_Cursor;
21070 else if (!NILP (mouse_face) && STRINGP (object))
21072 Lisp_Object b, e;
21073 int ignore;
21075 b = Fprevious_single_property_change (make_number (pos + 1),
21076 Qmouse_face,
21077 object, Qnil);
21078 e = Fnext_single_property_change (position, Qmouse_face,
21079 object, Qnil);
21080 if (NILP (b))
21081 b = make_number (0);
21082 if (NILP (e))
21083 e = make_number (SCHARS (object) - 1);
21084 fast_find_string_pos (w, XINT (b), object,
21085 &dpyinfo->mouse_face_beg_col,
21086 &dpyinfo->mouse_face_beg_row,
21087 &dpyinfo->mouse_face_beg_x,
21088 &dpyinfo->mouse_face_beg_y, 0);
21089 fast_find_string_pos (w, XINT (e), object,
21090 &dpyinfo->mouse_face_end_col,
21091 &dpyinfo->mouse_face_end_row,
21092 &dpyinfo->mouse_face_end_x,
21093 &dpyinfo->mouse_face_end_y, 1);
21094 dpyinfo->mouse_face_past_end = 0;
21095 dpyinfo->mouse_face_window = window;
21096 dpyinfo->mouse_face_face_id
21097 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21098 glyph->face_id, 1);
21099 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21100 cursor = No_Cursor;
21102 else if (STRINGP (object) && NILP (mouse_face))
21104 /* A string which doesn't have mouse-face, but
21105 the text ``under'' it might have. */
21106 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21107 int start = MATRIX_ROW_START_CHARPOS (r);
21109 pos = string_buffer_position (w, object, start);
21110 if (pos > 0)
21111 mouse_face = get_char_property_and_overlay (make_number (pos),
21112 Qmouse_face,
21113 w->buffer,
21114 &overlay);
21115 if (!NILP (mouse_face) && !NILP (overlay))
21117 Lisp_Object before = Foverlay_start (overlay);
21118 Lisp_Object after = Foverlay_end (overlay);
21119 int ignore;
21121 /* Note that we might not be able to find position
21122 BEFORE in the glyph matrix if the overlay is
21123 entirely covered by a `display' property. In
21124 this case, we overshoot. So let's stop in
21125 the glyph matrix before glyphs for OBJECT. */
21126 fast_find_position (w, XFASTINT (before),
21127 &dpyinfo->mouse_face_beg_col,
21128 &dpyinfo->mouse_face_beg_row,
21129 &dpyinfo->mouse_face_beg_x,
21130 &dpyinfo->mouse_face_beg_y,
21131 object);
21133 dpyinfo->mouse_face_past_end
21134 = !fast_find_position (w, XFASTINT (after),
21135 &dpyinfo->mouse_face_end_col,
21136 &dpyinfo->mouse_face_end_row,
21137 &dpyinfo->mouse_face_end_x,
21138 &dpyinfo->mouse_face_end_y,
21139 Qnil);
21140 dpyinfo->mouse_face_window = window;
21141 dpyinfo->mouse_face_face_id
21142 = face_at_buffer_position (w, pos, 0, 0,
21143 &ignore, pos + 1,
21144 !dpyinfo->mouse_face_hidden);
21146 /* Display it as active. */
21147 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21148 cursor = No_Cursor;
21153 check_help_echo:
21155 /* Look for a `help-echo' property. */
21156 if (NILP (help_echo_string)) {
21157 Lisp_Object help, overlay;
21159 /* Check overlays first. */
21160 help = overlay = Qnil;
21161 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21163 overlay = overlay_vec[i];
21164 help = Foverlay_get (overlay, Qhelp_echo);
21167 if (!NILP (help))
21169 help_echo_string = help;
21170 help_echo_window = window;
21171 help_echo_object = overlay;
21172 help_echo_pos = pos;
21174 else
21176 Lisp_Object object = glyph->object;
21177 int charpos = glyph->charpos;
21179 /* Try text properties. */
21180 if (STRINGP (object)
21181 && charpos >= 0
21182 && charpos < SCHARS (object))
21184 help = Fget_text_property (make_number (charpos),
21185 Qhelp_echo, object);
21186 if (NILP (help))
21188 /* If the string itself doesn't specify a help-echo,
21189 see if the buffer text ``under'' it does. */
21190 struct glyph_row *r
21191 = MATRIX_ROW (w->current_matrix, vpos);
21192 int start = MATRIX_ROW_START_CHARPOS (r);
21193 int pos = string_buffer_position (w, object, start);
21194 if (pos > 0)
21196 help = Fget_char_property (make_number (pos),
21197 Qhelp_echo, w->buffer);
21198 if (!NILP (help))
21200 charpos = pos;
21201 object = w->buffer;
21206 else if (BUFFERP (object)
21207 && charpos >= BEGV
21208 && charpos < ZV)
21209 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21210 object);
21212 if (!NILP (help))
21214 help_echo_string = help;
21215 help_echo_window = window;
21216 help_echo_object = object;
21217 help_echo_pos = charpos;
21222 /* Look for a `pointer' property. */
21223 if (NILP (pointer))
21225 /* Check overlays first. */
21226 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21227 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21229 if (NILP (pointer))
21231 Lisp_Object object = glyph->object;
21232 int charpos = glyph->charpos;
21234 /* Try text properties. */
21235 if (STRINGP (object)
21236 && charpos >= 0
21237 && charpos < SCHARS (object))
21239 pointer = Fget_text_property (make_number (charpos),
21240 Qpointer, object);
21241 if (NILP (pointer))
21243 /* If the string itself doesn't specify a pointer,
21244 see if the buffer text ``under'' it does. */
21245 struct glyph_row *r
21246 = MATRIX_ROW (w->current_matrix, vpos);
21247 int start = MATRIX_ROW_START_CHARPOS (r);
21248 int pos = string_buffer_position (w, object, start);
21249 if (pos > 0)
21250 pointer = Fget_char_property (make_number (pos),
21251 Qpointer, w->buffer);
21254 else if (BUFFERP (object)
21255 && charpos >= BEGV
21256 && charpos < ZV)
21257 pointer = Fget_text_property (make_number (charpos),
21258 Qpointer, object);
21262 BEGV = obegv;
21263 ZV = ozv;
21264 current_buffer = obuf;
21267 set_cursor:
21269 define_frame_cursor1 (f, cursor, pointer);
21273 /* EXPORT for RIF:
21274 Clear any mouse-face on window W. This function is part of the
21275 redisplay interface, and is called from try_window_id and similar
21276 functions to ensure the mouse-highlight is off. */
21278 void
21279 x_clear_window_mouse_face (w)
21280 struct window *w;
21282 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21283 Lisp_Object window;
21285 BLOCK_INPUT;
21286 XSETWINDOW (window, w);
21287 if (EQ (window, dpyinfo->mouse_face_window))
21288 clear_mouse_face (dpyinfo);
21289 UNBLOCK_INPUT;
21293 /* EXPORT:
21294 Just discard the mouse face information for frame F, if any.
21295 This is used when the size of F is changed. */
21297 void
21298 cancel_mouse_face (f)
21299 struct frame *f;
21301 Lisp_Object window;
21302 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21304 window = dpyinfo->mouse_face_window;
21305 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21307 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21308 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21309 dpyinfo->mouse_face_window = Qnil;
21314 #endif /* HAVE_WINDOW_SYSTEM */
21317 /***********************************************************************
21318 Exposure Events
21319 ***********************************************************************/
21321 #ifdef HAVE_WINDOW_SYSTEM
21323 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21324 which intersects rectangle R. R is in window-relative coordinates. */
21326 static void
21327 expose_area (w, row, r, area)
21328 struct window *w;
21329 struct glyph_row *row;
21330 XRectangle *r;
21331 enum glyph_row_area area;
21333 struct glyph *first = row->glyphs[area];
21334 struct glyph *end = row->glyphs[area] + row->used[area];
21335 struct glyph *last;
21336 int first_x, start_x, x;
21338 if (area == TEXT_AREA && row->fill_line_p)
21339 /* If row extends face to end of line write the whole line. */
21340 draw_glyphs (w, 0, row, area,
21341 0, row->used[area],
21342 DRAW_NORMAL_TEXT, 0);
21343 else
21345 /* Set START_X to the window-relative start position for drawing glyphs of
21346 AREA. The first glyph of the text area can be partially visible.
21347 The first glyphs of other areas cannot. */
21348 start_x = window_box_left_offset (w, area);
21349 x = start_x;
21350 if (area == TEXT_AREA)
21351 x += row->x;
21353 /* Find the first glyph that must be redrawn. */
21354 while (first < end
21355 && x + first->pixel_width < r->x)
21357 x += first->pixel_width;
21358 ++first;
21361 /* Find the last one. */
21362 last = first;
21363 first_x = x;
21364 while (last < end
21365 && x < r->x + r->width)
21367 x += last->pixel_width;
21368 ++last;
21371 /* Repaint. */
21372 if (last > first)
21373 draw_glyphs (w, first_x - start_x, row, area,
21374 first - row->glyphs[area], last - row->glyphs[area],
21375 DRAW_NORMAL_TEXT, 0);
21380 /* Redraw the parts of the glyph row ROW on window W intersecting
21381 rectangle R. R is in window-relative coordinates. Value is
21382 non-zero if mouse-face was overwritten. */
21384 static int
21385 expose_line (w, row, r)
21386 struct window *w;
21387 struct glyph_row *row;
21388 XRectangle *r;
21390 xassert (row->enabled_p);
21392 if (row->mode_line_p || w->pseudo_window_p)
21393 draw_glyphs (w, 0, row, TEXT_AREA,
21394 0, row->used[TEXT_AREA],
21395 DRAW_NORMAL_TEXT, 0);
21396 else
21398 if (row->used[LEFT_MARGIN_AREA])
21399 expose_area (w, row, r, LEFT_MARGIN_AREA);
21400 if (row->used[TEXT_AREA])
21401 expose_area (w, row, r, TEXT_AREA);
21402 if (row->used[RIGHT_MARGIN_AREA])
21403 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21404 draw_row_fringe_bitmaps (w, row);
21407 return row->mouse_face_p;
21411 /* Redraw those parts of glyphs rows during expose event handling that
21412 overlap other rows. Redrawing of an exposed line writes over parts
21413 of lines overlapping that exposed line; this function fixes that.
21415 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21416 row in W's current matrix that is exposed and overlaps other rows.
21417 LAST_OVERLAPPING_ROW is the last such row. */
21419 static void
21420 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21421 struct window *w;
21422 struct glyph_row *first_overlapping_row;
21423 struct glyph_row *last_overlapping_row;
21425 struct glyph_row *row;
21427 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21428 if (row->overlapping_p)
21430 xassert (row->enabled_p && !row->mode_line_p);
21432 if (row->used[LEFT_MARGIN_AREA])
21433 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21435 if (row->used[TEXT_AREA])
21436 x_fix_overlapping_area (w, row, TEXT_AREA);
21438 if (row->used[RIGHT_MARGIN_AREA])
21439 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21444 /* Return non-zero if W's cursor intersects rectangle R. */
21446 static int
21447 phys_cursor_in_rect_p (w, r)
21448 struct window *w;
21449 XRectangle *r;
21451 XRectangle cr, result;
21452 struct glyph *cursor_glyph;
21454 cursor_glyph = get_phys_cursor_glyph (w);
21455 if (cursor_glyph)
21457 /* r is relative to W's box, but w->phys_cursor.x is relative
21458 to left edge of W's TEXT area. Adjust it. */
21459 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21460 cr.y = w->phys_cursor.y;
21461 cr.width = cursor_glyph->pixel_width;
21462 cr.height = w->phys_cursor_height;
21463 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21464 I assume the effect is the same -- and this is portable. */
21465 return x_intersect_rectangles (&cr, r, &result);
21467 else
21468 return 0;
21472 /* EXPORT:
21473 Draw a vertical window border to the right of window W if W doesn't
21474 have vertical scroll bars. */
21476 void
21477 x_draw_vertical_border (w)
21478 struct window *w;
21480 /* We could do better, if we knew what type of scroll-bar the adjacent
21481 windows (on either side) have... But we don't :-(
21482 However, I think this works ok. ++KFS 2003-04-25 */
21484 /* Redraw borders between horizontally adjacent windows. Don't
21485 do it for frames with vertical scroll bars because either the
21486 right scroll bar of a window, or the left scroll bar of its
21487 neighbor will suffice as a border. */
21488 if (!WINDOW_RIGHTMOST_P (w)
21489 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21491 int x0, x1, y0, y1;
21493 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21494 y1 -= 1;
21496 rif->draw_vertical_window_border (w, x1, y0, y1);
21498 else if (!WINDOW_LEFTMOST_P (w)
21499 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21501 int x0, x1, y0, y1;
21503 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21504 y1 -= 1;
21506 rif->draw_vertical_window_border (w, x0, y0, y1);
21511 /* Redraw the part of window W intersection rectangle FR. Pixel
21512 coordinates in FR are frame-relative. Call this function with
21513 input blocked. Value is non-zero if the exposure overwrites
21514 mouse-face. */
21516 static int
21517 expose_window (w, fr)
21518 struct window *w;
21519 XRectangle *fr;
21521 struct frame *f = XFRAME (w->frame);
21522 XRectangle wr, r;
21523 int mouse_face_overwritten_p = 0;
21525 /* If window is not yet fully initialized, do nothing. This can
21526 happen when toolkit scroll bars are used and a window is split.
21527 Reconfiguring the scroll bar will generate an expose for a newly
21528 created window. */
21529 if (w->current_matrix == NULL)
21530 return 0;
21532 /* When we're currently updating the window, display and current
21533 matrix usually don't agree. Arrange for a thorough display
21534 later. */
21535 if (w == updated_window)
21537 SET_FRAME_GARBAGED (f);
21538 return 0;
21541 /* Frame-relative pixel rectangle of W. */
21542 wr.x = WINDOW_LEFT_EDGE_X (w);
21543 wr.y = WINDOW_TOP_EDGE_Y (w);
21544 wr.width = WINDOW_TOTAL_WIDTH (w);
21545 wr.height = WINDOW_TOTAL_HEIGHT (w);
21547 if (x_intersect_rectangles (fr, &wr, &r))
21549 int yb = window_text_bottom_y (w);
21550 struct glyph_row *row;
21551 int cursor_cleared_p;
21552 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21554 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21555 r.x, r.y, r.width, r.height));
21557 /* Convert to window coordinates. */
21558 r.x -= WINDOW_LEFT_EDGE_X (w);
21559 r.y -= WINDOW_TOP_EDGE_Y (w);
21561 /* Turn off the cursor. */
21562 if (!w->pseudo_window_p
21563 && phys_cursor_in_rect_p (w, &r))
21565 x_clear_cursor (w);
21566 cursor_cleared_p = 1;
21568 else
21569 cursor_cleared_p = 0;
21571 /* Update lines intersecting rectangle R. */
21572 first_overlapping_row = last_overlapping_row = NULL;
21573 for (row = w->current_matrix->rows;
21574 row->enabled_p;
21575 ++row)
21577 int y0 = row->y;
21578 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21580 if ((y0 >= r.y && y0 < r.y + r.height)
21581 || (y1 > r.y && y1 < r.y + r.height)
21582 || (r.y >= y0 && r.y < y1)
21583 || (r.y + r.height > y0 && r.y + r.height < y1))
21585 if (row->overlapping_p)
21587 if (first_overlapping_row == NULL)
21588 first_overlapping_row = row;
21589 last_overlapping_row = row;
21592 if (expose_line (w, row, &r))
21593 mouse_face_overwritten_p = 1;
21596 if (y1 >= yb)
21597 break;
21600 /* Display the mode line if there is one. */
21601 if (WINDOW_WANTS_MODELINE_P (w)
21602 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21603 row->enabled_p)
21604 && row->y < r.y + r.height)
21606 if (expose_line (w, row, &r))
21607 mouse_face_overwritten_p = 1;
21610 if (!w->pseudo_window_p)
21612 /* Fix the display of overlapping rows. */
21613 if (first_overlapping_row)
21614 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21616 /* Draw border between windows. */
21617 x_draw_vertical_border (w);
21619 /* Turn the cursor on again. */
21620 if (cursor_cleared_p)
21621 update_window_cursor (w, 1);
21625 #ifdef HAVE_CARBON
21626 /* Display scroll bar for this window. */
21627 if (!NILP (w->vertical_scroll_bar))
21629 /* ++KFS:
21630 If this doesn't work here (maybe some header files are missing),
21631 make a function in macterm.c and call it to do the job! */
21632 ControlHandle ch
21633 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21635 Draw1Control (ch);
21637 #endif
21639 return mouse_face_overwritten_p;
21644 /* Redraw (parts) of all windows in the window tree rooted at W that
21645 intersect R. R contains frame pixel coordinates. Value is
21646 non-zero if the exposure overwrites mouse-face. */
21648 static int
21649 expose_window_tree (w, r)
21650 struct window *w;
21651 XRectangle *r;
21653 struct frame *f = XFRAME (w->frame);
21654 int mouse_face_overwritten_p = 0;
21656 while (w && !FRAME_GARBAGED_P (f))
21658 if (!NILP (w->hchild))
21659 mouse_face_overwritten_p
21660 |= expose_window_tree (XWINDOW (w->hchild), r);
21661 else if (!NILP (w->vchild))
21662 mouse_face_overwritten_p
21663 |= expose_window_tree (XWINDOW (w->vchild), r);
21664 else
21665 mouse_face_overwritten_p |= expose_window (w, r);
21667 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21670 return mouse_face_overwritten_p;
21674 /* EXPORT:
21675 Redisplay an exposed area of frame F. X and Y are the upper-left
21676 corner of the exposed rectangle. W and H are width and height of
21677 the exposed area. All are pixel values. W or H zero means redraw
21678 the entire frame. */
21680 void
21681 expose_frame (f, x, y, w, h)
21682 struct frame *f;
21683 int x, y, w, h;
21685 XRectangle r;
21686 int mouse_face_overwritten_p = 0;
21688 TRACE ((stderr, "expose_frame "));
21690 /* No need to redraw if frame will be redrawn soon. */
21691 if (FRAME_GARBAGED_P (f))
21693 TRACE ((stderr, " garbaged\n"));
21694 return;
21697 #ifdef HAVE_CARBON
21698 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21699 or deactivated here, for unknown reasons, activated scroll bars
21700 are shown in deactivated frames in some instances. */
21701 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21702 activate_scroll_bars (f);
21703 else
21704 deactivate_scroll_bars (f);
21705 #endif
21707 /* If basic faces haven't been realized yet, there is no point in
21708 trying to redraw anything. This can happen when we get an expose
21709 event while Emacs is starting, e.g. by moving another window. */
21710 if (FRAME_FACE_CACHE (f) == NULL
21711 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21713 TRACE ((stderr, " no faces\n"));
21714 return;
21717 if (w == 0 || h == 0)
21719 r.x = r.y = 0;
21720 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21721 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21723 else
21725 r.x = x;
21726 r.y = y;
21727 r.width = w;
21728 r.height = h;
21731 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21732 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21734 if (WINDOWP (f->tool_bar_window))
21735 mouse_face_overwritten_p
21736 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21738 #ifdef HAVE_X_WINDOWS
21739 #ifndef MSDOS
21740 #ifndef USE_X_TOOLKIT
21741 if (WINDOWP (f->menu_bar_window))
21742 mouse_face_overwritten_p
21743 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21744 #endif /* not USE_X_TOOLKIT */
21745 #endif
21746 #endif
21748 /* Some window managers support a focus-follows-mouse style with
21749 delayed raising of frames. Imagine a partially obscured frame,
21750 and moving the mouse into partially obscured mouse-face on that
21751 frame. The visible part of the mouse-face will be highlighted,
21752 then the WM raises the obscured frame. With at least one WM, KDE
21753 2.1, Emacs is not getting any event for the raising of the frame
21754 (even tried with SubstructureRedirectMask), only Expose events.
21755 These expose events will draw text normally, i.e. not
21756 highlighted. Which means we must redo the highlight here.
21757 Subsume it under ``we love X''. --gerd 2001-08-15 */
21758 /* Included in Windows version because Windows most likely does not
21759 do the right thing if any third party tool offers
21760 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21761 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21763 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21764 if (f == dpyinfo->mouse_face_mouse_frame)
21766 int x = dpyinfo->mouse_face_mouse_x;
21767 int y = dpyinfo->mouse_face_mouse_y;
21768 clear_mouse_face (dpyinfo);
21769 note_mouse_highlight (f, x, y);
21775 /* EXPORT:
21776 Determine the intersection of two rectangles R1 and R2. Return
21777 the intersection in *RESULT. Value is non-zero if RESULT is not
21778 empty. */
21781 x_intersect_rectangles (r1, r2, result)
21782 XRectangle *r1, *r2, *result;
21784 XRectangle *left, *right;
21785 XRectangle *upper, *lower;
21786 int intersection_p = 0;
21788 /* Rearrange so that R1 is the left-most rectangle. */
21789 if (r1->x < r2->x)
21790 left = r1, right = r2;
21791 else
21792 left = r2, right = r1;
21794 /* X0 of the intersection is right.x0, if this is inside R1,
21795 otherwise there is no intersection. */
21796 if (right->x <= left->x + left->width)
21798 result->x = right->x;
21800 /* The right end of the intersection is the minimum of the
21801 the right ends of left and right. */
21802 result->width = (min (left->x + left->width, right->x + right->width)
21803 - result->x);
21805 /* Same game for Y. */
21806 if (r1->y < r2->y)
21807 upper = r1, lower = r2;
21808 else
21809 upper = r2, lower = r1;
21811 /* The upper end of the intersection is lower.y0, if this is inside
21812 of upper. Otherwise, there is no intersection. */
21813 if (lower->y <= upper->y + upper->height)
21815 result->y = lower->y;
21817 /* The lower end of the intersection is the minimum of the lower
21818 ends of upper and lower. */
21819 result->height = (min (lower->y + lower->height,
21820 upper->y + upper->height)
21821 - result->y);
21822 intersection_p = 1;
21826 return intersection_p;
21829 #endif /* HAVE_WINDOW_SYSTEM */
21832 /***********************************************************************
21833 Initialization
21834 ***********************************************************************/
21836 void
21837 syms_of_xdisp ()
21839 Vwith_echo_area_save_vector = Qnil;
21840 staticpro (&Vwith_echo_area_save_vector);
21842 Vmessage_stack = Qnil;
21843 staticpro (&Vmessage_stack);
21845 Qinhibit_redisplay = intern ("inhibit-redisplay");
21846 staticpro (&Qinhibit_redisplay);
21848 message_dolog_marker1 = Fmake_marker ();
21849 staticpro (&message_dolog_marker1);
21850 message_dolog_marker2 = Fmake_marker ();
21851 staticpro (&message_dolog_marker2);
21852 message_dolog_marker3 = Fmake_marker ();
21853 staticpro (&message_dolog_marker3);
21855 #if GLYPH_DEBUG
21856 defsubr (&Sdump_frame_glyph_matrix);
21857 defsubr (&Sdump_glyph_matrix);
21858 defsubr (&Sdump_glyph_row);
21859 defsubr (&Sdump_tool_bar_row);
21860 defsubr (&Strace_redisplay);
21861 defsubr (&Strace_to_stderr);
21862 #endif
21863 #ifdef HAVE_WINDOW_SYSTEM
21864 defsubr (&Stool_bar_lines_needed);
21865 defsubr (&Slookup_image_map);
21866 #endif
21867 defsubr (&Sformat_mode_line);
21869 staticpro (&Qmenu_bar_update_hook);
21870 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21872 staticpro (&Qoverriding_terminal_local_map);
21873 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21875 staticpro (&Qoverriding_local_map);
21876 Qoverriding_local_map = intern ("overriding-local-map");
21878 staticpro (&Qwindow_scroll_functions);
21879 Qwindow_scroll_functions = intern ("window-scroll-functions");
21881 staticpro (&Qredisplay_end_trigger_functions);
21882 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21884 staticpro (&Qinhibit_point_motion_hooks);
21885 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21887 QCdata = intern (":data");
21888 staticpro (&QCdata);
21889 Qdisplay = intern ("display");
21890 staticpro (&Qdisplay);
21891 Qspace_width = intern ("space-width");
21892 staticpro (&Qspace_width);
21893 Qraise = intern ("raise");
21894 staticpro (&Qraise);
21895 Qspace = intern ("space");
21896 staticpro (&Qspace);
21897 Qmargin = intern ("margin");
21898 staticpro (&Qmargin);
21899 Qpointer = intern ("pointer");
21900 staticpro (&Qpointer);
21901 Qleft_margin = intern ("left-margin");
21902 staticpro (&Qleft_margin);
21903 Qright_margin = intern ("right-margin");
21904 staticpro (&Qright_margin);
21905 QCalign_to = intern (":align-to");
21906 staticpro (&QCalign_to);
21907 QCrelative_width = intern (":relative-width");
21908 staticpro (&QCrelative_width);
21909 QCrelative_height = intern (":relative-height");
21910 staticpro (&QCrelative_height);
21911 QCeval = intern (":eval");
21912 staticpro (&QCeval);
21913 QCpropertize = intern (":propertize");
21914 staticpro (&QCpropertize);
21915 QCfile = intern (":file");
21916 staticpro (&QCfile);
21917 Qfontified = intern ("fontified");
21918 staticpro (&Qfontified);
21919 Qfontification_functions = intern ("fontification-functions");
21920 staticpro (&Qfontification_functions);
21921 Qtrailing_whitespace = intern ("trailing-whitespace");
21922 staticpro (&Qtrailing_whitespace);
21923 Qimage = intern ("image");
21924 staticpro (&Qimage);
21925 QCmap = intern (":map");
21926 staticpro (&QCmap);
21927 QCpointer = intern (":pointer");
21928 staticpro (&QCpointer);
21929 Qrect = intern ("rect");
21930 staticpro (&Qrect);
21931 Qcircle = intern ("circle");
21932 staticpro (&Qcircle);
21933 Qpoly = intern ("poly");
21934 staticpro (&Qpoly);
21935 Qmessage_truncate_lines = intern ("message-truncate-lines");
21936 staticpro (&Qmessage_truncate_lines);
21937 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21938 staticpro (&Qcursor_in_non_selected_windows);
21939 Qgrow_only = intern ("grow-only");
21940 staticpro (&Qgrow_only);
21941 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21942 staticpro (&Qinhibit_menubar_update);
21943 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21944 staticpro (&Qinhibit_eval_during_redisplay);
21945 Qposition = intern ("position");
21946 staticpro (&Qposition);
21947 Qbuffer_position = intern ("buffer-position");
21948 staticpro (&Qbuffer_position);
21949 Qobject = intern ("object");
21950 staticpro (&Qobject);
21951 Qbar = intern ("bar");
21952 staticpro (&Qbar);
21953 Qhbar = intern ("hbar");
21954 staticpro (&Qhbar);
21955 Qbox = intern ("box");
21956 staticpro (&Qbox);
21957 Qhollow = intern ("hollow");
21958 staticpro (&Qhollow);
21959 Qhand = intern ("hand");
21960 staticpro (&Qhand);
21961 Qarrow = intern ("arrow");
21962 staticpro (&Qarrow);
21963 Qtext = intern ("text");
21964 staticpro (&Qtext);
21965 Qrisky_local_variable = intern ("risky-local-variable");
21966 staticpro (&Qrisky_local_variable);
21967 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21968 staticpro (&Qinhibit_free_realized_faces);
21970 list_of_error = Fcons (intern ("error"), Qnil);
21971 staticpro (&list_of_error);
21973 last_arrow_position = Qnil;
21974 last_arrow_string = Qnil;
21975 staticpro (&last_arrow_position);
21976 staticpro (&last_arrow_string);
21978 echo_buffer[0] = echo_buffer[1] = Qnil;
21979 staticpro (&echo_buffer[0]);
21980 staticpro (&echo_buffer[1]);
21982 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21983 staticpro (&echo_area_buffer[0]);
21984 staticpro (&echo_area_buffer[1]);
21986 Vmessages_buffer_name = build_string ("*Messages*");
21987 staticpro (&Vmessages_buffer_name);
21989 mode_line_proptrans_alist = Qnil;
21990 staticpro (&mode_line_proptrans_alist);
21992 mode_line_string_list = Qnil;
21993 staticpro (&mode_line_string_list);
21995 help_echo_string = Qnil;
21996 staticpro (&help_echo_string);
21997 help_echo_object = Qnil;
21998 staticpro (&help_echo_object);
21999 help_echo_window = Qnil;
22000 staticpro (&help_echo_window);
22001 previous_help_echo_string = Qnil;
22002 staticpro (&previous_help_echo_string);
22003 help_echo_pos = -1;
22005 #ifdef HAVE_WINDOW_SYSTEM
22006 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22007 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22008 For example, if a block cursor is over a tab, it will be drawn as
22009 wide as that tab on the display. */);
22010 x_stretch_cursor_p = 0;
22011 #endif
22013 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22014 doc: /* *Non-nil means highlight trailing whitespace.
22015 The face used for trailing whitespace is `trailing-whitespace'. */);
22016 Vshow_trailing_whitespace = Qnil;
22018 #ifdef HAVE_WINDOW_SYSTEM
22019 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
22020 doc: /* *Non-nil means that newline may flow into the right fringe.
22021 This means that display lines which are exactly as wide as the window
22022 (not counting the final newline) will only occupy one screen line, by
22023 showing (or hiding) the final newline in the right fringe; when point
22024 is at the final newline, the cursor is shown in the right fringe.
22025 If nil, also continue lines which are exactly as wide as the window. */);
22026 Voverflow_newline_into_fringe = Qt;
22027 #endif
22029 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22030 doc: /* *The pointer shape to show in void text areas.
22031 Nil means to show the text pointer. Other options are `arrow', `text',
22032 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22033 Vvoid_text_area_pointer = Qarrow;
22035 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22036 doc: /* Non-nil means don't actually do any redisplay.
22037 This is used for internal purposes. */);
22038 Vinhibit_redisplay = Qnil;
22040 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22041 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22042 Vglobal_mode_string = Qnil;
22044 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22045 doc: /* Marker for where to display an arrow on top of the buffer text.
22046 This must be the beginning of a line in order to work.
22047 See also `overlay-arrow-string'. */);
22048 Voverlay_arrow_position = Qnil;
22050 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22051 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
22052 Voverlay_arrow_string = Qnil;
22054 DEFVAR_INT ("scroll-step", &scroll_step,
22055 doc: /* *The number of lines to try scrolling a window by when point moves out.
22056 If that fails to bring point back on frame, point is centered instead.
22057 If this is zero, point is always centered after it moves off frame.
22058 If you want scrolling to always be a line at a time, you should set
22059 `scroll-conservatively' to a large value rather than set this to 1. */);
22061 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22062 doc: /* *Scroll up to this many lines, to bring point back on screen.
22063 A value of zero means to scroll the text to center point vertically
22064 in the window. */);
22065 scroll_conservatively = 0;
22067 DEFVAR_INT ("scroll-margin", &scroll_margin,
22068 doc: /* *Number of lines of margin at the top and bottom of a window.
22069 Recenter the window whenever point gets within this many lines
22070 of the top or bottom of the window. */);
22071 scroll_margin = 0;
22073 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22074 doc: /* Pixels per inch on current display.
22075 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22076 Vdisplay_pixels_per_inch = make_float (72.0);
22078 #if GLYPH_DEBUG
22079 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22080 #endif
22082 DEFVAR_BOOL ("truncate-partial-width-windows",
22083 &truncate_partial_width_windows,
22084 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22085 truncate_partial_width_windows = 1;
22087 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22088 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22089 Any other value means to use the appropriate face, `mode-line',
22090 `header-line', or `menu' respectively. */);
22091 mode_line_inverse_video = 1;
22093 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22094 doc: /* *Maximum buffer size for which line number should be displayed.
22095 If the buffer is bigger than this, the line number does not appear
22096 in the mode line. A value of nil means no limit. */);
22097 Vline_number_display_limit = Qnil;
22099 DEFVAR_INT ("line-number-display-limit-width",
22100 &line_number_display_limit_width,
22101 doc: /* *Maximum line width (in characters) for line number display.
22102 If the average length of the lines near point is bigger than this, then the
22103 line number may be omitted from the mode line. */);
22104 line_number_display_limit_width = 200;
22106 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22107 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22108 highlight_nonselected_windows = 0;
22110 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22111 doc: /* Non-nil if more than one frame is visible on this display.
22112 Minibuffer-only frames don't count, but iconified frames do.
22113 This variable is not guaranteed to be accurate except while processing
22114 `frame-title-format' and `icon-title-format'. */);
22116 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22117 doc: /* Template for displaying the title bar of visible frames.
22118 \(Assuming the window manager supports this feature.)
22119 This variable has the same structure as `mode-line-format' (which see),
22120 and is used only on frames for which no explicit name has been set
22121 \(see `modify-frame-parameters'). */);
22123 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22124 doc: /* Template for displaying the title bar of an iconified frame.
22125 \(Assuming the window manager supports this feature.)
22126 This variable has the same structure as `mode-line-format' (which see),
22127 and is used only on frames for which no explicit name has been set
22128 \(see `modify-frame-parameters'). */);
22129 Vicon_title_format
22130 = Vframe_title_format
22131 = Fcons (intern ("multiple-frames"),
22132 Fcons (build_string ("%b"),
22133 Fcons (Fcons (empty_string,
22134 Fcons (intern ("invocation-name"),
22135 Fcons (build_string ("@"),
22136 Fcons (intern ("system-name"),
22137 Qnil)))),
22138 Qnil)));
22140 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22141 doc: /* Maximum number of lines to keep in the message log buffer.
22142 If nil, disable message logging. If t, log messages but don't truncate
22143 the buffer when it becomes large. */);
22144 Vmessage_log_max = make_number (50);
22146 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22147 doc: /* Functions called before redisplay, if window sizes have changed.
22148 The value should be a list of functions that take one argument.
22149 Just before redisplay, for each frame, if any of its windows have changed
22150 size since the last redisplay, or have been split or deleted,
22151 all the functions in the list are called, with the frame as argument. */);
22152 Vwindow_size_change_functions = Qnil;
22154 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22155 doc: /* List of Functions to call before redisplaying a window with scrolling.
22156 Each function is called with two arguments, the window
22157 and its new display-start position. Note that the value of `window-end'
22158 is not valid when these functions are called. */);
22159 Vwindow_scroll_functions = Qnil;
22161 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22162 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22163 mouse_autoselect_window = 0;
22165 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22166 doc: /* *Non-nil means automatically resize tool-bars.
22167 This increases a tool-bar's height if not all tool-bar items are visible.
22168 It decreases a tool-bar's height when it would display blank lines
22169 otherwise. */);
22170 auto_resize_tool_bars_p = 1;
22172 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22173 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22174 auto_raise_tool_bar_buttons_p = 1;
22176 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22177 doc: /* *Margin around tool-bar buttons in pixels.
22178 If an integer, use that for both horizontal and vertical margins.
22179 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22180 HORZ specifying the horizontal margin, and VERT specifying the
22181 vertical margin. */);
22182 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22184 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22185 doc: /* *Relief thickness of tool-bar buttons. */);
22186 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22188 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22189 doc: /* List of functions to call to fontify regions of text.
22190 Each function is called with one argument POS. Functions must
22191 fontify a region starting at POS in the current buffer, and give
22192 fontified regions the property `fontified'. */);
22193 Vfontification_functions = Qnil;
22194 Fmake_variable_buffer_local (Qfontification_functions);
22196 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22197 &unibyte_display_via_language_environment,
22198 doc: /* *Non-nil means display unibyte text according to language environment.
22199 Specifically this means that unibyte non-ASCII characters
22200 are displayed by converting them to the equivalent multibyte characters
22201 according to the current language environment. As a result, they are
22202 displayed according to the current fontset. */);
22203 unibyte_display_via_language_environment = 0;
22205 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22206 doc: /* *Maximum height for resizing mini-windows.
22207 If a float, it specifies a fraction of the mini-window frame's height.
22208 If an integer, it specifies a number of lines. */);
22209 Vmax_mini_window_height = make_float (0.25);
22211 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22212 doc: /* *How to resize mini-windows.
22213 A value of nil means don't automatically resize mini-windows.
22214 A value of t means resize them to fit the text displayed in them.
22215 A value of `grow-only', the default, means let mini-windows grow
22216 only, until their display becomes empty, at which point the windows
22217 go back to their normal size. */);
22218 Vresize_mini_windows = Qgrow_only;
22220 DEFVAR_LISP ("cursor-in-non-selected-windows",
22221 &Vcursor_in_non_selected_windows,
22222 doc: /* *Cursor type to display in non-selected windows.
22223 t means to use hollow box cursor. See `cursor-type' for other values. */);
22224 Vcursor_in_non_selected_windows = Qt;
22226 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22227 doc: /* Alist specifying how to blink the cursor off.
22228 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22229 `cursor-type' frame-parameter or variable equals ON-STATE,
22230 comparing using `equal', Emacs uses OFF-STATE to specify
22231 how to blink it off. */);
22232 Vblink_cursor_alist = Qnil;
22234 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22235 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22236 automatic_hscrolling_p = 1;
22238 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22239 doc: /* *How many columns away from the window edge point is allowed to get
22240 before automatic hscrolling will horizontally scroll the window. */);
22241 hscroll_margin = 5;
22243 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22244 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22245 When point is less than `automatic-hscroll-margin' columns from the window
22246 edge, automatic hscrolling will scroll the window by the amount of columns
22247 determined by this variable. If its value is a positive integer, scroll that
22248 many columns. If it's a positive floating-point number, it specifies the
22249 fraction of the window's width to scroll. If it's nil or zero, point will be
22250 centered horizontally after the scroll. Any other value, including negative
22251 numbers, are treated as if the value were zero.
22253 Automatic hscrolling always moves point outside the scroll margin, so if
22254 point was more than scroll step columns inside the margin, the window will
22255 scroll more than the value given by the scroll step.
22257 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22258 and `scroll-right' overrides this variable's effect. */);
22259 Vhscroll_step = make_number (0);
22261 DEFVAR_LISP ("image-types", &Vimage_types,
22262 doc: /* List of supported image types.
22263 Each element of the list is a symbol for a supported image type. */);
22264 Vimage_types = Qnil;
22266 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22267 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22268 Bind this around calls to `message' to let it take effect. */);
22269 message_truncate_lines = 0;
22271 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22272 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22273 Can be used to update submenus whose contents should vary. */);
22274 Vmenu_bar_update_hook = Qnil;
22276 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22277 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22278 inhibit_menubar_update = 0;
22280 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22281 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22282 inhibit_eval_during_redisplay = 0;
22284 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22285 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22286 inhibit_free_realized_faces = 0;
22288 #if GLYPH_DEBUG
22289 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22290 doc: /* Inhibit try_window_id display optimization. */);
22291 inhibit_try_window_id = 0;
22293 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22294 doc: /* Inhibit try_window_reusing display optimization. */);
22295 inhibit_try_window_reusing = 0;
22297 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22298 doc: /* Inhibit try_cursor_movement display optimization. */);
22299 inhibit_try_cursor_movement = 0;
22300 #endif /* GLYPH_DEBUG */
22304 /* Initialize this module when Emacs starts. */
22306 void
22307 init_xdisp ()
22309 Lisp_Object root_window;
22310 struct window *mini_w;
22312 current_header_line_height = current_mode_line_height = -1;
22314 CHARPOS (this_line_start_pos) = 0;
22316 mini_w = XWINDOW (minibuf_window);
22317 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22319 if (!noninteractive)
22321 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22322 int i;
22324 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22325 set_window_height (root_window,
22326 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22328 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22329 set_window_height (minibuf_window, 1, 0);
22331 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22332 mini_w->total_cols = make_number (FRAME_COLS (f));
22334 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22335 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22336 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22338 /* The default ellipsis glyphs `...'. */
22339 for (i = 0; i < 3; ++i)
22340 default_invis_vector[i] = make_number ('.');
22344 /* Allocate the buffer for frame titles.
22345 Also used for `format-mode-line'. */
22346 int size = 100;
22347 frame_title_buf = (char *) xmalloc (size);
22348 frame_title_buf_end = frame_title_buf + size;
22349 frame_title_ptr = NULL;
22352 help_echo_showing_p = 0;
22356 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22357 (do not change this comment) */