Fix bug #14575 with window-specific overlays with line-prefix or wrap-prefix.
[emacs.git] / src / xdisp.c
blob2097929128b6445bf3db5eedce0f21f832a95ad0
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
4 Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23 Redisplay.
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa. Under window systems
38 like X, some portions of the redisplay code are also called
39 asynchronously during mouse movement or expose events. It is very
40 important that these code parts do NOT use the C library (malloc,
41 free) because many C libraries under Unix are not reentrant. They
42 may also NOT call functions of the Lisp interpreter which could
43 change the interpreter's state. If you don't follow these rules,
44 you will encounter bugs which are very hard to explain.
46 +--------------+ redisplay +----------------+
47 | Lisp machine |---------------->| Redisplay code |<--+
48 +--------------+ (xdisp.c) +----------------+ |
49 ^ | |
50 +----------------------------------+ |
51 Don't use this path when called |
52 asynchronously! |
54 expose_window (asynchronous) |
56 X expose events -----+
58 What does redisplay do? Obviously, it has to figure out somehow what
59 has been changed since the last time the display has been updated,
60 and to make these changes visible. Preferably it would do that in
61 a moderately intelligent way, i.e. fast.
63 Changes in buffer text can be deduced from window and buffer
64 structures, and from some global variables like `beg_unchanged' and
65 `end_unchanged'. The contents of the display are additionally
66 recorded in a `glyph matrix', a two-dimensional matrix of glyph
67 structures. Each row in such a matrix corresponds to a line on the
68 display, and each glyph in a row corresponds to a column displaying
69 a character, an image, or what else. This matrix is called the
70 `current glyph matrix' or `current matrix' in redisplay
71 terminology.
73 For buffer parts that have been changed since the last update, a
74 second glyph matrix is constructed, the so called `desired glyph
75 matrix' or short `desired matrix'. Current and desired matrix are
76 then compared to find a cheap way to update the display, e.g. by
77 reusing part of the display by scrolling lines.
79 You will find a lot of redisplay optimizations when you start
80 looking at the innards of redisplay. The overall goal of all these
81 optimizations is to make redisplay fast because it is done
82 frequently. Some of these optimizations are implemented by the
83 following functions:
85 . try_cursor_movement
87 This function tries to update the display if the text in the
88 window did not change and did not scroll, only point moved, and
89 it did not move off the displayed portion of the text.
91 . try_window_reusing_current_matrix
93 This function reuses the current matrix of a window when text
94 has not changed, but the window start changed (e.g., due to
95 scrolling).
97 . try_window_id
99 This function attempts to redisplay a window by reusing parts of
100 its existing display. It finds and reuses the part that was not
101 changed, and redraws the rest.
103 . try_window
105 This function performs the full redisplay of a single window
106 assuming that its fonts were not changed and that the cursor
107 will not end up in the scroll margins. (Loading fonts requires
108 re-adjustment of dimensions of glyph matrices, which makes this
109 method impossible to use.)
111 These optimizations are tried in sequence (some can be skipped if
112 it is known that they are not applicable). If none of the
113 optimizations were successful, redisplay calls redisplay_windows,
114 which performs a full redisplay of all windows.
116 Desired matrices.
118 Desired matrices are always built per Emacs window. The function
119 `display_line' is the central function to look at if you are
120 interested. It constructs one row in a desired matrix given an
121 iterator structure containing both a buffer position and a
122 description of the environment in which the text is to be
123 displayed. But this is too early, read on.
125 Characters and pixmaps displayed for a range of buffer text depend
126 on various settings of buffers and windows, on overlays and text
127 properties, on display tables, on selective display. The good news
128 is that all this hairy stuff is hidden behind a small set of
129 interface functions taking an iterator structure (struct it)
130 argument.
132 Iteration over things to be displayed is then simple. It is
133 started by initializing an iterator with a call to init_iterator,
134 passing it the buffer position where to start iteration. For
135 iteration over strings, pass -1 as the position to init_iterator,
136 and call reseat_to_string when the string is ready, to initialize
137 the iterator for that string. Thereafter, calls to
138 get_next_display_element fill the iterator structure with relevant
139 information about the next thing to display. Calls to
140 set_iterator_to_next move the iterator to the next thing.
142 Besides this, an iterator also contains information about the
143 display environment in which glyphs for display elements are to be
144 produced. It has fields for the width and height of the display,
145 the information whether long lines are truncated or continued, a
146 current X and Y position, and lots of other stuff you can better
147 see in dispextern.h.
149 Glyphs in a desired matrix are normally constructed in a loop
150 calling get_next_display_element and then PRODUCE_GLYPHS. The call
151 to PRODUCE_GLYPHS will fill the iterator structure with pixel
152 information about the element being displayed and at the same time
153 produce glyphs for it. If the display element fits on the line
154 being displayed, set_iterator_to_next is called next, otherwise the
155 glyphs produced are discarded. The function display_line is the
156 workhorse of filling glyph rows in the desired matrix with glyphs.
157 In addition to producing glyphs, it also handles line truncation
158 and continuation, word wrap, and cursor positioning (for the
159 latter, see also set_cursor_from_row).
161 Frame matrices.
163 That just couldn't be all, could it? What about terminal types not
164 supporting operations on sub-windows of the screen? To update the
165 display on such a terminal, window-based glyph matrices are not
166 well suited. To be able to reuse part of the display (scrolling
167 lines up and down), we must instead have a view of the whole
168 screen. This is what `frame matrices' are for. They are a trick.
170 Frames on terminals like above have a glyph pool. Windows on such
171 a frame sub-allocate their glyph memory from their frame's glyph
172 pool. The frame itself is given its own glyph matrices. By
173 coincidence---or maybe something else---rows in window glyph
174 matrices are slices of corresponding rows in frame matrices. Thus
175 writing to window matrices implicitly updates a frame matrix which
176 provides us with the view of the whole screen that we originally
177 wanted to have without having to move many bytes around. To be
178 honest, there is a little bit more done, but not much more. If you
179 plan to extend that code, take a look at dispnew.c. The function
180 build_frame_matrix is a good starting point.
182 Bidirectional display.
184 Bidirectional display adds quite some hair to this already complex
185 design. The good news are that a large portion of that hairy stuff
186 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
187 reordering engine which is called by set_iterator_to_next and
188 returns the next character to display in the visual order. See
189 commentary on bidi.c for more details. As far as redisplay is
190 concerned, the effect of calling bidi_move_to_visually_next, the
191 main interface of the reordering engine, is that the iterator gets
192 magically placed on the buffer or string position that is to be
193 displayed next. In other words, a linear iteration through the
194 buffer/string is replaced with a non-linear one. All the rest of
195 the redisplay is oblivious to the bidi reordering.
197 Well, almost oblivious---there are still complications, most of
198 them due to the fact that buffer and string positions no longer
199 change monotonously with glyph indices in a glyph row. Moreover,
200 for continued lines, the buffer positions may not even be
201 monotonously changing with vertical positions. Also, accounting
202 for face changes, overlays, etc. becomes more complex because
203 non-linear iteration could potentially skip many positions with
204 changes, and then cross them again on the way back...
206 One other prominent effect of bidirectional display is that some
207 paragraphs of text need to be displayed starting at the right
208 margin of the window---the so-called right-to-left, or R2L
209 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
210 which have their reversed_p flag set. The bidi reordering engine
211 produces characters in such rows starting from the character which
212 should be the rightmost on display. PRODUCE_GLYPHS then reverses
213 the order, when it fills up the glyph row whose reversed_p flag is
214 set, by prepending each new glyph to what is already there, instead
215 of appending it. When the glyph row is complete, the function
216 extend_face_to_end_of_line fills the empty space to the left of the
217 leftmost character with special glyphs, which will display as,
218 well, empty. On text terminals, these special glyphs are simply
219 blank characters. On graphics terminals, there's a single stretch
220 glyph of a suitably computed width. Both the blanks and the
221 stretch glyph are given the face of the background of the line.
222 This way, the terminal-specific back-end can still draw the glyphs
223 left to right, even for R2L lines.
225 Bidirectional display and character compositions
227 Some scripts cannot be displayed by drawing each character
228 individually, because adjacent characters change each other's shape
229 on display. For example, Arabic and Indic scripts belong to this
230 category.
232 Emacs display supports this by providing "character compositions",
233 most of which is implemented in composite.c. During the buffer
234 scan that delivers characters to PRODUCE_GLYPHS, if the next
235 character to be delivered is a composed character, the iteration
236 calls composition_reseat_it and next_element_from_composition. If
237 they succeed to compose the character with one or more of the
238 following characters, the whole sequence of characters that where
239 composed is recorded in the `struct composition_it' object that is
240 part of the buffer iterator. The composed sequence could produce
241 one or more font glyphs (called "grapheme clusters") on the screen.
242 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
243 in the direction corresponding to the current bidi scan direction
244 (recorded in the scan_dir member of the `struct bidi_it' object
245 that is part of the buffer iterator). In particular, if the bidi
246 iterator currently scans the buffer backwards, the grapheme
247 clusters are delivered back to front. This reorders the grapheme
248 clusters as appropriate for the current bidi context. Note that
249 this means that the grapheme clusters are always stored in the
250 LGSTRING object (see composite.c) in the logical order.
252 Moving an iterator in bidirectional text
253 without producing glyphs
255 Note one important detail mentioned above: that the bidi reordering
256 engine, driven by the iterator, produces characters in R2L rows
257 starting at the character that will be the rightmost on display.
258 As far as the iterator is concerned, the geometry of such rows is
259 still left to right, i.e. the iterator "thinks" the first character
260 is at the leftmost pixel position. The iterator does not know that
261 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
262 delivers. This is important when functions from the move_it_*
263 family are used to get to certain screen position or to match
264 screen coordinates with buffer coordinates: these functions use the
265 iterator geometry, which is left to right even in R2L paragraphs.
266 This works well with most callers of move_it_*, because they need
267 to get to a specific column, and columns are still numbered in the
268 reading order, i.e. the rightmost character in a R2L paragraph is
269 still column zero. But some callers do not get well with this; a
270 notable example is mouse clicks that need to find the character
271 that corresponds to certain pixel coordinates. See
272 buffer_posn_from_coords in dispnew.c for how this is handled. */
274 #include <config.h>
275 #include <stdio.h>
276 #include <limits.h>
278 #include "lisp.h"
279 #include "atimer.h"
280 #include "keyboard.h"
281 #include "frame.h"
282 #include "window.h"
283 #include "termchar.h"
284 #include "dispextern.h"
285 #include "character.h"
286 #include "buffer.h"
287 #include "charset.h"
288 #include "indent.h"
289 #include "commands.h"
290 #include "keymap.h"
291 #include "macros.h"
292 #include "disptab.h"
293 #include "termhooks.h"
294 #include "termopts.h"
295 #include "intervals.h"
296 #include "coding.h"
297 #include "process.h"
298 #include "region-cache.h"
299 #include "font.h"
300 #include "fontset.h"
301 #include "blockinput.h"
303 #ifdef HAVE_X_WINDOWS
304 #include "xterm.h"
305 #endif
306 #ifdef HAVE_NTGUI
307 #include "w32term.h"
308 #endif
309 #ifdef HAVE_NS
310 #include "nsterm.h"
311 #endif
312 #ifdef USE_GTK
313 #include "gtkutil.h"
314 #endif
316 #include "font.h"
318 #ifndef FRAME_X_OUTPUT
319 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
320 #endif
322 #define INFINITY 10000000
324 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
325 Lisp_Object Qwindow_scroll_functions;
326 static Lisp_Object Qwindow_text_change_functions;
327 static Lisp_Object Qredisplay_end_trigger_functions;
328 Lisp_Object Qinhibit_point_motion_hooks;
329 static Lisp_Object QCeval, QCpropertize;
330 Lisp_Object QCfile, QCdata;
331 static Lisp_Object Qfontified;
332 static Lisp_Object Qgrow_only;
333 static Lisp_Object Qinhibit_eval_during_redisplay;
334 static Lisp_Object Qbuffer_position, Qposition, Qobject;
335 static Lisp_Object Qright_to_left, Qleft_to_right;
337 /* Cursor shapes. */
338 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
340 /* Pointer shapes. */
341 static Lisp_Object Qarrow, Qhand;
342 Lisp_Object Qtext;
344 /* Holds the list (error). */
345 static Lisp_Object list_of_error;
347 static Lisp_Object Qfontification_functions;
349 static Lisp_Object Qwrap_prefix;
350 static Lisp_Object Qline_prefix;
351 static Lisp_Object Qredisplay_internal;
353 /* Non-nil means don't actually do any redisplay. */
355 Lisp_Object Qinhibit_redisplay;
357 /* Names of text properties relevant for redisplay. */
359 Lisp_Object Qdisplay;
361 Lisp_Object Qspace, QCalign_to;
362 static Lisp_Object QCrelative_width, QCrelative_height;
363 Lisp_Object Qleft_margin, Qright_margin;
364 static Lisp_Object Qspace_width, Qraise;
365 static Lisp_Object Qslice;
366 Lisp_Object Qcenter;
367 static Lisp_Object Qmargin, Qpointer;
368 static Lisp_Object Qline_height;
370 #ifdef HAVE_WINDOW_SYSTEM
372 /* Test if overflow newline into fringe. Called with iterator IT
373 at or past right window margin, and with IT->current_x set. */
375 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
376 (!NILP (Voverflow_newline_into_fringe) \
377 && FRAME_WINDOW_P ((IT)->f) \
378 && ((IT)->bidi_it.paragraph_dir == R2L \
379 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
380 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
381 && (IT)->current_x == (IT)->last_visible_x \
382 && (IT)->line_wrap != WORD_WRAP)
384 #else /* !HAVE_WINDOW_SYSTEM */
385 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
386 #endif /* HAVE_WINDOW_SYSTEM */
388 /* Test if the display element loaded in IT, or the underlying buffer
389 or string character, is a space or a TAB character. This is used
390 to determine where word wrapping can occur. */
392 #define IT_DISPLAYING_WHITESPACE(it) \
393 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
394 || ((STRINGP (it->string) \
395 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
396 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
397 || (it->s \
398 && (it->s[IT_BYTEPOS (*it)] == ' ' \
399 || it->s[IT_BYTEPOS (*it)] == '\t')) \
400 || (IT_BYTEPOS (*it) < ZV_BYTE \
401 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
402 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
404 /* Name of the face used to highlight trailing whitespace. */
406 static Lisp_Object Qtrailing_whitespace;
408 /* Name and number of the face used to highlight escape glyphs. */
410 static Lisp_Object Qescape_glyph;
412 /* Name and number of the face used to highlight non-breaking spaces. */
414 static Lisp_Object Qnobreak_space;
416 /* The symbol `image' which is the car of the lists used to represent
417 images in Lisp. Also a tool bar style. */
419 Lisp_Object Qimage;
421 /* The image map types. */
422 Lisp_Object QCmap;
423 static Lisp_Object QCpointer;
424 static Lisp_Object Qrect, Qcircle, Qpoly;
426 /* Tool bar styles */
427 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
429 /* Non-zero means print newline to stdout before next mini-buffer
430 message. */
432 int noninteractive_need_newline;
434 /* Non-zero means print newline to message log before next message. */
436 static int message_log_need_newline;
438 /* Three markers that message_dolog uses.
439 It could allocate them itself, but that causes trouble
440 in handling memory-full errors. */
441 static Lisp_Object message_dolog_marker1;
442 static Lisp_Object message_dolog_marker2;
443 static Lisp_Object message_dolog_marker3;
445 /* The buffer position of the first character appearing entirely or
446 partially on the line of the selected window which contains the
447 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
448 redisplay optimization in redisplay_internal. */
450 static struct text_pos this_line_start_pos;
452 /* Number of characters past the end of the line above, including the
453 terminating newline. */
455 static struct text_pos this_line_end_pos;
457 /* The vertical positions and the height of this line. */
459 static int this_line_vpos;
460 static int this_line_y;
461 static int this_line_pixel_height;
463 /* X position at which this display line starts. Usually zero;
464 negative if first character is partially visible. */
466 static int this_line_start_x;
468 /* The smallest character position seen by move_it_* functions as they
469 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
470 hscrolled lines, see display_line. */
472 static struct text_pos this_line_min_pos;
474 /* Buffer that this_line_.* variables are referring to. */
476 static struct buffer *this_line_buffer;
479 /* Values of those variables at last redisplay are stored as
480 properties on `overlay-arrow-position' symbol. However, if
481 Voverlay_arrow_position is a marker, last-arrow-position is its
482 numerical position. */
484 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
486 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
487 properties on a symbol in overlay-arrow-variable-list. */
489 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
491 Lisp_Object Qmenu_bar_update_hook;
493 /* Nonzero if an overlay arrow has been displayed in this window. */
495 static int overlay_arrow_seen;
497 /* Vector containing glyphs for an ellipsis `...'. */
499 static Lisp_Object default_invis_vector[3];
501 /* This is the window where the echo area message was displayed. It
502 is always a mini-buffer window, but it may not be the same window
503 currently active as a mini-buffer. */
505 Lisp_Object echo_area_window;
507 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
508 pushes the current message and the value of
509 message_enable_multibyte on the stack, the function restore_message
510 pops the stack and displays MESSAGE again. */
512 static Lisp_Object Vmessage_stack;
514 /* Nonzero means multibyte characters were enabled when the echo area
515 message was specified. */
517 static int message_enable_multibyte;
519 /* Nonzero if we should redraw the mode lines on the next redisplay. */
521 int update_mode_lines;
523 /* Nonzero if window sizes or contents have changed since last
524 redisplay that finished. */
526 int windows_or_buffers_changed;
528 /* Nonzero means a frame's cursor type has been changed. */
530 int cursor_type_changed;
532 /* Nonzero after display_mode_line if %l was used and it displayed a
533 line number. */
535 static int line_number_displayed;
537 /* The name of the *Messages* buffer, a string. */
539 static Lisp_Object Vmessages_buffer_name;
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
544 Lisp_Object echo_area_buffer[2];
546 /* The buffers referenced from echo_area_buffer. */
548 static Lisp_Object echo_buffer[2];
550 /* A vector saved used in with_area_buffer to reduce consing. */
552 static Lisp_Object Vwith_echo_area_save_vector;
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
557 static int display_last_displayed_message_p;
559 /* Nonzero if echo area is being used by print; zero if being used by
560 message. */
562 static int message_buf_print;
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
566 static Lisp_Object Qinhibit_menubar_update;
567 static Lisp_Object Qmessage_truncate_lines;
569 /* Set to 1 in clear_message to make redisplay_internal aware
570 of an emptied echo area. */
572 static int message_cleared_p;
574 /* A scratch glyph row with contents used for generating truncation
575 glyphs. Also used in direct_output_for_insert. */
577 #define MAX_SCRATCH_GLYPHS 100
578 static struct glyph_row scratch_glyph_row;
579 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
581 /* Ascent and height of the last line processed by move_it_to. */
583 static int last_height;
585 /* Non-zero if there's a help-echo in the echo area. */
587 int help_echo_showing_p;
589 /* If >= 0, computed, exact values of mode-line and header-line height
590 to use in the macros CURRENT_MODE_LINE_HEIGHT and
591 CURRENT_HEADER_LINE_HEIGHT. */
593 int current_mode_line_height, current_header_line_height;
595 /* The maximum distance to look ahead for text properties. Values
596 that are too small let us call compute_char_face and similar
597 functions too often which is expensive. Values that are too large
598 let us call compute_char_face and alike too often because we
599 might not be interested in text properties that far away. */
601 #define TEXT_PROP_DISTANCE_LIMIT 100
603 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
604 iterator state and later restore it. This is needed because the
605 bidi iterator on bidi.c keeps a stacked cache of its states, which
606 is really a singleton. When we use scratch iterator objects to
607 move around the buffer, we can cause the bidi cache to be pushed or
608 popped, and therefore we need to restore the cache state when we
609 return to the original iterator. */
610 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
611 do { \
612 if (CACHE) \
613 bidi_unshelve_cache (CACHE, 1); \
614 ITCOPY = ITORIG; \
615 CACHE = bidi_shelve_cache (); \
616 } while (0)
618 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
619 do { \
620 if (pITORIG != pITCOPY) \
621 *(pITORIG) = *(pITCOPY); \
622 bidi_unshelve_cache (CACHE, 0); \
623 CACHE = NULL; \
624 } while (0)
626 #ifdef GLYPH_DEBUG
628 /* Non-zero means print traces of redisplay if compiled with
629 GLYPH_DEBUG defined. */
631 int trace_redisplay_p;
633 #endif /* GLYPH_DEBUG */
635 #ifdef DEBUG_TRACE_MOVE
636 /* Non-zero means trace with TRACE_MOVE to stderr. */
637 int trace_move;
639 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
640 #else
641 #define TRACE_MOVE(x) (void) 0
642 #endif
644 static Lisp_Object Qauto_hscroll_mode;
646 /* Buffer being redisplayed -- for redisplay_window_error. */
648 static struct buffer *displayed_buffer;
650 /* Value returned from text property handlers (see below). */
652 enum prop_handled
654 HANDLED_NORMALLY,
655 HANDLED_RECOMPUTE_PROPS,
656 HANDLED_OVERLAY_STRING_CONSUMED,
657 HANDLED_RETURN
660 /* A description of text properties that redisplay is interested
661 in. */
663 struct props
665 /* The name of the property. */
666 Lisp_Object *name;
668 /* A unique index for the property. */
669 enum prop_idx idx;
671 /* A handler function called to set up iterator IT from the property
672 at IT's current position. Value is used to steer handle_stop. */
673 enum prop_handled (*handler) (struct it *it);
676 static enum prop_handled handle_face_prop (struct it *);
677 static enum prop_handled handle_invisible_prop (struct it *);
678 static enum prop_handled handle_display_prop (struct it *);
679 static enum prop_handled handle_composition_prop (struct it *);
680 static enum prop_handled handle_overlay_change (struct it *);
681 static enum prop_handled handle_fontified_prop (struct it *);
683 /* Properties handled by iterators. */
685 static struct props it_props[] =
687 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
688 /* Handle `face' before `display' because some sub-properties of
689 `display' need to know the face. */
690 {&Qface, FACE_PROP_IDX, handle_face_prop},
691 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
692 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
693 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
694 {NULL, 0, NULL}
697 /* Value is the position described by X. If X is a marker, value is
698 the marker_position of X. Otherwise, value is X. */
700 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
702 /* Enumeration returned by some move_it_.* functions internally. */
704 enum move_it_result
706 /* Not used. Undefined value. */
707 MOVE_UNDEFINED,
709 /* Move ended at the requested buffer position or ZV. */
710 MOVE_POS_MATCH_OR_ZV,
712 /* Move ended at the requested X pixel position. */
713 MOVE_X_REACHED,
715 /* Move within a line ended at the end of a line that must be
716 continued. */
717 MOVE_LINE_CONTINUED,
719 /* Move within a line ended at the end of a line that would
720 be displayed truncated. */
721 MOVE_LINE_TRUNCATED,
723 /* Move within a line ended at a line end. */
724 MOVE_NEWLINE_OR_CR
727 /* This counter is used to clear the face cache every once in a while
728 in redisplay_internal. It is incremented for each redisplay.
729 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
730 cleared. */
732 #define CLEAR_FACE_CACHE_COUNT 500
733 static int clear_face_cache_count;
735 /* Similarly for the image cache. */
737 #ifdef HAVE_WINDOW_SYSTEM
738 #define CLEAR_IMAGE_CACHE_COUNT 101
739 static int clear_image_cache_count;
741 /* Null glyph slice */
742 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
743 #endif
745 /* True while redisplay_internal is in progress. */
747 bool redisplaying_p;
749 static Lisp_Object Qinhibit_free_realized_faces;
750 static Lisp_Object Qmode_line_default_help_echo;
752 /* If a string, XTread_socket generates an event to display that string.
753 (The display is done in read_char.) */
755 Lisp_Object help_echo_string;
756 Lisp_Object help_echo_window;
757 Lisp_Object help_echo_object;
758 ptrdiff_t help_echo_pos;
760 /* Temporary variable for XTread_socket. */
762 Lisp_Object previous_help_echo_string;
764 /* Platform-independent portion of hourglass implementation. */
766 /* Non-zero means an hourglass cursor is currently shown. */
767 int hourglass_shown_p;
769 /* If non-null, an asynchronous timer that, when it expires, displays
770 an hourglass cursor on all frames. */
771 struct atimer *hourglass_atimer;
773 /* Name of the face used to display glyphless characters. */
774 Lisp_Object Qglyphless_char;
776 /* Symbol for the purpose of Vglyphless_char_display. */
777 static Lisp_Object Qglyphless_char_display;
779 /* Method symbols for Vglyphless_char_display. */
780 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
782 /* Default pixel width of `thin-space' display method. */
783 #define THIN_SPACE_WIDTH 1
785 /* Default number of seconds to wait before displaying an hourglass
786 cursor. */
787 #define DEFAULT_HOURGLASS_DELAY 1
790 /* Function prototypes. */
792 static void setup_for_ellipsis (struct it *, int);
793 static void set_iterator_to_next (struct it *, int);
794 static void mark_window_display_accurate_1 (struct window *, int);
795 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
796 static int display_prop_string_p (Lisp_Object, Lisp_Object);
797 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
798 static int cursor_row_p (struct glyph_row *);
799 static int redisplay_mode_lines (Lisp_Object, int);
800 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
802 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
804 static void handle_line_prefix (struct it *);
806 static void pint2str (char *, int, ptrdiff_t);
807 static void pint2hrstr (char *, int, ptrdiff_t);
808 static struct text_pos run_window_scroll_functions (Lisp_Object,
809 struct text_pos);
810 static void reconsider_clip_changes (struct window *, struct buffer *);
811 static int text_outside_line_unchanged_p (struct window *,
812 ptrdiff_t, ptrdiff_t);
813 static void store_mode_line_noprop_char (char);
814 static int store_mode_line_noprop (const char *, int, int);
815 static void handle_stop (struct it *);
816 static void handle_stop_backwards (struct it *, ptrdiff_t);
817 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
818 static void ensure_echo_area_buffers (void);
819 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
820 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
821 static int with_echo_area_buffer (struct window *, int,
822 int (*) (ptrdiff_t, Lisp_Object),
823 ptrdiff_t, Lisp_Object);
824 static void clear_garbaged_frames (void);
825 static int current_message_1 (ptrdiff_t, Lisp_Object);
826 static void pop_message (void);
827 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
828 static void set_message (Lisp_Object);
829 static int set_message_1 (ptrdiff_t, Lisp_Object);
830 static int display_echo_area (struct window *);
831 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
832 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
833 static Lisp_Object unwind_redisplay (Lisp_Object);
834 static int string_char_and_length (const unsigned char *, int *);
835 static struct text_pos display_prop_end (struct it *, Lisp_Object,
836 struct text_pos);
837 static int compute_window_start_on_continuation_line (struct window *);
838 static void insert_left_trunc_glyphs (struct it *);
839 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
840 Lisp_Object);
841 static void extend_face_to_end_of_line (struct it *);
842 static int append_space_for_newline (struct it *, int);
843 static int cursor_row_fully_visible_p (struct window *, int, int);
844 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
845 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
846 static int trailing_whitespace_p (ptrdiff_t);
847 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
848 static void push_it (struct it *, struct text_pos *);
849 static void iterate_out_of_display_property (struct it *);
850 static void pop_it (struct it *);
851 static void sync_frame_with_window_matrix_rows (struct window *);
852 static void redisplay_internal (void);
853 static int echo_area_display (int);
854 static void redisplay_windows (Lisp_Object);
855 static void redisplay_window (Lisp_Object, int);
856 static Lisp_Object redisplay_window_error (Lisp_Object);
857 static Lisp_Object redisplay_window_0 (Lisp_Object);
858 static Lisp_Object redisplay_window_1 (Lisp_Object);
859 static int set_cursor_from_row (struct window *, struct glyph_row *,
860 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
861 int, int);
862 static int update_menu_bar (struct frame *, int, int);
863 static int try_window_reusing_current_matrix (struct window *);
864 static int try_window_id (struct window *);
865 static int display_line (struct it *);
866 static int display_mode_lines (struct window *);
867 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
868 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
869 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
870 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
871 static void display_menu_bar (struct window *);
872 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
873 ptrdiff_t *);
874 static int display_string (const char *, Lisp_Object, Lisp_Object,
875 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
876 static void compute_line_metrics (struct it *);
877 static void run_redisplay_end_trigger_hook (struct it *);
878 static int get_overlay_strings (struct it *, ptrdiff_t);
879 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
880 static void next_overlay_string (struct it *);
881 static void reseat (struct it *, struct text_pos, int);
882 static void reseat_1 (struct it *, struct text_pos, int);
883 static void back_to_previous_visible_line_start (struct it *);
884 static void reseat_at_next_visible_line_start (struct it *, int);
885 static int next_element_from_ellipsis (struct it *);
886 static int next_element_from_display_vector (struct it *);
887 static int next_element_from_string (struct it *);
888 static int next_element_from_c_string (struct it *);
889 static int next_element_from_buffer (struct it *);
890 static int next_element_from_composition (struct it *);
891 static int next_element_from_image (struct it *);
892 static int next_element_from_stretch (struct it *);
893 static void load_overlay_strings (struct it *, ptrdiff_t);
894 static int init_from_display_pos (struct it *, struct window *,
895 struct display_pos *);
896 static void reseat_to_string (struct it *, const char *,
897 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
898 static int get_next_display_element (struct it *);
899 static enum move_it_result
900 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
901 enum move_operation_enum);
902 static void get_visually_first_element (struct it *);
903 static void init_to_row_start (struct it *, struct window *,
904 struct glyph_row *);
905 static int init_to_row_end (struct it *, struct window *,
906 struct glyph_row *);
907 static void back_to_previous_line_start (struct it *);
908 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
909 static struct text_pos string_pos_nchars_ahead (struct text_pos,
910 Lisp_Object, ptrdiff_t);
911 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
912 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
913 static ptrdiff_t number_of_chars (const char *, bool);
914 static void compute_stop_pos (struct it *);
915 static void compute_string_pos (struct text_pos *, struct text_pos,
916 Lisp_Object);
917 static int face_before_or_after_it_pos (struct it *, int);
918 static ptrdiff_t next_overlay_change (ptrdiff_t);
919 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
920 Lisp_Object, struct text_pos *, ptrdiff_t, int);
921 static int handle_single_display_spec (struct it *, Lisp_Object,
922 Lisp_Object, Lisp_Object,
923 struct text_pos *, ptrdiff_t, int, int);
924 static int underlying_face_id (struct it *);
925 static int in_ellipses_for_invisible_text_p (struct display_pos *,
926 struct window *);
928 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
929 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931 #ifdef HAVE_WINDOW_SYSTEM
933 static void x_consider_frame_title (Lisp_Object);
934 static int tool_bar_lines_needed (struct frame *, int *);
935 static void update_tool_bar (struct frame *, int);
936 static void build_desired_tool_bar_string (struct frame *f);
937 static int redisplay_tool_bar (struct frame *);
938 static void display_tool_bar_line (struct it *, int);
939 static void notice_overwritten_cursor (struct window *,
940 enum glyph_row_area,
941 int, int, int, int);
942 static void append_stretch_glyph (struct it *, Lisp_Object,
943 int, int, int);
946 #endif /* HAVE_WINDOW_SYSTEM */
948 static void produce_special_glyphs (struct it *, enum display_element_type);
949 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
950 static int coords_in_mouse_face_p (struct window *, int, int);
954 /***********************************************************************
955 Window display dimensions
956 ***********************************************************************/
958 /* Return the bottom boundary y-position for text lines in window W.
959 This is the first y position at which a line cannot start.
960 It is relative to the top of the window.
962 This is the height of W minus the height of a mode line, if any. */
965 window_text_bottom_y (struct window *w)
967 int height = WINDOW_TOTAL_HEIGHT (w);
969 if (WINDOW_WANTS_MODELINE_P (w))
970 height -= CURRENT_MODE_LINE_HEIGHT (w);
971 return height;
974 /* Return the pixel width of display area AREA of window W. AREA < 0
975 means return the total width of W, not including fringes to
976 the left and right of the window. */
979 window_box_width (struct window *w, int area)
981 int cols = w->total_cols;
982 int pixels = 0;
984 if (!w->pseudo_window_p)
986 cols -= WINDOW_SCROLL_BAR_COLS (w);
988 if (area == TEXT_AREA)
990 if (INTEGERP (w->left_margin_cols))
991 cols -= XFASTINT (w->left_margin_cols);
992 if (INTEGERP (w->right_margin_cols))
993 cols -= XFASTINT (w->right_margin_cols);
994 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
996 else if (area == LEFT_MARGIN_AREA)
998 cols = (INTEGERP (w->left_margin_cols)
999 ? XFASTINT (w->left_margin_cols) : 0);
1000 pixels = 0;
1002 else if (area == RIGHT_MARGIN_AREA)
1004 cols = (INTEGERP (w->right_margin_cols)
1005 ? XFASTINT (w->right_margin_cols) : 0);
1006 pixels = 0;
1010 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1014 /* Return the pixel height of the display area of window W, not
1015 including mode lines of W, if any. */
1018 window_box_height (struct window *w)
1020 struct frame *f = XFRAME (w->frame);
1021 int height = WINDOW_TOTAL_HEIGHT (w);
1023 eassert (height >= 0);
1025 /* Note: the code below that determines the mode-line/header-line
1026 height is essentially the same as that contained in the macro
1027 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1028 the appropriate glyph row has its `mode_line_p' flag set,
1029 and if it doesn't, uses estimate_mode_line_height instead. */
1031 if (WINDOW_WANTS_MODELINE_P (w))
1033 struct glyph_row *ml_row
1034 = (w->current_matrix && w->current_matrix->rows
1035 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1036 : 0);
1037 if (ml_row && ml_row->mode_line_p)
1038 height -= ml_row->height;
1039 else
1040 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1043 if (WINDOW_WANTS_HEADER_LINE_P (w))
1045 struct glyph_row *hl_row
1046 = (w->current_matrix && w->current_matrix->rows
1047 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1048 : 0);
1049 if (hl_row && hl_row->mode_line_p)
1050 height -= hl_row->height;
1051 else
1052 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1055 /* With a very small font and a mode-line that's taller than
1056 default, we might end up with a negative height. */
1057 return max (0, height);
1060 /* Return the window-relative coordinate of the left edge of display
1061 area AREA of window W. AREA < 0 means return the left edge of the
1062 whole window, to the right of the left fringe of W. */
1065 window_box_left_offset (struct window *w, int area)
1067 int x;
1069 if (w->pseudo_window_p)
1070 return 0;
1072 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1074 if (area == TEXT_AREA)
1075 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1076 + window_box_width (w, LEFT_MARGIN_AREA));
1077 else if (area == RIGHT_MARGIN_AREA)
1078 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1079 + window_box_width (w, LEFT_MARGIN_AREA)
1080 + window_box_width (w, TEXT_AREA)
1081 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1083 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1084 else if (area == LEFT_MARGIN_AREA
1085 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1086 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1088 return x;
1092 /* Return the window-relative coordinate of the right edge of display
1093 area AREA of window W. AREA < 0 means return the right edge of the
1094 whole window, to the left of the right fringe of W. */
1097 window_box_right_offset (struct window *w, int area)
1099 return window_box_left_offset (w, area) + window_box_width (w, area);
1102 /* Return the frame-relative coordinate of the left edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the right of the left fringe of W. */
1107 window_box_left (struct window *w, int area)
1109 struct frame *f = XFRAME (w->frame);
1110 int x;
1112 if (w->pseudo_window_p)
1113 return FRAME_INTERNAL_BORDER_WIDTH (f);
1115 x = (WINDOW_LEFT_EDGE_X (w)
1116 + window_box_left_offset (w, area));
1118 return x;
1122 /* Return the frame-relative coordinate of the right edge of display
1123 area AREA of window W. AREA < 0 means return the right edge of the
1124 whole window, to the left of the right fringe of W. */
1127 window_box_right (struct window *w, int area)
1129 return window_box_left (w, area) + window_box_width (w, area);
1132 /* Get the bounding box of the display area AREA of window W, without
1133 mode lines, in frame-relative coordinates. AREA < 0 means the
1134 whole window, not including the left and right fringes of
1135 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1136 coordinates of the upper-left corner of the box. Return in
1137 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1139 void
1140 window_box (struct window *w, int area, int *box_x, int *box_y,
1141 int *box_width, int *box_height)
1143 if (box_width)
1144 *box_width = window_box_width (w, area);
1145 if (box_height)
1146 *box_height = window_box_height (w);
1147 if (box_x)
1148 *box_x = window_box_left (w, area);
1149 if (box_y)
1151 *box_y = WINDOW_TOP_EDGE_Y (w);
1152 if (WINDOW_WANTS_HEADER_LINE_P (w))
1153 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1158 /* Get the bounding box of the display area AREA of window W, without
1159 mode lines. AREA < 0 means the whole window, not including the
1160 left and right fringe of the window. Return in *TOP_LEFT_X
1161 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1162 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1163 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1164 box. */
1166 static void
1167 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1168 int *bottom_right_x, int *bottom_right_y)
1170 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1171 bottom_right_y);
1172 *bottom_right_x += *top_left_x;
1173 *bottom_right_y += *top_left_y;
1178 /***********************************************************************
1179 Utilities
1180 ***********************************************************************/
1182 /* Return the bottom y-position of the line the iterator IT is in.
1183 This can modify IT's settings. */
1186 line_bottom_y (struct it *it)
1188 int line_height = it->max_ascent + it->max_descent;
1189 int line_top_y = it->current_y;
1191 if (line_height == 0)
1193 if (last_height)
1194 line_height = last_height;
1195 else if (IT_CHARPOS (*it) < ZV)
1197 move_it_by_lines (it, 1);
1198 line_height = (it->max_ascent || it->max_descent
1199 ? it->max_ascent + it->max_descent
1200 : last_height);
1202 else
1204 struct glyph_row *row = it->glyph_row;
1206 /* Use the default character height. */
1207 it->glyph_row = NULL;
1208 it->what = IT_CHARACTER;
1209 it->c = ' ';
1210 it->len = 1;
1211 PRODUCE_GLYPHS (it);
1212 line_height = it->ascent + it->descent;
1213 it->glyph_row = row;
1217 return line_top_y + line_height;
1220 /* Subroutine of pos_visible_p below. Extracts a display string, if
1221 any, from the display spec given as its argument. */
1222 static Lisp_Object
1223 string_from_display_spec (Lisp_Object spec)
1225 if (CONSP (spec))
1227 while (CONSP (spec))
1229 if (STRINGP (XCAR (spec)))
1230 return XCAR (spec);
1231 spec = XCDR (spec);
1234 else if (VECTORP (spec))
1236 ptrdiff_t i;
1238 for (i = 0; i < ASIZE (spec); i++)
1240 if (STRINGP (AREF (spec, i)))
1241 return AREF (spec, i);
1243 return Qnil;
1246 return spec;
1250 /* Limit insanely large values of W->hscroll on frame F to the largest
1251 value that will still prevent first_visible_x and last_visible_x of
1252 'struct it' from overflowing an int. */
1253 static int
1254 window_hscroll_limited (struct window *w, struct frame *f)
1256 ptrdiff_t window_hscroll = w->hscroll;
1257 int window_text_width = window_box_width (w, TEXT_AREA);
1258 int colwidth = FRAME_COLUMN_WIDTH (f);
1260 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1261 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1263 return window_hscroll;
1266 /* Return 1 if position CHARPOS is visible in window W.
1267 CHARPOS < 0 means return info about WINDOW_END position.
1268 If visible, set *X and *Y to pixel coordinates of top left corner.
1269 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1270 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1273 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1274 int *rtop, int *rbot, int *rowh, int *vpos)
1276 struct it it;
1277 void *itdata = bidi_shelve_cache ();
1278 struct text_pos top;
1279 int visible_p = 0;
1280 struct buffer *old_buffer = NULL;
1282 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1283 return visible_p;
1285 if (XBUFFER (w->contents) != current_buffer)
1287 old_buffer = current_buffer;
1288 set_buffer_internal_1 (XBUFFER (w->contents));
1291 SET_TEXT_POS_FROM_MARKER (top, w->start);
1292 /* Scrolling a minibuffer window via scroll bar when the echo area
1293 shows long text sometimes resets the minibuffer contents behind
1294 our backs. */
1295 if (CHARPOS (top) > ZV)
1296 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1298 /* Compute exact mode line heights. */
1299 if (WINDOW_WANTS_MODELINE_P (w))
1300 current_mode_line_height
1301 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1302 BVAR (current_buffer, mode_line_format));
1304 if (WINDOW_WANTS_HEADER_LINE_P (w))
1305 current_header_line_height
1306 = display_mode_line (w, HEADER_LINE_FACE_ID,
1307 BVAR (current_buffer, header_line_format));
1309 start_display (&it, w, top);
1310 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1311 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1313 if (charpos >= 0
1314 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1315 && IT_CHARPOS (it) >= charpos)
1316 /* When scanning backwards under bidi iteration, move_it_to
1317 stops at or _before_ CHARPOS, because it stops at or to
1318 the _right_ of the character at CHARPOS. */
1319 || (it.bidi_p && it.bidi_it.scan_dir == -1
1320 && IT_CHARPOS (it) <= charpos)))
1322 /* We have reached CHARPOS, or passed it. How the call to
1323 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1324 or covered by a display property, move_it_to stops at the end
1325 of the invisible text, to the right of CHARPOS. (ii) If
1326 CHARPOS is in a display vector, move_it_to stops on its last
1327 glyph. */
1328 int top_x = it.current_x;
1329 int top_y = it.current_y;
1330 /* Calling line_bottom_y may change it.method, it.position, etc. */
1331 enum it_method it_method = it.method;
1332 int bottom_y = (last_height = 0, line_bottom_y (&it));
1333 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1335 if (top_y < window_top_y)
1336 visible_p = bottom_y > window_top_y;
1337 else if (top_y < it.last_visible_y)
1338 visible_p = 1;
1339 if (bottom_y >= it.last_visible_y
1340 && it.bidi_p && it.bidi_it.scan_dir == -1
1341 && IT_CHARPOS (it) < charpos)
1343 /* When the last line of the window is scanned backwards
1344 under bidi iteration, we could be duped into thinking
1345 that we have passed CHARPOS, when in fact move_it_to
1346 simply stopped short of CHARPOS because it reached
1347 last_visible_y. To see if that's what happened, we call
1348 move_it_to again with a slightly larger vertical limit,
1349 and see if it actually moved vertically; if it did, we
1350 didn't really reach CHARPOS, which is beyond window end. */
1351 struct it save_it = it;
1352 /* Why 10? because we don't know how many canonical lines
1353 will the height of the next line(s) be. So we guess. */
1354 int ten_more_lines =
1355 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
1357 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1358 MOVE_TO_POS | MOVE_TO_Y);
1359 if (it.current_y > top_y)
1360 visible_p = 0;
1362 it = save_it;
1364 if (visible_p)
1366 if (it_method == GET_FROM_DISPLAY_VECTOR)
1368 /* We stopped on the last glyph of a display vector.
1369 Try and recompute. Hack alert! */
1370 if (charpos < 2 || top.charpos >= charpos)
1371 top_x = it.glyph_row->x;
1372 else
1374 struct it it2, it2_prev;
1375 /* The idea is to get to the previous buffer
1376 position, consume the character there, and use
1377 the pixel coordinates we get after that. But if
1378 the previous buffer position is also displayed
1379 from a display vector, we need to consume all of
1380 the glyphs from that display vector. */
1381 start_display (&it2, w, top);
1382 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1383 /* If we didn't get to CHARPOS - 1, there's some
1384 replacing display property at that position, and
1385 we stopped after it. That is exactly the place
1386 whose coordinates we want. */
1387 if (IT_CHARPOS (it2) != charpos - 1)
1388 it2_prev = it2;
1389 else
1391 /* Iterate until we get out of the display
1392 vector that displays the character at
1393 CHARPOS - 1. */
1394 do {
1395 get_next_display_element (&it2);
1396 PRODUCE_GLYPHS (&it2);
1397 it2_prev = it2;
1398 set_iterator_to_next (&it2, 1);
1399 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1400 && IT_CHARPOS (it2) < charpos);
1402 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1403 || it2_prev.current_x > it2_prev.last_visible_x)
1404 top_x = it.glyph_row->x;
1405 else
1407 top_x = it2_prev.current_x;
1408 top_y = it2_prev.current_y;
1412 else if (IT_CHARPOS (it) != charpos)
1414 Lisp_Object cpos = make_number (charpos);
1415 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1416 Lisp_Object string = string_from_display_spec (spec);
1417 struct text_pos tpos;
1418 int replacing_spec_p;
1419 bool newline_in_string
1420 = (STRINGP (string)
1421 && memchr (SDATA (string), '\n', SBYTES (string)));
1423 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1424 replacing_spec_p
1425 = (!NILP (spec)
1426 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1427 charpos, FRAME_WINDOW_P (it.f)));
1428 /* The tricky code below is needed because there's a
1429 discrepancy between move_it_to and how we set cursor
1430 when PT is at the beginning of a portion of text
1431 covered by a display property or an overlay with a
1432 display property, or the display line ends in a
1433 newline from a display string. move_it_to will stop
1434 _after_ such display strings, whereas
1435 set_cursor_from_row conspires with cursor_row_p to
1436 place the cursor on the first glyph produced from the
1437 display string. */
1439 /* We have overshoot PT because it is covered by a
1440 display property that replaces the text it covers.
1441 If the string includes embedded newlines, we are also
1442 in the wrong display line. Backtrack to the correct
1443 line, where the display property begins. */
1444 if (replacing_spec_p)
1446 Lisp_Object startpos, endpos;
1447 EMACS_INT start, end;
1448 struct it it3;
1449 int it3_moved;
1451 /* Find the first and the last buffer positions
1452 covered by the display string. */
1453 endpos =
1454 Fnext_single_char_property_change (cpos, Qdisplay,
1455 Qnil, Qnil);
1456 startpos =
1457 Fprevious_single_char_property_change (endpos, Qdisplay,
1458 Qnil, Qnil);
1459 start = XFASTINT (startpos);
1460 end = XFASTINT (endpos);
1461 /* Move to the last buffer position before the
1462 display property. */
1463 start_display (&it3, w, top);
1464 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1465 /* Move forward one more line if the position before
1466 the display string is a newline or if it is the
1467 rightmost character on a line that is
1468 continued or word-wrapped. */
1469 if (it3.method == GET_FROM_BUFFER
1470 && (it3.c == '\n'
1471 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1472 move_it_by_lines (&it3, 1);
1473 else if (move_it_in_display_line_to (&it3, -1,
1474 it3.current_x
1475 + it3.pixel_width,
1476 MOVE_TO_X)
1477 == MOVE_LINE_CONTINUED)
1479 move_it_by_lines (&it3, 1);
1480 /* When we are under word-wrap, the #$@%!
1481 move_it_by_lines moves 2 lines, so we need to
1482 fix that up. */
1483 if (it3.line_wrap == WORD_WRAP)
1484 move_it_by_lines (&it3, -1);
1487 /* Record the vertical coordinate of the display
1488 line where we wound up. */
1489 top_y = it3.current_y;
1490 if (it3.bidi_p)
1492 /* When characters are reordered for display,
1493 the character displayed to the left of the
1494 display string could be _after_ the display
1495 property in the logical order. Use the
1496 smallest vertical position of these two. */
1497 start_display (&it3, w, top);
1498 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1499 if (it3.current_y < top_y)
1500 top_y = it3.current_y;
1502 /* Move from the top of the window to the beginning
1503 of the display line where the display string
1504 begins. */
1505 start_display (&it3, w, top);
1506 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1507 /* If it3_moved stays zero after the 'while' loop
1508 below, that means we already were at a newline
1509 before the loop (e.g., the display string begins
1510 with a newline), so we don't need to (and cannot)
1511 inspect the glyphs of it3.glyph_row, because
1512 PRODUCE_GLYPHS will not produce anything for a
1513 newline, and thus it3.glyph_row stays at its
1514 stale content it got at top of the window. */
1515 it3_moved = 0;
1516 /* Finally, advance the iterator until we hit the
1517 first display element whose character position is
1518 CHARPOS, or until the first newline from the
1519 display string, which signals the end of the
1520 display line. */
1521 while (get_next_display_element (&it3))
1523 PRODUCE_GLYPHS (&it3);
1524 if (IT_CHARPOS (it3) == charpos
1525 || ITERATOR_AT_END_OF_LINE_P (&it3))
1526 break;
1527 it3_moved = 1;
1528 set_iterator_to_next (&it3, 0);
1530 top_x = it3.current_x - it3.pixel_width;
1531 /* Normally, we would exit the above loop because we
1532 found the display element whose character
1533 position is CHARPOS. For the contingency that we
1534 didn't, and stopped at the first newline from the
1535 display string, move back over the glyphs
1536 produced from the string, until we find the
1537 rightmost glyph not from the string. */
1538 if (it3_moved
1539 && newline_in_string
1540 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1542 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1543 + it3.glyph_row->used[TEXT_AREA];
1545 while (EQ ((g - 1)->object, string))
1547 --g;
1548 top_x -= g->pixel_width;
1550 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1551 + it3.glyph_row->used[TEXT_AREA]);
1556 *x = top_x;
1557 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1558 *rtop = max (0, window_top_y - top_y);
1559 *rbot = max (0, bottom_y - it.last_visible_y);
1560 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1561 - max (top_y, window_top_y)));
1562 *vpos = it.vpos;
1565 else
1567 /* We were asked to provide info about WINDOW_END. */
1568 struct it it2;
1569 void *it2data = NULL;
1571 SAVE_IT (it2, it, it2data);
1572 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1573 move_it_by_lines (&it, 1);
1574 if (charpos < IT_CHARPOS (it)
1575 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1577 visible_p = 1;
1578 RESTORE_IT (&it2, &it2, it2data);
1579 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1580 *x = it2.current_x;
1581 *y = it2.current_y + it2.max_ascent - it2.ascent;
1582 *rtop = max (0, -it2.current_y);
1583 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1584 - it.last_visible_y));
1585 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1586 it.last_visible_y)
1587 - max (it2.current_y,
1588 WINDOW_HEADER_LINE_HEIGHT (w))));
1589 *vpos = it2.vpos;
1591 else
1592 bidi_unshelve_cache (it2data, 1);
1594 bidi_unshelve_cache (itdata, 0);
1596 if (old_buffer)
1597 set_buffer_internal_1 (old_buffer);
1599 current_header_line_height = current_mode_line_height = -1;
1601 if (visible_p && w->hscroll > 0)
1602 *x -=
1603 window_hscroll_limited (w, WINDOW_XFRAME (w))
1604 * WINDOW_FRAME_COLUMN_WIDTH (w);
1606 #if 0
1607 /* Debugging code. */
1608 if (visible_p)
1609 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1610 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1611 else
1612 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1613 #endif
1615 return visible_p;
1619 /* Return the next character from STR. Return in *LEN the length of
1620 the character. This is like STRING_CHAR_AND_LENGTH but never
1621 returns an invalid character. If we find one, we return a `?', but
1622 with the length of the invalid character. */
1624 static int
1625 string_char_and_length (const unsigned char *str, int *len)
1627 int c;
1629 c = STRING_CHAR_AND_LENGTH (str, *len);
1630 if (!CHAR_VALID_P (c))
1631 /* We may not change the length here because other places in Emacs
1632 don't use this function, i.e. they silently accept invalid
1633 characters. */
1634 c = '?';
1636 return c;
1641 /* Given a position POS containing a valid character and byte position
1642 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1644 static struct text_pos
1645 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1647 eassert (STRINGP (string) && nchars >= 0);
1649 if (STRING_MULTIBYTE (string))
1651 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1652 int len;
1654 while (nchars--)
1656 string_char_and_length (p, &len);
1657 p += len;
1658 CHARPOS (pos) += 1;
1659 BYTEPOS (pos) += len;
1662 else
1663 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1665 return pos;
1669 /* Value is the text position, i.e. character and byte position,
1670 for character position CHARPOS in STRING. */
1672 static struct text_pos
1673 string_pos (ptrdiff_t charpos, Lisp_Object string)
1675 struct text_pos pos;
1676 eassert (STRINGP (string));
1677 eassert (charpos >= 0);
1678 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1679 return pos;
1683 /* Value is a text position, i.e. character and byte position, for
1684 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1685 means recognize multibyte characters. */
1687 static struct text_pos
1688 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1690 struct text_pos pos;
1692 eassert (s != NULL);
1693 eassert (charpos >= 0);
1695 if (multibyte_p)
1697 int len;
1699 SET_TEXT_POS (pos, 0, 0);
1700 while (charpos--)
1702 string_char_and_length ((const unsigned char *) s, &len);
1703 s += len;
1704 CHARPOS (pos) += 1;
1705 BYTEPOS (pos) += len;
1708 else
1709 SET_TEXT_POS (pos, charpos, charpos);
1711 return pos;
1715 /* Value is the number of characters in C string S. MULTIBYTE_P
1716 non-zero means recognize multibyte characters. */
1718 static ptrdiff_t
1719 number_of_chars (const char *s, bool multibyte_p)
1721 ptrdiff_t nchars;
1723 if (multibyte_p)
1725 ptrdiff_t rest = strlen (s);
1726 int len;
1727 const unsigned char *p = (const unsigned char *) s;
1729 for (nchars = 0; rest > 0; ++nchars)
1731 string_char_and_length (p, &len);
1732 rest -= len, p += len;
1735 else
1736 nchars = strlen (s);
1738 return nchars;
1742 /* Compute byte position NEWPOS->bytepos corresponding to
1743 NEWPOS->charpos. POS is a known position in string STRING.
1744 NEWPOS->charpos must be >= POS.charpos. */
1746 static void
1747 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1749 eassert (STRINGP (string));
1750 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1752 if (STRING_MULTIBYTE (string))
1753 *newpos = string_pos_nchars_ahead (pos, string,
1754 CHARPOS (*newpos) - CHARPOS (pos));
1755 else
1756 BYTEPOS (*newpos) = CHARPOS (*newpos);
1759 /* EXPORT:
1760 Return an estimation of the pixel height of mode or header lines on
1761 frame F. FACE_ID specifies what line's height to estimate. */
1764 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1766 #ifdef HAVE_WINDOW_SYSTEM
1767 if (FRAME_WINDOW_P (f))
1769 int height = FONT_HEIGHT (FRAME_FONT (f));
1771 /* This function is called so early when Emacs starts that the face
1772 cache and mode line face are not yet initialized. */
1773 if (FRAME_FACE_CACHE (f))
1775 struct face *face = FACE_FROM_ID (f, face_id);
1776 if (face)
1778 if (face->font)
1779 height = FONT_HEIGHT (face->font);
1780 if (face->box_line_width > 0)
1781 height += 2 * face->box_line_width;
1785 return height;
1787 #endif
1789 return 1;
1792 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1793 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1794 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1795 not force the value into range. */
1797 void
1798 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1799 int *x, int *y, NativeRectangle *bounds, int noclip)
1802 #ifdef HAVE_WINDOW_SYSTEM
1803 if (FRAME_WINDOW_P (f))
1805 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1806 even for negative values. */
1807 if (pix_x < 0)
1808 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1809 if (pix_y < 0)
1810 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1812 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1813 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1815 if (bounds)
1816 STORE_NATIVE_RECT (*bounds,
1817 FRAME_COL_TO_PIXEL_X (f, pix_x),
1818 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1819 FRAME_COLUMN_WIDTH (f) - 1,
1820 FRAME_LINE_HEIGHT (f) - 1);
1822 if (!noclip)
1824 if (pix_x < 0)
1825 pix_x = 0;
1826 else if (pix_x > FRAME_TOTAL_COLS (f))
1827 pix_x = FRAME_TOTAL_COLS (f);
1829 if (pix_y < 0)
1830 pix_y = 0;
1831 else if (pix_y > FRAME_LINES (f))
1832 pix_y = FRAME_LINES (f);
1835 #endif
1837 *x = pix_x;
1838 *y = pix_y;
1842 /* Find the glyph under window-relative coordinates X/Y in window W.
1843 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1844 strings. Return in *HPOS and *VPOS the row and column number of
1845 the glyph found. Return in *AREA the glyph area containing X.
1846 Value is a pointer to the glyph found or null if X/Y is not on
1847 text, or we can't tell because W's current matrix is not up to
1848 date. */
1850 static
1851 struct glyph *
1852 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1853 int *dx, int *dy, int *area)
1855 struct glyph *glyph, *end;
1856 struct glyph_row *row = NULL;
1857 int x0, i;
1859 /* Find row containing Y. Give up if some row is not enabled. */
1860 for (i = 0; i < w->current_matrix->nrows; ++i)
1862 row = MATRIX_ROW (w->current_matrix, i);
1863 if (!row->enabled_p)
1864 return NULL;
1865 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1866 break;
1869 *vpos = i;
1870 *hpos = 0;
1872 /* Give up if Y is not in the window. */
1873 if (i == w->current_matrix->nrows)
1874 return NULL;
1876 /* Get the glyph area containing X. */
1877 if (w->pseudo_window_p)
1879 *area = TEXT_AREA;
1880 x0 = 0;
1882 else
1884 if (x < window_box_left_offset (w, TEXT_AREA))
1886 *area = LEFT_MARGIN_AREA;
1887 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1889 else if (x < window_box_right_offset (w, TEXT_AREA))
1891 *area = TEXT_AREA;
1892 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1894 else
1896 *area = RIGHT_MARGIN_AREA;
1897 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1901 /* Find glyph containing X. */
1902 glyph = row->glyphs[*area];
1903 end = glyph + row->used[*area];
1904 x -= x0;
1905 while (glyph < end && x >= glyph->pixel_width)
1907 x -= glyph->pixel_width;
1908 ++glyph;
1911 if (glyph == end)
1912 return NULL;
1914 if (dx)
1916 *dx = x;
1917 *dy = y - (row->y + row->ascent - glyph->ascent);
1920 *hpos = glyph - row->glyphs[*area];
1921 return glyph;
1924 /* Convert frame-relative x/y to coordinates relative to window W.
1925 Takes pseudo-windows into account. */
1927 static void
1928 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1930 if (w->pseudo_window_p)
1932 /* A pseudo-window is always full-width, and starts at the
1933 left edge of the frame, plus a frame border. */
1934 struct frame *f = XFRAME (w->frame);
1935 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1936 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1938 else
1940 *x -= WINDOW_LEFT_EDGE_X (w);
1941 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1945 #ifdef HAVE_WINDOW_SYSTEM
1947 /* EXPORT:
1948 Return in RECTS[] at most N clipping rectangles for glyph string S.
1949 Return the number of stored rectangles. */
1952 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1954 XRectangle r;
1956 if (n <= 0)
1957 return 0;
1959 if (s->row->full_width_p)
1961 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1962 r.x = WINDOW_LEFT_EDGE_X (s->w);
1963 r.width = WINDOW_TOTAL_WIDTH (s->w);
1965 /* Unless displaying a mode or menu bar line, which are always
1966 fully visible, clip to the visible part of the row. */
1967 if (s->w->pseudo_window_p)
1968 r.height = s->row->visible_height;
1969 else
1970 r.height = s->height;
1972 else
1974 /* This is a text line that may be partially visible. */
1975 r.x = window_box_left (s->w, s->area);
1976 r.width = window_box_width (s->w, s->area);
1977 r.height = s->row->visible_height;
1980 if (s->clip_head)
1981 if (r.x < s->clip_head->x)
1983 if (r.width >= s->clip_head->x - r.x)
1984 r.width -= s->clip_head->x - r.x;
1985 else
1986 r.width = 0;
1987 r.x = s->clip_head->x;
1989 if (s->clip_tail)
1990 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1992 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1993 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1994 else
1995 r.width = 0;
1998 /* If S draws overlapping rows, it's sufficient to use the top and
1999 bottom of the window for clipping because this glyph string
2000 intentionally draws over other lines. */
2001 if (s->for_overlaps)
2003 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2004 r.height = window_text_bottom_y (s->w) - r.y;
2006 /* Alas, the above simple strategy does not work for the
2007 environments with anti-aliased text: if the same text is
2008 drawn onto the same place multiple times, it gets thicker.
2009 If the overlap we are processing is for the erased cursor, we
2010 take the intersection with the rectangle of the cursor. */
2011 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2013 XRectangle rc, r_save = r;
2015 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2016 rc.y = s->w->phys_cursor.y;
2017 rc.width = s->w->phys_cursor_width;
2018 rc.height = s->w->phys_cursor_height;
2020 x_intersect_rectangles (&r_save, &rc, &r);
2023 else
2025 /* Don't use S->y for clipping because it doesn't take partially
2026 visible lines into account. For example, it can be negative for
2027 partially visible lines at the top of a window. */
2028 if (!s->row->full_width_p
2029 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2030 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2031 else
2032 r.y = max (0, s->row->y);
2035 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2037 /* If drawing the cursor, don't let glyph draw outside its
2038 advertised boundaries. Cleartype does this under some circumstances. */
2039 if (s->hl == DRAW_CURSOR)
2041 struct glyph *glyph = s->first_glyph;
2042 int height, max_y;
2044 if (s->x > r.x)
2046 r.width -= s->x - r.x;
2047 r.x = s->x;
2049 r.width = min (r.width, glyph->pixel_width);
2051 /* If r.y is below window bottom, ensure that we still see a cursor. */
2052 height = min (glyph->ascent + glyph->descent,
2053 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2054 max_y = window_text_bottom_y (s->w) - height;
2055 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2056 if (s->ybase - glyph->ascent > max_y)
2058 r.y = max_y;
2059 r.height = height;
2061 else
2063 /* Don't draw cursor glyph taller than our actual glyph. */
2064 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2065 if (height < r.height)
2067 max_y = r.y + r.height;
2068 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2069 r.height = min (max_y - r.y, height);
2074 if (s->row->clip)
2076 XRectangle r_save = r;
2078 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2079 r.width = 0;
2082 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2083 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2085 #ifdef CONVERT_FROM_XRECT
2086 CONVERT_FROM_XRECT (r, *rects);
2087 #else
2088 *rects = r;
2089 #endif
2090 return 1;
2092 else
2094 /* If we are processing overlapping and allowed to return
2095 multiple clipping rectangles, we exclude the row of the glyph
2096 string from the clipping rectangle. This is to avoid drawing
2097 the same text on the environment with anti-aliasing. */
2098 #ifdef CONVERT_FROM_XRECT
2099 XRectangle rs[2];
2100 #else
2101 XRectangle *rs = rects;
2102 #endif
2103 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2105 if (s->for_overlaps & OVERLAPS_PRED)
2107 rs[i] = r;
2108 if (r.y + r.height > row_y)
2110 if (r.y < row_y)
2111 rs[i].height = row_y - r.y;
2112 else
2113 rs[i].height = 0;
2115 i++;
2117 if (s->for_overlaps & OVERLAPS_SUCC)
2119 rs[i] = r;
2120 if (r.y < row_y + s->row->visible_height)
2122 if (r.y + r.height > row_y + s->row->visible_height)
2124 rs[i].y = row_y + s->row->visible_height;
2125 rs[i].height = r.y + r.height - rs[i].y;
2127 else
2128 rs[i].height = 0;
2130 i++;
2133 n = i;
2134 #ifdef CONVERT_FROM_XRECT
2135 for (i = 0; i < n; i++)
2136 CONVERT_FROM_XRECT (rs[i], rects[i]);
2137 #endif
2138 return n;
2142 /* EXPORT:
2143 Return in *NR the clipping rectangle for glyph string S. */
2145 void
2146 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2148 get_glyph_string_clip_rects (s, nr, 1);
2152 /* EXPORT:
2153 Return the position and height of the phys cursor in window W.
2154 Set w->phys_cursor_width to width of phys cursor.
2157 void
2158 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2159 struct glyph *glyph, int *xp, int *yp, int *heightp)
2161 struct frame *f = XFRAME (WINDOW_FRAME (w));
2162 int x, y, wd, h, h0, y0;
2164 /* Compute the width of the rectangle to draw. If on a stretch
2165 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2166 rectangle as wide as the glyph, but use a canonical character
2167 width instead. */
2168 wd = glyph->pixel_width - 1;
2169 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2170 wd++; /* Why? */
2171 #endif
2173 x = w->phys_cursor.x;
2174 if (x < 0)
2176 wd += x;
2177 x = 0;
2180 if (glyph->type == STRETCH_GLYPH
2181 && !x_stretch_cursor_p)
2182 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2183 w->phys_cursor_width = wd;
2185 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2187 /* If y is below window bottom, ensure that we still see a cursor. */
2188 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2190 h = max (h0, glyph->ascent + glyph->descent);
2191 h0 = min (h0, glyph->ascent + glyph->descent);
2193 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2194 if (y < y0)
2196 h = max (h - (y0 - y) + 1, h0);
2197 y = y0 - 1;
2199 else
2201 y0 = window_text_bottom_y (w) - h0;
2202 if (y > y0)
2204 h += y - y0;
2205 y = y0;
2209 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2210 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2211 *heightp = h;
2215 * Remember which glyph the mouse is over.
2218 void
2219 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2221 Lisp_Object window;
2222 struct window *w;
2223 struct glyph_row *r, *gr, *end_row;
2224 enum window_part part;
2225 enum glyph_row_area area;
2226 int x, y, width, height;
2228 /* Try to determine frame pixel position and size of the glyph under
2229 frame pixel coordinates X/Y on frame F. */
2231 if (!f->glyphs_initialized_p
2232 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2233 NILP (window)))
2235 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2236 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2237 goto virtual_glyph;
2240 w = XWINDOW (window);
2241 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2242 height = WINDOW_FRAME_LINE_HEIGHT (w);
2244 x = window_relative_x_coord (w, part, gx);
2245 y = gy - WINDOW_TOP_EDGE_Y (w);
2247 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2248 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2250 if (w->pseudo_window_p)
2252 area = TEXT_AREA;
2253 part = ON_MODE_LINE; /* Don't adjust margin. */
2254 goto text_glyph;
2257 switch (part)
2259 case ON_LEFT_MARGIN:
2260 area = LEFT_MARGIN_AREA;
2261 goto text_glyph;
2263 case ON_RIGHT_MARGIN:
2264 area = RIGHT_MARGIN_AREA;
2265 goto text_glyph;
2267 case ON_HEADER_LINE:
2268 case ON_MODE_LINE:
2269 gr = (part == ON_HEADER_LINE
2270 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2271 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2272 gy = gr->y;
2273 area = TEXT_AREA;
2274 goto text_glyph_row_found;
2276 case ON_TEXT:
2277 area = TEXT_AREA;
2279 text_glyph:
2280 gr = 0; gy = 0;
2281 for (; r <= end_row && r->enabled_p; ++r)
2282 if (r->y + r->height > y)
2284 gr = r; gy = r->y;
2285 break;
2288 text_glyph_row_found:
2289 if (gr && gy <= y)
2291 struct glyph *g = gr->glyphs[area];
2292 struct glyph *end = g + gr->used[area];
2294 height = gr->height;
2295 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2296 if (gx + g->pixel_width > x)
2297 break;
2299 if (g < end)
2301 if (g->type == IMAGE_GLYPH)
2303 /* Don't remember when mouse is over image, as
2304 image may have hot-spots. */
2305 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2306 return;
2308 width = g->pixel_width;
2310 else
2312 /* Use nominal char spacing at end of line. */
2313 x -= gx;
2314 gx += (x / width) * width;
2317 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2318 gx += window_box_left_offset (w, area);
2320 else
2322 /* Use nominal line height at end of window. */
2323 gx = (x / width) * width;
2324 y -= gy;
2325 gy += (y / height) * height;
2327 break;
2329 case ON_LEFT_FRINGE:
2330 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2331 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2332 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2333 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2334 goto row_glyph;
2336 case ON_RIGHT_FRINGE:
2337 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2338 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2339 : window_box_right_offset (w, TEXT_AREA));
2340 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2341 goto row_glyph;
2343 case ON_SCROLL_BAR:
2344 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2346 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2347 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2348 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2349 : 0)));
2350 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2352 row_glyph:
2353 gr = 0, gy = 0;
2354 for (; r <= end_row && r->enabled_p; ++r)
2355 if (r->y + r->height > y)
2357 gr = r; gy = r->y;
2358 break;
2361 if (gr && gy <= y)
2362 height = gr->height;
2363 else
2365 /* Use nominal line height at end of window. */
2366 y -= gy;
2367 gy += (y / height) * height;
2369 break;
2371 default:
2373 virtual_glyph:
2374 /* If there is no glyph under the mouse, then we divide the screen
2375 into a grid of the smallest glyph in the frame, and use that
2376 as our "glyph". */
2378 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2379 round down even for negative values. */
2380 if (gx < 0)
2381 gx -= width - 1;
2382 if (gy < 0)
2383 gy -= height - 1;
2385 gx = (gx / width) * width;
2386 gy = (gy / height) * height;
2388 goto store_rect;
2391 gx += WINDOW_LEFT_EDGE_X (w);
2392 gy += WINDOW_TOP_EDGE_Y (w);
2394 store_rect:
2395 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2397 /* Visible feedback for debugging. */
2398 #if 0
2399 #if HAVE_X_WINDOWS
2400 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2401 f->output_data.x->normal_gc,
2402 gx, gy, width, height);
2403 #endif
2404 #endif
2408 #endif /* HAVE_WINDOW_SYSTEM */
2411 /***********************************************************************
2412 Lisp form evaluation
2413 ***********************************************************************/
2415 /* Error handler for safe_eval and safe_call. */
2417 static Lisp_Object
2418 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2420 add_to_log ("Error during redisplay: %S signaled %S",
2421 Flist (nargs, args), arg);
2422 return Qnil;
2425 /* Call function FUNC with the rest of NARGS - 1 arguments
2426 following. Return the result, or nil if something went
2427 wrong. Prevent redisplay during the evaluation. */
2429 Lisp_Object
2430 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2432 Lisp_Object val;
2434 if (inhibit_eval_during_redisplay)
2435 val = Qnil;
2436 else
2438 va_list ap;
2439 ptrdiff_t i;
2440 ptrdiff_t count = SPECPDL_INDEX ();
2441 struct gcpro gcpro1;
2442 Lisp_Object *args = alloca (nargs * word_size);
2444 args[0] = func;
2445 va_start (ap, func);
2446 for (i = 1; i < nargs; i++)
2447 args[i] = va_arg (ap, Lisp_Object);
2448 va_end (ap);
2450 GCPRO1 (args[0]);
2451 gcpro1.nvars = nargs;
2452 specbind (Qinhibit_redisplay, Qt);
2453 /* Use Qt to ensure debugger does not run,
2454 so there is no possibility of wanting to redisplay. */
2455 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2456 safe_eval_handler);
2457 UNGCPRO;
2458 val = unbind_to (count, val);
2461 return val;
2465 /* Call function FN with one argument ARG.
2466 Return the result, or nil if something went wrong. */
2468 Lisp_Object
2469 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2471 return safe_call (2, fn, arg);
2474 static Lisp_Object Qeval;
2476 Lisp_Object
2477 safe_eval (Lisp_Object sexpr)
2479 return safe_call1 (Qeval, sexpr);
2482 /* Call function FN with two arguments ARG1 and ARG2.
2483 Return the result, or nil if something went wrong. */
2485 Lisp_Object
2486 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2488 return safe_call (3, fn, arg1, arg2);
2493 /***********************************************************************
2494 Debugging
2495 ***********************************************************************/
2497 #if 0
2499 /* Define CHECK_IT to perform sanity checks on iterators.
2500 This is for debugging. It is too slow to do unconditionally. */
2502 static void
2503 check_it (struct it *it)
2505 if (it->method == GET_FROM_STRING)
2507 eassert (STRINGP (it->string));
2508 eassert (IT_STRING_CHARPOS (*it) >= 0);
2510 else
2512 eassert (IT_STRING_CHARPOS (*it) < 0);
2513 if (it->method == GET_FROM_BUFFER)
2515 /* Check that character and byte positions agree. */
2516 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2520 if (it->dpvec)
2521 eassert (it->current.dpvec_index >= 0);
2522 else
2523 eassert (it->current.dpvec_index < 0);
2526 #define CHECK_IT(IT) check_it ((IT))
2528 #else /* not 0 */
2530 #define CHECK_IT(IT) (void) 0
2532 #endif /* not 0 */
2535 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2537 /* Check that the window end of window W is what we expect it
2538 to be---the last row in the current matrix displaying text. */
2540 static void
2541 check_window_end (struct window *w)
2543 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2545 struct glyph_row *row;
2546 eassert ((row = MATRIX_ROW (w->current_matrix,
2547 XFASTINT (w->window_end_vpos)),
2548 !row->enabled_p
2549 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2550 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2554 #define CHECK_WINDOW_END(W) check_window_end ((W))
2556 #else
2558 #define CHECK_WINDOW_END(W) (void) 0
2560 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2562 /* Return mark position if current buffer has the region of non-zero length,
2563 or -1 otherwise. */
2565 static ptrdiff_t
2566 markpos_of_region (void)
2568 if (!NILP (Vtransient_mark_mode)
2569 && !NILP (BVAR (current_buffer, mark_active))
2570 && XMARKER (BVAR (current_buffer, mark))->buffer != NULL)
2572 ptrdiff_t markpos = XMARKER (BVAR (current_buffer, mark))->charpos;
2574 if (markpos != PT)
2575 return markpos;
2577 return -1;
2580 /***********************************************************************
2581 Iterator initialization
2582 ***********************************************************************/
2584 /* Initialize IT for displaying current_buffer in window W, starting
2585 at character position CHARPOS. CHARPOS < 0 means that no buffer
2586 position is specified which is useful when the iterator is assigned
2587 a position later. BYTEPOS is the byte position corresponding to
2588 CHARPOS.
2590 If ROW is not null, calls to produce_glyphs with IT as parameter
2591 will produce glyphs in that row.
2593 BASE_FACE_ID is the id of a base face to use. It must be one of
2594 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2595 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2596 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2598 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2599 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2600 will be initialized to use the corresponding mode line glyph row of
2601 the desired matrix of W. */
2603 void
2604 init_iterator (struct it *it, struct window *w,
2605 ptrdiff_t charpos, ptrdiff_t bytepos,
2606 struct glyph_row *row, enum face_id base_face_id)
2608 ptrdiff_t markpos;
2609 enum face_id remapped_base_face_id = base_face_id;
2611 /* Some precondition checks. */
2612 eassert (w != NULL && it != NULL);
2613 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2614 && charpos <= ZV));
2616 /* If face attributes have been changed since the last redisplay,
2617 free realized faces now because they depend on face definitions
2618 that might have changed. Don't free faces while there might be
2619 desired matrices pending which reference these faces. */
2620 if (face_change_count && !inhibit_free_realized_faces)
2622 face_change_count = 0;
2623 free_all_realized_faces (Qnil);
2626 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2627 if (! NILP (Vface_remapping_alist))
2628 remapped_base_face_id
2629 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2631 /* Use one of the mode line rows of W's desired matrix if
2632 appropriate. */
2633 if (row == NULL)
2635 if (base_face_id == MODE_LINE_FACE_ID
2636 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2637 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2638 else if (base_face_id == HEADER_LINE_FACE_ID)
2639 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2642 /* Clear IT. */
2643 memset (it, 0, sizeof *it);
2644 it->current.overlay_string_index = -1;
2645 it->current.dpvec_index = -1;
2646 it->base_face_id = remapped_base_face_id;
2647 it->string = Qnil;
2648 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2649 it->paragraph_embedding = L2R;
2650 it->bidi_it.string.lstring = Qnil;
2651 it->bidi_it.string.s = NULL;
2652 it->bidi_it.string.bufpos = 0;
2653 it->bidi_it.w = w;
2655 /* The window in which we iterate over current_buffer: */
2656 XSETWINDOW (it->window, w);
2657 it->w = w;
2658 it->f = XFRAME (w->frame);
2660 it->cmp_it.id = -1;
2662 /* Extra space between lines (on window systems only). */
2663 if (base_face_id == DEFAULT_FACE_ID
2664 && FRAME_WINDOW_P (it->f))
2666 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2667 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2668 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2669 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2670 * FRAME_LINE_HEIGHT (it->f));
2671 else if (it->f->extra_line_spacing > 0)
2672 it->extra_line_spacing = it->f->extra_line_spacing;
2673 it->max_extra_line_spacing = 0;
2676 /* If realized faces have been removed, e.g. because of face
2677 attribute changes of named faces, recompute them. When running
2678 in batch mode, the face cache of the initial frame is null. If
2679 we happen to get called, make a dummy face cache. */
2680 if (FRAME_FACE_CACHE (it->f) == NULL)
2681 init_frame_faces (it->f);
2682 if (FRAME_FACE_CACHE (it->f)->used == 0)
2683 recompute_basic_faces (it->f);
2685 /* Current value of the `slice', `space-width', and 'height' properties. */
2686 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2687 it->space_width = Qnil;
2688 it->font_height = Qnil;
2689 it->override_ascent = -1;
2691 /* Are control characters displayed as `^C'? */
2692 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2694 /* -1 means everything between a CR and the following line end
2695 is invisible. >0 means lines indented more than this value are
2696 invisible. */
2697 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2698 ? (clip_to_bounds
2699 (-1, XINT (BVAR (current_buffer, selective_display)),
2700 PTRDIFF_MAX))
2701 : (!NILP (BVAR (current_buffer, selective_display))
2702 ? -1 : 0));
2703 it->selective_display_ellipsis_p
2704 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2706 /* Display table to use. */
2707 it->dp = window_display_table (w);
2709 /* Are multibyte characters enabled in current_buffer? */
2710 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2712 /* If visible region is of non-zero length, set IT->region_beg_charpos
2713 and IT->region_end_charpos to the start and end of a visible region
2714 in window IT->w. Set both to -1 to indicate no region. */
2715 markpos = markpos_of_region ();
2716 if (markpos >= 0
2717 /* Maybe highlight only in selected window. */
2718 && (/* Either show region everywhere. */
2719 highlight_nonselected_windows
2720 /* Or show region in the selected window. */
2721 || w == XWINDOW (selected_window)
2722 /* Or show the region if we are in the mini-buffer and W is
2723 the window the mini-buffer refers to. */
2724 || (MINI_WINDOW_P (XWINDOW (selected_window))
2725 && WINDOWP (minibuf_selected_window)
2726 && w == XWINDOW (minibuf_selected_window))))
2728 it->region_beg_charpos = min (PT, markpos);
2729 it->region_end_charpos = max (PT, markpos);
2731 else
2732 it->region_beg_charpos = it->region_end_charpos = -1;
2734 /* Get the position at which the redisplay_end_trigger hook should
2735 be run, if it is to be run at all. */
2736 if (MARKERP (w->redisplay_end_trigger)
2737 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2738 it->redisplay_end_trigger_charpos
2739 = marker_position (w->redisplay_end_trigger);
2740 else if (INTEGERP (w->redisplay_end_trigger))
2741 it->redisplay_end_trigger_charpos =
2742 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2744 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2746 /* Are lines in the display truncated? */
2747 if (base_face_id != DEFAULT_FACE_ID
2748 || it->w->hscroll
2749 || (! WINDOW_FULL_WIDTH_P (it->w)
2750 && ((!NILP (Vtruncate_partial_width_windows)
2751 && !INTEGERP (Vtruncate_partial_width_windows))
2752 || (INTEGERP (Vtruncate_partial_width_windows)
2753 && (WINDOW_TOTAL_COLS (it->w)
2754 < XINT (Vtruncate_partial_width_windows))))))
2755 it->line_wrap = TRUNCATE;
2756 else if (NILP (BVAR (current_buffer, truncate_lines)))
2757 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2758 ? WINDOW_WRAP : WORD_WRAP;
2759 else
2760 it->line_wrap = TRUNCATE;
2762 /* Get dimensions of truncation and continuation glyphs. These are
2763 displayed as fringe bitmaps under X, but we need them for such
2764 frames when the fringes are turned off. But leave the dimensions
2765 zero for tooltip frames, as these glyphs look ugly there and also
2766 sabotage calculations of tooltip dimensions in x-show-tip. */
2767 #ifdef HAVE_WINDOW_SYSTEM
2768 if (!(FRAME_WINDOW_P (it->f)
2769 && FRAMEP (tip_frame)
2770 && it->f == XFRAME (tip_frame)))
2771 #endif
2773 if (it->line_wrap == TRUNCATE)
2775 /* We will need the truncation glyph. */
2776 eassert (it->glyph_row == NULL);
2777 produce_special_glyphs (it, IT_TRUNCATION);
2778 it->truncation_pixel_width = it->pixel_width;
2780 else
2782 /* We will need the continuation glyph. */
2783 eassert (it->glyph_row == NULL);
2784 produce_special_glyphs (it, IT_CONTINUATION);
2785 it->continuation_pixel_width = it->pixel_width;
2789 /* Reset these values to zero because the produce_special_glyphs
2790 above has changed them. */
2791 it->pixel_width = it->ascent = it->descent = 0;
2792 it->phys_ascent = it->phys_descent = 0;
2794 /* Set this after getting the dimensions of truncation and
2795 continuation glyphs, so that we don't produce glyphs when calling
2796 produce_special_glyphs, above. */
2797 it->glyph_row = row;
2798 it->area = TEXT_AREA;
2800 /* Forget any previous info about this row being reversed. */
2801 if (it->glyph_row)
2802 it->glyph_row->reversed_p = 0;
2804 /* Get the dimensions of the display area. The display area
2805 consists of the visible window area plus a horizontally scrolled
2806 part to the left of the window. All x-values are relative to the
2807 start of this total display area. */
2808 if (base_face_id != DEFAULT_FACE_ID)
2810 /* Mode lines, menu bar in terminal frames. */
2811 it->first_visible_x = 0;
2812 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2814 else
2816 it->first_visible_x =
2817 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2818 it->last_visible_x = (it->first_visible_x
2819 + window_box_width (w, TEXT_AREA));
2821 /* If we truncate lines, leave room for the truncation glyph(s) at
2822 the right margin. Otherwise, leave room for the continuation
2823 glyph(s). Done only if the window has no fringes. Since we
2824 don't know at this point whether there will be any R2L lines in
2825 the window, we reserve space for truncation/continuation glyphs
2826 even if only one of the fringes is absent. */
2827 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2828 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2830 if (it->line_wrap == TRUNCATE)
2831 it->last_visible_x -= it->truncation_pixel_width;
2832 else
2833 it->last_visible_x -= it->continuation_pixel_width;
2836 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2837 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2840 /* Leave room for a border glyph. */
2841 if (!FRAME_WINDOW_P (it->f)
2842 && !WINDOW_RIGHTMOST_P (it->w))
2843 it->last_visible_x -= 1;
2845 it->last_visible_y = window_text_bottom_y (w);
2847 /* For mode lines and alike, arrange for the first glyph having a
2848 left box line if the face specifies a box. */
2849 if (base_face_id != DEFAULT_FACE_ID)
2851 struct face *face;
2853 it->face_id = remapped_base_face_id;
2855 /* If we have a boxed mode line, make the first character appear
2856 with a left box line. */
2857 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2858 if (face->box != FACE_NO_BOX)
2859 it->start_of_box_run_p = 1;
2862 /* If a buffer position was specified, set the iterator there,
2863 getting overlays and face properties from that position. */
2864 if (charpos >= BUF_BEG (current_buffer))
2866 it->end_charpos = ZV;
2867 eassert (charpos == BYTE_TO_CHAR (bytepos));
2868 IT_CHARPOS (*it) = charpos;
2869 IT_BYTEPOS (*it) = bytepos;
2871 /* We will rely on `reseat' to set this up properly, via
2872 handle_face_prop. */
2873 it->face_id = it->base_face_id;
2875 it->start = it->current;
2876 /* Do we need to reorder bidirectional text? Not if this is a
2877 unibyte buffer: by definition, none of the single-byte
2878 characters are strong R2L, so no reordering is needed. And
2879 bidi.c doesn't support unibyte buffers anyway. Also, don't
2880 reorder while we are loading loadup.el, since the tables of
2881 character properties needed for reordering are not yet
2882 available. */
2883 it->bidi_p =
2884 NILP (Vpurify_flag)
2885 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2886 && it->multibyte_p;
2888 /* If we are to reorder bidirectional text, init the bidi
2889 iterator. */
2890 if (it->bidi_p)
2892 /* Note the paragraph direction that this buffer wants to
2893 use. */
2894 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2895 Qleft_to_right))
2896 it->paragraph_embedding = L2R;
2897 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2898 Qright_to_left))
2899 it->paragraph_embedding = R2L;
2900 else
2901 it->paragraph_embedding = NEUTRAL_DIR;
2902 bidi_unshelve_cache (NULL, 0);
2903 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2904 &it->bidi_it);
2907 /* Compute faces etc. */
2908 reseat (it, it->current.pos, 1);
2911 CHECK_IT (it);
2915 /* Initialize IT for the display of window W with window start POS. */
2917 void
2918 start_display (struct it *it, struct window *w, struct text_pos pos)
2920 struct glyph_row *row;
2921 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2923 row = w->desired_matrix->rows + first_vpos;
2924 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2925 it->first_vpos = first_vpos;
2927 /* Don't reseat to previous visible line start if current start
2928 position is in a string or image. */
2929 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2931 int start_at_line_beg_p;
2932 int first_y = it->current_y;
2934 /* If window start is not at a line start, skip forward to POS to
2935 get the correct continuation lines width. */
2936 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2937 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2938 if (!start_at_line_beg_p)
2940 int new_x;
2942 reseat_at_previous_visible_line_start (it);
2943 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2945 new_x = it->current_x + it->pixel_width;
2947 /* If lines are continued, this line may end in the middle
2948 of a multi-glyph character (e.g. a control character
2949 displayed as \003, or in the middle of an overlay
2950 string). In this case move_it_to above will not have
2951 taken us to the start of the continuation line but to the
2952 end of the continued line. */
2953 if (it->current_x > 0
2954 && it->line_wrap != TRUNCATE /* Lines are continued. */
2955 && (/* And glyph doesn't fit on the line. */
2956 new_x > it->last_visible_x
2957 /* Or it fits exactly and we're on a window
2958 system frame. */
2959 || (new_x == it->last_visible_x
2960 && FRAME_WINDOW_P (it->f)
2961 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
2962 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
2963 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
2965 if ((it->current.dpvec_index >= 0
2966 || it->current.overlay_string_index >= 0)
2967 /* If we are on a newline from a display vector or
2968 overlay string, then we are already at the end of
2969 a screen line; no need to go to the next line in
2970 that case, as this line is not really continued.
2971 (If we do go to the next line, C-e will not DTRT.) */
2972 && it->c != '\n')
2974 set_iterator_to_next (it, 1);
2975 move_it_in_display_line_to (it, -1, -1, 0);
2978 it->continuation_lines_width += it->current_x;
2980 /* If the character at POS is displayed via a display
2981 vector, move_it_to above stops at the final glyph of
2982 IT->dpvec. To make the caller redisplay that character
2983 again (a.k.a. start at POS), we need to reset the
2984 dpvec_index to the beginning of IT->dpvec. */
2985 else if (it->current.dpvec_index >= 0)
2986 it->current.dpvec_index = 0;
2988 /* We're starting a new display line, not affected by the
2989 height of the continued line, so clear the appropriate
2990 fields in the iterator structure. */
2991 it->max_ascent = it->max_descent = 0;
2992 it->max_phys_ascent = it->max_phys_descent = 0;
2994 it->current_y = first_y;
2995 it->vpos = 0;
2996 it->current_x = it->hpos = 0;
3002 /* Return 1 if POS is a position in ellipses displayed for invisible
3003 text. W is the window we display, for text property lookup. */
3005 static int
3006 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3008 Lisp_Object prop, window;
3009 int ellipses_p = 0;
3010 ptrdiff_t charpos = CHARPOS (pos->pos);
3012 /* If POS specifies a position in a display vector, this might
3013 be for an ellipsis displayed for invisible text. We won't
3014 get the iterator set up for delivering that ellipsis unless
3015 we make sure that it gets aware of the invisible text. */
3016 if (pos->dpvec_index >= 0
3017 && pos->overlay_string_index < 0
3018 && CHARPOS (pos->string_pos) < 0
3019 && charpos > BEGV
3020 && (XSETWINDOW (window, w),
3021 prop = Fget_char_property (make_number (charpos),
3022 Qinvisible, window),
3023 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3025 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3026 window);
3027 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3030 return ellipses_p;
3034 /* Initialize IT for stepping through current_buffer in window W,
3035 starting at position POS that includes overlay string and display
3036 vector/ control character translation position information. Value
3037 is zero if there are overlay strings with newlines at POS. */
3039 static int
3040 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3042 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3043 int i, overlay_strings_with_newlines = 0;
3045 /* If POS specifies a position in a display vector, this might
3046 be for an ellipsis displayed for invisible text. We won't
3047 get the iterator set up for delivering that ellipsis unless
3048 we make sure that it gets aware of the invisible text. */
3049 if (in_ellipses_for_invisible_text_p (pos, w))
3051 --charpos;
3052 bytepos = 0;
3055 /* Keep in mind: the call to reseat in init_iterator skips invisible
3056 text, so we might end up at a position different from POS. This
3057 is only a problem when POS is a row start after a newline and an
3058 overlay starts there with an after-string, and the overlay has an
3059 invisible property. Since we don't skip invisible text in
3060 display_line and elsewhere immediately after consuming the
3061 newline before the row start, such a POS will not be in a string,
3062 but the call to init_iterator below will move us to the
3063 after-string. */
3064 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3066 /* This only scans the current chunk -- it should scan all chunks.
3067 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3068 to 16 in 22.1 to make this a lesser problem. */
3069 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3071 const char *s = SSDATA (it->overlay_strings[i]);
3072 const char *e = s + SBYTES (it->overlay_strings[i]);
3074 while (s < e && *s != '\n')
3075 ++s;
3077 if (s < e)
3079 overlay_strings_with_newlines = 1;
3080 break;
3084 /* If position is within an overlay string, set up IT to the right
3085 overlay string. */
3086 if (pos->overlay_string_index >= 0)
3088 int relative_index;
3090 /* If the first overlay string happens to have a `display'
3091 property for an image, the iterator will be set up for that
3092 image, and we have to undo that setup first before we can
3093 correct the overlay string index. */
3094 if (it->method == GET_FROM_IMAGE)
3095 pop_it (it);
3097 /* We already have the first chunk of overlay strings in
3098 IT->overlay_strings. Load more until the one for
3099 pos->overlay_string_index is in IT->overlay_strings. */
3100 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3102 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3103 it->current.overlay_string_index = 0;
3104 while (n--)
3106 load_overlay_strings (it, 0);
3107 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3111 it->current.overlay_string_index = pos->overlay_string_index;
3112 relative_index = (it->current.overlay_string_index
3113 % OVERLAY_STRING_CHUNK_SIZE);
3114 it->string = it->overlay_strings[relative_index];
3115 eassert (STRINGP (it->string));
3116 it->current.string_pos = pos->string_pos;
3117 it->method = GET_FROM_STRING;
3118 it->end_charpos = SCHARS (it->string);
3119 /* Set up the bidi iterator for this overlay string. */
3120 if (it->bidi_p)
3122 it->bidi_it.string.lstring = it->string;
3123 it->bidi_it.string.s = NULL;
3124 it->bidi_it.string.schars = SCHARS (it->string);
3125 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3126 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3127 it->bidi_it.string.unibyte = !it->multibyte_p;
3128 it->bidi_it.w = it->w;
3129 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3130 FRAME_WINDOW_P (it->f), &it->bidi_it);
3132 /* Synchronize the state of the bidi iterator with
3133 pos->string_pos. For any string position other than
3134 zero, this will be done automagically when we resume
3135 iteration over the string and get_visually_first_element
3136 is called. But if string_pos is zero, and the string is
3137 to be reordered for display, we need to resync manually,
3138 since it could be that the iteration state recorded in
3139 pos ended at string_pos of 0 moving backwards in string. */
3140 if (CHARPOS (pos->string_pos) == 0)
3142 get_visually_first_element (it);
3143 if (IT_STRING_CHARPOS (*it) != 0)
3144 do {
3145 /* Paranoia. */
3146 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3147 bidi_move_to_visually_next (&it->bidi_it);
3148 } while (it->bidi_it.charpos != 0);
3150 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3151 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3155 if (CHARPOS (pos->string_pos) >= 0)
3157 /* Recorded position is not in an overlay string, but in another
3158 string. This can only be a string from a `display' property.
3159 IT should already be filled with that string. */
3160 it->current.string_pos = pos->string_pos;
3161 eassert (STRINGP (it->string));
3162 if (it->bidi_p)
3163 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3164 FRAME_WINDOW_P (it->f), &it->bidi_it);
3167 /* Restore position in display vector translations, control
3168 character translations or ellipses. */
3169 if (pos->dpvec_index >= 0)
3171 if (it->dpvec == NULL)
3172 get_next_display_element (it);
3173 eassert (it->dpvec && it->current.dpvec_index == 0);
3174 it->current.dpvec_index = pos->dpvec_index;
3177 CHECK_IT (it);
3178 return !overlay_strings_with_newlines;
3182 /* Initialize IT for stepping through current_buffer in window W
3183 starting at ROW->start. */
3185 static void
3186 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3188 init_from_display_pos (it, w, &row->start);
3189 it->start = row->start;
3190 it->continuation_lines_width = row->continuation_lines_width;
3191 CHECK_IT (it);
3195 /* Initialize IT for stepping through current_buffer in window W
3196 starting in the line following ROW, i.e. starting at ROW->end.
3197 Value is zero if there are overlay strings with newlines at ROW's
3198 end position. */
3200 static int
3201 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3203 int success = 0;
3205 if (init_from_display_pos (it, w, &row->end))
3207 if (row->continued_p)
3208 it->continuation_lines_width
3209 = row->continuation_lines_width + row->pixel_width;
3210 CHECK_IT (it);
3211 success = 1;
3214 return success;
3220 /***********************************************************************
3221 Text properties
3222 ***********************************************************************/
3224 /* Called when IT reaches IT->stop_charpos. Handle text property and
3225 overlay changes. Set IT->stop_charpos to the next position where
3226 to stop. */
3228 static void
3229 handle_stop (struct it *it)
3231 enum prop_handled handled;
3232 int handle_overlay_change_p;
3233 struct props *p;
3235 it->dpvec = NULL;
3236 it->current.dpvec_index = -1;
3237 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3238 it->ignore_overlay_strings_at_pos_p = 0;
3239 it->ellipsis_p = 0;
3241 /* Use face of preceding text for ellipsis (if invisible) */
3242 if (it->selective_display_ellipsis_p)
3243 it->saved_face_id = it->face_id;
3247 handled = HANDLED_NORMALLY;
3249 /* Call text property handlers. */
3250 for (p = it_props; p->handler; ++p)
3252 handled = p->handler (it);
3254 if (handled == HANDLED_RECOMPUTE_PROPS)
3255 break;
3256 else if (handled == HANDLED_RETURN)
3258 /* We still want to show before and after strings from
3259 overlays even if the actual buffer text is replaced. */
3260 if (!handle_overlay_change_p
3261 || it->sp > 1
3262 /* Don't call get_overlay_strings_1 if we already
3263 have overlay strings loaded, because doing so
3264 will load them again and push the iterator state
3265 onto the stack one more time, which is not
3266 expected by the rest of the code that processes
3267 overlay strings. */
3268 || (it->current.overlay_string_index < 0
3269 ? !get_overlay_strings_1 (it, 0, 0)
3270 : 0))
3272 if (it->ellipsis_p)
3273 setup_for_ellipsis (it, 0);
3274 /* When handling a display spec, we might load an
3275 empty string. In that case, discard it here. We
3276 used to discard it in handle_single_display_spec,
3277 but that causes get_overlay_strings_1, above, to
3278 ignore overlay strings that we must check. */
3279 if (STRINGP (it->string) && !SCHARS (it->string))
3280 pop_it (it);
3281 return;
3283 else if (STRINGP (it->string) && !SCHARS (it->string))
3284 pop_it (it);
3285 else
3287 it->ignore_overlay_strings_at_pos_p = 1;
3288 it->string_from_display_prop_p = 0;
3289 it->from_disp_prop_p = 0;
3290 handle_overlay_change_p = 0;
3292 handled = HANDLED_RECOMPUTE_PROPS;
3293 break;
3295 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3296 handle_overlay_change_p = 0;
3299 if (handled != HANDLED_RECOMPUTE_PROPS)
3301 /* Don't check for overlay strings below when set to deliver
3302 characters from a display vector. */
3303 if (it->method == GET_FROM_DISPLAY_VECTOR)
3304 handle_overlay_change_p = 0;
3306 /* Handle overlay changes.
3307 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3308 if it finds overlays. */
3309 if (handle_overlay_change_p)
3310 handled = handle_overlay_change (it);
3313 if (it->ellipsis_p)
3315 setup_for_ellipsis (it, 0);
3316 break;
3319 while (handled == HANDLED_RECOMPUTE_PROPS);
3321 /* Determine where to stop next. */
3322 if (handled == HANDLED_NORMALLY)
3323 compute_stop_pos (it);
3327 /* Compute IT->stop_charpos from text property and overlay change
3328 information for IT's current position. */
3330 static void
3331 compute_stop_pos (struct it *it)
3333 register INTERVAL iv, next_iv;
3334 Lisp_Object object, limit, position;
3335 ptrdiff_t charpos, bytepos;
3337 if (STRINGP (it->string))
3339 /* Strings are usually short, so don't limit the search for
3340 properties. */
3341 it->stop_charpos = it->end_charpos;
3342 object = it->string;
3343 limit = Qnil;
3344 charpos = IT_STRING_CHARPOS (*it);
3345 bytepos = IT_STRING_BYTEPOS (*it);
3347 else
3349 ptrdiff_t pos;
3351 /* If end_charpos is out of range for some reason, such as a
3352 misbehaving display function, rationalize it (Bug#5984). */
3353 if (it->end_charpos > ZV)
3354 it->end_charpos = ZV;
3355 it->stop_charpos = it->end_charpos;
3357 /* If next overlay change is in front of the current stop pos
3358 (which is IT->end_charpos), stop there. Note: value of
3359 next_overlay_change is point-max if no overlay change
3360 follows. */
3361 charpos = IT_CHARPOS (*it);
3362 bytepos = IT_BYTEPOS (*it);
3363 pos = next_overlay_change (charpos);
3364 if (pos < it->stop_charpos)
3365 it->stop_charpos = pos;
3367 /* If showing the region, we have to stop at the region
3368 start or end because the face might change there. */
3369 if (it->region_beg_charpos > 0)
3371 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3372 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3373 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3374 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3377 /* Set up variables for computing the stop position from text
3378 property changes. */
3379 XSETBUFFER (object, current_buffer);
3380 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3383 /* Get the interval containing IT's position. Value is a null
3384 interval if there isn't such an interval. */
3385 position = make_number (charpos);
3386 iv = validate_interval_range (object, &position, &position, 0);
3387 if (iv)
3389 Lisp_Object values_here[LAST_PROP_IDX];
3390 struct props *p;
3392 /* Get properties here. */
3393 for (p = it_props; p->handler; ++p)
3394 values_here[p->idx] = textget (iv->plist, *p->name);
3396 /* Look for an interval following iv that has different
3397 properties. */
3398 for (next_iv = next_interval (iv);
3399 (next_iv
3400 && (NILP (limit)
3401 || XFASTINT (limit) > next_iv->position));
3402 next_iv = next_interval (next_iv))
3404 for (p = it_props; p->handler; ++p)
3406 Lisp_Object new_value;
3408 new_value = textget (next_iv->plist, *p->name);
3409 if (!EQ (values_here[p->idx], new_value))
3410 break;
3413 if (p->handler)
3414 break;
3417 if (next_iv)
3419 if (INTEGERP (limit)
3420 && next_iv->position >= XFASTINT (limit))
3421 /* No text property change up to limit. */
3422 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3423 else
3424 /* Text properties change in next_iv. */
3425 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3429 if (it->cmp_it.id < 0)
3431 ptrdiff_t stoppos = it->end_charpos;
3433 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3434 stoppos = -1;
3435 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3436 stoppos, it->string);
3439 eassert (STRINGP (it->string)
3440 || (it->stop_charpos >= BEGV
3441 && it->stop_charpos >= IT_CHARPOS (*it)));
3445 /* Return the position of the next overlay change after POS in
3446 current_buffer. Value is point-max if no overlay change
3447 follows. This is like `next-overlay-change' but doesn't use
3448 xmalloc. */
3450 static ptrdiff_t
3451 next_overlay_change (ptrdiff_t pos)
3453 ptrdiff_t i, noverlays;
3454 ptrdiff_t endpos;
3455 Lisp_Object *overlays;
3457 /* Get all overlays at the given position. */
3458 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3460 /* If any of these overlays ends before endpos,
3461 use its ending point instead. */
3462 for (i = 0; i < noverlays; ++i)
3464 Lisp_Object oend;
3465 ptrdiff_t oendpos;
3467 oend = OVERLAY_END (overlays[i]);
3468 oendpos = OVERLAY_POSITION (oend);
3469 endpos = min (endpos, oendpos);
3472 return endpos;
3475 /* How many characters forward to search for a display property or
3476 display string. Searching too far forward makes the bidi display
3477 sluggish, especially in small windows. */
3478 #define MAX_DISP_SCAN 250
3480 /* Return the character position of a display string at or after
3481 position specified by POSITION. If no display string exists at or
3482 after POSITION, return ZV. A display string is either an overlay
3483 with `display' property whose value is a string, or a `display'
3484 text property whose value is a string. STRING is data about the
3485 string to iterate; if STRING->lstring is nil, we are iterating a
3486 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3487 on a GUI frame. DISP_PROP is set to zero if we searched
3488 MAX_DISP_SCAN characters forward without finding any display
3489 strings, non-zero otherwise. It is set to 2 if the display string
3490 uses any kind of `(space ...)' spec that will produce a stretch of
3491 white space in the text area. */
3492 ptrdiff_t
3493 compute_display_string_pos (struct text_pos *position,
3494 struct bidi_string_data *string,
3495 struct window *w,
3496 int frame_window_p, int *disp_prop)
3498 /* OBJECT = nil means current buffer. */
3499 Lisp_Object object, object1;
3500 Lisp_Object pos, spec, limpos;
3501 int string_p = (string && (STRINGP (string->lstring) || string->s));
3502 ptrdiff_t eob = string_p ? string->schars : ZV;
3503 ptrdiff_t begb = string_p ? 0 : BEGV;
3504 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3505 ptrdiff_t lim =
3506 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3507 struct text_pos tpos;
3508 int rv = 0;
3510 if (string && STRINGP (string->lstring))
3511 object1 = object = string->lstring;
3512 else if (!string_p)
3514 eassert (w != NULL);
3515 XSETWINDOW (object, w);
3516 object1 = Qnil;
3518 else
3519 object1 = object = Qnil;
3521 *disp_prop = 1;
3523 if (charpos >= eob
3524 /* We don't support display properties whose values are strings
3525 that have display string properties. */
3526 || string->from_disp_str
3527 /* C strings cannot have display properties. */
3528 || (string->s && !STRINGP (object)))
3530 *disp_prop = 0;
3531 return eob;
3534 /* If the character at CHARPOS is where the display string begins,
3535 return CHARPOS. */
3536 pos = make_number (charpos);
3537 if (STRINGP (object))
3538 bufpos = string->bufpos;
3539 else
3540 bufpos = charpos;
3541 tpos = *position;
3542 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3543 && (charpos <= begb
3544 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3545 object),
3546 spec))
3547 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3548 frame_window_p)))
3550 if (rv == 2)
3551 *disp_prop = 2;
3552 return charpos;
3555 /* Look forward for the first character with a `display' property
3556 that will replace the underlying text when displayed. */
3557 limpos = make_number (lim);
3558 do {
3559 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3560 CHARPOS (tpos) = XFASTINT (pos);
3561 if (CHARPOS (tpos) >= lim)
3563 *disp_prop = 0;
3564 break;
3566 if (STRINGP (object))
3567 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3568 else
3569 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3570 spec = Fget_char_property (pos, Qdisplay, object);
3571 if (!STRINGP (object))
3572 bufpos = CHARPOS (tpos);
3573 } while (NILP (spec)
3574 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3575 bufpos, frame_window_p)));
3576 if (rv == 2)
3577 *disp_prop = 2;
3579 return CHARPOS (tpos);
3582 /* Return the character position of the end of the display string that
3583 started at CHARPOS. If there's no display string at CHARPOS,
3584 return -1. A display string is either an overlay with `display'
3585 property whose value is a string or a `display' text property whose
3586 value is a string. */
3587 ptrdiff_t
3588 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3590 /* OBJECT = nil means current buffer. */
3591 Lisp_Object object =
3592 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3593 Lisp_Object pos = make_number (charpos);
3594 ptrdiff_t eob =
3595 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3597 if (charpos >= eob || (string->s && !STRINGP (object)))
3598 return eob;
3600 /* It could happen that the display property or overlay was removed
3601 since we found it in compute_display_string_pos above. One way
3602 this can happen is if JIT font-lock was called (through
3603 handle_fontified_prop), and jit-lock-functions remove text
3604 properties or overlays from the portion of buffer that includes
3605 CHARPOS. Muse mode is known to do that, for example. In this
3606 case, we return -1 to the caller, to signal that no display
3607 string is actually present at CHARPOS. See bidi_fetch_char for
3608 how this is handled.
3610 An alternative would be to never look for display properties past
3611 it->stop_charpos. But neither compute_display_string_pos nor
3612 bidi_fetch_char that calls it know or care where the next
3613 stop_charpos is. */
3614 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3615 return -1;
3617 /* Look forward for the first character where the `display' property
3618 changes. */
3619 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3621 return XFASTINT (pos);
3626 /***********************************************************************
3627 Fontification
3628 ***********************************************************************/
3630 /* Handle changes in the `fontified' property of the current buffer by
3631 calling hook functions from Qfontification_functions to fontify
3632 regions of text. */
3634 static enum prop_handled
3635 handle_fontified_prop (struct it *it)
3637 Lisp_Object prop, pos;
3638 enum prop_handled handled = HANDLED_NORMALLY;
3640 if (!NILP (Vmemory_full))
3641 return handled;
3643 /* Get the value of the `fontified' property at IT's current buffer
3644 position. (The `fontified' property doesn't have a special
3645 meaning in strings.) If the value is nil, call functions from
3646 Qfontification_functions. */
3647 if (!STRINGP (it->string)
3648 && it->s == NULL
3649 && !NILP (Vfontification_functions)
3650 && !NILP (Vrun_hooks)
3651 && (pos = make_number (IT_CHARPOS (*it)),
3652 prop = Fget_char_property (pos, Qfontified, Qnil),
3653 /* Ignore the special cased nil value always present at EOB since
3654 no amount of fontifying will be able to change it. */
3655 NILP (prop) && IT_CHARPOS (*it) < Z))
3657 ptrdiff_t count = SPECPDL_INDEX ();
3658 Lisp_Object val;
3659 struct buffer *obuf = current_buffer;
3660 int begv = BEGV, zv = ZV;
3661 int old_clip_changed = current_buffer->clip_changed;
3663 val = Vfontification_functions;
3664 specbind (Qfontification_functions, Qnil);
3666 eassert (it->end_charpos == ZV);
3668 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3669 safe_call1 (val, pos);
3670 else
3672 Lisp_Object fns, fn;
3673 struct gcpro gcpro1, gcpro2;
3675 fns = Qnil;
3676 GCPRO2 (val, fns);
3678 for (; CONSP (val); val = XCDR (val))
3680 fn = XCAR (val);
3682 if (EQ (fn, Qt))
3684 /* A value of t indicates this hook has a local
3685 binding; it means to run the global binding too.
3686 In a global value, t should not occur. If it
3687 does, we must ignore it to avoid an endless
3688 loop. */
3689 for (fns = Fdefault_value (Qfontification_functions);
3690 CONSP (fns);
3691 fns = XCDR (fns))
3693 fn = XCAR (fns);
3694 if (!EQ (fn, Qt))
3695 safe_call1 (fn, pos);
3698 else
3699 safe_call1 (fn, pos);
3702 UNGCPRO;
3705 unbind_to (count, Qnil);
3707 /* Fontification functions routinely call `save-restriction'.
3708 Normally, this tags clip_changed, which can confuse redisplay
3709 (see discussion in Bug#6671). Since we don't perform any
3710 special handling of fontification changes in the case where
3711 `save-restriction' isn't called, there's no point doing so in
3712 this case either. So, if the buffer's restrictions are
3713 actually left unchanged, reset clip_changed. */
3714 if (obuf == current_buffer)
3716 if (begv == BEGV && zv == ZV)
3717 current_buffer->clip_changed = old_clip_changed;
3719 /* There isn't much we can reasonably do to protect against
3720 misbehaving fontification, but here's a fig leaf. */
3721 else if (BUFFER_LIVE_P (obuf))
3722 set_buffer_internal_1 (obuf);
3724 /* The fontification code may have added/removed text.
3725 It could do even a lot worse, but let's at least protect against
3726 the most obvious case where only the text past `pos' gets changed',
3727 as is/was done in grep.el where some escapes sequences are turned
3728 into face properties (bug#7876). */
3729 it->end_charpos = ZV;
3731 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3732 something. This avoids an endless loop if they failed to
3733 fontify the text for which reason ever. */
3734 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3735 handled = HANDLED_RECOMPUTE_PROPS;
3738 return handled;
3743 /***********************************************************************
3744 Faces
3745 ***********************************************************************/
3747 /* Set up iterator IT from face properties at its current position.
3748 Called from handle_stop. */
3750 static enum prop_handled
3751 handle_face_prop (struct it *it)
3753 int new_face_id;
3754 ptrdiff_t next_stop;
3756 if (!STRINGP (it->string))
3758 new_face_id
3759 = face_at_buffer_position (it->w,
3760 IT_CHARPOS (*it),
3761 it->region_beg_charpos,
3762 it->region_end_charpos,
3763 &next_stop,
3764 (IT_CHARPOS (*it)
3765 + TEXT_PROP_DISTANCE_LIMIT),
3766 0, it->base_face_id);
3768 /* Is this a start of a run of characters with box face?
3769 Caveat: this can be called for a freshly initialized
3770 iterator; face_id is -1 in this case. We know that the new
3771 face will not change until limit, i.e. if the new face has a
3772 box, all characters up to limit will have one. But, as
3773 usual, we don't know whether limit is really the end. */
3774 if (new_face_id != it->face_id)
3776 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3777 /* If it->face_id is -1, old_face below will be NULL, see
3778 the definition of FACE_FROM_ID. This will happen if this
3779 is the initial call that gets the face. */
3780 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3782 /* If the value of face_id of the iterator is -1, we have to
3783 look in front of IT's position and see whether there is a
3784 face there that's different from new_face_id. */
3785 if (!old_face && IT_CHARPOS (*it) > BEG)
3787 int prev_face_id = face_before_it_pos (it);
3789 old_face = FACE_FROM_ID (it->f, prev_face_id);
3792 /* If the new face has a box, but the old face does not,
3793 this is the start of a run of characters with box face,
3794 i.e. this character has a shadow on the left side. */
3795 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3796 && (old_face == NULL || !old_face->box));
3797 it->face_box_p = new_face->box != FACE_NO_BOX;
3800 else
3802 int base_face_id;
3803 ptrdiff_t bufpos;
3804 int i;
3805 Lisp_Object from_overlay
3806 = (it->current.overlay_string_index >= 0
3807 ? it->string_overlays[it->current.overlay_string_index
3808 % OVERLAY_STRING_CHUNK_SIZE]
3809 : Qnil);
3811 /* See if we got to this string directly or indirectly from
3812 an overlay property. That includes the before-string or
3813 after-string of an overlay, strings in display properties
3814 provided by an overlay, their text properties, etc.
3816 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3817 if (! NILP (from_overlay))
3818 for (i = it->sp - 1; i >= 0; i--)
3820 if (it->stack[i].current.overlay_string_index >= 0)
3821 from_overlay
3822 = it->string_overlays[it->stack[i].current.overlay_string_index
3823 % OVERLAY_STRING_CHUNK_SIZE];
3824 else if (! NILP (it->stack[i].from_overlay))
3825 from_overlay = it->stack[i].from_overlay;
3827 if (!NILP (from_overlay))
3828 break;
3831 if (! NILP (from_overlay))
3833 bufpos = IT_CHARPOS (*it);
3834 /* For a string from an overlay, the base face depends
3835 only on text properties and ignores overlays. */
3836 base_face_id
3837 = face_for_overlay_string (it->w,
3838 IT_CHARPOS (*it),
3839 it->region_beg_charpos,
3840 it->region_end_charpos,
3841 &next_stop,
3842 (IT_CHARPOS (*it)
3843 + TEXT_PROP_DISTANCE_LIMIT),
3845 from_overlay);
3847 else
3849 bufpos = 0;
3851 /* For strings from a `display' property, use the face at
3852 IT's current buffer position as the base face to merge
3853 with, so that overlay strings appear in the same face as
3854 surrounding text, unless they specify their own
3855 faces. */
3856 base_face_id = it->string_from_prefix_prop_p
3857 ? DEFAULT_FACE_ID
3858 : underlying_face_id (it);
3861 new_face_id = face_at_string_position (it->w,
3862 it->string,
3863 IT_STRING_CHARPOS (*it),
3864 bufpos,
3865 it->region_beg_charpos,
3866 it->region_end_charpos,
3867 &next_stop,
3868 base_face_id, 0);
3870 /* Is this a start of a run of characters with box? Caveat:
3871 this can be called for a freshly allocated iterator; face_id
3872 is -1 is this case. We know that the new face will not
3873 change until the next check pos, i.e. if the new face has a
3874 box, all characters up to that position will have a
3875 box. But, as usual, we don't know whether that position
3876 is really the end. */
3877 if (new_face_id != it->face_id)
3879 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3880 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3882 /* If new face has a box but old face hasn't, this is the
3883 start of a run of characters with box, i.e. it has a
3884 shadow on the left side. */
3885 it->start_of_box_run_p
3886 = new_face->box && (old_face == NULL || !old_face->box);
3887 it->face_box_p = new_face->box != FACE_NO_BOX;
3891 it->face_id = new_face_id;
3892 return HANDLED_NORMALLY;
3896 /* Return the ID of the face ``underlying'' IT's current position,
3897 which is in a string. If the iterator is associated with a
3898 buffer, return the face at IT's current buffer position.
3899 Otherwise, use the iterator's base_face_id. */
3901 static int
3902 underlying_face_id (struct it *it)
3904 int face_id = it->base_face_id, i;
3906 eassert (STRINGP (it->string));
3908 for (i = it->sp - 1; i >= 0; --i)
3909 if (NILP (it->stack[i].string))
3910 face_id = it->stack[i].face_id;
3912 return face_id;
3916 /* Compute the face one character before or after the current position
3917 of IT, in the visual order. BEFORE_P non-zero means get the face
3918 in front (to the left in L2R paragraphs, to the right in R2L
3919 paragraphs) of IT's screen position. Value is the ID of the face. */
3921 static int
3922 face_before_or_after_it_pos (struct it *it, int before_p)
3924 int face_id, limit;
3925 ptrdiff_t next_check_charpos;
3926 struct it it_copy;
3927 void *it_copy_data = NULL;
3929 eassert (it->s == NULL);
3931 if (STRINGP (it->string))
3933 ptrdiff_t bufpos, charpos;
3934 int base_face_id;
3936 /* No face change past the end of the string (for the case
3937 we are padding with spaces). No face change before the
3938 string start. */
3939 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3940 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3941 return it->face_id;
3943 if (!it->bidi_p)
3945 /* Set charpos to the position before or after IT's current
3946 position, in the logical order, which in the non-bidi
3947 case is the same as the visual order. */
3948 if (before_p)
3949 charpos = IT_STRING_CHARPOS (*it) - 1;
3950 else if (it->what == IT_COMPOSITION)
3951 /* For composition, we must check the character after the
3952 composition. */
3953 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3954 else
3955 charpos = IT_STRING_CHARPOS (*it) + 1;
3957 else
3959 if (before_p)
3961 /* With bidi iteration, the character before the current
3962 in the visual order cannot be found by simple
3963 iteration, because "reverse" reordering is not
3964 supported. Instead, we need to use the move_it_*
3965 family of functions. */
3966 /* Ignore face changes before the first visible
3967 character on this display line. */
3968 if (it->current_x <= it->first_visible_x)
3969 return it->face_id;
3970 SAVE_IT (it_copy, *it, it_copy_data);
3971 /* Implementation note: Since move_it_in_display_line
3972 works in the iterator geometry, and thinks the first
3973 character is always the leftmost, even in R2L lines,
3974 we don't need to distinguish between the R2L and L2R
3975 cases here. */
3976 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3977 it_copy.current_x - 1, MOVE_TO_X);
3978 charpos = IT_STRING_CHARPOS (it_copy);
3979 RESTORE_IT (it, it, it_copy_data);
3981 else
3983 /* Set charpos to the string position of the character
3984 that comes after IT's current position in the visual
3985 order. */
3986 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3988 it_copy = *it;
3989 while (n--)
3990 bidi_move_to_visually_next (&it_copy.bidi_it);
3992 charpos = it_copy.bidi_it.charpos;
3995 eassert (0 <= charpos && charpos <= SCHARS (it->string));
3997 if (it->current.overlay_string_index >= 0)
3998 bufpos = IT_CHARPOS (*it);
3999 else
4000 bufpos = 0;
4002 base_face_id = underlying_face_id (it);
4004 /* Get the face for ASCII, or unibyte. */
4005 face_id = face_at_string_position (it->w,
4006 it->string,
4007 charpos,
4008 bufpos,
4009 it->region_beg_charpos,
4010 it->region_end_charpos,
4011 &next_check_charpos,
4012 base_face_id, 0);
4014 /* Correct the face for charsets different from ASCII. Do it
4015 for the multibyte case only. The face returned above is
4016 suitable for unibyte text if IT->string is unibyte. */
4017 if (STRING_MULTIBYTE (it->string))
4019 struct text_pos pos1 = string_pos (charpos, it->string);
4020 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4021 int c, len;
4022 struct face *face = FACE_FROM_ID (it->f, face_id);
4024 c = string_char_and_length (p, &len);
4025 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4028 else
4030 struct text_pos pos;
4032 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4033 || (IT_CHARPOS (*it) <= BEGV && before_p))
4034 return it->face_id;
4036 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4037 pos = it->current.pos;
4039 if (!it->bidi_p)
4041 if (before_p)
4042 DEC_TEXT_POS (pos, it->multibyte_p);
4043 else
4045 if (it->what == IT_COMPOSITION)
4047 /* For composition, we must check the position after
4048 the composition. */
4049 pos.charpos += it->cmp_it.nchars;
4050 pos.bytepos += it->len;
4052 else
4053 INC_TEXT_POS (pos, it->multibyte_p);
4056 else
4058 if (before_p)
4060 /* With bidi iteration, the character before the current
4061 in the visual order cannot be found by simple
4062 iteration, because "reverse" reordering is not
4063 supported. Instead, we need to use the move_it_*
4064 family of functions. */
4065 /* Ignore face changes before the first visible
4066 character on this display line. */
4067 if (it->current_x <= it->first_visible_x)
4068 return it->face_id;
4069 SAVE_IT (it_copy, *it, it_copy_data);
4070 /* Implementation note: Since move_it_in_display_line
4071 works in the iterator geometry, and thinks the first
4072 character is always the leftmost, even in R2L lines,
4073 we don't need to distinguish between the R2L and L2R
4074 cases here. */
4075 move_it_in_display_line (&it_copy, ZV,
4076 it_copy.current_x - 1, MOVE_TO_X);
4077 pos = it_copy.current.pos;
4078 RESTORE_IT (it, it, it_copy_data);
4080 else
4082 /* Set charpos to the buffer position of the character
4083 that comes after IT's current position in the visual
4084 order. */
4085 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4087 it_copy = *it;
4088 while (n--)
4089 bidi_move_to_visually_next (&it_copy.bidi_it);
4091 SET_TEXT_POS (pos,
4092 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4095 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4097 /* Determine face for CHARSET_ASCII, or unibyte. */
4098 face_id = face_at_buffer_position (it->w,
4099 CHARPOS (pos),
4100 it->region_beg_charpos,
4101 it->region_end_charpos,
4102 &next_check_charpos,
4103 limit, 0, -1);
4105 /* Correct the face for charsets different from ASCII. Do it
4106 for the multibyte case only. The face returned above is
4107 suitable for unibyte text if current_buffer is unibyte. */
4108 if (it->multibyte_p)
4110 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4111 struct face *face = FACE_FROM_ID (it->f, face_id);
4112 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4116 return face_id;
4121 /***********************************************************************
4122 Invisible text
4123 ***********************************************************************/
4125 /* Set up iterator IT from invisible properties at its current
4126 position. Called from handle_stop. */
4128 static enum prop_handled
4129 handle_invisible_prop (struct it *it)
4131 enum prop_handled handled = HANDLED_NORMALLY;
4132 int invis_p;
4133 Lisp_Object prop;
4135 if (STRINGP (it->string))
4137 Lisp_Object end_charpos, limit, charpos;
4139 /* Get the value of the invisible text property at the
4140 current position. Value will be nil if there is no such
4141 property. */
4142 charpos = make_number (IT_STRING_CHARPOS (*it));
4143 prop = Fget_text_property (charpos, Qinvisible, it->string);
4144 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4146 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4148 /* Record whether we have to display an ellipsis for the
4149 invisible text. */
4150 int display_ellipsis_p = (invis_p == 2);
4151 ptrdiff_t len, endpos;
4153 handled = HANDLED_RECOMPUTE_PROPS;
4155 /* Get the position at which the next visible text can be
4156 found in IT->string, if any. */
4157 endpos = len = SCHARS (it->string);
4158 XSETINT (limit, len);
4161 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4162 it->string, limit);
4163 if (INTEGERP (end_charpos))
4165 endpos = XFASTINT (end_charpos);
4166 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4167 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4168 if (invis_p == 2)
4169 display_ellipsis_p = 1;
4172 while (invis_p && endpos < len);
4174 if (display_ellipsis_p)
4175 it->ellipsis_p = 1;
4177 if (endpos < len)
4179 /* Text at END_CHARPOS is visible. Move IT there. */
4180 struct text_pos old;
4181 ptrdiff_t oldpos;
4183 old = it->current.string_pos;
4184 oldpos = CHARPOS (old);
4185 if (it->bidi_p)
4187 if (it->bidi_it.first_elt
4188 && it->bidi_it.charpos < SCHARS (it->string))
4189 bidi_paragraph_init (it->paragraph_embedding,
4190 &it->bidi_it, 1);
4191 /* Bidi-iterate out of the invisible text. */
4194 bidi_move_to_visually_next (&it->bidi_it);
4196 while (oldpos <= it->bidi_it.charpos
4197 && it->bidi_it.charpos < endpos);
4199 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4200 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4201 if (IT_CHARPOS (*it) >= endpos)
4202 it->prev_stop = endpos;
4204 else
4206 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4207 compute_string_pos (&it->current.string_pos, old, it->string);
4210 else
4212 /* The rest of the string is invisible. If this is an
4213 overlay string, proceed with the next overlay string
4214 or whatever comes and return a character from there. */
4215 if (it->current.overlay_string_index >= 0
4216 && !display_ellipsis_p)
4218 next_overlay_string (it);
4219 /* Don't check for overlay strings when we just
4220 finished processing them. */
4221 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4223 else
4225 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4226 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4231 else
4233 ptrdiff_t newpos, next_stop, start_charpos, tem;
4234 Lisp_Object pos, overlay;
4236 /* First of all, is there invisible text at this position? */
4237 tem = start_charpos = IT_CHARPOS (*it);
4238 pos = make_number (tem);
4239 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4240 &overlay);
4241 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4243 /* If we are on invisible text, skip over it. */
4244 if (invis_p && start_charpos < it->end_charpos)
4246 /* Record whether we have to display an ellipsis for the
4247 invisible text. */
4248 int display_ellipsis_p = invis_p == 2;
4250 handled = HANDLED_RECOMPUTE_PROPS;
4252 /* Loop skipping over invisible text. The loop is left at
4253 ZV or with IT on the first char being visible again. */
4256 /* Try to skip some invisible text. Return value is the
4257 position reached which can be equal to where we start
4258 if there is nothing invisible there. This skips both
4259 over invisible text properties and overlays with
4260 invisible property. */
4261 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4263 /* If we skipped nothing at all we weren't at invisible
4264 text in the first place. If everything to the end of
4265 the buffer was skipped, end the loop. */
4266 if (newpos == tem || newpos >= ZV)
4267 invis_p = 0;
4268 else
4270 /* We skipped some characters but not necessarily
4271 all there are. Check if we ended up on visible
4272 text. Fget_char_property returns the property of
4273 the char before the given position, i.e. if we
4274 get invis_p = 0, this means that the char at
4275 newpos is visible. */
4276 pos = make_number (newpos);
4277 prop = Fget_char_property (pos, Qinvisible, it->window);
4278 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4281 /* If we ended up on invisible text, proceed to
4282 skip starting with next_stop. */
4283 if (invis_p)
4284 tem = next_stop;
4286 /* If there are adjacent invisible texts, don't lose the
4287 second one's ellipsis. */
4288 if (invis_p == 2)
4289 display_ellipsis_p = 1;
4291 while (invis_p);
4293 /* The position newpos is now either ZV or on visible text. */
4294 if (it->bidi_p)
4296 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4297 int on_newline =
4298 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4299 int after_newline =
4300 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4302 /* If the invisible text ends on a newline or on a
4303 character after a newline, we can avoid the costly,
4304 character by character, bidi iteration to NEWPOS, and
4305 instead simply reseat the iterator there. That's
4306 because all bidi reordering information is tossed at
4307 the newline. This is a big win for modes that hide
4308 complete lines, like Outline, Org, etc. */
4309 if (on_newline || after_newline)
4311 struct text_pos tpos;
4312 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4314 SET_TEXT_POS (tpos, newpos, bpos);
4315 reseat_1 (it, tpos, 0);
4316 /* If we reseat on a newline/ZV, we need to prep the
4317 bidi iterator for advancing to the next character
4318 after the newline/EOB, keeping the current paragraph
4319 direction (so that PRODUCE_GLYPHS does TRT wrt
4320 prepending/appending glyphs to a glyph row). */
4321 if (on_newline)
4323 it->bidi_it.first_elt = 0;
4324 it->bidi_it.paragraph_dir = pdir;
4325 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4326 it->bidi_it.nchars = 1;
4327 it->bidi_it.ch_len = 1;
4330 else /* Must use the slow method. */
4332 /* With bidi iteration, the region of invisible text
4333 could start and/or end in the middle of a
4334 non-base embedding level. Therefore, we need to
4335 skip invisible text using the bidi iterator,
4336 starting at IT's current position, until we find
4337 ourselves outside of the invisible text.
4338 Skipping invisible text _after_ bidi iteration
4339 avoids affecting the visual order of the
4340 displayed text when invisible properties are
4341 added or removed. */
4342 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4344 /* If we were `reseat'ed to a new paragraph,
4345 determine the paragraph base direction. We
4346 need to do it now because
4347 next_element_from_buffer may not have a
4348 chance to do it, if we are going to skip any
4349 text at the beginning, which resets the
4350 FIRST_ELT flag. */
4351 bidi_paragraph_init (it->paragraph_embedding,
4352 &it->bidi_it, 1);
4356 bidi_move_to_visually_next (&it->bidi_it);
4358 while (it->stop_charpos <= it->bidi_it.charpos
4359 && it->bidi_it.charpos < newpos);
4360 IT_CHARPOS (*it) = it->bidi_it.charpos;
4361 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4362 /* If we overstepped NEWPOS, record its position in
4363 the iterator, so that we skip invisible text if
4364 later the bidi iteration lands us in the
4365 invisible region again. */
4366 if (IT_CHARPOS (*it) >= newpos)
4367 it->prev_stop = newpos;
4370 else
4372 IT_CHARPOS (*it) = newpos;
4373 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4376 /* If there are before-strings at the start of invisible
4377 text, and the text is invisible because of a text
4378 property, arrange to show before-strings because 20.x did
4379 it that way. (If the text is invisible because of an
4380 overlay property instead of a text property, this is
4381 already handled in the overlay code.) */
4382 if (NILP (overlay)
4383 && get_overlay_strings (it, it->stop_charpos))
4385 handled = HANDLED_RECOMPUTE_PROPS;
4386 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4388 else if (display_ellipsis_p)
4390 /* Make sure that the glyphs of the ellipsis will get
4391 correct `charpos' values. If we would not update
4392 it->position here, the glyphs would belong to the
4393 last visible character _before_ the invisible
4394 text, which confuses `set_cursor_from_row'.
4396 We use the last invisible position instead of the
4397 first because this way the cursor is always drawn on
4398 the first "." of the ellipsis, whenever PT is inside
4399 the invisible text. Otherwise the cursor would be
4400 placed _after_ the ellipsis when the point is after the
4401 first invisible character. */
4402 if (!STRINGP (it->object))
4404 it->position.charpos = newpos - 1;
4405 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4407 it->ellipsis_p = 1;
4408 /* Let the ellipsis display before
4409 considering any properties of the following char.
4410 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4411 handled = HANDLED_RETURN;
4416 return handled;
4420 /* Make iterator IT return `...' next.
4421 Replaces LEN characters from buffer. */
4423 static void
4424 setup_for_ellipsis (struct it *it, int len)
4426 /* Use the display table definition for `...'. Invalid glyphs
4427 will be handled by the method returning elements from dpvec. */
4428 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4430 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4431 it->dpvec = v->contents;
4432 it->dpend = v->contents + v->header.size;
4434 else
4436 /* Default `...'. */
4437 it->dpvec = default_invis_vector;
4438 it->dpend = default_invis_vector + 3;
4441 it->dpvec_char_len = len;
4442 it->current.dpvec_index = 0;
4443 it->dpvec_face_id = -1;
4445 /* Remember the current face id in case glyphs specify faces.
4446 IT's face is restored in set_iterator_to_next.
4447 saved_face_id was set to preceding char's face in handle_stop. */
4448 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4449 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4451 it->method = GET_FROM_DISPLAY_VECTOR;
4452 it->ellipsis_p = 1;
4457 /***********************************************************************
4458 'display' property
4459 ***********************************************************************/
4461 /* Set up iterator IT from `display' property at its current position.
4462 Called from handle_stop.
4463 We return HANDLED_RETURN if some part of the display property
4464 overrides the display of the buffer text itself.
4465 Otherwise we return HANDLED_NORMALLY. */
4467 static enum prop_handled
4468 handle_display_prop (struct it *it)
4470 Lisp_Object propval, object, overlay;
4471 struct text_pos *position;
4472 ptrdiff_t bufpos;
4473 /* Nonzero if some property replaces the display of the text itself. */
4474 int display_replaced_p = 0;
4476 if (STRINGP (it->string))
4478 object = it->string;
4479 position = &it->current.string_pos;
4480 bufpos = CHARPOS (it->current.pos);
4482 else
4484 XSETWINDOW (object, it->w);
4485 position = &it->current.pos;
4486 bufpos = CHARPOS (*position);
4489 /* Reset those iterator values set from display property values. */
4490 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4491 it->space_width = Qnil;
4492 it->font_height = Qnil;
4493 it->voffset = 0;
4495 /* We don't support recursive `display' properties, i.e. string
4496 values that have a string `display' property, that have a string
4497 `display' property etc. */
4498 if (!it->string_from_display_prop_p)
4499 it->area = TEXT_AREA;
4501 propval = get_char_property_and_overlay (make_number (position->charpos),
4502 Qdisplay, object, &overlay);
4503 if (NILP (propval))
4504 return HANDLED_NORMALLY;
4505 /* Now OVERLAY is the overlay that gave us this property, or nil
4506 if it was a text property. */
4508 if (!STRINGP (it->string))
4509 object = it->w->contents;
4511 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4512 position, bufpos,
4513 FRAME_WINDOW_P (it->f));
4515 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4518 /* Subroutine of handle_display_prop. Returns non-zero if the display
4519 specification in SPEC is a replacing specification, i.e. it would
4520 replace the text covered by `display' property with something else,
4521 such as an image or a display string. If SPEC includes any kind or
4522 `(space ...) specification, the value is 2; this is used by
4523 compute_display_string_pos, which see.
4525 See handle_single_display_spec for documentation of arguments.
4526 frame_window_p is non-zero if the window being redisplayed is on a
4527 GUI frame; this argument is used only if IT is NULL, see below.
4529 IT can be NULL, if this is called by the bidi reordering code
4530 through compute_display_string_pos, which see. In that case, this
4531 function only examines SPEC, but does not otherwise "handle" it, in
4532 the sense that it doesn't set up members of IT from the display
4533 spec. */
4534 static int
4535 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4536 Lisp_Object overlay, struct text_pos *position,
4537 ptrdiff_t bufpos, int frame_window_p)
4539 int replacing_p = 0;
4540 int rv;
4542 if (CONSP (spec)
4543 /* Simple specifications. */
4544 && !EQ (XCAR (spec), Qimage)
4545 && !EQ (XCAR (spec), Qspace)
4546 && !EQ (XCAR (spec), Qwhen)
4547 && !EQ (XCAR (spec), Qslice)
4548 && !EQ (XCAR (spec), Qspace_width)
4549 && !EQ (XCAR (spec), Qheight)
4550 && !EQ (XCAR (spec), Qraise)
4551 /* Marginal area specifications. */
4552 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4553 && !EQ (XCAR (spec), Qleft_fringe)
4554 && !EQ (XCAR (spec), Qright_fringe)
4555 && !NILP (XCAR (spec)))
4557 for (; CONSP (spec); spec = XCDR (spec))
4559 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4560 overlay, position, bufpos,
4561 replacing_p, frame_window_p)))
4563 replacing_p = rv;
4564 /* If some text in a string is replaced, `position' no
4565 longer points to the position of `object'. */
4566 if (!it || STRINGP (object))
4567 break;
4571 else if (VECTORP (spec))
4573 ptrdiff_t i;
4574 for (i = 0; i < ASIZE (spec); ++i)
4575 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4576 overlay, position, bufpos,
4577 replacing_p, frame_window_p)))
4579 replacing_p = rv;
4580 /* If some text in a string is replaced, `position' no
4581 longer points to the position of `object'. */
4582 if (!it || STRINGP (object))
4583 break;
4586 else
4588 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4589 position, bufpos, 0,
4590 frame_window_p)))
4591 replacing_p = rv;
4594 return replacing_p;
4597 /* Value is the position of the end of the `display' property starting
4598 at START_POS in OBJECT. */
4600 static struct text_pos
4601 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4603 Lisp_Object end;
4604 struct text_pos end_pos;
4606 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4607 Qdisplay, object, Qnil);
4608 CHARPOS (end_pos) = XFASTINT (end);
4609 if (STRINGP (object))
4610 compute_string_pos (&end_pos, start_pos, it->string);
4611 else
4612 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4614 return end_pos;
4618 /* Set up IT from a single `display' property specification SPEC. OBJECT
4619 is the object in which the `display' property was found. *POSITION
4620 is the position in OBJECT at which the `display' property was found.
4621 BUFPOS is the buffer position of OBJECT (different from POSITION if
4622 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4623 previously saw a display specification which already replaced text
4624 display with something else, for example an image; we ignore such
4625 properties after the first one has been processed.
4627 OVERLAY is the overlay this `display' property came from,
4628 or nil if it was a text property.
4630 If SPEC is a `space' or `image' specification, and in some other
4631 cases too, set *POSITION to the position where the `display'
4632 property ends.
4634 If IT is NULL, only examine the property specification in SPEC, but
4635 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4636 is intended to be displayed in a window on a GUI frame.
4638 Value is non-zero if something was found which replaces the display
4639 of buffer or string text. */
4641 static int
4642 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4643 Lisp_Object overlay, struct text_pos *position,
4644 ptrdiff_t bufpos, int display_replaced_p,
4645 int frame_window_p)
4647 Lisp_Object form;
4648 Lisp_Object location, value;
4649 struct text_pos start_pos = *position;
4650 int valid_p;
4652 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4653 If the result is non-nil, use VALUE instead of SPEC. */
4654 form = Qt;
4655 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4657 spec = XCDR (spec);
4658 if (!CONSP (spec))
4659 return 0;
4660 form = XCAR (spec);
4661 spec = XCDR (spec);
4664 if (!NILP (form) && !EQ (form, Qt))
4666 ptrdiff_t count = SPECPDL_INDEX ();
4667 struct gcpro gcpro1;
4669 /* Bind `object' to the object having the `display' property, a
4670 buffer or string. Bind `position' to the position in the
4671 object where the property was found, and `buffer-position'
4672 to the current position in the buffer. */
4674 if (NILP (object))
4675 XSETBUFFER (object, current_buffer);
4676 specbind (Qobject, object);
4677 specbind (Qposition, make_number (CHARPOS (*position)));
4678 specbind (Qbuffer_position, make_number (bufpos));
4679 GCPRO1 (form);
4680 form = safe_eval (form);
4681 UNGCPRO;
4682 unbind_to (count, Qnil);
4685 if (NILP (form))
4686 return 0;
4688 /* Handle `(height HEIGHT)' specifications. */
4689 if (CONSP (spec)
4690 && EQ (XCAR (spec), Qheight)
4691 && CONSP (XCDR (spec)))
4693 if (it)
4695 if (!FRAME_WINDOW_P (it->f))
4696 return 0;
4698 it->font_height = XCAR (XCDR (spec));
4699 if (!NILP (it->font_height))
4701 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4702 int new_height = -1;
4704 if (CONSP (it->font_height)
4705 && (EQ (XCAR (it->font_height), Qplus)
4706 || EQ (XCAR (it->font_height), Qminus))
4707 && CONSP (XCDR (it->font_height))
4708 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4710 /* `(+ N)' or `(- N)' where N is an integer. */
4711 int steps = XINT (XCAR (XCDR (it->font_height)));
4712 if (EQ (XCAR (it->font_height), Qplus))
4713 steps = - steps;
4714 it->face_id = smaller_face (it->f, it->face_id, steps);
4716 else if (FUNCTIONP (it->font_height))
4718 /* Call function with current height as argument.
4719 Value is the new height. */
4720 Lisp_Object height;
4721 height = safe_call1 (it->font_height,
4722 face->lface[LFACE_HEIGHT_INDEX]);
4723 if (NUMBERP (height))
4724 new_height = XFLOATINT (height);
4726 else if (NUMBERP (it->font_height))
4728 /* Value is a multiple of the canonical char height. */
4729 struct face *f;
4731 f = FACE_FROM_ID (it->f,
4732 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4733 new_height = (XFLOATINT (it->font_height)
4734 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4736 else
4738 /* Evaluate IT->font_height with `height' bound to the
4739 current specified height to get the new height. */
4740 ptrdiff_t count = SPECPDL_INDEX ();
4742 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4743 value = safe_eval (it->font_height);
4744 unbind_to (count, Qnil);
4746 if (NUMBERP (value))
4747 new_height = XFLOATINT (value);
4750 if (new_height > 0)
4751 it->face_id = face_with_height (it->f, it->face_id, new_height);
4755 return 0;
4758 /* Handle `(space-width WIDTH)'. */
4759 if (CONSP (spec)
4760 && EQ (XCAR (spec), Qspace_width)
4761 && CONSP (XCDR (spec)))
4763 if (it)
4765 if (!FRAME_WINDOW_P (it->f))
4766 return 0;
4768 value = XCAR (XCDR (spec));
4769 if (NUMBERP (value) && XFLOATINT (value) > 0)
4770 it->space_width = value;
4773 return 0;
4776 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4777 if (CONSP (spec)
4778 && EQ (XCAR (spec), Qslice))
4780 Lisp_Object tem;
4782 if (it)
4784 if (!FRAME_WINDOW_P (it->f))
4785 return 0;
4787 if (tem = XCDR (spec), CONSP (tem))
4789 it->slice.x = XCAR (tem);
4790 if (tem = XCDR (tem), CONSP (tem))
4792 it->slice.y = XCAR (tem);
4793 if (tem = XCDR (tem), CONSP (tem))
4795 it->slice.width = XCAR (tem);
4796 if (tem = XCDR (tem), CONSP (tem))
4797 it->slice.height = XCAR (tem);
4803 return 0;
4806 /* Handle `(raise FACTOR)'. */
4807 if (CONSP (spec)
4808 && EQ (XCAR (spec), Qraise)
4809 && CONSP (XCDR (spec)))
4811 if (it)
4813 if (!FRAME_WINDOW_P (it->f))
4814 return 0;
4816 #ifdef HAVE_WINDOW_SYSTEM
4817 value = XCAR (XCDR (spec));
4818 if (NUMBERP (value))
4820 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4821 it->voffset = - (XFLOATINT (value)
4822 * (FONT_HEIGHT (face->font)));
4824 #endif /* HAVE_WINDOW_SYSTEM */
4827 return 0;
4830 /* Don't handle the other kinds of display specifications
4831 inside a string that we got from a `display' property. */
4832 if (it && it->string_from_display_prop_p)
4833 return 0;
4835 /* Characters having this form of property are not displayed, so
4836 we have to find the end of the property. */
4837 if (it)
4839 start_pos = *position;
4840 *position = display_prop_end (it, object, start_pos);
4842 value = Qnil;
4844 /* Stop the scan at that end position--we assume that all
4845 text properties change there. */
4846 if (it)
4847 it->stop_charpos = position->charpos;
4849 /* Handle `(left-fringe BITMAP [FACE])'
4850 and `(right-fringe BITMAP [FACE])'. */
4851 if (CONSP (spec)
4852 && (EQ (XCAR (spec), Qleft_fringe)
4853 || EQ (XCAR (spec), Qright_fringe))
4854 && CONSP (XCDR (spec)))
4856 int fringe_bitmap;
4858 if (it)
4860 if (!FRAME_WINDOW_P (it->f))
4861 /* If we return here, POSITION has been advanced
4862 across the text with this property. */
4864 /* Synchronize the bidi iterator with POSITION. This is
4865 needed because we are not going to push the iterator
4866 on behalf of this display property, so there will be
4867 no pop_it call to do this synchronization for us. */
4868 if (it->bidi_p)
4870 it->position = *position;
4871 iterate_out_of_display_property (it);
4872 *position = it->position;
4874 return 1;
4877 else if (!frame_window_p)
4878 return 1;
4880 #ifdef HAVE_WINDOW_SYSTEM
4881 value = XCAR (XCDR (spec));
4882 if (!SYMBOLP (value)
4883 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4884 /* If we return here, POSITION has been advanced
4885 across the text with this property. */
4887 if (it && it->bidi_p)
4889 it->position = *position;
4890 iterate_out_of_display_property (it);
4891 *position = it->position;
4893 return 1;
4896 if (it)
4898 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4900 if (CONSP (XCDR (XCDR (spec))))
4902 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4903 int face_id2 = lookup_derived_face (it->f, face_name,
4904 FRINGE_FACE_ID, 0);
4905 if (face_id2 >= 0)
4906 face_id = face_id2;
4909 /* Save current settings of IT so that we can restore them
4910 when we are finished with the glyph property value. */
4911 push_it (it, position);
4913 it->area = TEXT_AREA;
4914 it->what = IT_IMAGE;
4915 it->image_id = -1; /* no image */
4916 it->position = start_pos;
4917 it->object = NILP (object) ? it->w->contents : object;
4918 it->method = GET_FROM_IMAGE;
4919 it->from_overlay = Qnil;
4920 it->face_id = face_id;
4921 it->from_disp_prop_p = 1;
4923 /* Say that we haven't consumed the characters with
4924 `display' property yet. The call to pop_it in
4925 set_iterator_to_next will clean this up. */
4926 *position = start_pos;
4928 if (EQ (XCAR (spec), Qleft_fringe))
4930 it->left_user_fringe_bitmap = fringe_bitmap;
4931 it->left_user_fringe_face_id = face_id;
4933 else
4935 it->right_user_fringe_bitmap = fringe_bitmap;
4936 it->right_user_fringe_face_id = face_id;
4939 #endif /* HAVE_WINDOW_SYSTEM */
4940 return 1;
4943 /* Prepare to handle `((margin left-margin) ...)',
4944 `((margin right-margin) ...)' and `((margin nil) ...)'
4945 prefixes for display specifications. */
4946 location = Qunbound;
4947 if (CONSP (spec) && CONSP (XCAR (spec)))
4949 Lisp_Object tem;
4951 value = XCDR (spec);
4952 if (CONSP (value))
4953 value = XCAR (value);
4955 tem = XCAR (spec);
4956 if (EQ (XCAR (tem), Qmargin)
4957 && (tem = XCDR (tem),
4958 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4959 (NILP (tem)
4960 || EQ (tem, Qleft_margin)
4961 || EQ (tem, Qright_margin))))
4962 location = tem;
4965 if (EQ (location, Qunbound))
4967 location = Qnil;
4968 value = spec;
4971 /* After this point, VALUE is the property after any
4972 margin prefix has been stripped. It must be a string,
4973 an image specification, or `(space ...)'.
4975 LOCATION specifies where to display: `left-margin',
4976 `right-margin' or nil. */
4978 valid_p = (STRINGP (value)
4979 #ifdef HAVE_WINDOW_SYSTEM
4980 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4981 && valid_image_p (value))
4982 #endif /* not HAVE_WINDOW_SYSTEM */
4983 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4985 if (valid_p && !display_replaced_p)
4987 int retval = 1;
4989 if (!it)
4991 /* Callers need to know whether the display spec is any kind
4992 of `(space ...)' spec that is about to affect text-area
4993 display. */
4994 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4995 retval = 2;
4996 return retval;
4999 /* Save current settings of IT so that we can restore them
5000 when we are finished with the glyph property value. */
5001 push_it (it, position);
5002 it->from_overlay = overlay;
5003 it->from_disp_prop_p = 1;
5005 if (NILP (location))
5006 it->area = TEXT_AREA;
5007 else if (EQ (location, Qleft_margin))
5008 it->area = LEFT_MARGIN_AREA;
5009 else
5010 it->area = RIGHT_MARGIN_AREA;
5012 if (STRINGP (value))
5014 it->string = value;
5015 it->multibyte_p = STRING_MULTIBYTE (it->string);
5016 it->current.overlay_string_index = -1;
5017 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5018 it->end_charpos = it->string_nchars = SCHARS (it->string);
5019 it->method = GET_FROM_STRING;
5020 it->stop_charpos = 0;
5021 it->prev_stop = 0;
5022 it->base_level_stop = 0;
5023 it->string_from_display_prop_p = 1;
5024 /* Say that we haven't consumed the characters with
5025 `display' property yet. The call to pop_it in
5026 set_iterator_to_next will clean this up. */
5027 if (BUFFERP (object))
5028 *position = start_pos;
5030 /* Force paragraph direction to be that of the parent
5031 object. If the parent object's paragraph direction is
5032 not yet determined, default to L2R. */
5033 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5034 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5035 else
5036 it->paragraph_embedding = L2R;
5038 /* Set up the bidi iterator for this display string. */
5039 if (it->bidi_p)
5041 it->bidi_it.string.lstring = it->string;
5042 it->bidi_it.string.s = NULL;
5043 it->bidi_it.string.schars = it->end_charpos;
5044 it->bidi_it.string.bufpos = bufpos;
5045 it->bidi_it.string.from_disp_str = 1;
5046 it->bidi_it.string.unibyte = !it->multibyte_p;
5047 it->bidi_it.w = it->w;
5048 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5051 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5053 it->method = GET_FROM_STRETCH;
5054 it->object = value;
5055 *position = it->position = start_pos;
5056 retval = 1 + (it->area == TEXT_AREA);
5058 #ifdef HAVE_WINDOW_SYSTEM
5059 else
5061 it->what = IT_IMAGE;
5062 it->image_id = lookup_image (it->f, value);
5063 it->position = start_pos;
5064 it->object = NILP (object) ? it->w->contents : object;
5065 it->method = GET_FROM_IMAGE;
5067 /* Say that we haven't consumed the characters with
5068 `display' property yet. The call to pop_it in
5069 set_iterator_to_next will clean this up. */
5070 *position = start_pos;
5072 #endif /* HAVE_WINDOW_SYSTEM */
5074 return retval;
5077 /* Invalid property or property not supported. Restore
5078 POSITION to what it was before. */
5079 *position = start_pos;
5080 return 0;
5083 /* Check if PROP is a display property value whose text should be
5084 treated as intangible. OVERLAY is the overlay from which PROP
5085 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5086 specify the buffer position covered by PROP. */
5089 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5090 ptrdiff_t charpos, ptrdiff_t bytepos)
5092 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5093 struct text_pos position;
5095 SET_TEXT_POS (position, charpos, bytepos);
5096 return handle_display_spec (NULL, prop, Qnil, overlay,
5097 &position, charpos, frame_window_p);
5101 /* Return 1 if PROP is a display sub-property value containing STRING.
5103 Implementation note: this and the following function are really
5104 special cases of handle_display_spec and
5105 handle_single_display_spec, and should ideally use the same code.
5106 Until they do, these two pairs must be consistent and must be
5107 modified in sync. */
5109 static int
5110 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5112 if (EQ (string, prop))
5113 return 1;
5115 /* Skip over `when FORM'. */
5116 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5118 prop = XCDR (prop);
5119 if (!CONSP (prop))
5120 return 0;
5121 /* Actually, the condition following `when' should be eval'ed,
5122 like handle_single_display_spec does, and we should return
5123 zero if it evaluates to nil. However, this function is
5124 called only when the buffer was already displayed and some
5125 glyph in the glyph matrix was found to come from a display
5126 string. Therefore, the condition was already evaluated, and
5127 the result was non-nil, otherwise the display string wouldn't
5128 have been displayed and we would have never been called for
5129 this property. Thus, we can skip the evaluation and assume
5130 its result is non-nil. */
5131 prop = XCDR (prop);
5134 if (CONSP (prop))
5135 /* Skip over `margin LOCATION'. */
5136 if (EQ (XCAR (prop), Qmargin))
5138 prop = XCDR (prop);
5139 if (!CONSP (prop))
5140 return 0;
5142 prop = XCDR (prop);
5143 if (!CONSP (prop))
5144 return 0;
5147 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5151 /* Return 1 if STRING appears in the `display' property PROP. */
5153 static int
5154 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5156 if (CONSP (prop)
5157 && !EQ (XCAR (prop), Qwhen)
5158 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5160 /* A list of sub-properties. */
5161 while (CONSP (prop))
5163 if (single_display_spec_string_p (XCAR (prop), string))
5164 return 1;
5165 prop = XCDR (prop);
5168 else if (VECTORP (prop))
5170 /* A vector of sub-properties. */
5171 ptrdiff_t i;
5172 for (i = 0; i < ASIZE (prop); ++i)
5173 if (single_display_spec_string_p (AREF (prop, i), string))
5174 return 1;
5176 else
5177 return single_display_spec_string_p (prop, string);
5179 return 0;
5182 /* Look for STRING in overlays and text properties in the current
5183 buffer, between character positions FROM and TO (excluding TO).
5184 BACK_P non-zero means look back (in this case, TO is supposed to be
5185 less than FROM).
5186 Value is the first character position where STRING was found, or
5187 zero if it wasn't found before hitting TO.
5189 This function may only use code that doesn't eval because it is
5190 called asynchronously from note_mouse_highlight. */
5192 static ptrdiff_t
5193 string_buffer_position_lim (Lisp_Object string,
5194 ptrdiff_t from, ptrdiff_t to, int back_p)
5196 Lisp_Object limit, prop, pos;
5197 int found = 0;
5199 pos = make_number (max (from, BEGV));
5201 if (!back_p) /* looking forward */
5203 limit = make_number (min (to, ZV));
5204 while (!found && !EQ (pos, limit))
5206 prop = Fget_char_property (pos, Qdisplay, Qnil);
5207 if (!NILP (prop) && display_prop_string_p (prop, string))
5208 found = 1;
5209 else
5210 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5211 limit);
5214 else /* looking back */
5216 limit = make_number (max (to, BEGV));
5217 while (!found && !EQ (pos, limit))
5219 prop = Fget_char_property (pos, Qdisplay, Qnil);
5220 if (!NILP (prop) && display_prop_string_p (prop, string))
5221 found = 1;
5222 else
5223 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5224 limit);
5228 return found ? XINT (pos) : 0;
5231 /* Determine which buffer position in current buffer STRING comes from.
5232 AROUND_CHARPOS is an approximate position where it could come from.
5233 Value is the buffer position or 0 if it couldn't be determined.
5235 This function is necessary because we don't record buffer positions
5236 in glyphs generated from strings (to keep struct glyph small).
5237 This function may only use code that doesn't eval because it is
5238 called asynchronously from note_mouse_highlight. */
5240 static ptrdiff_t
5241 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5243 const int MAX_DISTANCE = 1000;
5244 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5245 around_charpos + MAX_DISTANCE,
5248 if (!found)
5249 found = string_buffer_position_lim (string, around_charpos,
5250 around_charpos - MAX_DISTANCE, 1);
5251 return found;
5256 /***********************************************************************
5257 `composition' property
5258 ***********************************************************************/
5260 /* Set up iterator IT from `composition' property at its current
5261 position. Called from handle_stop. */
5263 static enum prop_handled
5264 handle_composition_prop (struct it *it)
5266 Lisp_Object prop, string;
5267 ptrdiff_t pos, pos_byte, start, end;
5269 if (STRINGP (it->string))
5271 unsigned char *s;
5273 pos = IT_STRING_CHARPOS (*it);
5274 pos_byte = IT_STRING_BYTEPOS (*it);
5275 string = it->string;
5276 s = SDATA (string) + pos_byte;
5277 it->c = STRING_CHAR (s);
5279 else
5281 pos = IT_CHARPOS (*it);
5282 pos_byte = IT_BYTEPOS (*it);
5283 string = Qnil;
5284 it->c = FETCH_CHAR (pos_byte);
5287 /* If there's a valid composition and point is not inside of the
5288 composition (in the case that the composition is from the current
5289 buffer), draw a glyph composed from the composition components. */
5290 if (find_composition (pos, -1, &start, &end, &prop, string)
5291 && COMPOSITION_VALID_P (start, end, prop)
5292 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5294 if (start < pos)
5295 /* As we can't handle this situation (perhaps font-lock added
5296 a new composition), we just return here hoping that next
5297 redisplay will detect this composition much earlier. */
5298 return HANDLED_NORMALLY;
5299 if (start != pos)
5301 if (STRINGP (it->string))
5302 pos_byte = string_char_to_byte (it->string, start);
5303 else
5304 pos_byte = CHAR_TO_BYTE (start);
5306 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5307 prop, string);
5309 if (it->cmp_it.id >= 0)
5311 it->cmp_it.ch = -1;
5312 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5313 it->cmp_it.nglyphs = -1;
5317 return HANDLED_NORMALLY;
5322 /***********************************************************************
5323 Overlay strings
5324 ***********************************************************************/
5326 /* The following structure is used to record overlay strings for
5327 later sorting in load_overlay_strings. */
5329 struct overlay_entry
5331 Lisp_Object overlay;
5332 Lisp_Object string;
5333 EMACS_INT priority;
5334 int after_string_p;
5338 /* Set up iterator IT from overlay strings at its current position.
5339 Called from handle_stop. */
5341 static enum prop_handled
5342 handle_overlay_change (struct it *it)
5344 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5345 return HANDLED_RECOMPUTE_PROPS;
5346 else
5347 return HANDLED_NORMALLY;
5351 /* Set up the next overlay string for delivery by IT, if there is an
5352 overlay string to deliver. Called by set_iterator_to_next when the
5353 end of the current overlay string is reached. If there are more
5354 overlay strings to display, IT->string and
5355 IT->current.overlay_string_index are set appropriately here.
5356 Otherwise IT->string is set to nil. */
5358 static void
5359 next_overlay_string (struct it *it)
5361 ++it->current.overlay_string_index;
5362 if (it->current.overlay_string_index == it->n_overlay_strings)
5364 /* No more overlay strings. Restore IT's settings to what
5365 they were before overlay strings were processed, and
5366 continue to deliver from current_buffer. */
5368 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5369 pop_it (it);
5370 eassert (it->sp > 0
5371 || (NILP (it->string)
5372 && it->method == GET_FROM_BUFFER
5373 && it->stop_charpos >= BEGV
5374 && it->stop_charpos <= it->end_charpos));
5375 it->current.overlay_string_index = -1;
5376 it->n_overlay_strings = 0;
5377 it->overlay_strings_charpos = -1;
5378 /* If there's an empty display string on the stack, pop the
5379 stack, to resync the bidi iterator with IT's position. Such
5380 empty strings are pushed onto the stack in
5381 get_overlay_strings_1. */
5382 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5383 pop_it (it);
5385 /* If we're at the end of the buffer, record that we have
5386 processed the overlay strings there already, so that
5387 next_element_from_buffer doesn't try it again. */
5388 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5389 it->overlay_strings_at_end_processed_p = 1;
5391 else
5393 /* There are more overlay strings to process. If
5394 IT->current.overlay_string_index has advanced to a position
5395 where we must load IT->overlay_strings with more strings, do
5396 it. We must load at the IT->overlay_strings_charpos where
5397 IT->n_overlay_strings was originally computed; when invisible
5398 text is present, this might not be IT_CHARPOS (Bug#7016). */
5399 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5401 if (it->current.overlay_string_index && i == 0)
5402 load_overlay_strings (it, it->overlay_strings_charpos);
5404 /* Initialize IT to deliver display elements from the overlay
5405 string. */
5406 it->string = it->overlay_strings[i];
5407 it->multibyte_p = STRING_MULTIBYTE (it->string);
5408 SET_TEXT_POS (it->current.string_pos, 0, 0);
5409 it->method = GET_FROM_STRING;
5410 it->stop_charpos = 0;
5411 it->end_charpos = SCHARS (it->string);
5412 if (it->cmp_it.stop_pos >= 0)
5413 it->cmp_it.stop_pos = 0;
5414 it->prev_stop = 0;
5415 it->base_level_stop = 0;
5417 /* Set up the bidi iterator for this overlay string. */
5418 if (it->bidi_p)
5420 it->bidi_it.string.lstring = it->string;
5421 it->bidi_it.string.s = NULL;
5422 it->bidi_it.string.schars = SCHARS (it->string);
5423 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5424 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5425 it->bidi_it.string.unibyte = !it->multibyte_p;
5426 it->bidi_it.w = it->w;
5427 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5431 CHECK_IT (it);
5435 /* Compare two overlay_entry structures E1 and E2. Used as a
5436 comparison function for qsort in load_overlay_strings. Overlay
5437 strings for the same position are sorted so that
5439 1. All after-strings come in front of before-strings, except
5440 when they come from the same overlay.
5442 2. Within after-strings, strings are sorted so that overlay strings
5443 from overlays with higher priorities come first.
5445 2. Within before-strings, strings are sorted so that overlay
5446 strings from overlays with higher priorities come last.
5448 Value is analogous to strcmp. */
5451 static int
5452 compare_overlay_entries (const void *e1, const void *e2)
5454 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5455 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5456 int result;
5458 if (entry1->after_string_p != entry2->after_string_p)
5460 /* Let after-strings appear in front of before-strings if
5461 they come from different overlays. */
5462 if (EQ (entry1->overlay, entry2->overlay))
5463 result = entry1->after_string_p ? 1 : -1;
5464 else
5465 result = entry1->after_string_p ? -1 : 1;
5467 else if (entry1->priority != entry2->priority)
5469 if (entry1->after_string_p)
5470 /* After-strings sorted in order of decreasing priority. */
5471 result = entry2->priority < entry1->priority ? -1 : 1;
5472 else
5473 /* Before-strings sorted in order of increasing priority. */
5474 result = entry1->priority < entry2->priority ? -1 : 1;
5476 else
5477 result = 0;
5479 return result;
5483 /* Load the vector IT->overlay_strings with overlay strings from IT's
5484 current buffer position, or from CHARPOS if that is > 0. Set
5485 IT->n_overlays to the total number of overlay strings found.
5487 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5488 a time. On entry into load_overlay_strings,
5489 IT->current.overlay_string_index gives the number of overlay
5490 strings that have already been loaded by previous calls to this
5491 function.
5493 IT->add_overlay_start contains an additional overlay start
5494 position to consider for taking overlay strings from, if non-zero.
5495 This position comes into play when the overlay has an `invisible'
5496 property, and both before and after-strings. When we've skipped to
5497 the end of the overlay, because of its `invisible' property, we
5498 nevertheless want its before-string to appear.
5499 IT->add_overlay_start will contain the overlay start position
5500 in this case.
5502 Overlay strings are sorted so that after-string strings come in
5503 front of before-string strings. Within before and after-strings,
5504 strings are sorted by overlay priority. See also function
5505 compare_overlay_entries. */
5507 static void
5508 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5510 Lisp_Object overlay, window, str, invisible;
5511 struct Lisp_Overlay *ov;
5512 ptrdiff_t start, end;
5513 ptrdiff_t size = 20;
5514 ptrdiff_t n = 0, i, j;
5515 int invis_p;
5516 struct overlay_entry *entries = alloca (size * sizeof *entries);
5517 USE_SAFE_ALLOCA;
5519 if (charpos <= 0)
5520 charpos = IT_CHARPOS (*it);
5522 /* Append the overlay string STRING of overlay OVERLAY to vector
5523 `entries' which has size `size' and currently contains `n'
5524 elements. AFTER_P non-zero means STRING is an after-string of
5525 OVERLAY. */
5526 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5527 do \
5529 Lisp_Object priority; \
5531 if (n == size) \
5533 struct overlay_entry *old = entries; \
5534 SAFE_NALLOCA (entries, 2, size); \
5535 memcpy (entries, old, size * sizeof *entries); \
5536 size *= 2; \
5539 entries[n].string = (STRING); \
5540 entries[n].overlay = (OVERLAY); \
5541 priority = Foverlay_get ((OVERLAY), Qpriority); \
5542 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5543 entries[n].after_string_p = (AFTER_P); \
5544 ++n; \
5546 while (0)
5548 /* Process overlay before the overlay center. */
5549 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5551 XSETMISC (overlay, ov);
5552 eassert (OVERLAYP (overlay));
5553 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5554 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5556 if (end < charpos)
5557 break;
5559 /* Skip this overlay if it doesn't start or end at IT's current
5560 position. */
5561 if (end != charpos && start != charpos)
5562 continue;
5564 /* Skip this overlay if it doesn't apply to IT->w. */
5565 window = Foverlay_get (overlay, Qwindow);
5566 if (WINDOWP (window) && XWINDOW (window) != it->w)
5567 continue;
5569 /* If the text ``under'' the overlay is invisible, both before-
5570 and after-strings from this overlay are visible; start and
5571 end position are indistinguishable. */
5572 invisible = Foverlay_get (overlay, Qinvisible);
5573 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5575 /* If overlay has a non-empty before-string, record it. */
5576 if ((start == charpos || (end == charpos && invis_p))
5577 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5578 && SCHARS (str))
5579 RECORD_OVERLAY_STRING (overlay, str, 0);
5581 /* If overlay has a non-empty after-string, record it. */
5582 if ((end == charpos || (start == charpos && invis_p))
5583 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5584 && SCHARS (str))
5585 RECORD_OVERLAY_STRING (overlay, str, 1);
5588 /* Process overlays after the overlay center. */
5589 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5591 XSETMISC (overlay, ov);
5592 eassert (OVERLAYP (overlay));
5593 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5594 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5596 if (start > charpos)
5597 break;
5599 /* Skip this overlay if it doesn't start or end at IT's current
5600 position. */
5601 if (end != charpos && start != charpos)
5602 continue;
5604 /* Skip this overlay if it doesn't apply to IT->w. */
5605 window = Foverlay_get (overlay, Qwindow);
5606 if (WINDOWP (window) && XWINDOW (window) != it->w)
5607 continue;
5609 /* If the text ``under'' the overlay is invisible, it has a zero
5610 dimension, and both before- and after-strings apply. */
5611 invisible = Foverlay_get (overlay, Qinvisible);
5612 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5614 /* If overlay has a non-empty before-string, record it. */
5615 if ((start == charpos || (end == charpos && invis_p))
5616 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5617 && SCHARS (str))
5618 RECORD_OVERLAY_STRING (overlay, str, 0);
5620 /* If overlay has a non-empty after-string, record it. */
5621 if ((end == charpos || (start == charpos && invis_p))
5622 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5623 && SCHARS (str))
5624 RECORD_OVERLAY_STRING (overlay, str, 1);
5627 #undef RECORD_OVERLAY_STRING
5629 /* Sort entries. */
5630 if (n > 1)
5631 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5633 /* Record number of overlay strings, and where we computed it. */
5634 it->n_overlay_strings = n;
5635 it->overlay_strings_charpos = charpos;
5637 /* IT->current.overlay_string_index is the number of overlay strings
5638 that have already been consumed by IT. Copy some of the
5639 remaining overlay strings to IT->overlay_strings. */
5640 i = 0;
5641 j = it->current.overlay_string_index;
5642 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5644 it->overlay_strings[i] = entries[j].string;
5645 it->string_overlays[i++] = entries[j++].overlay;
5648 CHECK_IT (it);
5649 SAFE_FREE ();
5653 /* Get the first chunk of overlay strings at IT's current buffer
5654 position, or at CHARPOS if that is > 0. Value is non-zero if at
5655 least one overlay string was found. */
5657 static int
5658 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5660 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5661 process. This fills IT->overlay_strings with strings, and sets
5662 IT->n_overlay_strings to the total number of strings to process.
5663 IT->pos.overlay_string_index has to be set temporarily to zero
5664 because load_overlay_strings needs this; it must be set to -1
5665 when no overlay strings are found because a zero value would
5666 indicate a position in the first overlay string. */
5667 it->current.overlay_string_index = 0;
5668 load_overlay_strings (it, charpos);
5670 /* If we found overlay strings, set up IT to deliver display
5671 elements from the first one. Otherwise set up IT to deliver
5672 from current_buffer. */
5673 if (it->n_overlay_strings)
5675 /* Make sure we know settings in current_buffer, so that we can
5676 restore meaningful values when we're done with the overlay
5677 strings. */
5678 if (compute_stop_p)
5679 compute_stop_pos (it);
5680 eassert (it->face_id >= 0);
5682 /* Save IT's settings. They are restored after all overlay
5683 strings have been processed. */
5684 eassert (!compute_stop_p || it->sp == 0);
5686 /* When called from handle_stop, there might be an empty display
5687 string loaded. In that case, don't bother saving it. But
5688 don't use this optimization with the bidi iterator, since we
5689 need the corresponding pop_it call to resync the bidi
5690 iterator's position with IT's position, after we are done
5691 with the overlay strings. (The corresponding call to pop_it
5692 in case of an empty display string is in
5693 next_overlay_string.) */
5694 if (!(!it->bidi_p
5695 && STRINGP (it->string) && !SCHARS (it->string)))
5696 push_it (it, NULL);
5698 /* Set up IT to deliver display elements from the first overlay
5699 string. */
5700 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5701 it->string = it->overlay_strings[0];
5702 it->from_overlay = Qnil;
5703 it->stop_charpos = 0;
5704 eassert (STRINGP (it->string));
5705 it->end_charpos = SCHARS (it->string);
5706 it->prev_stop = 0;
5707 it->base_level_stop = 0;
5708 it->multibyte_p = STRING_MULTIBYTE (it->string);
5709 it->method = GET_FROM_STRING;
5710 it->from_disp_prop_p = 0;
5712 /* Force paragraph direction to be that of the parent
5713 buffer. */
5714 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5715 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5716 else
5717 it->paragraph_embedding = L2R;
5719 /* Set up the bidi iterator for this overlay string. */
5720 if (it->bidi_p)
5722 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5724 it->bidi_it.string.lstring = it->string;
5725 it->bidi_it.string.s = NULL;
5726 it->bidi_it.string.schars = SCHARS (it->string);
5727 it->bidi_it.string.bufpos = pos;
5728 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5729 it->bidi_it.string.unibyte = !it->multibyte_p;
5730 it->bidi_it.w = it->w;
5731 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5733 return 1;
5736 it->current.overlay_string_index = -1;
5737 return 0;
5740 static int
5741 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5743 it->string = Qnil;
5744 it->method = GET_FROM_BUFFER;
5746 (void) get_overlay_strings_1 (it, charpos, 1);
5748 CHECK_IT (it);
5750 /* Value is non-zero if we found at least one overlay string. */
5751 return STRINGP (it->string);
5756 /***********************************************************************
5757 Saving and restoring state
5758 ***********************************************************************/
5760 /* Save current settings of IT on IT->stack. Called, for example,
5761 before setting up IT for an overlay string, to be able to restore
5762 IT's settings to what they were after the overlay string has been
5763 processed. If POSITION is non-NULL, it is the position to save on
5764 the stack instead of IT->position. */
5766 static void
5767 push_it (struct it *it, struct text_pos *position)
5769 struct iterator_stack_entry *p;
5771 eassert (it->sp < IT_STACK_SIZE);
5772 p = it->stack + it->sp;
5774 p->stop_charpos = it->stop_charpos;
5775 p->prev_stop = it->prev_stop;
5776 p->base_level_stop = it->base_level_stop;
5777 p->cmp_it = it->cmp_it;
5778 eassert (it->face_id >= 0);
5779 p->face_id = it->face_id;
5780 p->string = it->string;
5781 p->method = it->method;
5782 p->from_overlay = it->from_overlay;
5783 switch (p->method)
5785 case GET_FROM_IMAGE:
5786 p->u.image.object = it->object;
5787 p->u.image.image_id = it->image_id;
5788 p->u.image.slice = it->slice;
5789 break;
5790 case GET_FROM_STRETCH:
5791 p->u.stretch.object = it->object;
5792 break;
5794 p->position = position ? *position : it->position;
5795 p->current = it->current;
5796 p->end_charpos = it->end_charpos;
5797 p->string_nchars = it->string_nchars;
5798 p->area = it->area;
5799 p->multibyte_p = it->multibyte_p;
5800 p->avoid_cursor_p = it->avoid_cursor_p;
5801 p->space_width = it->space_width;
5802 p->font_height = it->font_height;
5803 p->voffset = it->voffset;
5804 p->string_from_display_prop_p = it->string_from_display_prop_p;
5805 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5806 p->display_ellipsis_p = 0;
5807 p->line_wrap = it->line_wrap;
5808 p->bidi_p = it->bidi_p;
5809 p->paragraph_embedding = it->paragraph_embedding;
5810 p->from_disp_prop_p = it->from_disp_prop_p;
5811 ++it->sp;
5813 /* Save the state of the bidi iterator as well. */
5814 if (it->bidi_p)
5815 bidi_push_it (&it->bidi_it);
5818 static void
5819 iterate_out_of_display_property (struct it *it)
5821 int buffer_p = !STRINGP (it->string);
5822 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5823 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5825 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5827 /* Maybe initialize paragraph direction. If we are at the beginning
5828 of a new paragraph, next_element_from_buffer may not have a
5829 chance to do that. */
5830 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5831 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5832 /* prev_stop can be zero, so check against BEGV as well. */
5833 while (it->bidi_it.charpos >= bob
5834 && it->prev_stop <= it->bidi_it.charpos
5835 && it->bidi_it.charpos < CHARPOS (it->position)
5836 && it->bidi_it.charpos < eob)
5837 bidi_move_to_visually_next (&it->bidi_it);
5838 /* Record the stop_pos we just crossed, for when we cross it
5839 back, maybe. */
5840 if (it->bidi_it.charpos > CHARPOS (it->position))
5841 it->prev_stop = CHARPOS (it->position);
5842 /* If we ended up not where pop_it put us, resync IT's
5843 positional members with the bidi iterator. */
5844 if (it->bidi_it.charpos != CHARPOS (it->position))
5845 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5846 if (buffer_p)
5847 it->current.pos = it->position;
5848 else
5849 it->current.string_pos = it->position;
5852 /* Restore IT's settings from IT->stack. Called, for example, when no
5853 more overlay strings must be processed, and we return to delivering
5854 display elements from a buffer, or when the end of a string from a
5855 `display' property is reached and we return to delivering display
5856 elements from an overlay string, or from a buffer. */
5858 static void
5859 pop_it (struct it *it)
5861 struct iterator_stack_entry *p;
5862 int from_display_prop = it->from_disp_prop_p;
5864 eassert (it->sp > 0);
5865 --it->sp;
5866 p = it->stack + it->sp;
5867 it->stop_charpos = p->stop_charpos;
5868 it->prev_stop = p->prev_stop;
5869 it->base_level_stop = p->base_level_stop;
5870 it->cmp_it = p->cmp_it;
5871 it->face_id = p->face_id;
5872 it->current = p->current;
5873 it->position = p->position;
5874 it->string = p->string;
5875 it->from_overlay = p->from_overlay;
5876 if (NILP (it->string))
5877 SET_TEXT_POS (it->current.string_pos, -1, -1);
5878 it->method = p->method;
5879 switch (it->method)
5881 case GET_FROM_IMAGE:
5882 it->image_id = p->u.image.image_id;
5883 it->object = p->u.image.object;
5884 it->slice = p->u.image.slice;
5885 break;
5886 case GET_FROM_STRETCH:
5887 it->object = p->u.stretch.object;
5888 break;
5889 case GET_FROM_BUFFER:
5890 it->object = it->w->contents;
5891 break;
5892 case GET_FROM_STRING:
5893 it->object = it->string;
5894 break;
5895 case GET_FROM_DISPLAY_VECTOR:
5896 if (it->s)
5897 it->method = GET_FROM_C_STRING;
5898 else if (STRINGP (it->string))
5899 it->method = GET_FROM_STRING;
5900 else
5902 it->method = GET_FROM_BUFFER;
5903 it->object = it->w->contents;
5906 it->end_charpos = p->end_charpos;
5907 it->string_nchars = p->string_nchars;
5908 it->area = p->area;
5909 it->multibyte_p = p->multibyte_p;
5910 it->avoid_cursor_p = p->avoid_cursor_p;
5911 it->space_width = p->space_width;
5912 it->font_height = p->font_height;
5913 it->voffset = p->voffset;
5914 it->string_from_display_prop_p = p->string_from_display_prop_p;
5915 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5916 it->line_wrap = p->line_wrap;
5917 it->bidi_p = p->bidi_p;
5918 it->paragraph_embedding = p->paragraph_embedding;
5919 it->from_disp_prop_p = p->from_disp_prop_p;
5920 if (it->bidi_p)
5922 bidi_pop_it (&it->bidi_it);
5923 /* Bidi-iterate until we get out of the portion of text, if any,
5924 covered by a `display' text property or by an overlay with
5925 `display' property. (We cannot just jump there, because the
5926 internal coherency of the bidi iterator state can not be
5927 preserved across such jumps.) We also must determine the
5928 paragraph base direction if the overlay we just processed is
5929 at the beginning of a new paragraph. */
5930 if (from_display_prop
5931 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5932 iterate_out_of_display_property (it);
5934 eassert ((BUFFERP (it->object)
5935 && IT_CHARPOS (*it) == it->bidi_it.charpos
5936 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5937 || (STRINGP (it->object)
5938 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5939 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5940 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5946 /***********************************************************************
5947 Moving over lines
5948 ***********************************************************************/
5950 /* Set IT's current position to the previous line start. */
5952 static void
5953 back_to_previous_line_start (struct it *it)
5955 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
5957 DEC_BOTH (cp, bp);
5958 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
5962 /* Move IT to the next line start.
5964 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5965 we skipped over part of the text (as opposed to moving the iterator
5966 continuously over the text). Otherwise, don't change the value
5967 of *SKIPPED_P.
5969 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5970 iterator on the newline, if it was found.
5972 Newlines may come from buffer text, overlay strings, or strings
5973 displayed via the `display' property. That's the reason we can't
5974 simply use find_newline_no_quit.
5976 Note that this function may not skip over invisible text that is so
5977 because of text properties and immediately follows a newline. If
5978 it would, function reseat_at_next_visible_line_start, when called
5979 from set_iterator_to_next, would effectively make invisible
5980 characters following a newline part of the wrong glyph row, which
5981 leads to wrong cursor motion. */
5983 static int
5984 forward_to_next_line_start (struct it *it, int *skipped_p,
5985 struct bidi_it *bidi_it_prev)
5987 ptrdiff_t old_selective;
5988 int newline_found_p, n;
5989 const int MAX_NEWLINE_DISTANCE = 500;
5991 /* If already on a newline, just consume it to avoid unintended
5992 skipping over invisible text below. */
5993 if (it->what == IT_CHARACTER
5994 && it->c == '\n'
5995 && CHARPOS (it->position) == IT_CHARPOS (*it))
5997 if (it->bidi_p && bidi_it_prev)
5998 *bidi_it_prev = it->bidi_it;
5999 set_iterator_to_next (it, 0);
6000 it->c = 0;
6001 return 1;
6004 /* Don't handle selective display in the following. It's (a)
6005 unnecessary because it's done by the caller, and (b) leads to an
6006 infinite recursion because next_element_from_ellipsis indirectly
6007 calls this function. */
6008 old_selective = it->selective;
6009 it->selective = 0;
6011 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6012 from buffer text. */
6013 for (n = newline_found_p = 0;
6014 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6015 n += STRINGP (it->string) ? 0 : 1)
6017 if (!get_next_display_element (it))
6018 return 0;
6019 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6020 if (newline_found_p && it->bidi_p && bidi_it_prev)
6021 *bidi_it_prev = it->bidi_it;
6022 set_iterator_to_next (it, 0);
6025 /* If we didn't find a newline near enough, see if we can use a
6026 short-cut. */
6027 if (!newline_found_p)
6029 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6030 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6031 1, &bytepos);
6032 Lisp_Object pos;
6034 eassert (!STRINGP (it->string));
6036 /* If there isn't any `display' property in sight, and no
6037 overlays, we can just use the position of the newline in
6038 buffer text. */
6039 if (it->stop_charpos >= limit
6040 || ((pos = Fnext_single_property_change (make_number (start),
6041 Qdisplay, Qnil,
6042 make_number (limit)),
6043 NILP (pos))
6044 && next_overlay_change (start) == ZV))
6046 if (!it->bidi_p)
6048 IT_CHARPOS (*it) = limit;
6049 IT_BYTEPOS (*it) = bytepos;
6051 else
6053 struct bidi_it bprev;
6055 /* Help bidi.c avoid expensive searches for display
6056 properties and overlays, by telling it that there are
6057 none up to `limit'. */
6058 if (it->bidi_it.disp_pos < limit)
6060 it->bidi_it.disp_pos = limit;
6061 it->bidi_it.disp_prop = 0;
6063 do {
6064 bprev = it->bidi_it;
6065 bidi_move_to_visually_next (&it->bidi_it);
6066 } while (it->bidi_it.charpos != limit);
6067 IT_CHARPOS (*it) = limit;
6068 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6069 if (bidi_it_prev)
6070 *bidi_it_prev = bprev;
6072 *skipped_p = newline_found_p = 1;
6074 else
6076 while (get_next_display_element (it)
6077 && !newline_found_p)
6079 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6080 if (newline_found_p && it->bidi_p && bidi_it_prev)
6081 *bidi_it_prev = it->bidi_it;
6082 set_iterator_to_next (it, 0);
6087 it->selective = old_selective;
6088 return newline_found_p;
6092 /* Set IT's current position to the previous visible line start. Skip
6093 invisible text that is so either due to text properties or due to
6094 selective display. Caution: this does not change IT->current_x and
6095 IT->hpos. */
6097 static void
6098 back_to_previous_visible_line_start (struct it *it)
6100 while (IT_CHARPOS (*it) > BEGV)
6102 back_to_previous_line_start (it);
6104 if (IT_CHARPOS (*it) <= BEGV)
6105 break;
6107 /* If selective > 0, then lines indented more than its value are
6108 invisible. */
6109 if (it->selective > 0
6110 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6111 it->selective))
6112 continue;
6114 /* Check the newline before point for invisibility. */
6116 Lisp_Object prop;
6117 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6118 Qinvisible, it->window);
6119 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6120 continue;
6123 if (IT_CHARPOS (*it) <= BEGV)
6124 break;
6127 struct it it2;
6128 void *it2data = NULL;
6129 ptrdiff_t pos;
6130 ptrdiff_t beg, end;
6131 Lisp_Object val, overlay;
6133 SAVE_IT (it2, *it, it2data);
6135 /* If newline is part of a composition, continue from start of composition */
6136 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6137 && beg < IT_CHARPOS (*it))
6138 goto replaced;
6140 /* If newline is replaced by a display property, find start of overlay
6141 or interval and continue search from that point. */
6142 pos = --IT_CHARPOS (it2);
6143 --IT_BYTEPOS (it2);
6144 it2.sp = 0;
6145 bidi_unshelve_cache (NULL, 0);
6146 it2.string_from_display_prop_p = 0;
6147 it2.from_disp_prop_p = 0;
6148 if (handle_display_prop (&it2) == HANDLED_RETURN
6149 && !NILP (val = get_char_property_and_overlay
6150 (make_number (pos), Qdisplay, Qnil, &overlay))
6151 && (OVERLAYP (overlay)
6152 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6153 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6155 RESTORE_IT (it, it, it2data);
6156 goto replaced;
6159 /* Newline is not replaced by anything -- so we are done. */
6160 RESTORE_IT (it, it, it2data);
6161 break;
6163 replaced:
6164 if (beg < BEGV)
6165 beg = BEGV;
6166 IT_CHARPOS (*it) = beg;
6167 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6171 it->continuation_lines_width = 0;
6173 eassert (IT_CHARPOS (*it) >= BEGV);
6174 eassert (IT_CHARPOS (*it) == BEGV
6175 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6176 CHECK_IT (it);
6180 /* Reseat iterator IT at the previous visible line start. Skip
6181 invisible text that is so either due to text properties or due to
6182 selective display. At the end, update IT's overlay information,
6183 face information etc. */
6185 void
6186 reseat_at_previous_visible_line_start (struct it *it)
6188 back_to_previous_visible_line_start (it);
6189 reseat (it, it->current.pos, 1);
6190 CHECK_IT (it);
6194 /* Reseat iterator IT on the next visible line start in the current
6195 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6196 preceding the line start. Skip over invisible text that is so
6197 because of selective display. Compute faces, overlays etc at the
6198 new position. Note that this function does not skip over text that
6199 is invisible because of text properties. */
6201 static void
6202 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6204 int newline_found_p, skipped_p = 0;
6205 struct bidi_it bidi_it_prev;
6207 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6209 /* Skip over lines that are invisible because they are indented
6210 more than the value of IT->selective. */
6211 if (it->selective > 0)
6212 while (IT_CHARPOS (*it) < ZV
6213 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6214 it->selective))
6216 eassert (IT_BYTEPOS (*it) == BEGV
6217 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6218 newline_found_p =
6219 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6222 /* Position on the newline if that's what's requested. */
6223 if (on_newline_p && newline_found_p)
6225 if (STRINGP (it->string))
6227 if (IT_STRING_CHARPOS (*it) > 0)
6229 if (!it->bidi_p)
6231 --IT_STRING_CHARPOS (*it);
6232 --IT_STRING_BYTEPOS (*it);
6234 else
6236 /* We need to restore the bidi iterator to the state
6237 it had on the newline, and resync the IT's
6238 position with that. */
6239 it->bidi_it = bidi_it_prev;
6240 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6241 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6245 else if (IT_CHARPOS (*it) > BEGV)
6247 if (!it->bidi_p)
6249 --IT_CHARPOS (*it);
6250 --IT_BYTEPOS (*it);
6252 else
6254 /* We need to restore the bidi iterator to the state it
6255 had on the newline and resync IT with that. */
6256 it->bidi_it = bidi_it_prev;
6257 IT_CHARPOS (*it) = it->bidi_it.charpos;
6258 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6260 reseat (it, it->current.pos, 0);
6263 else if (skipped_p)
6264 reseat (it, it->current.pos, 0);
6266 CHECK_IT (it);
6271 /***********************************************************************
6272 Changing an iterator's position
6273 ***********************************************************************/
6275 /* Change IT's current position to POS in current_buffer. If FORCE_P
6276 is non-zero, always check for text properties at the new position.
6277 Otherwise, text properties are only looked up if POS >=
6278 IT->check_charpos of a property. */
6280 static void
6281 reseat (struct it *it, struct text_pos pos, int force_p)
6283 ptrdiff_t original_pos = IT_CHARPOS (*it);
6285 reseat_1 (it, pos, 0);
6287 /* Determine where to check text properties. Avoid doing it
6288 where possible because text property lookup is very expensive. */
6289 if (force_p
6290 || CHARPOS (pos) > it->stop_charpos
6291 || CHARPOS (pos) < original_pos)
6293 if (it->bidi_p)
6295 /* For bidi iteration, we need to prime prev_stop and
6296 base_level_stop with our best estimations. */
6297 /* Implementation note: Of course, POS is not necessarily a
6298 stop position, so assigning prev_pos to it is a lie; we
6299 should have called compute_stop_backwards. However, if
6300 the current buffer does not include any R2L characters,
6301 that call would be a waste of cycles, because the
6302 iterator will never move back, and thus never cross this
6303 "fake" stop position. So we delay that backward search
6304 until the time we really need it, in next_element_from_buffer. */
6305 if (CHARPOS (pos) != it->prev_stop)
6306 it->prev_stop = CHARPOS (pos);
6307 if (CHARPOS (pos) < it->base_level_stop)
6308 it->base_level_stop = 0; /* meaning it's unknown */
6309 handle_stop (it);
6311 else
6313 handle_stop (it);
6314 it->prev_stop = it->base_level_stop = 0;
6319 CHECK_IT (it);
6323 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6324 IT->stop_pos to POS, also. */
6326 static void
6327 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6329 /* Don't call this function when scanning a C string. */
6330 eassert (it->s == NULL);
6332 /* POS must be a reasonable value. */
6333 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6335 it->current.pos = it->position = pos;
6336 it->end_charpos = ZV;
6337 it->dpvec = NULL;
6338 it->current.dpvec_index = -1;
6339 it->current.overlay_string_index = -1;
6340 IT_STRING_CHARPOS (*it) = -1;
6341 IT_STRING_BYTEPOS (*it) = -1;
6342 it->string = Qnil;
6343 it->method = GET_FROM_BUFFER;
6344 it->object = it->w->contents;
6345 it->area = TEXT_AREA;
6346 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6347 it->sp = 0;
6348 it->string_from_display_prop_p = 0;
6349 it->string_from_prefix_prop_p = 0;
6351 it->from_disp_prop_p = 0;
6352 it->face_before_selective_p = 0;
6353 if (it->bidi_p)
6355 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6356 &it->bidi_it);
6357 bidi_unshelve_cache (NULL, 0);
6358 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6359 it->bidi_it.string.s = NULL;
6360 it->bidi_it.string.lstring = Qnil;
6361 it->bidi_it.string.bufpos = 0;
6362 it->bidi_it.string.unibyte = 0;
6363 it->bidi_it.w = it->w;
6366 if (set_stop_p)
6368 it->stop_charpos = CHARPOS (pos);
6369 it->base_level_stop = CHARPOS (pos);
6371 /* This make the information stored in it->cmp_it invalidate. */
6372 it->cmp_it.id = -1;
6376 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6377 If S is non-null, it is a C string to iterate over. Otherwise,
6378 STRING gives a Lisp string to iterate over.
6380 If PRECISION > 0, don't return more then PRECISION number of
6381 characters from the string.
6383 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6384 characters have been returned. FIELD_WIDTH < 0 means an infinite
6385 field width.
6387 MULTIBYTE = 0 means disable processing of multibyte characters,
6388 MULTIBYTE > 0 means enable it,
6389 MULTIBYTE < 0 means use IT->multibyte_p.
6391 IT must be initialized via a prior call to init_iterator before
6392 calling this function. */
6394 static void
6395 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6396 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6397 int multibyte)
6399 /* No region in strings. */
6400 it->region_beg_charpos = it->region_end_charpos = -1;
6402 /* No text property checks performed by default, but see below. */
6403 it->stop_charpos = -1;
6405 /* Set iterator position and end position. */
6406 memset (&it->current, 0, sizeof it->current);
6407 it->current.overlay_string_index = -1;
6408 it->current.dpvec_index = -1;
6409 eassert (charpos >= 0);
6411 /* If STRING is specified, use its multibyteness, otherwise use the
6412 setting of MULTIBYTE, if specified. */
6413 if (multibyte >= 0)
6414 it->multibyte_p = multibyte > 0;
6416 /* Bidirectional reordering of strings is controlled by the default
6417 value of bidi-display-reordering. Don't try to reorder while
6418 loading loadup.el, as the necessary character property tables are
6419 not yet available. */
6420 it->bidi_p =
6421 NILP (Vpurify_flag)
6422 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6424 if (s == NULL)
6426 eassert (STRINGP (string));
6427 it->string = string;
6428 it->s = NULL;
6429 it->end_charpos = it->string_nchars = SCHARS (string);
6430 it->method = GET_FROM_STRING;
6431 it->current.string_pos = string_pos (charpos, string);
6433 if (it->bidi_p)
6435 it->bidi_it.string.lstring = string;
6436 it->bidi_it.string.s = NULL;
6437 it->bidi_it.string.schars = it->end_charpos;
6438 it->bidi_it.string.bufpos = 0;
6439 it->bidi_it.string.from_disp_str = 0;
6440 it->bidi_it.string.unibyte = !it->multibyte_p;
6441 it->bidi_it.w = it->w;
6442 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6443 FRAME_WINDOW_P (it->f), &it->bidi_it);
6446 else
6448 it->s = (const unsigned char *) s;
6449 it->string = Qnil;
6451 /* Note that we use IT->current.pos, not it->current.string_pos,
6452 for displaying C strings. */
6453 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6454 if (it->multibyte_p)
6456 it->current.pos = c_string_pos (charpos, s, 1);
6457 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6459 else
6461 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6462 it->end_charpos = it->string_nchars = strlen (s);
6465 if (it->bidi_p)
6467 it->bidi_it.string.lstring = Qnil;
6468 it->bidi_it.string.s = (const unsigned char *) s;
6469 it->bidi_it.string.schars = it->end_charpos;
6470 it->bidi_it.string.bufpos = 0;
6471 it->bidi_it.string.from_disp_str = 0;
6472 it->bidi_it.string.unibyte = !it->multibyte_p;
6473 it->bidi_it.w = it->w;
6474 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6475 &it->bidi_it);
6477 it->method = GET_FROM_C_STRING;
6480 /* PRECISION > 0 means don't return more than PRECISION characters
6481 from the string. */
6482 if (precision > 0 && it->end_charpos - charpos > precision)
6484 it->end_charpos = it->string_nchars = charpos + precision;
6485 if (it->bidi_p)
6486 it->bidi_it.string.schars = it->end_charpos;
6489 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6490 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6491 FIELD_WIDTH < 0 means infinite field width. This is useful for
6492 padding with `-' at the end of a mode line. */
6493 if (field_width < 0)
6494 field_width = INFINITY;
6495 /* Implementation note: We deliberately don't enlarge
6496 it->bidi_it.string.schars here to fit it->end_charpos, because
6497 the bidi iterator cannot produce characters out of thin air. */
6498 if (field_width > it->end_charpos - charpos)
6499 it->end_charpos = charpos + field_width;
6501 /* Use the standard display table for displaying strings. */
6502 if (DISP_TABLE_P (Vstandard_display_table))
6503 it->dp = XCHAR_TABLE (Vstandard_display_table);
6505 it->stop_charpos = charpos;
6506 it->prev_stop = charpos;
6507 it->base_level_stop = 0;
6508 if (it->bidi_p)
6510 it->bidi_it.first_elt = 1;
6511 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6512 it->bidi_it.disp_pos = -1;
6514 if (s == NULL && it->multibyte_p)
6516 ptrdiff_t endpos = SCHARS (it->string);
6517 if (endpos > it->end_charpos)
6518 endpos = it->end_charpos;
6519 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6520 it->string);
6522 CHECK_IT (it);
6527 /***********************************************************************
6528 Iteration
6529 ***********************************************************************/
6531 /* Map enum it_method value to corresponding next_element_from_* function. */
6533 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6535 next_element_from_buffer,
6536 next_element_from_display_vector,
6537 next_element_from_string,
6538 next_element_from_c_string,
6539 next_element_from_image,
6540 next_element_from_stretch
6543 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6546 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6547 (possibly with the following characters). */
6549 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6550 ((IT)->cmp_it.id >= 0 \
6551 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6552 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6553 END_CHARPOS, (IT)->w, \
6554 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6555 (IT)->string)))
6558 /* Lookup the char-table Vglyphless_char_display for character C (-1
6559 if we want information for no-font case), and return the display
6560 method symbol. By side-effect, update it->what and
6561 it->glyphless_method. This function is called from
6562 get_next_display_element for each character element, and from
6563 x_produce_glyphs when no suitable font was found. */
6565 Lisp_Object
6566 lookup_glyphless_char_display (int c, struct it *it)
6568 Lisp_Object glyphless_method = Qnil;
6570 if (CHAR_TABLE_P (Vglyphless_char_display)
6571 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6573 if (c >= 0)
6575 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6576 if (CONSP (glyphless_method))
6577 glyphless_method = FRAME_WINDOW_P (it->f)
6578 ? XCAR (glyphless_method)
6579 : XCDR (glyphless_method);
6581 else
6582 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6585 retry:
6586 if (NILP (glyphless_method))
6588 if (c >= 0)
6589 /* The default is to display the character by a proper font. */
6590 return Qnil;
6591 /* The default for the no-font case is to display an empty box. */
6592 glyphless_method = Qempty_box;
6594 if (EQ (glyphless_method, Qzero_width))
6596 if (c >= 0)
6597 return glyphless_method;
6598 /* This method can't be used for the no-font case. */
6599 glyphless_method = Qempty_box;
6601 if (EQ (glyphless_method, Qthin_space))
6602 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6603 else if (EQ (glyphless_method, Qempty_box))
6604 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6605 else if (EQ (glyphless_method, Qhex_code))
6606 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6607 else if (STRINGP (glyphless_method))
6608 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6609 else
6611 /* Invalid value. We use the default method. */
6612 glyphless_method = Qnil;
6613 goto retry;
6615 it->what = IT_GLYPHLESS;
6616 return glyphless_method;
6619 /* Load IT's display element fields with information about the next
6620 display element from the current position of IT. Value is zero if
6621 end of buffer (or C string) is reached. */
6623 static struct frame *last_escape_glyph_frame = NULL;
6624 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6625 static int last_escape_glyph_merged_face_id = 0;
6627 struct frame *last_glyphless_glyph_frame = NULL;
6628 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6629 int last_glyphless_glyph_merged_face_id = 0;
6631 static int
6632 get_next_display_element (struct it *it)
6634 /* Non-zero means that we found a display element. Zero means that
6635 we hit the end of what we iterate over. Performance note: the
6636 function pointer `method' used here turns out to be faster than
6637 using a sequence of if-statements. */
6638 int success_p;
6640 get_next:
6641 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6643 if (it->what == IT_CHARACTER)
6645 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6646 and only if (a) the resolved directionality of that character
6647 is R..." */
6648 /* FIXME: Do we need an exception for characters from display
6649 tables? */
6650 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6651 it->c = bidi_mirror_char (it->c);
6652 /* Map via display table or translate control characters.
6653 IT->c, IT->len etc. have been set to the next character by
6654 the function call above. If we have a display table, and it
6655 contains an entry for IT->c, translate it. Don't do this if
6656 IT->c itself comes from a display table, otherwise we could
6657 end up in an infinite recursion. (An alternative could be to
6658 count the recursion depth of this function and signal an
6659 error when a certain maximum depth is reached.) Is it worth
6660 it? */
6661 if (success_p && it->dpvec == NULL)
6663 Lisp_Object dv;
6664 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6665 int nonascii_space_p = 0;
6666 int nonascii_hyphen_p = 0;
6667 int c = it->c; /* This is the character to display. */
6669 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6671 eassert (SINGLE_BYTE_CHAR_P (c));
6672 if (unibyte_display_via_language_environment)
6674 c = DECODE_CHAR (unibyte, c);
6675 if (c < 0)
6676 c = BYTE8_TO_CHAR (it->c);
6678 else
6679 c = BYTE8_TO_CHAR (it->c);
6682 if (it->dp
6683 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6684 VECTORP (dv)))
6686 struct Lisp_Vector *v = XVECTOR (dv);
6688 /* Return the first character from the display table
6689 entry, if not empty. If empty, don't display the
6690 current character. */
6691 if (v->header.size)
6693 it->dpvec_char_len = it->len;
6694 it->dpvec = v->contents;
6695 it->dpend = v->contents + v->header.size;
6696 it->current.dpvec_index = 0;
6697 it->dpvec_face_id = -1;
6698 it->saved_face_id = it->face_id;
6699 it->method = GET_FROM_DISPLAY_VECTOR;
6700 it->ellipsis_p = 0;
6702 else
6704 set_iterator_to_next (it, 0);
6706 goto get_next;
6709 if (! NILP (lookup_glyphless_char_display (c, it)))
6711 if (it->what == IT_GLYPHLESS)
6712 goto done;
6713 /* Don't display this character. */
6714 set_iterator_to_next (it, 0);
6715 goto get_next;
6718 /* If `nobreak-char-display' is non-nil, we display
6719 non-ASCII spaces and hyphens specially. */
6720 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6722 if (c == 0xA0)
6723 nonascii_space_p = 1;
6724 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6725 nonascii_hyphen_p = 1;
6728 /* Translate control characters into `\003' or `^C' form.
6729 Control characters coming from a display table entry are
6730 currently not translated because we use IT->dpvec to hold
6731 the translation. This could easily be changed but I
6732 don't believe that it is worth doing.
6734 The characters handled by `nobreak-char-display' must be
6735 translated too.
6737 Non-printable characters and raw-byte characters are also
6738 translated to octal form. */
6739 if (((c < ' ' || c == 127) /* ASCII control chars */
6740 ? (it->area != TEXT_AREA
6741 /* In mode line, treat \n, \t like other crl chars. */
6742 || (c != '\t'
6743 && it->glyph_row
6744 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6745 || (c != '\n' && c != '\t'))
6746 : (nonascii_space_p
6747 || nonascii_hyphen_p
6748 || CHAR_BYTE8_P (c)
6749 || ! CHAR_PRINTABLE_P (c))))
6751 /* C is a control character, non-ASCII space/hyphen,
6752 raw-byte, or a non-printable character which must be
6753 displayed either as '\003' or as `^C' where the '\\'
6754 and '^' can be defined in the display table. Fill
6755 IT->ctl_chars with glyphs for what we have to
6756 display. Then, set IT->dpvec to these glyphs. */
6757 Lisp_Object gc;
6758 int ctl_len;
6759 int face_id;
6760 int lface_id = 0;
6761 int escape_glyph;
6763 /* Handle control characters with ^. */
6765 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6767 int g;
6769 g = '^'; /* default glyph for Control */
6770 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6771 if (it->dp
6772 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6774 g = GLYPH_CODE_CHAR (gc);
6775 lface_id = GLYPH_CODE_FACE (gc);
6777 if (lface_id)
6779 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6781 else if (it->f == last_escape_glyph_frame
6782 && it->face_id == last_escape_glyph_face_id)
6784 face_id = last_escape_glyph_merged_face_id;
6786 else
6788 /* Merge the escape-glyph face into the current face. */
6789 face_id = merge_faces (it->f, Qescape_glyph, 0,
6790 it->face_id);
6791 last_escape_glyph_frame = it->f;
6792 last_escape_glyph_face_id = it->face_id;
6793 last_escape_glyph_merged_face_id = face_id;
6796 XSETINT (it->ctl_chars[0], g);
6797 XSETINT (it->ctl_chars[1], c ^ 0100);
6798 ctl_len = 2;
6799 goto display_control;
6802 /* Handle non-ascii space in the mode where it only gets
6803 highlighting. */
6805 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6807 /* Merge `nobreak-space' into the current face. */
6808 face_id = merge_faces (it->f, Qnobreak_space, 0,
6809 it->face_id);
6810 XSETINT (it->ctl_chars[0], ' ');
6811 ctl_len = 1;
6812 goto display_control;
6815 /* Handle sequences that start with the "escape glyph". */
6817 /* the default escape glyph is \. */
6818 escape_glyph = '\\';
6820 if (it->dp
6821 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6823 escape_glyph = GLYPH_CODE_CHAR (gc);
6824 lface_id = GLYPH_CODE_FACE (gc);
6826 if (lface_id)
6828 /* The display table specified a face.
6829 Merge it into face_id and also into escape_glyph. */
6830 face_id = merge_faces (it->f, Qt, lface_id,
6831 it->face_id);
6833 else if (it->f == last_escape_glyph_frame
6834 && it->face_id == last_escape_glyph_face_id)
6836 face_id = last_escape_glyph_merged_face_id;
6838 else
6840 /* Merge the escape-glyph face into the current face. */
6841 face_id = merge_faces (it->f, Qescape_glyph, 0,
6842 it->face_id);
6843 last_escape_glyph_frame = it->f;
6844 last_escape_glyph_face_id = it->face_id;
6845 last_escape_glyph_merged_face_id = face_id;
6848 /* Draw non-ASCII hyphen with just highlighting: */
6850 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6852 XSETINT (it->ctl_chars[0], '-');
6853 ctl_len = 1;
6854 goto display_control;
6857 /* Draw non-ASCII space/hyphen with escape glyph: */
6859 if (nonascii_space_p || nonascii_hyphen_p)
6861 XSETINT (it->ctl_chars[0], escape_glyph);
6862 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6863 ctl_len = 2;
6864 goto display_control;
6868 char str[10];
6869 int len, i;
6871 if (CHAR_BYTE8_P (c))
6872 /* Display \200 instead of \17777600. */
6873 c = CHAR_TO_BYTE8 (c);
6874 len = sprintf (str, "%03o", c);
6876 XSETINT (it->ctl_chars[0], escape_glyph);
6877 for (i = 0; i < len; i++)
6878 XSETINT (it->ctl_chars[i + 1], str[i]);
6879 ctl_len = len + 1;
6882 display_control:
6883 /* Set up IT->dpvec and return first character from it. */
6884 it->dpvec_char_len = it->len;
6885 it->dpvec = it->ctl_chars;
6886 it->dpend = it->dpvec + ctl_len;
6887 it->current.dpvec_index = 0;
6888 it->dpvec_face_id = face_id;
6889 it->saved_face_id = it->face_id;
6890 it->method = GET_FROM_DISPLAY_VECTOR;
6891 it->ellipsis_p = 0;
6892 goto get_next;
6894 it->char_to_display = c;
6896 else if (success_p)
6898 it->char_to_display = it->c;
6902 /* Adjust face id for a multibyte character. There are no multibyte
6903 character in unibyte text. */
6904 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6905 && it->multibyte_p
6906 && success_p
6907 && FRAME_WINDOW_P (it->f))
6909 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6911 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6913 /* Automatic composition with glyph-string. */
6914 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6916 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6918 else
6920 ptrdiff_t pos = (it->s ? -1
6921 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6922 : IT_CHARPOS (*it));
6923 int c;
6925 if (it->what == IT_CHARACTER)
6926 c = it->char_to_display;
6927 else
6929 struct composition *cmp = composition_table[it->cmp_it.id];
6930 int i;
6932 c = ' ';
6933 for (i = 0; i < cmp->glyph_len; i++)
6934 /* TAB in a composition means display glyphs with
6935 padding space on the left or right. */
6936 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6937 break;
6939 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6943 done:
6944 /* Is this character the last one of a run of characters with
6945 box? If yes, set IT->end_of_box_run_p to 1. */
6946 if (it->face_box_p
6947 && it->s == NULL)
6949 if (it->method == GET_FROM_STRING && it->sp)
6951 int face_id = underlying_face_id (it);
6952 struct face *face = FACE_FROM_ID (it->f, face_id);
6954 if (face)
6956 if (face->box == FACE_NO_BOX)
6958 /* If the box comes from face properties in a
6959 display string, check faces in that string. */
6960 int string_face_id = face_after_it_pos (it);
6961 it->end_of_box_run_p
6962 = (FACE_FROM_ID (it->f, string_face_id)->box
6963 == FACE_NO_BOX);
6965 /* Otherwise, the box comes from the underlying face.
6966 If this is the last string character displayed, check
6967 the next buffer location. */
6968 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6969 && (it->current.overlay_string_index
6970 == it->n_overlay_strings - 1))
6972 ptrdiff_t ignore;
6973 int next_face_id;
6974 struct text_pos pos = it->current.pos;
6975 INC_TEXT_POS (pos, it->multibyte_p);
6977 next_face_id = face_at_buffer_position
6978 (it->w, CHARPOS (pos), it->region_beg_charpos,
6979 it->region_end_charpos, &ignore,
6980 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6981 -1);
6982 it->end_of_box_run_p
6983 = (FACE_FROM_ID (it->f, next_face_id)->box
6984 == FACE_NO_BOX);
6988 else
6990 int face_id = face_after_it_pos (it);
6991 it->end_of_box_run_p
6992 = (face_id != it->face_id
6993 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6996 /* If we reached the end of the object we've been iterating (e.g., a
6997 display string or an overlay string), and there's something on
6998 IT->stack, proceed with what's on the stack. It doesn't make
6999 sense to return zero if there's unprocessed stuff on the stack,
7000 because otherwise that stuff will never be displayed. */
7001 if (!success_p && it->sp > 0)
7003 set_iterator_to_next (it, 0);
7004 success_p = get_next_display_element (it);
7007 /* Value is 0 if end of buffer or string reached. */
7008 return success_p;
7012 /* Move IT to the next display element.
7014 RESEAT_P non-zero means if called on a newline in buffer text,
7015 skip to the next visible line start.
7017 Functions get_next_display_element and set_iterator_to_next are
7018 separate because I find this arrangement easier to handle than a
7019 get_next_display_element function that also increments IT's
7020 position. The way it is we can first look at an iterator's current
7021 display element, decide whether it fits on a line, and if it does,
7022 increment the iterator position. The other way around we probably
7023 would either need a flag indicating whether the iterator has to be
7024 incremented the next time, or we would have to implement a
7025 decrement position function which would not be easy to write. */
7027 void
7028 set_iterator_to_next (struct it *it, int reseat_p)
7030 /* Reset flags indicating start and end of a sequence of characters
7031 with box. Reset them at the start of this function because
7032 moving the iterator to a new position might set them. */
7033 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7035 switch (it->method)
7037 case GET_FROM_BUFFER:
7038 /* The current display element of IT is a character from
7039 current_buffer. Advance in the buffer, and maybe skip over
7040 invisible lines that are so because of selective display. */
7041 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7042 reseat_at_next_visible_line_start (it, 0);
7043 else if (it->cmp_it.id >= 0)
7045 /* We are currently getting glyphs from a composition. */
7046 int i;
7048 if (! it->bidi_p)
7050 IT_CHARPOS (*it) += it->cmp_it.nchars;
7051 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7052 if (it->cmp_it.to < it->cmp_it.nglyphs)
7054 it->cmp_it.from = it->cmp_it.to;
7056 else
7058 it->cmp_it.id = -1;
7059 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7060 IT_BYTEPOS (*it),
7061 it->end_charpos, Qnil);
7064 else if (! it->cmp_it.reversed_p)
7066 /* Composition created while scanning forward. */
7067 /* Update IT's char/byte positions to point to the first
7068 character of the next grapheme cluster, or to the
7069 character visually after the current composition. */
7070 for (i = 0; i < it->cmp_it.nchars; i++)
7071 bidi_move_to_visually_next (&it->bidi_it);
7072 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7073 IT_CHARPOS (*it) = it->bidi_it.charpos;
7075 if (it->cmp_it.to < it->cmp_it.nglyphs)
7077 /* Proceed to the next grapheme cluster. */
7078 it->cmp_it.from = it->cmp_it.to;
7080 else
7082 /* No more grapheme clusters in this composition.
7083 Find the next stop position. */
7084 ptrdiff_t stop = it->end_charpos;
7085 if (it->bidi_it.scan_dir < 0)
7086 /* Now we are scanning backward and don't know
7087 where to stop. */
7088 stop = -1;
7089 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7090 IT_BYTEPOS (*it), stop, Qnil);
7093 else
7095 /* Composition created while scanning backward. */
7096 /* Update IT's char/byte positions to point to the last
7097 character of the previous grapheme cluster, or the
7098 character visually after the current composition. */
7099 for (i = 0; i < it->cmp_it.nchars; i++)
7100 bidi_move_to_visually_next (&it->bidi_it);
7101 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7102 IT_CHARPOS (*it) = it->bidi_it.charpos;
7103 if (it->cmp_it.from > 0)
7105 /* Proceed to the previous grapheme cluster. */
7106 it->cmp_it.to = it->cmp_it.from;
7108 else
7110 /* No more grapheme clusters in this composition.
7111 Find the next stop position. */
7112 ptrdiff_t stop = it->end_charpos;
7113 if (it->bidi_it.scan_dir < 0)
7114 /* Now we are scanning backward and don't know
7115 where to stop. */
7116 stop = -1;
7117 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7118 IT_BYTEPOS (*it), stop, Qnil);
7122 else
7124 eassert (it->len != 0);
7126 if (!it->bidi_p)
7128 IT_BYTEPOS (*it) += it->len;
7129 IT_CHARPOS (*it) += 1;
7131 else
7133 int prev_scan_dir = it->bidi_it.scan_dir;
7134 /* If this is a new paragraph, determine its base
7135 direction (a.k.a. its base embedding level). */
7136 if (it->bidi_it.new_paragraph)
7137 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7138 bidi_move_to_visually_next (&it->bidi_it);
7139 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7140 IT_CHARPOS (*it) = it->bidi_it.charpos;
7141 if (prev_scan_dir != it->bidi_it.scan_dir)
7143 /* As the scan direction was changed, we must
7144 re-compute the stop position for composition. */
7145 ptrdiff_t stop = it->end_charpos;
7146 if (it->bidi_it.scan_dir < 0)
7147 stop = -1;
7148 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7149 IT_BYTEPOS (*it), stop, Qnil);
7152 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7154 break;
7156 case GET_FROM_C_STRING:
7157 /* Current display element of IT is from a C string. */
7158 if (!it->bidi_p
7159 /* If the string position is beyond string's end, it means
7160 next_element_from_c_string is padding the string with
7161 blanks, in which case we bypass the bidi iterator,
7162 because it cannot deal with such virtual characters. */
7163 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7165 IT_BYTEPOS (*it) += it->len;
7166 IT_CHARPOS (*it) += 1;
7168 else
7170 bidi_move_to_visually_next (&it->bidi_it);
7171 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7172 IT_CHARPOS (*it) = it->bidi_it.charpos;
7174 break;
7176 case GET_FROM_DISPLAY_VECTOR:
7177 /* Current display element of IT is from a display table entry.
7178 Advance in the display table definition. Reset it to null if
7179 end reached, and continue with characters from buffers/
7180 strings. */
7181 ++it->current.dpvec_index;
7183 /* Restore face of the iterator to what they were before the
7184 display vector entry (these entries may contain faces). */
7185 it->face_id = it->saved_face_id;
7187 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7189 int recheck_faces = it->ellipsis_p;
7191 if (it->s)
7192 it->method = GET_FROM_C_STRING;
7193 else if (STRINGP (it->string))
7194 it->method = GET_FROM_STRING;
7195 else
7197 it->method = GET_FROM_BUFFER;
7198 it->object = it->w->contents;
7201 it->dpvec = NULL;
7202 it->current.dpvec_index = -1;
7204 /* Skip over characters which were displayed via IT->dpvec. */
7205 if (it->dpvec_char_len < 0)
7206 reseat_at_next_visible_line_start (it, 1);
7207 else if (it->dpvec_char_len > 0)
7209 if (it->method == GET_FROM_STRING
7210 && it->current.overlay_string_index >= 0
7211 && it->n_overlay_strings > 0)
7212 it->ignore_overlay_strings_at_pos_p = 1;
7213 it->len = it->dpvec_char_len;
7214 set_iterator_to_next (it, reseat_p);
7217 /* Maybe recheck faces after display vector */
7218 if (recheck_faces)
7219 it->stop_charpos = IT_CHARPOS (*it);
7221 break;
7223 case GET_FROM_STRING:
7224 /* Current display element is a character from a Lisp string. */
7225 eassert (it->s == NULL && STRINGP (it->string));
7226 /* Don't advance past string end. These conditions are true
7227 when set_iterator_to_next is called at the end of
7228 get_next_display_element, in which case the Lisp string is
7229 already exhausted, and all we want is pop the iterator
7230 stack. */
7231 if (it->current.overlay_string_index >= 0)
7233 /* This is an overlay string, so there's no padding with
7234 spaces, and the number of characters in the string is
7235 where the string ends. */
7236 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7237 goto consider_string_end;
7239 else
7241 /* Not an overlay string. There could be padding, so test
7242 against it->end_charpos . */
7243 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7244 goto consider_string_end;
7246 if (it->cmp_it.id >= 0)
7248 int i;
7250 if (! it->bidi_p)
7252 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7253 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7254 if (it->cmp_it.to < it->cmp_it.nglyphs)
7255 it->cmp_it.from = it->cmp_it.to;
7256 else
7258 it->cmp_it.id = -1;
7259 composition_compute_stop_pos (&it->cmp_it,
7260 IT_STRING_CHARPOS (*it),
7261 IT_STRING_BYTEPOS (*it),
7262 it->end_charpos, it->string);
7265 else if (! it->cmp_it.reversed_p)
7267 for (i = 0; i < it->cmp_it.nchars; i++)
7268 bidi_move_to_visually_next (&it->bidi_it);
7269 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7270 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7272 if (it->cmp_it.to < it->cmp_it.nglyphs)
7273 it->cmp_it.from = it->cmp_it.to;
7274 else
7276 ptrdiff_t stop = it->end_charpos;
7277 if (it->bidi_it.scan_dir < 0)
7278 stop = -1;
7279 composition_compute_stop_pos (&it->cmp_it,
7280 IT_STRING_CHARPOS (*it),
7281 IT_STRING_BYTEPOS (*it), stop,
7282 it->string);
7285 else
7287 for (i = 0; i < it->cmp_it.nchars; i++)
7288 bidi_move_to_visually_next (&it->bidi_it);
7289 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7290 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7291 if (it->cmp_it.from > 0)
7292 it->cmp_it.to = it->cmp_it.from;
7293 else
7295 ptrdiff_t stop = it->end_charpos;
7296 if (it->bidi_it.scan_dir < 0)
7297 stop = -1;
7298 composition_compute_stop_pos (&it->cmp_it,
7299 IT_STRING_CHARPOS (*it),
7300 IT_STRING_BYTEPOS (*it), stop,
7301 it->string);
7305 else
7307 if (!it->bidi_p
7308 /* If the string position is beyond string's end, it
7309 means next_element_from_string is padding the string
7310 with blanks, in which case we bypass the bidi
7311 iterator, because it cannot deal with such virtual
7312 characters. */
7313 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7315 IT_STRING_BYTEPOS (*it) += it->len;
7316 IT_STRING_CHARPOS (*it) += 1;
7318 else
7320 int prev_scan_dir = it->bidi_it.scan_dir;
7322 bidi_move_to_visually_next (&it->bidi_it);
7323 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7324 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7325 if (prev_scan_dir != it->bidi_it.scan_dir)
7327 ptrdiff_t stop = it->end_charpos;
7329 if (it->bidi_it.scan_dir < 0)
7330 stop = -1;
7331 composition_compute_stop_pos (&it->cmp_it,
7332 IT_STRING_CHARPOS (*it),
7333 IT_STRING_BYTEPOS (*it), stop,
7334 it->string);
7339 consider_string_end:
7341 if (it->current.overlay_string_index >= 0)
7343 /* IT->string is an overlay string. Advance to the
7344 next, if there is one. */
7345 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7347 it->ellipsis_p = 0;
7348 next_overlay_string (it);
7349 if (it->ellipsis_p)
7350 setup_for_ellipsis (it, 0);
7353 else
7355 /* IT->string is not an overlay string. If we reached
7356 its end, and there is something on IT->stack, proceed
7357 with what is on the stack. This can be either another
7358 string, this time an overlay string, or a buffer. */
7359 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7360 && it->sp > 0)
7362 pop_it (it);
7363 if (it->method == GET_FROM_STRING)
7364 goto consider_string_end;
7367 break;
7369 case GET_FROM_IMAGE:
7370 case GET_FROM_STRETCH:
7371 /* The position etc with which we have to proceed are on
7372 the stack. The position may be at the end of a string,
7373 if the `display' property takes up the whole string. */
7374 eassert (it->sp > 0);
7375 pop_it (it);
7376 if (it->method == GET_FROM_STRING)
7377 goto consider_string_end;
7378 break;
7380 default:
7381 /* There are no other methods defined, so this should be a bug. */
7382 emacs_abort ();
7385 eassert (it->method != GET_FROM_STRING
7386 || (STRINGP (it->string)
7387 && IT_STRING_CHARPOS (*it) >= 0));
7390 /* Load IT's display element fields with information about the next
7391 display element which comes from a display table entry or from the
7392 result of translating a control character to one of the forms `^C'
7393 or `\003'.
7395 IT->dpvec holds the glyphs to return as characters.
7396 IT->saved_face_id holds the face id before the display vector--it
7397 is restored into IT->face_id in set_iterator_to_next. */
7399 static int
7400 next_element_from_display_vector (struct it *it)
7402 Lisp_Object gc;
7404 /* Precondition. */
7405 eassert (it->dpvec && it->current.dpvec_index >= 0);
7407 it->face_id = it->saved_face_id;
7409 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7410 That seemed totally bogus - so I changed it... */
7411 gc = it->dpvec[it->current.dpvec_index];
7413 if (GLYPH_CODE_P (gc))
7415 it->c = GLYPH_CODE_CHAR (gc);
7416 it->len = CHAR_BYTES (it->c);
7418 /* The entry may contain a face id to use. Such a face id is
7419 the id of a Lisp face, not a realized face. A face id of
7420 zero means no face is specified. */
7421 if (it->dpvec_face_id >= 0)
7422 it->face_id = it->dpvec_face_id;
7423 else
7425 int lface_id = GLYPH_CODE_FACE (gc);
7426 if (lface_id > 0)
7427 it->face_id = merge_faces (it->f, Qt, lface_id,
7428 it->saved_face_id);
7431 else
7432 /* Display table entry is invalid. Return a space. */
7433 it->c = ' ', it->len = 1;
7435 /* Don't change position and object of the iterator here. They are
7436 still the values of the character that had this display table
7437 entry or was translated, and that's what we want. */
7438 it->what = IT_CHARACTER;
7439 return 1;
7442 /* Get the first element of string/buffer in the visual order, after
7443 being reseated to a new position in a string or a buffer. */
7444 static void
7445 get_visually_first_element (struct it *it)
7447 int string_p = STRINGP (it->string) || it->s;
7448 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7449 ptrdiff_t bob = (string_p ? 0 : BEGV);
7451 if (STRINGP (it->string))
7453 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7454 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7456 else
7458 it->bidi_it.charpos = IT_CHARPOS (*it);
7459 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7462 if (it->bidi_it.charpos == eob)
7464 /* Nothing to do, but reset the FIRST_ELT flag, like
7465 bidi_paragraph_init does, because we are not going to
7466 call it. */
7467 it->bidi_it.first_elt = 0;
7469 else if (it->bidi_it.charpos == bob
7470 || (!string_p
7471 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7472 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7474 /* If we are at the beginning of a line/string, we can produce
7475 the next element right away. */
7476 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7477 bidi_move_to_visually_next (&it->bidi_it);
7479 else
7481 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7483 /* We need to prime the bidi iterator starting at the line's or
7484 string's beginning, before we will be able to produce the
7485 next element. */
7486 if (string_p)
7487 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7488 else
7489 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7490 IT_BYTEPOS (*it), -1,
7491 &it->bidi_it.bytepos);
7492 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7495 /* Now return to buffer/string position where we were asked
7496 to get the next display element, and produce that. */
7497 bidi_move_to_visually_next (&it->bidi_it);
7499 while (it->bidi_it.bytepos != orig_bytepos
7500 && it->bidi_it.charpos < eob);
7503 /* Adjust IT's position information to where we ended up. */
7504 if (STRINGP (it->string))
7506 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7507 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7509 else
7511 IT_CHARPOS (*it) = it->bidi_it.charpos;
7512 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7515 if (STRINGP (it->string) || !it->s)
7517 ptrdiff_t stop, charpos, bytepos;
7519 if (STRINGP (it->string))
7521 eassert (!it->s);
7522 stop = SCHARS (it->string);
7523 if (stop > it->end_charpos)
7524 stop = it->end_charpos;
7525 charpos = IT_STRING_CHARPOS (*it);
7526 bytepos = IT_STRING_BYTEPOS (*it);
7528 else
7530 stop = it->end_charpos;
7531 charpos = IT_CHARPOS (*it);
7532 bytepos = IT_BYTEPOS (*it);
7534 if (it->bidi_it.scan_dir < 0)
7535 stop = -1;
7536 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7537 it->string);
7541 /* Load IT with the next display element from Lisp string IT->string.
7542 IT->current.string_pos is the current position within the string.
7543 If IT->current.overlay_string_index >= 0, the Lisp string is an
7544 overlay string. */
7546 static int
7547 next_element_from_string (struct it *it)
7549 struct text_pos position;
7551 eassert (STRINGP (it->string));
7552 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7553 eassert (IT_STRING_CHARPOS (*it) >= 0);
7554 position = it->current.string_pos;
7556 /* With bidi reordering, the character to display might not be the
7557 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7558 that we were reseat()ed to a new string, whose paragraph
7559 direction is not known. */
7560 if (it->bidi_p && it->bidi_it.first_elt)
7562 get_visually_first_element (it);
7563 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7566 /* Time to check for invisible text? */
7567 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7569 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7571 if (!(!it->bidi_p
7572 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7573 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7575 /* With bidi non-linear iteration, we could find
7576 ourselves far beyond the last computed stop_charpos,
7577 with several other stop positions in between that we
7578 missed. Scan them all now, in buffer's logical
7579 order, until we find and handle the last stop_charpos
7580 that precedes our current position. */
7581 handle_stop_backwards (it, it->stop_charpos);
7582 return GET_NEXT_DISPLAY_ELEMENT (it);
7584 else
7586 if (it->bidi_p)
7588 /* Take note of the stop position we just moved
7589 across, for when we will move back across it. */
7590 it->prev_stop = it->stop_charpos;
7591 /* If we are at base paragraph embedding level, take
7592 note of the last stop position seen at this
7593 level. */
7594 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7595 it->base_level_stop = it->stop_charpos;
7597 handle_stop (it);
7599 /* Since a handler may have changed IT->method, we must
7600 recurse here. */
7601 return GET_NEXT_DISPLAY_ELEMENT (it);
7604 else if (it->bidi_p
7605 /* If we are before prev_stop, we may have overstepped
7606 on our way backwards a stop_pos, and if so, we need
7607 to handle that stop_pos. */
7608 && IT_STRING_CHARPOS (*it) < it->prev_stop
7609 /* We can sometimes back up for reasons that have nothing
7610 to do with bidi reordering. E.g., compositions. The
7611 code below is only needed when we are above the base
7612 embedding level, so test for that explicitly. */
7613 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7615 /* If we lost track of base_level_stop, we have no better
7616 place for handle_stop_backwards to start from than string
7617 beginning. This happens, e.g., when we were reseated to
7618 the previous screenful of text by vertical-motion. */
7619 if (it->base_level_stop <= 0
7620 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7621 it->base_level_stop = 0;
7622 handle_stop_backwards (it, it->base_level_stop);
7623 return GET_NEXT_DISPLAY_ELEMENT (it);
7627 if (it->current.overlay_string_index >= 0)
7629 /* Get the next character from an overlay string. In overlay
7630 strings, there is no field width or padding with spaces to
7631 do. */
7632 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7634 it->what = IT_EOB;
7635 return 0;
7637 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7638 IT_STRING_BYTEPOS (*it),
7639 it->bidi_it.scan_dir < 0
7640 ? -1
7641 : SCHARS (it->string))
7642 && next_element_from_composition (it))
7644 return 1;
7646 else if (STRING_MULTIBYTE (it->string))
7648 const unsigned char *s = (SDATA (it->string)
7649 + IT_STRING_BYTEPOS (*it));
7650 it->c = string_char_and_length (s, &it->len);
7652 else
7654 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7655 it->len = 1;
7658 else
7660 /* Get the next character from a Lisp string that is not an
7661 overlay string. Such strings come from the mode line, for
7662 example. We may have to pad with spaces, or truncate the
7663 string. See also next_element_from_c_string. */
7664 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7666 it->what = IT_EOB;
7667 return 0;
7669 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7671 /* Pad with spaces. */
7672 it->c = ' ', it->len = 1;
7673 CHARPOS (position) = BYTEPOS (position) = -1;
7675 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7676 IT_STRING_BYTEPOS (*it),
7677 it->bidi_it.scan_dir < 0
7678 ? -1
7679 : it->string_nchars)
7680 && next_element_from_composition (it))
7682 return 1;
7684 else if (STRING_MULTIBYTE (it->string))
7686 const unsigned char *s = (SDATA (it->string)
7687 + IT_STRING_BYTEPOS (*it));
7688 it->c = string_char_and_length (s, &it->len);
7690 else
7692 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7693 it->len = 1;
7697 /* Record what we have and where it came from. */
7698 it->what = IT_CHARACTER;
7699 it->object = it->string;
7700 it->position = position;
7701 return 1;
7705 /* Load IT with next display element from C string IT->s.
7706 IT->string_nchars is the maximum number of characters to return
7707 from the string. IT->end_charpos may be greater than
7708 IT->string_nchars when this function is called, in which case we
7709 may have to return padding spaces. Value is zero if end of string
7710 reached, including padding spaces. */
7712 static int
7713 next_element_from_c_string (struct it *it)
7715 int success_p = 1;
7717 eassert (it->s);
7718 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7719 it->what = IT_CHARACTER;
7720 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7721 it->object = Qnil;
7723 /* With bidi reordering, the character to display might not be the
7724 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7725 we were reseated to a new string, whose paragraph direction is
7726 not known. */
7727 if (it->bidi_p && it->bidi_it.first_elt)
7728 get_visually_first_element (it);
7730 /* IT's position can be greater than IT->string_nchars in case a
7731 field width or precision has been specified when the iterator was
7732 initialized. */
7733 if (IT_CHARPOS (*it) >= it->end_charpos)
7735 /* End of the game. */
7736 it->what = IT_EOB;
7737 success_p = 0;
7739 else if (IT_CHARPOS (*it) >= it->string_nchars)
7741 /* Pad with spaces. */
7742 it->c = ' ', it->len = 1;
7743 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7745 else if (it->multibyte_p)
7746 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7747 else
7748 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7750 return success_p;
7754 /* Set up IT to return characters from an ellipsis, if appropriate.
7755 The definition of the ellipsis glyphs may come from a display table
7756 entry. This function fills IT with the first glyph from the
7757 ellipsis if an ellipsis is to be displayed. */
7759 static int
7760 next_element_from_ellipsis (struct it *it)
7762 if (it->selective_display_ellipsis_p)
7763 setup_for_ellipsis (it, it->len);
7764 else
7766 /* The face at the current position may be different from the
7767 face we find after the invisible text. Remember what it
7768 was in IT->saved_face_id, and signal that it's there by
7769 setting face_before_selective_p. */
7770 it->saved_face_id = it->face_id;
7771 it->method = GET_FROM_BUFFER;
7772 it->object = it->w->contents;
7773 reseat_at_next_visible_line_start (it, 1);
7774 it->face_before_selective_p = 1;
7777 return GET_NEXT_DISPLAY_ELEMENT (it);
7781 /* Deliver an image display element. The iterator IT is already
7782 filled with image information (done in handle_display_prop). Value
7783 is always 1. */
7786 static int
7787 next_element_from_image (struct it *it)
7789 it->what = IT_IMAGE;
7790 it->ignore_overlay_strings_at_pos_p = 0;
7791 return 1;
7795 /* Fill iterator IT with next display element from a stretch glyph
7796 property. IT->object is the value of the text property. Value is
7797 always 1. */
7799 static int
7800 next_element_from_stretch (struct it *it)
7802 it->what = IT_STRETCH;
7803 return 1;
7806 /* Scan backwards from IT's current position until we find a stop
7807 position, or until BEGV. This is called when we find ourself
7808 before both the last known prev_stop and base_level_stop while
7809 reordering bidirectional text. */
7811 static void
7812 compute_stop_pos_backwards (struct it *it)
7814 const int SCAN_BACK_LIMIT = 1000;
7815 struct text_pos pos;
7816 struct display_pos save_current = it->current;
7817 struct text_pos save_position = it->position;
7818 ptrdiff_t charpos = IT_CHARPOS (*it);
7819 ptrdiff_t where_we_are = charpos;
7820 ptrdiff_t save_stop_pos = it->stop_charpos;
7821 ptrdiff_t save_end_pos = it->end_charpos;
7823 eassert (NILP (it->string) && !it->s);
7824 eassert (it->bidi_p);
7825 it->bidi_p = 0;
7828 it->end_charpos = min (charpos + 1, ZV);
7829 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7830 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
7831 reseat_1 (it, pos, 0);
7832 compute_stop_pos (it);
7833 /* We must advance forward, right? */
7834 if (it->stop_charpos <= charpos)
7835 emacs_abort ();
7837 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7839 if (it->stop_charpos <= where_we_are)
7840 it->prev_stop = it->stop_charpos;
7841 else
7842 it->prev_stop = BEGV;
7843 it->bidi_p = 1;
7844 it->current = save_current;
7845 it->position = save_position;
7846 it->stop_charpos = save_stop_pos;
7847 it->end_charpos = save_end_pos;
7850 /* Scan forward from CHARPOS in the current buffer/string, until we
7851 find a stop position > current IT's position. Then handle the stop
7852 position before that. This is called when we bump into a stop
7853 position while reordering bidirectional text. CHARPOS should be
7854 the last previously processed stop_pos (or BEGV/0, if none were
7855 processed yet) whose position is less that IT's current
7856 position. */
7858 static void
7859 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7861 int bufp = !STRINGP (it->string);
7862 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7863 struct display_pos save_current = it->current;
7864 struct text_pos save_position = it->position;
7865 struct text_pos pos1;
7866 ptrdiff_t next_stop;
7868 /* Scan in strict logical order. */
7869 eassert (it->bidi_p);
7870 it->bidi_p = 0;
7873 it->prev_stop = charpos;
7874 if (bufp)
7876 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7877 reseat_1 (it, pos1, 0);
7879 else
7880 it->current.string_pos = string_pos (charpos, it->string);
7881 compute_stop_pos (it);
7882 /* We must advance forward, right? */
7883 if (it->stop_charpos <= it->prev_stop)
7884 emacs_abort ();
7885 charpos = it->stop_charpos;
7887 while (charpos <= where_we_are);
7889 it->bidi_p = 1;
7890 it->current = save_current;
7891 it->position = save_position;
7892 next_stop = it->stop_charpos;
7893 it->stop_charpos = it->prev_stop;
7894 handle_stop (it);
7895 it->stop_charpos = next_stop;
7898 /* Load IT with the next display element from current_buffer. Value
7899 is zero if end of buffer reached. IT->stop_charpos is the next
7900 position at which to stop and check for text properties or buffer
7901 end. */
7903 static int
7904 next_element_from_buffer (struct it *it)
7906 int success_p = 1;
7908 eassert (IT_CHARPOS (*it) >= BEGV);
7909 eassert (NILP (it->string) && !it->s);
7910 eassert (!it->bidi_p
7911 || (EQ (it->bidi_it.string.lstring, Qnil)
7912 && it->bidi_it.string.s == NULL));
7914 /* With bidi reordering, the character to display might not be the
7915 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7916 we were reseat()ed to a new buffer position, which is potentially
7917 a different paragraph. */
7918 if (it->bidi_p && it->bidi_it.first_elt)
7920 get_visually_first_element (it);
7921 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7924 if (IT_CHARPOS (*it) >= it->stop_charpos)
7926 if (IT_CHARPOS (*it) >= it->end_charpos)
7928 int overlay_strings_follow_p;
7930 /* End of the game, except when overlay strings follow that
7931 haven't been returned yet. */
7932 if (it->overlay_strings_at_end_processed_p)
7933 overlay_strings_follow_p = 0;
7934 else
7936 it->overlay_strings_at_end_processed_p = 1;
7937 overlay_strings_follow_p = get_overlay_strings (it, 0);
7940 if (overlay_strings_follow_p)
7941 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7942 else
7944 it->what = IT_EOB;
7945 it->position = it->current.pos;
7946 success_p = 0;
7949 else if (!(!it->bidi_p
7950 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7951 || IT_CHARPOS (*it) == it->stop_charpos))
7953 /* With bidi non-linear iteration, we could find ourselves
7954 far beyond the last computed stop_charpos, with several
7955 other stop positions in between that we missed. Scan
7956 them all now, in buffer's logical order, until we find
7957 and handle the last stop_charpos that precedes our
7958 current position. */
7959 handle_stop_backwards (it, it->stop_charpos);
7960 return GET_NEXT_DISPLAY_ELEMENT (it);
7962 else
7964 if (it->bidi_p)
7966 /* Take note of the stop position we just moved across,
7967 for when we will move back across it. */
7968 it->prev_stop = it->stop_charpos;
7969 /* If we are at base paragraph embedding level, take
7970 note of the last stop position seen at this
7971 level. */
7972 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7973 it->base_level_stop = it->stop_charpos;
7975 handle_stop (it);
7976 return GET_NEXT_DISPLAY_ELEMENT (it);
7979 else if (it->bidi_p
7980 /* If we are before prev_stop, we may have overstepped on
7981 our way backwards a stop_pos, and if so, we need to
7982 handle that stop_pos. */
7983 && IT_CHARPOS (*it) < it->prev_stop
7984 /* We can sometimes back up for reasons that have nothing
7985 to do with bidi reordering. E.g., compositions. The
7986 code below is only needed when we are above the base
7987 embedding level, so test for that explicitly. */
7988 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7990 if (it->base_level_stop <= 0
7991 || IT_CHARPOS (*it) < it->base_level_stop)
7993 /* If we lost track of base_level_stop, we need to find
7994 prev_stop by looking backwards. This happens, e.g., when
7995 we were reseated to the previous screenful of text by
7996 vertical-motion. */
7997 it->base_level_stop = BEGV;
7998 compute_stop_pos_backwards (it);
7999 handle_stop_backwards (it, it->prev_stop);
8001 else
8002 handle_stop_backwards (it, it->base_level_stop);
8003 return GET_NEXT_DISPLAY_ELEMENT (it);
8005 else
8007 /* No face changes, overlays etc. in sight, so just return a
8008 character from current_buffer. */
8009 unsigned char *p;
8010 ptrdiff_t stop;
8012 /* Maybe run the redisplay end trigger hook. Performance note:
8013 This doesn't seem to cost measurable time. */
8014 if (it->redisplay_end_trigger_charpos
8015 && it->glyph_row
8016 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8017 run_redisplay_end_trigger_hook (it);
8019 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8020 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8021 stop)
8022 && next_element_from_composition (it))
8024 return 1;
8027 /* Get the next character, maybe multibyte. */
8028 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8029 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8030 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8031 else
8032 it->c = *p, it->len = 1;
8034 /* Record what we have and where it came from. */
8035 it->what = IT_CHARACTER;
8036 it->object = it->w->contents;
8037 it->position = it->current.pos;
8039 /* Normally we return the character found above, except when we
8040 really want to return an ellipsis for selective display. */
8041 if (it->selective)
8043 if (it->c == '\n')
8045 /* A value of selective > 0 means hide lines indented more
8046 than that number of columns. */
8047 if (it->selective > 0
8048 && IT_CHARPOS (*it) + 1 < ZV
8049 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8050 IT_BYTEPOS (*it) + 1,
8051 it->selective))
8053 success_p = next_element_from_ellipsis (it);
8054 it->dpvec_char_len = -1;
8057 else if (it->c == '\r' && it->selective == -1)
8059 /* A value of selective == -1 means that everything from the
8060 CR to the end of the line is invisible, with maybe an
8061 ellipsis displayed for it. */
8062 success_p = next_element_from_ellipsis (it);
8063 it->dpvec_char_len = -1;
8068 /* Value is zero if end of buffer reached. */
8069 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8070 return success_p;
8074 /* Run the redisplay end trigger hook for IT. */
8076 static void
8077 run_redisplay_end_trigger_hook (struct it *it)
8079 Lisp_Object args[3];
8081 /* IT->glyph_row should be non-null, i.e. we should be actually
8082 displaying something, or otherwise we should not run the hook. */
8083 eassert (it->glyph_row);
8085 /* Set up hook arguments. */
8086 args[0] = Qredisplay_end_trigger_functions;
8087 args[1] = it->window;
8088 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8089 it->redisplay_end_trigger_charpos = 0;
8091 /* Since we are *trying* to run these functions, don't try to run
8092 them again, even if they get an error. */
8093 wset_redisplay_end_trigger (it->w, Qnil);
8094 Frun_hook_with_args (3, args);
8096 /* Notice if it changed the face of the character we are on. */
8097 handle_face_prop (it);
8101 /* Deliver a composition display element. Unlike the other
8102 next_element_from_XXX, this function is not registered in the array
8103 get_next_element[]. It is called from next_element_from_buffer and
8104 next_element_from_string when necessary. */
8106 static int
8107 next_element_from_composition (struct it *it)
8109 it->what = IT_COMPOSITION;
8110 it->len = it->cmp_it.nbytes;
8111 if (STRINGP (it->string))
8113 if (it->c < 0)
8115 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8116 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8117 return 0;
8119 it->position = it->current.string_pos;
8120 it->object = it->string;
8121 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8122 IT_STRING_BYTEPOS (*it), it->string);
8124 else
8126 if (it->c < 0)
8128 IT_CHARPOS (*it) += it->cmp_it.nchars;
8129 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8130 if (it->bidi_p)
8132 if (it->bidi_it.new_paragraph)
8133 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8134 /* Resync the bidi iterator with IT's new position.
8135 FIXME: this doesn't support bidirectional text. */
8136 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8137 bidi_move_to_visually_next (&it->bidi_it);
8139 return 0;
8141 it->position = it->current.pos;
8142 it->object = it->w->contents;
8143 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8144 IT_BYTEPOS (*it), Qnil);
8146 return 1;
8151 /***********************************************************************
8152 Moving an iterator without producing glyphs
8153 ***********************************************************************/
8155 /* Check if iterator is at a position corresponding to a valid buffer
8156 position after some move_it_ call. */
8158 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8159 ((it)->method == GET_FROM_STRING \
8160 ? IT_STRING_CHARPOS (*it) == 0 \
8161 : 1)
8164 /* Move iterator IT to a specified buffer or X position within one
8165 line on the display without producing glyphs.
8167 OP should be a bit mask including some or all of these bits:
8168 MOVE_TO_X: Stop upon reaching x-position TO_X.
8169 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8170 Regardless of OP's value, stop upon reaching the end of the display line.
8172 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8173 This means, in particular, that TO_X includes window's horizontal
8174 scroll amount.
8176 The return value has several possible values that
8177 say what condition caused the scan to stop:
8179 MOVE_POS_MATCH_OR_ZV
8180 - when TO_POS or ZV was reached.
8182 MOVE_X_REACHED
8183 -when TO_X was reached before TO_POS or ZV were reached.
8185 MOVE_LINE_CONTINUED
8186 - when we reached the end of the display area and the line must
8187 be continued.
8189 MOVE_LINE_TRUNCATED
8190 - when we reached the end of the display area and the line is
8191 truncated.
8193 MOVE_NEWLINE_OR_CR
8194 - when we stopped at a line end, i.e. a newline or a CR and selective
8195 display is on. */
8197 static enum move_it_result
8198 move_it_in_display_line_to (struct it *it,
8199 ptrdiff_t to_charpos, int to_x,
8200 enum move_operation_enum op)
8202 enum move_it_result result = MOVE_UNDEFINED;
8203 struct glyph_row *saved_glyph_row;
8204 struct it wrap_it, atpos_it, atx_it, ppos_it;
8205 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8206 void *ppos_data = NULL;
8207 int may_wrap = 0;
8208 enum it_method prev_method = it->method;
8209 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8210 int saw_smaller_pos = prev_pos < to_charpos;
8212 /* Don't produce glyphs in produce_glyphs. */
8213 saved_glyph_row = it->glyph_row;
8214 it->glyph_row = NULL;
8216 /* Use wrap_it to save a copy of IT wherever a word wrap could
8217 occur. Use atpos_it to save a copy of IT at the desired buffer
8218 position, if found, so that we can scan ahead and check if the
8219 word later overshoots the window edge. Use atx_it similarly, for
8220 pixel positions. */
8221 wrap_it.sp = -1;
8222 atpos_it.sp = -1;
8223 atx_it.sp = -1;
8225 /* Use ppos_it under bidi reordering to save a copy of IT for the
8226 position > CHARPOS that is the closest to CHARPOS. We restore
8227 that position in IT when we have scanned the entire display line
8228 without finding a match for CHARPOS and all the character
8229 positions are greater than CHARPOS. */
8230 if (it->bidi_p)
8232 SAVE_IT (ppos_it, *it, ppos_data);
8233 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8234 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8235 SAVE_IT (ppos_it, *it, ppos_data);
8238 #define BUFFER_POS_REACHED_P() \
8239 ((op & MOVE_TO_POS) != 0 \
8240 && BUFFERP (it->object) \
8241 && (IT_CHARPOS (*it) == to_charpos \
8242 || ((!it->bidi_p \
8243 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8244 && IT_CHARPOS (*it) > to_charpos) \
8245 || (it->what == IT_COMPOSITION \
8246 && ((IT_CHARPOS (*it) > to_charpos \
8247 && to_charpos >= it->cmp_it.charpos) \
8248 || (IT_CHARPOS (*it) < to_charpos \
8249 && to_charpos <= it->cmp_it.charpos)))) \
8250 && (it->method == GET_FROM_BUFFER \
8251 || (it->method == GET_FROM_DISPLAY_VECTOR \
8252 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8254 /* If there's a line-/wrap-prefix, handle it. */
8255 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8256 && it->current_y < it->last_visible_y)
8257 handle_line_prefix (it);
8259 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8260 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8262 while (1)
8264 int x, i, ascent = 0, descent = 0;
8266 /* Utility macro to reset an iterator with x, ascent, and descent. */
8267 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8268 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8269 (IT)->max_descent = descent)
8271 /* Stop if we move beyond TO_CHARPOS (after an image or a
8272 display string or stretch glyph). */
8273 if ((op & MOVE_TO_POS) != 0
8274 && BUFFERP (it->object)
8275 && it->method == GET_FROM_BUFFER
8276 && (((!it->bidi_p
8277 /* When the iterator is at base embedding level, we
8278 are guaranteed that characters are delivered for
8279 display in strictly increasing order of their
8280 buffer positions. */
8281 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8282 && IT_CHARPOS (*it) > to_charpos)
8283 || (it->bidi_p
8284 && (prev_method == GET_FROM_IMAGE
8285 || prev_method == GET_FROM_STRETCH
8286 || prev_method == GET_FROM_STRING)
8287 /* Passed TO_CHARPOS from left to right. */
8288 && ((prev_pos < to_charpos
8289 && IT_CHARPOS (*it) > to_charpos)
8290 /* Passed TO_CHARPOS from right to left. */
8291 || (prev_pos > to_charpos
8292 && IT_CHARPOS (*it) < to_charpos)))))
8294 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8296 result = MOVE_POS_MATCH_OR_ZV;
8297 break;
8299 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8300 /* If wrap_it is valid, the current position might be in a
8301 word that is wrapped. So, save the iterator in
8302 atpos_it and continue to see if wrapping happens. */
8303 SAVE_IT (atpos_it, *it, atpos_data);
8306 /* Stop when ZV reached.
8307 We used to stop here when TO_CHARPOS reached as well, but that is
8308 too soon if this glyph does not fit on this line. So we handle it
8309 explicitly below. */
8310 if (!get_next_display_element (it))
8312 result = MOVE_POS_MATCH_OR_ZV;
8313 break;
8316 if (it->line_wrap == TRUNCATE)
8318 if (BUFFER_POS_REACHED_P ())
8320 result = MOVE_POS_MATCH_OR_ZV;
8321 break;
8324 else
8326 if (it->line_wrap == WORD_WRAP)
8328 if (IT_DISPLAYING_WHITESPACE (it))
8329 may_wrap = 1;
8330 else if (may_wrap)
8332 /* We have reached a glyph that follows one or more
8333 whitespace characters. If the position is
8334 already found, we are done. */
8335 if (atpos_it.sp >= 0)
8337 RESTORE_IT (it, &atpos_it, atpos_data);
8338 result = MOVE_POS_MATCH_OR_ZV;
8339 goto done;
8341 if (atx_it.sp >= 0)
8343 RESTORE_IT (it, &atx_it, atx_data);
8344 result = MOVE_X_REACHED;
8345 goto done;
8347 /* Otherwise, we can wrap here. */
8348 SAVE_IT (wrap_it, *it, wrap_data);
8349 may_wrap = 0;
8354 /* Remember the line height for the current line, in case
8355 the next element doesn't fit on the line. */
8356 ascent = it->max_ascent;
8357 descent = it->max_descent;
8359 /* The call to produce_glyphs will get the metrics of the
8360 display element IT is loaded with. Record the x-position
8361 before this display element, in case it doesn't fit on the
8362 line. */
8363 x = it->current_x;
8365 PRODUCE_GLYPHS (it);
8367 if (it->area != TEXT_AREA)
8369 prev_method = it->method;
8370 if (it->method == GET_FROM_BUFFER)
8371 prev_pos = IT_CHARPOS (*it);
8372 set_iterator_to_next (it, 1);
8373 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8374 SET_TEXT_POS (this_line_min_pos,
8375 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8376 if (it->bidi_p
8377 && (op & MOVE_TO_POS)
8378 && IT_CHARPOS (*it) > to_charpos
8379 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8380 SAVE_IT (ppos_it, *it, ppos_data);
8381 continue;
8384 /* The number of glyphs we get back in IT->nglyphs will normally
8385 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8386 character on a terminal frame, or (iii) a line end. For the
8387 second case, IT->nglyphs - 1 padding glyphs will be present.
8388 (On X frames, there is only one glyph produced for a
8389 composite character.)
8391 The behavior implemented below means, for continuation lines,
8392 that as many spaces of a TAB as fit on the current line are
8393 displayed there. For terminal frames, as many glyphs of a
8394 multi-glyph character are displayed in the current line, too.
8395 This is what the old redisplay code did, and we keep it that
8396 way. Under X, the whole shape of a complex character must
8397 fit on the line or it will be completely displayed in the
8398 next line.
8400 Note that both for tabs and padding glyphs, all glyphs have
8401 the same width. */
8402 if (it->nglyphs)
8404 /* More than one glyph or glyph doesn't fit on line. All
8405 glyphs have the same width. */
8406 int single_glyph_width = it->pixel_width / it->nglyphs;
8407 int new_x;
8408 int x_before_this_char = x;
8409 int hpos_before_this_char = it->hpos;
8411 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8413 new_x = x + single_glyph_width;
8415 /* We want to leave anything reaching TO_X to the caller. */
8416 if ((op & MOVE_TO_X) && new_x > to_x)
8418 if (BUFFER_POS_REACHED_P ())
8420 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8421 goto buffer_pos_reached;
8422 if (atpos_it.sp < 0)
8424 SAVE_IT (atpos_it, *it, atpos_data);
8425 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8428 else
8430 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8432 it->current_x = x;
8433 result = MOVE_X_REACHED;
8434 break;
8436 if (atx_it.sp < 0)
8438 SAVE_IT (atx_it, *it, atx_data);
8439 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8444 if (/* Lines are continued. */
8445 it->line_wrap != TRUNCATE
8446 && (/* And glyph doesn't fit on the line. */
8447 new_x > it->last_visible_x
8448 /* Or it fits exactly and we're on a window
8449 system frame. */
8450 || (new_x == it->last_visible_x
8451 && FRAME_WINDOW_P (it->f)
8452 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8453 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8454 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8456 if (/* IT->hpos == 0 means the very first glyph
8457 doesn't fit on the line, e.g. a wide image. */
8458 it->hpos == 0
8459 || (new_x == it->last_visible_x
8460 && FRAME_WINDOW_P (it->f)))
8462 ++it->hpos;
8463 it->current_x = new_x;
8465 /* The character's last glyph just barely fits
8466 in this row. */
8467 if (i == it->nglyphs - 1)
8469 /* If this is the destination position,
8470 return a position *before* it in this row,
8471 now that we know it fits in this row. */
8472 if (BUFFER_POS_REACHED_P ())
8474 if (it->line_wrap != WORD_WRAP
8475 || wrap_it.sp < 0)
8477 it->hpos = hpos_before_this_char;
8478 it->current_x = x_before_this_char;
8479 result = MOVE_POS_MATCH_OR_ZV;
8480 break;
8482 if (it->line_wrap == WORD_WRAP
8483 && atpos_it.sp < 0)
8485 SAVE_IT (atpos_it, *it, atpos_data);
8486 atpos_it.current_x = x_before_this_char;
8487 atpos_it.hpos = hpos_before_this_char;
8491 prev_method = it->method;
8492 if (it->method == GET_FROM_BUFFER)
8493 prev_pos = IT_CHARPOS (*it);
8494 set_iterator_to_next (it, 1);
8495 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8496 SET_TEXT_POS (this_line_min_pos,
8497 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8498 /* On graphical terminals, newlines may
8499 "overflow" into the fringe if
8500 overflow-newline-into-fringe is non-nil.
8501 On text terminals, and on graphical
8502 terminals with no right margin, newlines
8503 may overflow into the last glyph on the
8504 display line.*/
8505 if (!FRAME_WINDOW_P (it->f)
8506 || ((it->bidi_p
8507 && it->bidi_it.paragraph_dir == R2L)
8508 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8509 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8510 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8512 if (!get_next_display_element (it))
8514 result = MOVE_POS_MATCH_OR_ZV;
8515 break;
8517 if (BUFFER_POS_REACHED_P ())
8519 if (ITERATOR_AT_END_OF_LINE_P (it))
8520 result = MOVE_POS_MATCH_OR_ZV;
8521 else
8522 result = MOVE_LINE_CONTINUED;
8523 break;
8525 if (ITERATOR_AT_END_OF_LINE_P (it))
8527 result = MOVE_NEWLINE_OR_CR;
8528 break;
8533 else
8534 IT_RESET_X_ASCENT_DESCENT (it);
8536 if (wrap_it.sp >= 0)
8538 RESTORE_IT (it, &wrap_it, wrap_data);
8539 atpos_it.sp = -1;
8540 atx_it.sp = -1;
8543 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8544 IT_CHARPOS (*it)));
8545 result = MOVE_LINE_CONTINUED;
8546 break;
8549 if (BUFFER_POS_REACHED_P ())
8551 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8552 goto buffer_pos_reached;
8553 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8555 SAVE_IT (atpos_it, *it, atpos_data);
8556 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8560 if (new_x > it->first_visible_x)
8562 /* Glyph is visible. Increment number of glyphs that
8563 would be displayed. */
8564 ++it->hpos;
8568 if (result != MOVE_UNDEFINED)
8569 break;
8571 else if (BUFFER_POS_REACHED_P ())
8573 buffer_pos_reached:
8574 IT_RESET_X_ASCENT_DESCENT (it);
8575 result = MOVE_POS_MATCH_OR_ZV;
8576 break;
8578 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8580 /* Stop when TO_X specified and reached. This check is
8581 necessary here because of lines consisting of a line end,
8582 only. The line end will not produce any glyphs and we
8583 would never get MOVE_X_REACHED. */
8584 eassert (it->nglyphs == 0);
8585 result = MOVE_X_REACHED;
8586 break;
8589 /* Is this a line end? If yes, we're done. */
8590 if (ITERATOR_AT_END_OF_LINE_P (it))
8592 /* If we are past TO_CHARPOS, but never saw any character
8593 positions smaller than TO_CHARPOS, return
8594 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8595 did. */
8596 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8598 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8600 if (IT_CHARPOS (ppos_it) < ZV)
8602 RESTORE_IT (it, &ppos_it, ppos_data);
8603 result = MOVE_POS_MATCH_OR_ZV;
8605 else
8606 goto buffer_pos_reached;
8608 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8609 && IT_CHARPOS (*it) > to_charpos)
8610 goto buffer_pos_reached;
8611 else
8612 result = MOVE_NEWLINE_OR_CR;
8614 else
8615 result = MOVE_NEWLINE_OR_CR;
8616 break;
8619 prev_method = it->method;
8620 if (it->method == GET_FROM_BUFFER)
8621 prev_pos = IT_CHARPOS (*it);
8622 /* The current display element has been consumed. Advance
8623 to the next. */
8624 set_iterator_to_next (it, 1);
8625 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8626 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8627 if (IT_CHARPOS (*it) < to_charpos)
8628 saw_smaller_pos = 1;
8629 if (it->bidi_p
8630 && (op & MOVE_TO_POS)
8631 && IT_CHARPOS (*it) >= to_charpos
8632 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8633 SAVE_IT (ppos_it, *it, ppos_data);
8635 /* Stop if lines are truncated and IT's current x-position is
8636 past the right edge of the window now. */
8637 if (it->line_wrap == TRUNCATE
8638 && it->current_x >= it->last_visible_x)
8640 if (!FRAME_WINDOW_P (it->f)
8641 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8642 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8643 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8644 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8646 int at_eob_p = 0;
8648 if ((at_eob_p = !get_next_display_element (it))
8649 || BUFFER_POS_REACHED_P ()
8650 /* If we are past TO_CHARPOS, but never saw any
8651 character positions smaller than TO_CHARPOS,
8652 return MOVE_POS_MATCH_OR_ZV, like the
8653 unidirectional display did. */
8654 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8655 && !saw_smaller_pos
8656 && IT_CHARPOS (*it) > to_charpos))
8658 if (it->bidi_p
8659 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8660 RESTORE_IT (it, &ppos_it, ppos_data);
8661 result = MOVE_POS_MATCH_OR_ZV;
8662 break;
8664 if (ITERATOR_AT_END_OF_LINE_P (it))
8666 result = MOVE_NEWLINE_OR_CR;
8667 break;
8670 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8671 && !saw_smaller_pos
8672 && IT_CHARPOS (*it) > to_charpos)
8674 if (IT_CHARPOS (ppos_it) < ZV)
8675 RESTORE_IT (it, &ppos_it, ppos_data);
8676 result = MOVE_POS_MATCH_OR_ZV;
8677 break;
8679 result = MOVE_LINE_TRUNCATED;
8680 break;
8682 #undef IT_RESET_X_ASCENT_DESCENT
8685 #undef BUFFER_POS_REACHED_P
8687 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8688 restore the saved iterator. */
8689 if (atpos_it.sp >= 0)
8690 RESTORE_IT (it, &atpos_it, atpos_data);
8691 else if (atx_it.sp >= 0)
8692 RESTORE_IT (it, &atx_it, atx_data);
8694 done:
8696 if (atpos_data)
8697 bidi_unshelve_cache (atpos_data, 1);
8698 if (atx_data)
8699 bidi_unshelve_cache (atx_data, 1);
8700 if (wrap_data)
8701 bidi_unshelve_cache (wrap_data, 1);
8702 if (ppos_data)
8703 bidi_unshelve_cache (ppos_data, 1);
8705 /* Restore the iterator settings altered at the beginning of this
8706 function. */
8707 it->glyph_row = saved_glyph_row;
8708 return result;
8711 /* For external use. */
8712 void
8713 move_it_in_display_line (struct it *it,
8714 ptrdiff_t to_charpos, int to_x,
8715 enum move_operation_enum op)
8717 if (it->line_wrap == WORD_WRAP
8718 && (op & MOVE_TO_X))
8720 struct it save_it;
8721 void *save_data = NULL;
8722 int skip;
8724 SAVE_IT (save_it, *it, save_data);
8725 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8726 /* When word-wrap is on, TO_X may lie past the end
8727 of a wrapped line. Then it->current is the
8728 character on the next line, so backtrack to the
8729 space before the wrap point. */
8730 if (skip == MOVE_LINE_CONTINUED)
8732 int prev_x = max (it->current_x - 1, 0);
8733 RESTORE_IT (it, &save_it, save_data);
8734 move_it_in_display_line_to
8735 (it, -1, prev_x, MOVE_TO_X);
8737 else
8738 bidi_unshelve_cache (save_data, 1);
8740 else
8741 move_it_in_display_line_to (it, to_charpos, to_x, op);
8745 /* Move IT forward until it satisfies one or more of the criteria in
8746 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8748 OP is a bit-mask that specifies where to stop, and in particular,
8749 which of those four position arguments makes a difference. See the
8750 description of enum move_operation_enum.
8752 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8753 screen line, this function will set IT to the next position that is
8754 displayed to the right of TO_CHARPOS on the screen. */
8756 void
8757 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8759 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8760 int line_height, line_start_x = 0, reached = 0;
8761 void *backup_data = NULL;
8763 for (;;)
8765 if (op & MOVE_TO_VPOS)
8767 /* If no TO_CHARPOS and no TO_X specified, stop at the
8768 start of the line TO_VPOS. */
8769 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8771 if (it->vpos == to_vpos)
8773 reached = 1;
8774 break;
8776 else
8777 skip = move_it_in_display_line_to (it, -1, -1, 0);
8779 else
8781 /* TO_VPOS >= 0 means stop at TO_X in the line at
8782 TO_VPOS, or at TO_POS, whichever comes first. */
8783 if (it->vpos == to_vpos)
8785 reached = 2;
8786 break;
8789 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8791 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8793 reached = 3;
8794 break;
8796 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8798 /* We have reached TO_X but not in the line we want. */
8799 skip = move_it_in_display_line_to (it, to_charpos,
8800 -1, MOVE_TO_POS);
8801 if (skip == MOVE_POS_MATCH_OR_ZV)
8803 reached = 4;
8804 break;
8809 else if (op & MOVE_TO_Y)
8811 struct it it_backup;
8813 if (it->line_wrap == WORD_WRAP)
8814 SAVE_IT (it_backup, *it, backup_data);
8816 /* TO_Y specified means stop at TO_X in the line containing
8817 TO_Y---or at TO_CHARPOS if this is reached first. The
8818 problem is that we can't really tell whether the line
8819 contains TO_Y before we have completely scanned it, and
8820 this may skip past TO_X. What we do is to first scan to
8821 TO_X.
8823 If TO_X is not specified, use a TO_X of zero. The reason
8824 is to make the outcome of this function more predictable.
8825 If we didn't use TO_X == 0, we would stop at the end of
8826 the line which is probably not what a caller would expect
8827 to happen. */
8828 skip = move_it_in_display_line_to
8829 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8830 (MOVE_TO_X | (op & MOVE_TO_POS)));
8832 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8833 if (skip == MOVE_POS_MATCH_OR_ZV)
8834 reached = 5;
8835 else if (skip == MOVE_X_REACHED)
8837 /* If TO_X was reached, we want to know whether TO_Y is
8838 in the line. We know this is the case if the already
8839 scanned glyphs make the line tall enough. Otherwise,
8840 we must check by scanning the rest of the line. */
8841 line_height = it->max_ascent + it->max_descent;
8842 if (to_y >= it->current_y
8843 && to_y < it->current_y + line_height)
8845 reached = 6;
8846 break;
8848 SAVE_IT (it_backup, *it, backup_data);
8849 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8850 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8851 op & MOVE_TO_POS);
8852 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8853 line_height = it->max_ascent + it->max_descent;
8854 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8856 if (to_y >= it->current_y
8857 && to_y < it->current_y + line_height)
8859 /* If TO_Y is in this line and TO_X was reached
8860 above, we scanned too far. We have to restore
8861 IT's settings to the ones before skipping. But
8862 keep the more accurate values of max_ascent and
8863 max_descent we've found while skipping the rest
8864 of the line, for the sake of callers, such as
8865 pos_visible_p, that need to know the line
8866 height. */
8867 int max_ascent = it->max_ascent;
8868 int max_descent = it->max_descent;
8870 RESTORE_IT (it, &it_backup, backup_data);
8871 it->max_ascent = max_ascent;
8872 it->max_descent = max_descent;
8873 reached = 6;
8875 else
8877 skip = skip2;
8878 if (skip == MOVE_POS_MATCH_OR_ZV)
8879 reached = 7;
8882 else
8884 /* Check whether TO_Y is in this line. */
8885 line_height = it->max_ascent + it->max_descent;
8886 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8888 if (to_y >= it->current_y
8889 && to_y < it->current_y + line_height)
8891 /* When word-wrap is on, TO_X may lie past the end
8892 of a wrapped line. Then it->current is the
8893 character on the next line, so backtrack to the
8894 space before the wrap point. */
8895 if (skip == MOVE_LINE_CONTINUED
8896 && it->line_wrap == WORD_WRAP)
8898 int prev_x = max (it->current_x - 1, 0);
8899 RESTORE_IT (it, &it_backup, backup_data);
8900 skip = move_it_in_display_line_to
8901 (it, -1, prev_x, MOVE_TO_X);
8903 reached = 6;
8907 if (reached)
8908 break;
8910 else if (BUFFERP (it->object)
8911 && (it->method == GET_FROM_BUFFER
8912 || it->method == GET_FROM_STRETCH)
8913 && IT_CHARPOS (*it) >= to_charpos
8914 /* Under bidi iteration, a call to set_iterator_to_next
8915 can scan far beyond to_charpos if the initial
8916 portion of the next line needs to be reordered. In
8917 that case, give move_it_in_display_line_to another
8918 chance below. */
8919 && !(it->bidi_p
8920 && it->bidi_it.scan_dir == -1))
8921 skip = MOVE_POS_MATCH_OR_ZV;
8922 else
8923 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8925 switch (skip)
8927 case MOVE_POS_MATCH_OR_ZV:
8928 reached = 8;
8929 goto out;
8931 case MOVE_NEWLINE_OR_CR:
8932 set_iterator_to_next (it, 1);
8933 it->continuation_lines_width = 0;
8934 break;
8936 case MOVE_LINE_TRUNCATED:
8937 it->continuation_lines_width = 0;
8938 reseat_at_next_visible_line_start (it, 0);
8939 if ((op & MOVE_TO_POS) != 0
8940 && IT_CHARPOS (*it) > to_charpos)
8942 reached = 9;
8943 goto out;
8945 break;
8947 case MOVE_LINE_CONTINUED:
8948 /* For continued lines ending in a tab, some of the glyphs
8949 associated with the tab are displayed on the current
8950 line. Since it->current_x does not include these glyphs,
8951 we use it->last_visible_x instead. */
8952 if (it->c == '\t')
8954 it->continuation_lines_width += it->last_visible_x;
8955 /* When moving by vpos, ensure that the iterator really
8956 advances to the next line (bug#847, bug#969). Fixme:
8957 do we need to do this in other circumstances? */
8958 if (it->current_x != it->last_visible_x
8959 && (op & MOVE_TO_VPOS)
8960 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8962 line_start_x = it->current_x + it->pixel_width
8963 - it->last_visible_x;
8964 set_iterator_to_next (it, 0);
8967 else
8968 it->continuation_lines_width += it->current_x;
8969 break;
8971 default:
8972 emacs_abort ();
8975 /* Reset/increment for the next run. */
8976 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8977 it->current_x = line_start_x;
8978 line_start_x = 0;
8979 it->hpos = 0;
8980 it->current_y += it->max_ascent + it->max_descent;
8981 ++it->vpos;
8982 last_height = it->max_ascent + it->max_descent;
8983 it->max_ascent = it->max_descent = 0;
8986 out:
8988 /* On text terminals, we may stop at the end of a line in the middle
8989 of a multi-character glyph. If the glyph itself is continued,
8990 i.e. it is actually displayed on the next line, don't treat this
8991 stopping point as valid; move to the next line instead (unless
8992 that brings us offscreen). */
8993 if (!FRAME_WINDOW_P (it->f)
8994 && op & MOVE_TO_POS
8995 && IT_CHARPOS (*it) == to_charpos
8996 && it->what == IT_CHARACTER
8997 && it->nglyphs > 1
8998 && it->line_wrap == WINDOW_WRAP
8999 && it->current_x == it->last_visible_x - 1
9000 && it->c != '\n'
9001 && it->c != '\t'
9002 && it->vpos < XFASTINT (it->w->window_end_vpos))
9004 it->continuation_lines_width += it->current_x;
9005 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9006 it->current_y += it->max_ascent + it->max_descent;
9007 ++it->vpos;
9008 last_height = it->max_ascent + it->max_descent;
9011 if (backup_data)
9012 bidi_unshelve_cache (backup_data, 1);
9014 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9018 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9020 If DY > 0, move IT backward at least that many pixels. DY = 0
9021 means move IT backward to the preceding line start or BEGV. This
9022 function may move over more than DY pixels if IT->current_y - DY
9023 ends up in the middle of a line; in this case IT->current_y will be
9024 set to the top of the line moved to. */
9026 void
9027 move_it_vertically_backward (struct it *it, int dy)
9029 int nlines, h;
9030 struct it it2, it3;
9031 void *it2data = NULL, *it3data = NULL;
9032 ptrdiff_t start_pos;
9033 int nchars_per_row
9034 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9035 ptrdiff_t pos_limit;
9037 move_further_back:
9038 eassert (dy >= 0);
9040 start_pos = IT_CHARPOS (*it);
9042 /* Estimate how many newlines we must move back. */
9043 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
9044 if (it->line_wrap == TRUNCATE)
9045 pos_limit = BEGV;
9046 else
9047 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9049 /* Set the iterator's position that many lines back. But don't go
9050 back more than NLINES full screen lines -- this wins a day with
9051 buffers which have very long lines. */
9052 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9053 back_to_previous_visible_line_start (it);
9055 /* Reseat the iterator here. When moving backward, we don't want
9056 reseat to skip forward over invisible text, set up the iterator
9057 to deliver from overlay strings at the new position etc. So,
9058 use reseat_1 here. */
9059 reseat_1 (it, it->current.pos, 1);
9061 /* We are now surely at a line start. */
9062 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9063 reordering is in effect. */
9064 it->continuation_lines_width = 0;
9066 /* Move forward and see what y-distance we moved. First move to the
9067 start of the next line so that we get its height. We need this
9068 height to be able to tell whether we reached the specified
9069 y-distance. */
9070 SAVE_IT (it2, *it, it2data);
9071 it2.max_ascent = it2.max_descent = 0;
9074 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9075 MOVE_TO_POS | MOVE_TO_VPOS);
9077 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9078 /* If we are in a display string which starts at START_POS,
9079 and that display string includes a newline, and we are
9080 right after that newline (i.e. at the beginning of a
9081 display line), exit the loop, because otherwise we will
9082 infloop, since move_it_to will see that it is already at
9083 START_POS and will not move. */
9084 || (it2.method == GET_FROM_STRING
9085 && IT_CHARPOS (it2) == start_pos
9086 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9087 eassert (IT_CHARPOS (*it) >= BEGV);
9088 SAVE_IT (it3, it2, it3data);
9090 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9091 eassert (IT_CHARPOS (*it) >= BEGV);
9092 /* H is the actual vertical distance from the position in *IT
9093 and the starting position. */
9094 h = it2.current_y - it->current_y;
9095 /* NLINES is the distance in number of lines. */
9096 nlines = it2.vpos - it->vpos;
9098 /* Correct IT's y and vpos position
9099 so that they are relative to the starting point. */
9100 it->vpos -= nlines;
9101 it->current_y -= h;
9103 if (dy == 0)
9105 /* DY == 0 means move to the start of the screen line. The
9106 value of nlines is > 0 if continuation lines were involved,
9107 or if the original IT position was at start of a line. */
9108 RESTORE_IT (it, it, it2data);
9109 if (nlines > 0)
9110 move_it_by_lines (it, nlines);
9111 /* The above code moves us to some position NLINES down,
9112 usually to its first glyph (leftmost in an L2R line), but
9113 that's not necessarily the start of the line, under bidi
9114 reordering. We want to get to the character position
9115 that is immediately after the newline of the previous
9116 line. */
9117 if (it->bidi_p
9118 && !it->continuation_lines_width
9119 && !STRINGP (it->string)
9120 && IT_CHARPOS (*it) > BEGV
9121 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9123 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9125 DEC_BOTH (cp, bp);
9126 cp = find_newline_no_quit (cp, bp, -1, NULL);
9127 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9129 bidi_unshelve_cache (it3data, 1);
9131 else
9133 /* The y-position we try to reach, relative to *IT.
9134 Note that H has been subtracted in front of the if-statement. */
9135 int target_y = it->current_y + h - dy;
9136 int y0 = it3.current_y;
9137 int y1;
9138 int line_height;
9140 RESTORE_IT (&it3, &it3, it3data);
9141 y1 = line_bottom_y (&it3);
9142 line_height = y1 - y0;
9143 RESTORE_IT (it, it, it2data);
9144 /* If we did not reach target_y, try to move further backward if
9145 we can. If we moved too far backward, try to move forward. */
9146 if (target_y < it->current_y
9147 /* This is heuristic. In a window that's 3 lines high, with
9148 a line height of 13 pixels each, recentering with point
9149 on the bottom line will try to move -39/2 = 19 pixels
9150 backward. Try to avoid moving into the first line. */
9151 && (it->current_y - target_y
9152 > min (window_box_height (it->w), line_height * 2 / 3))
9153 && IT_CHARPOS (*it) > BEGV)
9155 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9156 target_y - it->current_y));
9157 dy = it->current_y - target_y;
9158 goto move_further_back;
9160 else if (target_y >= it->current_y + line_height
9161 && IT_CHARPOS (*it) < ZV)
9163 /* Should move forward by at least one line, maybe more.
9165 Note: Calling move_it_by_lines can be expensive on
9166 terminal frames, where compute_motion is used (via
9167 vmotion) to do the job, when there are very long lines
9168 and truncate-lines is nil. That's the reason for
9169 treating terminal frames specially here. */
9171 if (!FRAME_WINDOW_P (it->f))
9172 move_it_vertically (it, target_y - (it->current_y + line_height));
9173 else
9177 move_it_by_lines (it, 1);
9179 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9186 /* Move IT by a specified amount of pixel lines DY. DY negative means
9187 move backwards. DY = 0 means move to start of screen line. At the
9188 end, IT will be on the start of a screen line. */
9190 void
9191 move_it_vertically (struct it *it, int dy)
9193 if (dy <= 0)
9194 move_it_vertically_backward (it, -dy);
9195 else
9197 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9198 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9199 MOVE_TO_POS | MOVE_TO_Y);
9200 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9202 /* If buffer ends in ZV without a newline, move to the start of
9203 the line to satisfy the post-condition. */
9204 if (IT_CHARPOS (*it) == ZV
9205 && ZV > BEGV
9206 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9207 move_it_by_lines (it, 0);
9212 /* Move iterator IT past the end of the text line it is in. */
9214 void
9215 move_it_past_eol (struct it *it)
9217 enum move_it_result rc;
9219 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9220 if (rc == MOVE_NEWLINE_OR_CR)
9221 set_iterator_to_next (it, 0);
9225 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9226 negative means move up. DVPOS == 0 means move to the start of the
9227 screen line.
9229 Optimization idea: If we would know that IT->f doesn't use
9230 a face with proportional font, we could be faster for
9231 truncate-lines nil. */
9233 void
9234 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9237 /* The commented-out optimization uses vmotion on terminals. This
9238 gives bad results, because elements like it->what, on which
9239 callers such as pos_visible_p rely, aren't updated. */
9240 /* struct position pos;
9241 if (!FRAME_WINDOW_P (it->f))
9243 struct text_pos textpos;
9245 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9246 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9247 reseat (it, textpos, 1);
9248 it->vpos += pos.vpos;
9249 it->current_y += pos.vpos;
9251 else */
9253 if (dvpos == 0)
9255 /* DVPOS == 0 means move to the start of the screen line. */
9256 move_it_vertically_backward (it, 0);
9257 /* Let next call to line_bottom_y calculate real line height */
9258 last_height = 0;
9260 else if (dvpos > 0)
9262 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9263 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9265 /* Only move to the next buffer position if we ended up in a
9266 string from display property, not in an overlay string
9267 (before-string or after-string). That is because the
9268 latter don't conceal the underlying buffer position, so
9269 we can ask to move the iterator to the exact position we
9270 are interested in. Note that, even if we are already at
9271 IT_CHARPOS (*it), the call below is not a no-op, as it
9272 will detect that we are at the end of the string, pop the
9273 iterator, and compute it->current_x and it->hpos
9274 correctly. */
9275 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9276 -1, -1, -1, MOVE_TO_POS);
9279 else
9281 struct it it2;
9282 void *it2data = NULL;
9283 ptrdiff_t start_charpos, i;
9284 int nchars_per_row
9285 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9286 ptrdiff_t pos_limit;
9288 /* Start at the beginning of the screen line containing IT's
9289 position. This may actually move vertically backwards,
9290 in case of overlays, so adjust dvpos accordingly. */
9291 dvpos += it->vpos;
9292 move_it_vertically_backward (it, 0);
9293 dvpos -= it->vpos;
9295 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9296 screen lines, and reseat the iterator there. */
9297 start_charpos = IT_CHARPOS (*it);
9298 if (it->line_wrap == TRUNCATE)
9299 pos_limit = BEGV;
9300 else
9301 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9302 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9303 back_to_previous_visible_line_start (it);
9304 reseat (it, it->current.pos, 1);
9306 /* Move further back if we end up in a string or an image. */
9307 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9309 /* First try to move to start of display line. */
9310 dvpos += it->vpos;
9311 move_it_vertically_backward (it, 0);
9312 dvpos -= it->vpos;
9313 if (IT_POS_VALID_AFTER_MOVE_P (it))
9314 break;
9315 /* If start of line is still in string or image,
9316 move further back. */
9317 back_to_previous_visible_line_start (it);
9318 reseat (it, it->current.pos, 1);
9319 dvpos--;
9322 it->current_x = it->hpos = 0;
9324 /* Above call may have moved too far if continuation lines
9325 are involved. Scan forward and see if it did. */
9326 SAVE_IT (it2, *it, it2data);
9327 it2.vpos = it2.current_y = 0;
9328 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9329 it->vpos -= it2.vpos;
9330 it->current_y -= it2.current_y;
9331 it->current_x = it->hpos = 0;
9333 /* If we moved too far back, move IT some lines forward. */
9334 if (it2.vpos > -dvpos)
9336 int delta = it2.vpos + dvpos;
9338 RESTORE_IT (&it2, &it2, it2data);
9339 SAVE_IT (it2, *it, it2data);
9340 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9341 /* Move back again if we got too far ahead. */
9342 if (IT_CHARPOS (*it) >= start_charpos)
9343 RESTORE_IT (it, &it2, it2data);
9344 else
9345 bidi_unshelve_cache (it2data, 1);
9347 else
9348 RESTORE_IT (it, it, it2data);
9352 /* Return 1 if IT points into the middle of a display vector. */
9355 in_display_vector_p (struct it *it)
9357 return (it->method == GET_FROM_DISPLAY_VECTOR
9358 && it->current.dpvec_index > 0
9359 && it->dpvec + it->current.dpvec_index != it->dpend);
9363 /***********************************************************************
9364 Messages
9365 ***********************************************************************/
9368 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9369 to *Messages*. */
9371 void
9372 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9374 Lisp_Object args[3];
9375 Lisp_Object msg, fmt;
9376 char *buffer;
9377 ptrdiff_t len;
9378 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9379 USE_SAFE_ALLOCA;
9381 fmt = msg = Qnil;
9382 GCPRO4 (fmt, msg, arg1, arg2);
9384 args[0] = fmt = build_string (format);
9385 args[1] = arg1;
9386 args[2] = arg2;
9387 msg = Fformat (3, args);
9389 len = SBYTES (msg) + 1;
9390 buffer = SAFE_ALLOCA (len);
9391 memcpy (buffer, SDATA (msg), len);
9393 message_dolog (buffer, len - 1, 1, 0);
9394 SAFE_FREE ();
9396 UNGCPRO;
9400 /* Output a newline in the *Messages* buffer if "needs" one. */
9402 void
9403 message_log_maybe_newline (void)
9405 if (message_log_need_newline)
9406 message_dolog ("", 0, 1, 0);
9410 /* Add a string M of length NBYTES to the message log, optionally
9411 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9412 true, means interpret the contents of M as multibyte. This
9413 function calls low-level routines in order to bypass text property
9414 hooks, etc. which might not be safe to run.
9416 This may GC (insert may run before/after change hooks),
9417 so the buffer M must NOT point to a Lisp string. */
9419 void
9420 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9422 const unsigned char *msg = (const unsigned char *) m;
9424 if (!NILP (Vmemory_full))
9425 return;
9427 if (!NILP (Vmessage_log_max))
9429 struct buffer *oldbuf;
9430 Lisp_Object oldpoint, oldbegv, oldzv;
9431 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9432 ptrdiff_t point_at_end = 0;
9433 ptrdiff_t zv_at_end = 0;
9434 Lisp_Object old_deactivate_mark;
9435 bool shown;
9436 struct gcpro gcpro1;
9438 old_deactivate_mark = Vdeactivate_mark;
9439 oldbuf = current_buffer;
9440 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9441 bset_undo_list (current_buffer, Qt);
9443 oldpoint = message_dolog_marker1;
9444 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9445 oldbegv = message_dolog_marker2;
9446 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9447 oldzv = message_dolog_marker3;
9448 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9449 GCPRO1 (old_deactivate_mark);
9451 if (PT == Z)
9452 point_at_end = 1;
9453 if (ZV == Z)
9454 zv_at_end = 1;
9456 BEGV = BEG;
9457 BEGV_BYTE = BEG_BYTE;
9458 ZV = Z;
9459 ZV_BYTE = Z_BYTE;
9460 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9462 /* Insert the string--maybe converting multibyte to single byte
9463 or vice versa, so that all the text fits the buffer. */
9464 if (multibyte
9465 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9467 ptrdiff_t i;
9468 int c, char_bytes;
9469 char work[1];
9471 /* Convert a multibyte string to single-byte
9472 for the *Message* buffer. */
9473 for (i = 0; i < nbytes; i += char_bytes)
9475 c = string_char_and_length (msg + i, &char_bytes);
9476 work[0] = (ASCII_CHAR_P (c)
9478 : multibyte_char_to_unibyte (c));
9479 insert_1_both (work, 1, 1, 1, 0, 0);
9482 else if (! multibyte
9483 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9485 ptrdiff_t i;
9486 int c, char_bytes;
9487 unsigned char str[MAX_MULTIBYTE_LENGTH];
9488 /* Convert a single-byte string to multibyte
9489 for the *Message* buffer. */
9490 for (i = 0; i < nbytes; i++)
9492 c = msg[i];
9493 MAKE_CHAR_MULTIBYTE (c);
9494 char_bytes = CHAR_STRING (c, str);
9495 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9498 else if (nbytes)
9499 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9501 if (nlflag)
9503 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9504 printmax_t dups;
9506 insert_1_both ("\n", 1, 1, 1, 0, 0);
9508 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9509 this_bol = PT;
9510 this_bol_byte = PT_BYTE;
9512 /* See if this line duplicates the previous one.
9513 If so, combine duplicates. */
9514 if (this_bol > BEG)
9516 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9517 prev_bol = PT;
9518 prev_bol_byte = PT_BYTE;
9520 dups = message_log_check_duplicate (prev_bol_byte,
9521 this_bol_byte);
9522 if (dups)
9524 del_range_both (prev_bol, prev_bol_byte,
9525 this_bol, this_bol_byte, 0);
9526 if (dups > 1)
9528 char dupstr[sizeof " [ times]"
9529 + INT_STRLEN_BOUND (printmax_t)];
9531 /* If you change this format, don't forget to also
9532 change message_log_check_duplicate. */
9533 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9534 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9535 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
9540 /* If we have more than the desired maximum number of lines
9541 in the *Messages* buffer now, delete the oldest ones.
9542 This is safe because we don't have undo in this buffer. */
9544 if (NATNUMP (Vmessage_log_max))
9546 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9547 -XFASTINT (Vmessage_log_max) - 1, 0);
9548 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9551 BEGV = marker_position (oldbegv);
9552 BEGV_BYTE = marker_byte_position (oldbegv);
9554 if (zv_at_end)
9556 ZV = Z;
9557 ZV_BYTE = Z_BYTE;
9559 else
9561 ZV = marker_position (oldzv);
9562 ZV_BYTE = marker_byte_position (oldzv);
9565 if (point_at_end)
9566 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9567 else
9568 /* We can't do Fgoto_char (oldpoint) because it will run some
9569 Lisp code. */
9570 TEMP_SET_PT_BOTH (marker_position (oldpoint),
9571 marker_byte_position (oldpoint));
9573 UNGCPRO;
9574 unchain_marker (XMARKER (oldpoint));
9575 unchain_marker (XMARKER (oldbegv));
9576 unchain_marker (XMARKER (oldzv));
9578 shown = buffer_window_count (current_buffer) > 0;
9579 set_buffer_internal (oldbuf);
9580 /* We called insert_1_both above with its 5th argument (PREPARE)
9581 zero, which prevents insert_1_both from calling
9582 prepare_to_modify_buffer, which in turns prevents us from
9583 incrementing windows_or_buffers_changed even if *Messages* is
9584 shown in some window. So we must manually incrementing
9585 windows_or_buffers_changed here to make up for that. */
9586 if (shown)
9587 windows_or_buffers_changed++;
9588 else
9589 windows_or_buffers_changed = old_windows_or_buffers_changed;
9590 message_log_need_newline = !nlflag;
9591 Vdeactivate_mark = old_deactivate_mark;
9596 /* We are at the end of the buffer after just having inserted a newline.
9597 (Note: We depend on the fact we won't be crossing the gap.)
9598 Check to see if the most recent message looks a lot like the previous one.
9599 Return 0 if different, 1 if the new one should just replace it, or a
9600 value N > 1 if we should also append " [N times]". */
9602 static intmax_t
9603 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9605 ptrdiff_t i;
9606 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9607 int seen_dots = 0;
9608 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9609 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9611 for (i = 0; i < len; i++)
9613 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
9614 seen_dots = 1;
9615 if (p1[i] != p2[i])
9616 return seen_dots;
9618 p1 += len;
9619 if (*p1 == '\n')
9620 return 2;
9621 if (*p1++ == ' ' && *p1++ == '[')
9623 char *pend;
9624 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9625 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9626 return n + 1;
9628 return 0;
9632 /* Display an echo area message M with a specified length of NBYTES
9633 bytes. The string may include null characters. If M is not a
9634 string, clear out any existing message, and let the mini-buffer
9635 text show through.
9637 This function cancels echoing. */
9639 void
9640 message3 (Lisp_Object m)
9642 struct gcpro gcpro1;
9644 GCPRO1 (m);
9645 clear_message (1,1);
9646 cancel_echoing ();
9648 /* First flush out any partial line written with print. */
9649 message_log_maybe_newline ();
9650 if (STRINGP (m))
9652 ptrdiff_t nbytes = SBYTES (m);
9653 bool multibyte = STRING_MULTIBYTE (m);
9654 USE_SAFE_ALLOCA;
9655 char *buffer = SAFE_ALLOCA (nbytes);
9656 memcpy (buffer, SDATA (m), nbytes);
9657 message_dolog (buffer, nbytes, 1, multibyte);
9658 SAFE_FREE ();
9660 message3_nolog (m);
9662 UNGCPRO;
9666 /* The non-logging version of message3.
9667 This does not cancel echoing, because it is used for echoing.
9668 Perhaps we need to make a separate function for echoing
9669 and make this cancel echoing. */
9671 void
9672 message3_nolog (Lisp_Object m)
9674 struct frame *sf = SELECTED_FRAME ();
9676 if (FRAME_INITIAL_P (sf))
9678 if (noninteractive_need_newline)
9679 putc ('\n', stderr);
9680 noninteractive_need_newline = 0;
9681 if (STRINGP (m))
9682 fwrite (SDATA (m), SBYTES (m), 1, stderr);
9683 if (cursor_in_echo_area == 0)
9684 fprintf (stderr, "\n");
9685 fflush (stderr);
9687 /* Error messages get reported properly by cmd_error, so this must be just an
9688 informative message; if the frame hasn't really been initialized yet, just
9689 toss it. */
9690 else if (INTERACTIVE && sf->glyphs_initialized_p)
9692 /* Get the frame containing the mini-buffer
9693 that the selected frame is using. */
9694 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
9695 Lisp_Object frame = XWINDOW (mini_window)->frame;
9696 struct frame *f = XFRAME (frame);
9698 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
9699 Fmake_frame_visible (frame);
9701 if (STRINGP (m) && SCHARS (m) > 0)
9703 set_message (m);
9704 if (minibuffer_auto_raise)
9705 Fraise_frame (frame);
9706 /* Assume we are not echoing.
9707 (If we are, echo_now will override this.) */
9708 echo_message_buffer = Qnil;
9710 else
9711 clear_message (1, 1);
9713 do_pending_window_change (0);
9714 echo_area_display (1);
9715 do_pending_window_change (0);
9716 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
9717 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9722 /* Display a null-terminated echo area message M. If M is 0, clear
9723 out any existing message, and let the mini-buffer text show through.
9725 The buffer M must continue to exist until after the echo area gets
9726 cleared or some other message gets displayed there. Do not pass
9727 text that is stored in a Lisp string. Do not pass text in a buffer
9728 that was alloca'd. */
9730 void
9731 message1 (const char *m)
9733 message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil);
9737 /* The non-logging counterpart of message1. */
9739 void
9740 message1_nolog (const char *m)
9742 message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil);
9745 /* Display a message M which contains a single %s
9746 which gets replaced with STRING. */
9748 void
9749 message_with_string (const char *m, Lisp_Object string, int log)
9751 CHECK_STRING (string);
9753 if (noninteractive)
9755 if (m)
9757 if (noninteractive_need_newline)
9758 putc ('\n', stderr);
9759 noninteractive_need_newline = 0;
9760 fprintf (stderr, m, SDATA (string));
9761 if (!cursor_in_echo_area)
9762 fprintf (stderr, "\n");
9763 fflush (stderr);
9766 else if (INTERACTIVE)
9768 /* The frame whose minibuffer we're going to display the message on.
9769 It may be larger than the selected frame, so we need
9770 to use its buffer, not the selected frame's buffer. */
9771 Lisp_Object mini_window;
9772 struct frame *f, *sf = SELECTED_FRAME ();
9774 /* Get the frame containing the minibuffer
9775 that the selected frame is using. */
9776 mini_window = FRAME_MINIBUF_WINDOW (sf);
9777 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9779 /* Error messages get reported properly by cmd_error, so this must be
9780 just an informative message; if the frame hasn't really been
9781 initialized yet, just toss it. */
9782 if (f->glyphs_initialized_p)
9784 Lisp_Object args[2], msg;
9785 struct gcpro gcpro1, gcpro2;
9787 args[0] = build_string (m);
9788 args[1] = msg = string;
9789 GCPRO2 (args[0], msg);
9790 gcpro1.nvars = 2;
9792 msg = Fformat (2, args);
9794 if (log)
9795 message3 (msg);
9796 else
9797 message3_nolog (msg);
9799 UNGCPRO;
9801 /* Print should start at the beginning of the message
9802 buffer next time. */
9803 message_buf_print = 0;
9809 /* Dump an informative message to the minibuf. If M is 0, clear out
9810 any existing message, and let the mini-buffer text show through. */
9812 static void
9813 vmessage (const char *m, va_list ap)
9815 if (noninteractive)
9817 if (m)
9819 if (noninteractive_need_newline)
9820 putc ('\n', stderr);
9821 noninteractive_need_newline = 0;
9822 vfprintf (stderr, m, ap);
9823 if (cursor_in_echo_area == 0)
9824 fprintf (stderr, "\n");
9825 fflush (stderr);
9828 else if (INTERACTIVE)
9830 /* The frame whose mini-buffer we're going to display the message
9831 on. It may be larger than the selected frame, so we need to
9832 use its buffer, not the selected frame's buffer. */
9833 Lisp_Object mini_window;
9834 struct frame *f, *sf = SELECTED_FRAME ();
9836 /* Get the frame containing the mini-buffer
9837 that the selected frame is using. */
9838 mini_window = FRAME_MINIBUF_WINDOW (sf);
9839 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9841 /* Error messages get reported properly by cmd_error, so this must be
9842 just an informative message; if the frame hasn't really been
9843 initialized yet, just toss it. */
9844 if (f->glyphs_initialized_p)
9846 if (m)
9848 ptrdiff_t len;
9849 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9850 char *message_buf = alloca (maxsize + 1);
9852 len = doprnt (message_buf, maxsize, m, (char *)0, ap);
9854 message3 (make_string (message_buf, len));
9856 else
9857 message1 (0);
9859 /* Print should start at the beginning of the message
9860 buffer next time. */
9861 message_buf_print = 0;
9866 void
9867 message (const char *m, ...)
9869 va_list ap;
9870 va_start (ap, m);
9871 vmessage (m, ap);
9872 va_end (ap);
9876 #if 0
9877 /* The non-logging version of message. */
9879 void
9880 message_nolog (const char *m, ...)
9882 Lisp_Object old_log_max;
9883 va_list ap;
9884 va_start (ap, m);
9885 old_log_max = Vmessage_log_max;
9886 Vmessage_log_max = Qnil;
9887 vmessage (m, ap);
9888 Vmessage_log_max = old_log_max;
9889 va_end (ap);
9891 #endif
9894 /* Display the current message in the current mini-buffer. This is
9895 only called from error handlers in process.c, and is not time
9896 critical. */
9898 void
9899 update_echo_area (void)
9901 if (!NILP (echo_area_buffer[0]))
9903 Lisp_Object string;
9904 string = Fcurrent_message ();
9905 message3 (string);
9910 /* Make sure echo area buffers in `echo_buffers' are live.
9911 If they aren't, make new ones. */
9913 static void
9914 ensure_echo_area_buffers (void)
9916 int i;
9918 for (i = 0; i < 2; ++i)
9919 if (!BUFFERP (echo_buffer[i])
9920 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
9922 char name[30];
9923 Lisp_Object old_buffer;
9924 int j;
9926 old_buffer = echo_buffer[i];
9927 echo_buffer[i] = Fget_buffer_create
9928 (make_formatted_string (name, " *Echo Area %d*", i));
9929 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
9930 /* to force word wrap in echo area -
9931 it was decided to postpone this*/
9932 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9934 for (j = 0; j < 2; ++j)
9935 if (EQ (old_buffer, echo_area_buffer[j]))
9936 echo_area_buffer[j] = echo_buffer[i];
9941 /* Call FN with args A1..A2 with either the current or last displayed
9942 echo_area_buffer as current buffer.
9944 WHICH zero means use the current message buffer
9945 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9946 from echo_buffer[] and clear it.
9948 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9949 suitable buffer from echo_buffer[] and clear it.
9951 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9952 that the current message becomes the last displayed one, make
9953 choose a suitable buffer for echo_area_buffer[0], and clear it.
9955 Value is what FN returns. */
9957 static int
9958 with_echo_area_buffer (struct window *w, int which,
9959 int (*fn) (ptrdiff_t, Lisp_Object),
9960 ptrdiff_t a1, Lisp_Object a2)
9962 Lisp_Object buffer;
9963 int this_one, the_other, clear_buffer_p, rc;
9964 ptrdiff_t count = SPECPDL_INDEX ();
9966 /* If buffers aren't live, make new ones. */
9967 ensure_echo_area_buffers ();
9969 clear_buffer_p = 0;
9971 if (which == 0)
9972 this_one = 0, the_other = 1;
9973 else if (which > 0)
9974 this_one = 1, the_other = 0;
9975 else
9977 this_one = 0, the_other = 1;
9978 clear_buffer_p = 1;
9980 /* We need a fresh one in case the current echo buffer equals
9981 the one containing the last displayed echo area message. */
9982 if (!NILP (echo_area_buffer[this_one])
9983 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
9984 echo_area_buffer[this_one] = Qnil;
9987 /* Choose a suitable buffer from echo_buffer[] is we don't
9988 have one. */
9989 if (NILP (echo_area_buffer[this_one]))
9991 echo_area_buffer[this_one]
9992 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
9993 ? echo_buffer[the_other]
9994 : echo_buffer[this_one]);
9995 clear_buffer_p = 1;
9998 buffer = echo_area_buffer[this_one];
10000 /* Don't get confused by reusing the buffer used for echoing
10001 for a different purpose. */
10002 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10003 cancel_echoing ();
10005 record_unwind_protect (unwind_with_echo_area_buffer,
10006 with_echo_area_buffer_unwind_data (w));
10008 /* Make the echo area buffer current. Note that for display
10009 purposes, it is not necessary that the displayed window's buffer
10010 == current_buffer, except for text property lookup. So, let's
10011 only set that buffer temporarily here without doing a full
10012 Fset_window_buffer. We must also change w->pointm, though,
10013 because otherwise an assertions in unshow_buffer fails, and Emacs
10014 aborts. */
10015 set_buffer_internal_1 (XBUFFER (buffer));
10016 if (w)
10018 wset_buffer (w, buffer);
10019 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10022 bset_undo_list (current_buffer, Qt);
10023 bset_read_only (current_buffer, Qnil);
10024 specbind (Qinhibit_read_only, Qt);
10025 specbind (Qinhibit_modification_hooks, Qt);
10027 if (clear_buffer_p && Z > BEG)
10028 del_range (BEG, Z);
10030 eassert (BEGV >= BEG);
10031 eassert (ZV <= Z && ZV >= BEGV);
10033 rc = fn (a1, a2);
10035 eassert (BEGV >= BEG);
10036 eassert (ZV <= Z && ZV >= BEGV);
10038 unbind_to (count, Qnil);
10039 return rc;
10043 /* Save state that should be preserved around the call to the function
10044 FN called in with_echo_area_buffer. */
10046 static Lisp_Object
10047 with_echo_area_buffer_unwind_data (struct window *w)
10049 int i = 0;
10050 Lisp_Object vector, tmp;
10052 /* Reduce consing by keeping one vector in
10053 Vwith_echo_area_save_vector. */
10054 vector = Vwith_echo_area_save_vector;
10055 Vwith_echo_area_save_vector = Qnil;
10057 if (NILP (vector))
10058 vector = Fmake_vector (make_number (9), Qnil);
10060 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10061 ASET (vector, i, Vdeactivate_mark); ++i;
10062 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10064 if (w)
10066 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10067 ASET (vector, i, w->contents); ++i;
10068 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10069 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10070 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10071 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10073 else
10075 int end = i + 6;
10076 for (; i < end; ++i)
10077 ASET (vector, i, Qnil);
10080 eassert (i == ASIZE (vector));
10081 return vector;
10085 /* Restore global state from VECTOR which was created by
10086 with_echo_area_buffer_unwind_data. */
10088 static Lisp_Object
10089 unwind_with_echo_area_buffer (Lisp_Object vector)
10091 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10092 Vdeactivate_mark = AREF (vector, 1);
10093 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10095 if (WINDOWP (AREF (vector, 3)))
10097 struct window *w;
10098 Lisp_Object buffer;
10100 w = XWINDOW (AREF (vector, 3));
10101 buffer = AREF (vector, 4);
10103 wset_buffer (w, buffer);
10104 set_marker_both (w->pointm, buffer,
10105 XFASTINT (AREF (vector, 5)),
10106 XFASTINT (AREF (vector, 6)));
10107 set_marker_both (w->start, buffer,
10108 XFASTINT (AREF (vector, 7)),
10109 XFASTINT (AREF (vector, 8)));
10112 Vwith_echo_area_save_vector = vector;
10113 return Qnil;
10117 /* Set up the echo area for use by print functions. MULTIBYTE_P
10118 non-zero means we will print multibyte. */
10120 void
10121 setup_echo_area_for_printing (int multibyte_p)
10123 /* If we can't find an echo area any more, exit. */
10124 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10125 Fkill_emacs (Qnil);
10127 ensure_echo_area_buffers ();
10129 if (!message_buf_print)
10131 /* A message has been output since the last time we printed.
10132 Choose a fresh echo area buffer. */
10133 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10134 echo_area_buffer[0] = echo_buffer[1];
10135 else
10136 echo_area_buffer[0] = echo_buffer[0];
10138 /* Switch to that buffer and clear it. */
10139 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10140 bset_truncate_lines (current_buffer, Qnil);
10142 if (Z > BEG)
10144 ptrdiff_t count = SPECPDL_INDEX ();
10145 specbind (Qinhibit_read_only, Qt);
10146 /* Note that undo recording is always disabled. */
10147 del_range (BEG, Z);
10148 unbind_to (count, Qnil);
10150 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10152 /* Set up the buffer for the multibyteness we need. */
10153 if (multibyte_p
10154 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10155 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10157 /* Raise the frame containing the echo area. */
10158 if (minibuffer_auto_raise)
10160 struct frame *sf = SELECTED_FRAME ();
10161 Lisp_Object mini_window;
10162 mini_window = FRAME_MINIBUF_WINDOW (sf);
10163 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10166 message_log_maybe_newline ();
10167 message_buf_print = 1;
10169 else
10171 if (NILP (echo_area_buffer[0]))
10173 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10174 echo_area_buffer[0] = echo_buffer[1];
10175 else
10176 echo_area_buffer[0] = echo_buffer[0];
10179 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10181 /* Someone switched buffers between print requests. */
10182 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10183 bset_truncate_lines (current_buffer, Qnil);
10189 /* Display an echo area message in window W. Value is non-zero if W's
10190 height is changed. If display_last_displayed_message_p is
10191 non-zero, display the message that was last displayed, otherwise
10192 display the current message. */
10194 static int
10195 display_echo_area (struct window *w)
10197 int i, no_message_p, window_height_changed_p;
10199 /* Temporarily disable garbage collections while displaying the echo
10200 area. This is done because a GC can print a message itself.
10201 That message would modify the echo area buffer's contents while a
10202 redisplay of the buffer is going on, and seriously confuse
10203 redisplay. */
10204 ptrdiff_t count = inhibit_garbage_collection ();
10206 /* If there is no message, we must call display_echo_area_1
10207 nevertheless because it resizes the window. But we will have to
10208 reset the echo_area_buffer in question to nil at the end because
10209 with_echo_area_buffer will sets it to an empty buffer. */
10210 i = display_last_displayed_message_p ? 1 : 0;
10211 no_message_p = NILP (echo_area_buffer[i]);
10213 window_height_changed_p
10214 = with_echo_area_buffer (w, display_last_displayed_message_p,
10215 display_echo_area_1,
10216 (intptr_t) w, Qnil);
10218 if (no_message_p)
10219 echo_area_buffer[i] = Qnil;
10221 unbind_to (count, Qnil);
10222 return window_height_changed_p;
10226 /* Helper for display_echo_area. Display the current buffer which
10227 contains the current echo area message in window W, a mini-window,
10228 a pointer to which is passed in A1. A2..A4 are currently not used.
10229 Change the height of W so that all of the message is displayed.
10230 Value is non-zero if height of W was changed. */
10232 static int
10233 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10235 intptr_t i1 = a1;
10236 struct window *w = (struct window *) i1;
10237 Lisp_Object window;
10238 struct text_pos start;
10239 int window_height_changed_p = 0;
10241 /* Do this before displaying, so that we have a large enough glyph
10242 matrix for the display. If we can't get enough space for the
10243 whole text, display the last N lines. That works by setting w->start. */
10244 window_height_changed_p = resize_mini_window (w, 0);
10246 /* Use the starting position chosen by resize_mini_window. */
10247 SET_TEXT_POS_FROM_MARKER (start, w->start);
10249 /* Display. */
10250 clear_glyph_matrix (w->desired_matrix);
10251 XSETWINDOW (window, w);
10252 try_window (window, start, 0);
10254 return window_height_changed_p;
10258 /* Resize the echo area window to exactly the size needed for the
10259 currently displayed message, if there is one. If a mini-buffer
10260 is active, don't shrink it. */
10262 void
10263 resize_echo_area_exactly (void)
10265 if (BUFFERP (echo_area_buffer[0])
10266 && WINDOWP (echo_area_window))
10268 struct window *w = XWINDOW (echo_area_window);
10269 int resized_p;
10270 Lisp_Object resize_exactly;
10272 if (minibuf_level == 0)
10273 resize_exactly = Qt;
10274 else
10275 resize_exactly = Qnil;
10277 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10278 (intptr_t) w, resize_exactly);
10279 if (resized_p)
10281 ++windows_or_buffers_changed;
10282 ++update_mode_lines;
10283 redisplay_internal ();
10289 /* Callback function for with_echo_area_buffer, when used from
10290 resize_echo_area_exactly. A1 contains a pointer to the window to
10291 resize, EXACTLY non-nil means resize the mini-window exactly to the
10292 size of the text displayed. A3 and A4 are not used. Value is what
10293 resize_mini_window returns. */
10295 static int
10296 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10298 intptr_t i1 = a1;
10299 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10303 /* Resize mini-window W to fit the size of its contents. EXACT_P
10304 means size the window exactly to the size needed. Otherwise, it's
10305 only enlarged until W's buffer is empty.
10307 Set W->start to the right place to begin display. If the whole
10308 contents fit, start at the beginning. Otherwise, start so as
10309 to make the end of the contents appear. This is particularly
10310 important for y-or-n-p, but seems desirable generally.
10312 Value is non-zero if the window height has been changed. */
10315 resize_mini_window (struct window *w, int exact_p)
10317 struct frame *f = XFRAME (w->frame);
10318 int window_height_changed_p = 0;
10320 eassert (MINI_WINDOW_P (w));
10322 /* By default, start display at the beginning. */
10323 set_marker_both (w->start, w->contents,
10324 BUF_BEGV (XBUFFER (w->contents)),
10325 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10327 /* Don't resize windows while redisplaying a window; it would
10328 confuse redisplay functions when the size of the window they are
10329 displaying changes from under them. Such a resizing can happen,
10330 for instance, when which-func prints a long message while
10331 we are running fontification-functions. We're running these
10332 functions with safe_call which binds inhibit-redisplay to t. */
10333 if (!NILP (Vinhibit_redisplay))
10334 return 0;
10336 /* Nil means don't try to resize. */
10337 if (NILP (Vresize_mini_windows)
10338 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10339 return 0;
10341 if (!FRAME_MINIBUF_ONLY_P (f))
10343 struct it it;
10344 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10345 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10346 int height;
10347 EMACS_INT max_height;
10348 int unit = FRAME_LINE_HEIGHT (f);
10349 struct text_pos start;
10350 struct buffer *old_current_buffer = NULL;
10352 if (current_buffer != XBUFFER (w->contents))
10354 old_current_buffer = current_buffer;
10355 set_buffer_internal (XBUFFER (w->contents));
10358 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10360 /* Compute the max. number of lines specified by the user. */
10361 if (FLOATP (Vmax_mini_window_height))
10362 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10363 else if (INTEGERP (Vmax_mini_window_height))
10364 max_height = XINT (Vmax_mini_window_height);
10365 else
10366 max_height = total_height / 4;
10368 /* Correct that max. height if it's bogus. */
10369 max_height = clip_to_bounds (1, max_height, total_height);
10371 /* Find out the height of the text in the window. */
10372 if (it.line_wrap == TRUNCATE)
10373 height = 1;
10374 else
10376 last_height = 0;
10377 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10378 if (it.max_ascent == 0 && it.max_descent == 0)
10379 height = it.current_y + last_height;
10380 else
10381 height = it.current_y + it.max_ascent + it.max_descent;
10382 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10383 height = (height + unit - 1) / unit;
10386 /* Compute a suitable window start. */
10387 if (height > max_height)
10389 height = max_height;
10390 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10391 move_it_vertically_backward (&it, (height - 1) * unit);
10392 start = it.current.pos;
10394 else
10395 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10396 SET_MARKER_FROM_TEXT_POS (w->start, start);
10398 if (EQ (Vresize_mini_windows, Qgrow_only))
10400 /* Let it grow only, until we display an empty message, in which
10401 case the window shrinks again. */
10402 if (height > WINDOW_TOTAL_LINES (w))
10404 int old_height = WINDOW_TOTAL_LINES (w);
10405 freeze_window_starts (f, 1);
10406 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10407 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10409 else if (height < WINDOW_TOTAL_LINES (w)
10410 && (exact_p || BEGV == ZV))
10412 int old_height = WINDOW_TOTAL_LINES (w);
10413 freeze_window_starts (f, 0);
10414 shrink_mini_window (w);
10415 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10418 else
10420 /* Always resize to exact size needed. */
10421 if (height > WINDOW_TOTAL_LINES (w))
10423 int old_height = WINDOW_TOTAL_LINES (w);
10424 freeze_window_starts (f, 1);
10425 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10426 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10428 else if (height < WINDOW_TOTAL_LINES (w))
10430 int old_height = WINDOW_TOTAL_LINES (w);
10431 freeze_window_starts (f, 0);
10432 shrink_mini_window (w);
10434 if (height)
10436 freeze_window_starts (f, 1);
10437 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10440 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10444 if (old_current_buffer)
10445 set_buffer_internal (old_current_buffer);
10448 return window_height_changed_p;
10452 /* Value is the current message, a string, or nil if there is no
10453 current message. */
10455 Lisp_Object
10456 current_message (void)
10458 Lisp_Object msg;
10460 if (!BUFFERP (echo_area_buffer[0]))
10461 msg = Qnil;
10462 else
10464 with_echo_area_buffer (0, 0, current_message_1,
10465 (intptr_t) &msg, Qnil);
10466 if (NILP (msg))
10467 echo_area_buffer[0] = Qnil;
10470 return msg;
10474 static int
10475 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10477 intptr_t i1 = a1;
10478 Lisp_Object *msg = (Lisp_Object *) i1;
10480 if (Z > BEG)
10481 *msg = make_buffer_string (BEG, Z, 1);
10482 else
10483 *msg = Qnil;
10484 return 0;
10488 /* Push the current message on Vmessage_stack for later restoration
10489 by restore_message. Value is non-zero if the current message isn't
10490 empty. This is a relatively infrequent operation, so it's not
10491 worth optimizing. */
10493 bool
10494 push_message (void)
10496 Lisp_Object msg = current_message ();
10497 Vmessage_stack = Fcons (msg, Vmessage_stack);
10498 return STRINGP (msg);
10502 /* Restore message display from the top of Vmessage_stack. */
10504 void
10505 restore_message (void)
10507 eassert (CONSP (Vmessage_stack));
10508 message3_nolog (XCAR (Vmessage_stack));
10512 /* Handler for record_unwind_protect calling pop_message. */
10514 Lisp_Object
10515 pop_message_unwind (Lisp_Object dummy)
10517 pop_message ();
10518 return Qnil;
10521 /* Pop the top-most entry off Vmessage_stack. */
10523 static void
10524 pop_message (void)
10526 eassert (CONSP (Vmessage_stack));
10527 Vmessage_stack = XCDR (Vmessage_stack);
10531 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10532 exits. If the stack is not empty, we have a missing pop_message
10533 somewhere. */
10535 void
10536 check_message_stack (void)
10538 if (!NILP (Vmessage_stack))
10539 emacs_abort ();
10543 /* Truncate to NCHARS what will be displayed in the echo area the next
10544 time we display it---but don't redisplay it now. */
10546 void
10547 truncate_echo_area (ptrdiff_t nchars)
10549 if (nchars == 0)
10550 echo_area_buffer[0] = Qnil;
10551 else if (!noninteractive
10552 && INTERACTIVE
10553 && !NILP (echo_area_buffer[0]))
10555 struct frame *sf = SELECTED_FRAME ();
10556 /* Error messages get reported properly by cmd_error, so this must be
10557 just an informative message; if the frame hasn't really been
10558 initialized yet, just toss it. */
10559 if (sf->glyphs_initialized_p)
10560 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
10565 /* Helper function for truncate_echo_area. Truncate the current
10566 message to at most NCHARS characters. */
10568 static int
10569 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
10571 if (BEG + nchars < Z)
10572 del_range (BEG + nchars, Z);
10573 if (Z == BEG)
10574 echo_area_buffer[0] = Qnil;
10575 return 0;
10578 /* Set the current message to STRING. */
10580 static void
10581 set_message (Lisp_Object string)
10583 eassert (STRINGP (string));
10585 message_enable_multibyte = STRING_MULTIBYTE (string);
10587 with_echo_area_buffer (0, -1, set_message_1, 0, string);
10588 message_buf_print = 0;
10589 help_echo_showing_p = 0;
10591 if (STRINGP (Vdebug_on_message)
10592 && STRINGP (string)
10593 && fast_string_match (Vdebug_on_message, string) >= 0)
10594 call_debugger (list2 (Qerror, string));
10598 /* Helper function for set_message. First argument is ignored and second
10599 argument has the same meaning as for set_message.
10600 This function is called with the echo area buffer being current. */
10602 static int
10603 set_message_1 (ptrdiff_t a1, Lisp_Object string)
10605 eassert (STRINGP (string));
10607 /* Change multibyteness of the echo buffer appropriately. */
10608 if (message_enable_multibyte
10609 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10610 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10612 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10613 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10614 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10616 /* Insert new message at BEG. */
10617 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10619 /* This function takes care of single/multibyte conversion.
10620 We just have to ensure that the echo area buffer has the right
10621 setting of enable_multibyte_characters. */
10622 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
10624 return 0;
10628 /* Clear messages. CURRENT_P non-zero means clear the current
10629 message. LAST_DISPLAYED_P non-zero means clear the message
10630 last displayed. */
10632 void
10633 clear_message (int current_p, int last_displayed_p)
10635 if (current_p)
10637 echo_area_buffer[0] = Qnil;
10638 message_cleared_p = 1;
10641 if (last_displayed_p)
10642 echo_area_buffer[1] = Qnil;
10644 message_buf_print = 0;
10647 /* Clear garbaged frames.
10649 This function is used where the old redisplay called
10650 redraw_garbaged_frames which in turn called redraw_frame which in
10651 turn called clear_frame. The call to clear_frame was a source of
10652 flickering. I believe a clear_frame is not necessary. It should
10653 suffice in the new redisplay to invalidate all current matrices,
10654 and ensure a complete redisplay of all windows. */
10656 static void
10657 clear_garbaged_frames (void)
10659 if (frame_garbaged)
10661 Lisp_Object tail, frame;
10662 int changed_count = 0;
10664 FOR_EACH_FRAME (tail, frame)
10666 struct frame *f = XFRAME (frame);
10668 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10670 if (f->resized_p)
10672 redraw_frame (f);
10673 f->force_flush_display_p = 1;
10675 clear_current_matrices (f);
10676 changed_count++;
10677 f->garbaged = 0;
10678 f->resized_p = 0;
10682 frame_garbaged = 0;
10683 if (changed_count)
10684 ++windows_or_buffers_changed;
10689 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10690 is non-zero update selected_frame. Value is non-zero if the
10691 mini-windows height has been changed. */
10693 static int
10694 echo_area_display (int update_frame_p)
10696 Lisp_Object mini_window;
10697 struct window *w;
10698 struct frame *f;
10699 int window_height_changed_p = 0;
10700 struct frame *sf = SELECTED_FRAME ();
10702 mini_window = FRAME_MINIBUF_WINDOW (sf);
10703 w = XWINDOW (mini_window);
10704 f = XFRAME (WINDOW_FRAME (w));
10706 /* Don't display if frame is invisible or not yet initialized. */
10707 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10708 return 0;
10710 #ifdef HAVE_WINDOW_SYSTEM
10711 /* When Emacs starts, selected_frame may be the initial terminal
10712 frame. If we let this through, a message would be displayed on
10713 the terminal. */
10714 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10715 return 0;
10716 #endif /* HAVE_WINDOW_SYSTEM */
10718 /* Redraw garbaged frames. */
10719 clear_garbaged_frames ();
10721 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10723 echo_area_window = mini_window;
10724 window_height_changed_p = display_echo_area (w);
10725 w->must_be_updated_p = 1;
10727 /* Update the display, unless called from redisplay_internal.
10728 Also don't update the screen during redisplay itself. The
10729 update will happen at the end of redisplay, and an update
10730 here could cause confusion. */
10731 if (update_frame_p && !redisplaying_p)
10733 int n = 0;
10735 /* If the display update has been interrupted by pending
10736 input, update mode lines in the frame. Due to the
10737 pending input, it might have been that redisplay hasn't
10738 been called, so that mode lines above the echo area are
10739 garbaged. This looks odd, so we prevent it here. */
10740 if (!display_completed)
10741 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10743 if (window_height_changed_p
10744 /* Don't do this if Emacs is shutting down. Redisplay
10745 needs to run hooks. */
10746 && !NILP (Vrun_hooks))
10748 /* Must update other windows. Likewise as in other
10749 cases, don't let this update be interrupted by
10750 pending input. */
10751 ptrdiff_t count = SPECPDL_INDEX ();
10752 specbind (Qredisplay_dont_pause, Qt);
10753 windows_or_buffers_changed = 1;
10754 redisplay_internal ();
10755 unbind_to (count, Qnil);
10757 else if (FRAME_WINDOW_P (f) && n == 0)
10759 /* Window configuration is the same as before.
10760 Can do with a display update of the echo area,
10761 unless we displayed some mode lines. */
10762 update_single_window (w, 1);
10763 FRAME_RIF (f)->flush_display (f);
10765 else
10766 update_frame (f, 1, 1);
10768 /* If cursor is in the echo area, make sure that the next
10769 redisplay displays the minibuffer, so that the cursor will
10770 be replaced with what the minibuffer wants. */
10771 if (cursor_in_echo_area)
10772 ++windows_or_buffers_changed;
10775 else if (!EQ (mini_window, selected_window))
10776 windows_or_buffers_changed++;
10778 /* Last displayed message is now the current message. */
10779 echo_area_buffer[1] = echo_area_buffer[0];
10780 /* Inform read_char that we're not echoing. */
10781 echo_message_buffer = Qnil;
10783 /* Prevent redisplay optimization in redisplay_internal by resetting
10784 this_line_start_pos. This is done because the mini-buffer now
10785 displays the message instead of its buffer text. */
10786 if (EQ (mini_window, selected_window))
10787 CHARPOS (this_line_start_pos) = 0;
10789 return window_height_changed_p;
10792 /* Nonzero if the current window's buffer is shown in more than one
10793 window and was modified since last redisplay. */
10795 static int
10796 buffer_shared_and_changed (void)
10798 return (buffer_window_count (current_buffer) > 1
10799 && UNCHANGED_MODIFIED < MODIFF);
10802 /* Nonzero if W doesn't reflect the actual state of current buffer due
10803 to its text or overlays change. FIXME: this may be called when
10804 XBUFFER (w->contents) != current_buffer, which looks suspicious. */
10806 static int
10807 window_outdated (struct window *w)
10809 return (w->last_modified < MODIFF
10810 || w->last_overlay_modified < OVERLAY_MODIFF);
10813 /* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10814 is enabled and mark of W's buffer was changed since last W's update. */
10816 static int
10817 window_buffer_changed (struct window *w)
10819 struct buffer *b = XBUFFER (w->contents);
10821 eassert (BUFFER_LIVE_P (b));
10823 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star)
10824 || ((!NILP (Vtransient_mark_mode) && !NILP (BVAR (b, mark_active)))
10825 != (w->region_showing != 0)));
10828 /* Nonzero if W has %c in its mode line and mode line should be updated. */
10830 static int
10831 mode_line_update_needed (struct window *w)
10833 return (w->column_number_displayed != -1
10834 && !(PT == w->last_point && !window_outdated (w))
10835 && (w->column_number_displayed != current_column ()));
10838 /***********************************************************************
10839 Mode Lines and Frame Titles
10840 ***********************************************************************/
10842 /* A buffer for constructing non-propertized mode-line strings and
10843 frame titles in it; allocated from the heap in init_xdisp and
10844 resized as needed in store_mode_line_noprop_char. */
10846 static char *mode_line_noprop_buf;
10848 /* The buffer's end, and a current output position in it. */
10850 static char *mode_line_noprop_buf_end;
10851 static char *mode_line_noprop_ptr;
10853 #define MODE_LINE_NOPROP_LEN(start) \
10854 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10856 static enum {
10857 MODE_LINE_DISPLAY = 0,
10858 MODE_LINE_TITLE,
10859 MODE_LINE_NOPROP,
10860 MODE_LINE_STRING
10861 } mode_line_target;
10863 /* Alist that caches the results of :propertize.
10864 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10865 static Lisp_Object mode_line_proptrans_alist;
10867 /* List of strings making up the mode-line. */
10868 static Lisp_Object mode_line_string_list;
10870 /* Base face property when building propertized mode line string. */
10871 static Lisp_Object mode_line_string_face;
10872 static Lisp_Object mode_line_string_face_prop;
10875 /* Unwind data for mode line strings */
10877 static Lisp_Object Vmode_line_unwind_vector;
10879 static Lisp_Object
10880 format_mode_line_unwind_data (struct frame *target_frame,
10881 struct buffer *obuf,
10882 Lisp_Object owin,
10883 int save_proptrans)
10885 Lisp_Object vector, tmp;
10887 /* Reduce consing by keeping one vector in
10888 Vwith_echo_area_save_vector. */
10889 vector = Vmode_line_unwind_vector;
10890 Vmode_line_unwind_vector = Qnil;
10892 if (NILP (vector))
10893 vector = Fmake_vector (make_number (10), Qnil);
10895 ASET (vector, 0, make_number (mode_line_target));
10896 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10897 ASET (vector, 2, mode_line_string_list);
10898 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10899 ASET (vector, 4, mode_line_string_face);
10900 ASET (vector, 5, mode_line_string_face_prop);
10902 if (obuf)
10903 XSETBUFFER (tmp, obuf);
10904 else
10905 tmp = Qnil;
10906 ASET (vector, 6, tmp);
10907 ASET (vector, 7, owin);
10908 if (target_frame)
10910 /* Similarly to `with-selected-window', if the operation selects
10911 a window on another frame, we must restore that frame's
10912 selected window, and (for a tty) the top-frame. */
10913 ASET (vector, 8, target_frame->selected_window);
10914 if (FRAME_TERMCAP_P (target_frame))
10915 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10918 return vector;
10921 static Lisp_Object
10922 unwind_format_mode_line (Lisp_Object vector)
10924 Lisp_Object old_window = AREF (vector, 7);
10925 Lisp_Object target_frame_window = AREF (vector, 8);
10926 Lisp_Object old_top_frame = AREF (vector, 9);
10928 mode_line_target = XINT (AREF (vector, 0));
10929 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10930 mode_line_string_list = AREF (vector, 2);
10931 if (! EQ (AREF (vector, 3), Qt))
10932 mode_line_proptrans_alist = AREF (vector, 3);
10933 mode_line_string_face = AREF (vector, 4);
10934 mode_line_string_face_prop = AREF (vector, 5);
10936 /* Select window before buffer, since it may change the buffer. */
10937 if (!NILP (old_window))
10939 /* If the operation that we are unwinding had selected a window
10940 on a different frame, reset its frame-selected-window. For a
10941 text terminal, reset its top-frame if necessary. */
10942 if (!NILP (target_frame_window))
10944 Lisp_Object frame
10945 = WINDOW_FRAME (XWINDOW (target_frame_window));
10947 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
10948 Fselect_window (target_frame_window, Qt);
10950 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
10951 Fselect_frame (old_top_frame, Qt);
10954 Fselect_window (old_window, Qt);
10957 if (!NILP (AREF (vector, 6)))
10959 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10960 ASET (vector, 6, Qnil);
10963 Vmode_line_unwind_vector = vector;
10964 return Qnil;
10968 /* Store a single character C for the frame title in mode_line_noprop_buf.
10969 Re-allocate mode_line_noprop_buf if necessary. */
10971 static void
10972 store_mode_line_noprop_char (char c)
10974 /* If output position has reached the end of the allocated buffer,
10975 increase the buffer's size. */
10976 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10978 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
10979 ptrdiff_t size = len;
10980 mode_line_noprop_buf =
10981 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
10982 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
10983 mode_line_noprop_ptr = mode_line_noprop_buf + len;
10986 *mode_line_noprop_ptr++ = c;
10990 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10991 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10992 characters that yield more columns than PRECISION; PRECISION <= 0
10993 means copy the whole string. Pad with spaces until FIELD_WIDTH
10994 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10995 pad. Called from display_mode_element when it is used to build a
10996 frame title. */
10998 static int
10999 store_mode_line_noprop (const char *string, int field_width, int precision)
11001 const unsigned char *str = (const unsigned char *) string;
11002 int n = 0;
11003 ptrdiff_t dummy, nbytes;
11005 /* Copy at most PRECISION chars from STR. */
11006 nbytes = strlen (string);
11007 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11008 while (nbytes--)
11009 store_mode_line_noprop_char (*str++);
11011 /* Fill up with spaces until FIELD_WIDTH reached. */
11012 while (field_width > 0
11013 && n < field_width)
11015 store_mode_line_noprop_char (' ');
11016 ++n;
11019 return n;
11022 /***********************************************************************
11023 Frame Titles
11024 ***********************************************************************/
11026 #ifdef HAVE_WINDOW_SYSTEM
11028 /* Set the title of FRAME, if it has changed. The title format is
11029 Vicon_title_format if FRAME is iconified, otherwise it is
11030 frame_title_format. */
11032 static void
11033 x_consider_frame_title (Lisp_Object frame)
11035 struct frame *f = XFRAME (frame);
11037 if (FRAME_WINDOW_P (f)
11038 || FRAME_MINIBUF_ONLY_P (f)
11039 || f->explicit_name)
11041 /* Do we have more than one visible frame on this X display? */
11042 Lisp_Object tail, other_frame, fmt;
11043 ptrdiff_t title_start;
11044 char *title;
11045 ptrdiff_t len;
11046 struct it it;
11047 ptrdiff_t count = SPECPDL_INDEX ();
11049 FOR_EACH_FRAME (tail, other_frame)
11051 struct frame *tf = XFRAME (other_frame);
11053 if (tf != f
11054 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11055 && !FRAME_MINIBUF_ONLY_P (tf)
11056 && !EQ (other_frame, tip_frame)
11057 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11058 break;
11061 /* Set global variable indicating that multiple frames exist. */
11062 multiple_frames = CONSP (tail);
11064 /* Switch to the buffer of selected window of the frame. Set up
11065 mode_line_target so that display_mode_element will output into
11066 mode_line_noprop_buf; then display the title. */
11067 record_unwind_protect (unwind_format_mode_line,
11068 format_mode_line_unwind_data
11069 (f, current_buffer, selected_window, 0));
11071 Fselect_window (f->selected_window, Qt);
11072 set_buffer_internal_1
11073 (XBUFFER (XWINDOW (f->selected_window)->contents));
11074 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11076 mode_line_target = MODE_LINE_TITLE;
11077 title_start = MODE_LINE_NOPROP_LEN (0);
11078 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11079 NULL, DEFAULT_FACE_ID);
11080 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11081 len = MODE_LINE_NOPROP_LEN (title_start);
11082 title = mode_line_noprop_buf + title_start;
11083 unbind_to (count, Qnil);
11085 /* Set the title only if it's changed. This avoids consing in
11086 the common case where it hasn't. (If it turns out that we've
11087 already wasted too much time by walking through the list with
11088 display_mode_element, then we might need to optimize at a
11089 higher level than this.) */
11090 if (! STRINGP (f->name)
11091 || SBYTES (f->name) != len
11092 || memcmp (title, SDATA (f->name), len) != 0)
11093 x_implicitly_set_name (f, make_string (title, len), Qnil);
11097 #endif /* not HAVE_WINDOW_SYSTEM */
11100 /***********************************************************************
11101 Menu Bars
11102 ***********************************************************************/
11105 /* Prepare for redisplay by updating menu-bar item lists when
11106 appropriate. This can call eval. */
11108 void
11109 prepare_menu_bars (void)
11111 int all_windows;
11112 struct gcpro gcpro1, gcpro2;
11113 struct frame *f;
11114 Lisp_Object tooltip_frame;
11116 #ifdef HAVE_WINDOW_SYSTEM
11117 tooltip_frame = tip_frame;
11118 #else
11119 tooltip_frame = Qnil;
11120 #endif
11122 /* Update all frame titles based on their buffer names, etc. We do
11123 this before the menu bars so that the buffer-menu will show the
11124 up-to-date frame titles. */
11125 #ifdef HAVE_WINDOW_SYSTEM
11126 if (windows_or_buffers_changed || update_mode_lines)
11128 Lisp_Object tail, frame;
11130 FOR_EACH_FRAME (tail, frame)
11132 f = XFRAME (frame);
11133 if (!EQ (frame, tooltip_frame)
11134 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
11135 x_consider_frame_title (frame);
11138 #endif /* HAVE_WINDOW_SYSTEM */
11140 /* Update the menu bar item lists, if appropriate. This has to be
11141 done before any actual redisplay or generation of display lines. */
11142 all_windows = (update_mode_lines
11143 || buffer_shared_and_changed ()
11144 || windows_or_buffers_changed);
11145 if (all_windows)
11147 Lisp_Object tail, frame;
11148 ptrdiff_t count = SPECPDL_INDEX ();
11149 /* 1 means that update_menu_bar has run its hooks
11150 so any further calls to update_menu_bar shouldn't do so again. */
11151 int menu_bar_hooks_run = 0;
11153 record_unwind_save_match_data ();
11155 FOR_EACH_FRAME (tail, frame)
11157 f = XFRAME (frame);
11159 /* Ignore tooltip frame. */
11160 if (EQ (frame, tooltip_frame))
11161 continue;
11163 /* If a window on this frame changed size, report that to
11164 the user and clear the size-change flag. */
11165 if (FRAME_WINDOW_SIZES_CHANGED (f))
11167 Lisp_Object functions;
11169 /* Clear flag first in case we get an error below. */
11170 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11171 functions = Vwindow_size_change_functions;
11172 GCPRO2 (tail, functions);
11174 while (CONSP (functions))
11176 if (!EQ (XCAR (functions), Qt))
11177 call1 (XCAR (functions), frame);
11178 functions = XCDR (functions);
11180 UNGCPRO;
11183 GCPRO1 (tail);
11184 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11185 #ifdef HAVE_WINDOW_SYSTEM
11186 update_tool_bar (f, 0);
11187 #endif
11188 #ifdef HAVE_NS
11189 if (windows_or_buffers_changed
11190 && FRAME_NS_P (f))
11191 ns_set_doc_edited
11192 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11193 #endif
11194 UNGCPRO;
11197 unbind_to (count, Qnil);
11199 else
11201 struct frame *sf = SELECTED_FRAME ();
11202 update_menu_bar (sf, 1, 0);
11203 #ifdef HAVE_WINDOW_SYSTEM
11204 update_tool_bar (sf, 1);
11205 #endif
11210 /* Update the menu bar item list for frame F. This has to be done
11211 before we start to fill in any display lines, because it can call
11212 eval.
11214 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11216 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11217 already ran the menu bar hooks for this redisplay, so there
11218 is no need to run them again. The return value is the
11219 updated value of this flag, to pass to the next call. */
11221 static int
11222 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11224 Lisp_Object window;
11225 register struct window *w;
11227 /* If called recursively during a menu update, do nothing. This can
11228 happen when, for instance, an activate-menubar-hook causes a
11229 redisplay. */
11230 if (inhibit_menubar_update)
11231 return hooks_run;
11233 window = FRAME_SELECTED_WINDOW (f);
11234 w = XWINDOW (window);
11236 if (FRAME_WINDOW_P (f)
11238 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11239 || defined (HAVE_NS) || defined (USE_GTK)
11240 FRAME_EXTERNAL_MENU_BAR (f)
11241 #else
11242 FRAME_MENU_BAR_LINES (f) > 0
11243 #endif
11244 : FRAME_MENU_BAR_LINES (f) > 0)
11246 /* If the user has switched buffers or windows, we need to
11247 recompute to reflect the new bindings. But we'll
11248 recompute when update_mode_lines is set too; that means
11249 that people can use force-mode-line-update to request
11250 that the menu bar be recomputed. The adverse effect on
11251 the rest of the redisplay algorithm is about the same as
11252 windows_or_buffers_changed anyway. */
11253 if (windows_or_buffers_changed
11254 /* This used to test w->update_mode_line, but we believe
11255 there is no need to recompute the menu in that case. */
11256 || update_mode_lines
11257 || window_buffer_changed (w))
11259 struct buffer *prev = current_buffer;
11260 ptrdiff_t count = SPECPDL_INDEX ();
11262 specbind (Qinhibit_menubar_update, Qt);
11264 set_buffer_internal_1 (XBUFFER (w->contents));
11265 if (save_match_data)
11266 record_unwind_save_match_data ();
11267 if (NILP (Voverriding_local_map_menu_flag))
11269 specbind (Qoverriding_terminal_local_map, Qnil);
11270 specbind (Qoverriding_local_map, Qnil);
11273 if (!hooks_run)
11275 /* Run the Lucid hook. */
11276 safe_run_hooks (Qactivate_menubar_hook);
11278 /* If it has changed current-menubar from previous value,
11279 really recompute the menu-bar from the value. */
11280 if (! NILP (Vlucid_menu_bar_dirty_flag))
11281 call0 (Qrecompute_lucid_menubar);
11283 safe_run_hooks (Qmenu_bar_update_hook);
11285 hooks_run = 1;
11288 XSETFRAME (Vmenu_updating_frame, f);
11289 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11291 /* Redisplay the menu bar in case we changed it. */
11292 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11293 || defined (HAVE_NS) || defined (USE_GTK)
11294 if (FRAME_WINDOW_P (f))
11296 #if defined (HAVE_NS)
11297 /* All frames on Mac OS share the same menubar. So only
11298 the selected frame should be allowed to set it. */
11299 if (f == SELECTED_FRAME ())
11300 #endif
11301 set_frame_menubar (f, 0, 0);
11303 else
11304 /* On a terminal screen, the menu bar is an ordinary screen
11305 line, and this makes it get updated. */
11306 w->update_mode_line = 1;
11307 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11308 /* In the non-toolkit version, the menu bar is an ordinary screen
11309 line, and this makes it get updated. */
11310 w->update_mode_line = 1;
11311 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11313 unbind_to (count, Qnil);
11314 set_buffer_internal_1 (prev);
11318 return hooks_run;
11323 /***********************************************************************
11324 Output Cursor
11325 ***********************************************************************/
11327 #ifdef HAVE_WINDOW_SYSTEM
11329 /* EXPORT:
11330 Nominal cursor position -- where to draw output.
11331 HPOS and VPOS are window relative glyph matrix coordinates.
11332 X and Y are window relative pixel coordinates. */
11334 struct cursor_pos output_cursor;
11337 /* EXPORT:
11338 Set the global variable output_cursor to CURSOR. All cursor
11339 positions are relative to updated_window. */
11341 void
11342 set_output_cursor (struct cursor_pos *cursor)
11344 output_cursor.hpos = cursor->hpos;
11345 output_cursor.vpos = cursor->vpos;
11346 output_cursor.x = cursor->x;
11347 output_cursor.y = cursor->y;
11351 /* EXPORT for RIF:
11352 Set a nominal cursor position.
11354 HPOS and VPOS are column/row positions in a window glyph matrix. X
11355 and Y are window text area relative pixel positions.
11357 If this is done during an update, updated_window will contain the
11358 window that is being updated and the position is the future output
11359 cursor position for that window. If updated_window is null, use
11360 selected_window and display the cursor at the given position. */
11362 void
11363 x_cursor_to (int vpos, int hpos, int y, int x)
11365 struct window *w;
11367 /* If updated_window is not set, work on selected_window. */
11368 if (updated_window)
11369 w = updated_window;
11370 else
11371 w = XWINDOW (selected_window);
11373 /* Set the output cursor. */
11374 output_cursor.hpos = hpos;
11375 output_cursor.vpos = vpos;
11376 output_cursor.x = x;
11377 output_cursor.y = y;
11379 /* If not called as part of an update, really display the cursor.
11380 This will also set the cursor position of W. */
11381 if (updated_window == NULL)
11383 block_input ();
11384 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11385 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11386 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11387 unblock_input ();
11391 #endif /* HAVE_WINDOW_SYSTEM */
11394 /***********************************************************************
11395 Tool-bars
11396 ***********************************************************************/
11398 #ifdef HAVE_WINDOW_SYSTEM
11400 /* Where the mouse was last time we reported a mouse event. */
11402 FRAME_PTR last_mouse_frame;
11404 /* Tool-bar item index of the item on which a mouse button was pressed
11405 or -1. */
11407 int last_tool_bar_item;
11409 /* Select `frame' temporarily without running all the code in
11410 do_switch_frame.
11411 FIXME: Maybe do_switch_frame should be trimmed down similarly
11412 when `norecord' is set. */
11413 static Lisp_Object
11414 fast_set_selected_frame (Lisp_Object frame)
11416 if (!EQ (selected_frame, frame))
11418 selected_frame = frame;
11419 selected_window = XFRAME (frame)->selected_window;
11421 return Qnil;
11424 /* Update the tool-bar item list for frame F. This has to be done
11425 before we start to fill in any display lines. Called from
11426 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11427 and restore it here. */
11429 static void
11430 update_tool_bar (struct frame *f, int save_match_data)
11432 #if defined (USE_GTK) || defined (HAVE_NS)
11433 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11434 #else
11435 int do_update = WINDOWP (f->tool_bar_window)
11436 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11437 #endif
11439 if (do_update)
11441 Lisp_Object window;
11442 struct window *w;
11444 window = FRAME_SELECTED_WINDOW (f);
11445 w = XWINDOW (window);
11447 /* If the user has switched buffers or windows, we need to
11448 recompute to reflect the new bindings. But we'll
11449 recompute when update_mode_lines is set too; that means
11450 that people can use force-mode-line-update to request
11451 that the menu bar be recomputed. The adverse effect on
11452 the rest of the redisplay algorithm is about the same as
11453 windows_or_buffers_changed anyway. */
11454 if (windows_or_buffers_changed
11455 || w->update_mode_line
11456 || update_mode_lines
11457 || window_buffer_changed (w))
11459 struct buffer *prev = current_buffer;
11460 ptrdiff_t count = SPECPDL_INDEX ();
11461 Lisp_Object frame, new_tool_bar;
11462 int new_n_tool_bar;
11463 struct gcpro gcpro1;
11465 /* Set current_buffer to the buffer of the selected
11466 window of the frame, so that we get the right local
11467 keymaps. */
11468 set_buffer_internal_1 (XBUFFER (w->contents));
11470 /* Save match data, if we must. */
11471 if (save_match_data)
11472 record_unwind_save_match_data ();
11474 /* Make sure that we don't accidentally use bogus keymaps. */
11475 if (NILP (Voverriding_local_map_menu_flag))
11477 specbind (Qoverriding_terminal_local_map, Qnil);
11478 specbind (Qoverriding_local_map, Qnil);
11481 GCPRO1 (new_tool_bar);
11483 /* We must temporarily set the selected frame to this frame
11484 before calling tool_bar_items, because the calculation of
11485 the tool-bar keymap uses the selected frame (see
11486 `tool-bar-make-keymap' in tool-bar.el). */
11487 eassert (EQ (selected_window,
11488 /* Since we only explicitly preserve selected_frame,
11489 check that selected_window would be redundant. */
11490 XFRAME (selected_frame)->selected_window));
11491 record_unwind_protect (fast_set_selected_frame, selected_frame);
11492 XSETFRAME (frame, f);
11493 fast_set_selected_frame (frame);
11495 /* Build desired tool-bar items from keymaps. */
11496 new_tool_bar
11497 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11498 &new_n_tool_bar);
11500 /* Redisplay the tool-bar if we changed it. */
11501 if (new_n_tool_bar != f->n_tool_bar_items
11502 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11504 /* Redisplay that happens asynchronously due to an expose event
11505 may access f->tool_bar_items. Make sure we update both
11506 variables within BLOCK_INPUT so no such event interrupts. */
11507 block_input ();
11508 fset_tool_bar_items (f, new_tool_bar);
11509 f->n_tool_bar_items = new_n_tool_bar;
11510 w->update_mode_line = 1;
11511 unblock_input ();
11514 UNGCPRO;
11516 unbind_to (count, Qnil);
11517 set_buffer_internal_1 (prev);
11523 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11524 F's desired tool-bar contents. F->tool_bar_items must have
11525 been set up previously by calling prepare_menu_bars. */
11527 static void
11528 build_desired_tool_bar_string (struct frame *f)
11530 int i, size, size_needed;
11531 struct gcpro gcpro1, gcpro2, gcpro3;
11532 Lisp_Object image, plist, props;
11534 image = plist = props = Qnil;
11535 GCPRO3 (image, plist, props);
11537 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11538 Otherwise, make a new string. */
11540 /* The size of the string we might be able to reuse. */
11541 size = (STRINGP (f->desired_tool_bar_string)
11542 ? SCHARS (f->desired_tool_bar_string)
11543 : 0);
11545 /* We need one space in the string for each image. */
11546 size_needed = f->n_tool_bar_items;
11548 /* Reuse f->desired_tool_bar_string, if possible. */
11549 if (size < size_needed || NILP (f->desired_tool_bar_string))
11550 fset_desired_tool_bar_string
11551 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11552 else
11554 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11555 Fremove_text_properties (make_number (0), make_number (size),
11556 props, f->desired_tool_bar_string);
11559 /* Put a `display' property on the string for the images to display,
11560 put a `menu_item' property on tool-bar items with a value that
11561 is the index of the item in F's tool-bar item vector. */
11562 for (i = 0; i < f->n_tool_bar_items; ++i)
11564 #define PROP(IDX) \
11565 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11567 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11568 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11569 int hmargin, vmargin, relief, idx, end;
11571 /* If image is a vector, choose the image according to the
11572 button state. */
11573 image = PROP (TOOL_BAR_ITEM_IMAGES);
11574 if (VECTORP (image))
11576 if (enabled_p)
11577 idx = (selected_p
11578 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11579 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11580 else
11581 idx = (selected_p
11582 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11583 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11585 eassert (ASIZE (image) >= idx);
11586 image = AREF (image, idx);
11588 else
11589 idx = -1;
11591 /* Ignore invalid image specifications. */
11592 if (!valid_image_p (image))
11593 continue;
11595 /* Display the tool-bar button pressed, or depressed. */
11596 plist = Fcopy_sequence (XCDR (image));
11598 /* Compute margin and relief to draw. */
11599 relief = (tool_bar_button_relief >= 0
11600 ? tool_bar_button_relief
11601 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11602 hmargin = vmargin = relief;
11604 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11605 INT_MAX - max (hmargin, vmargin)))
11607 hmargin += XFASTINT (Vtool_bar_button_margin);
11608 vmargin += XFASTINT (Vtool_bar_button_margin);
11610 else if (CONSP (Vtool_bar_button_margin))
11612 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11613 INT_MAX - hmargin))
11614 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11616 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11617 INT_MAX - vmargin))
11618 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11621 if (auto_raise_tool_bar_buttons_p)
11623 /* Add a `:relief' property to the image spec if the item is
11624 selected. */
11625 if (selected_p)
11627 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11628 hmargin -= relief;
11629 vmargin -= relief;
11632 else
11634 /* If image is selected, display it pressed, i.e. with a
11635 negative relief. If it's not selected, display it with a
11636 raised relief. */
11637 plist = Fplist_put (plist, QCrelief,
11638 (selected_p
11639 ? make_number (-relief)
11640 : make_number (relief)));
11641 hmargin -= relief;
11642 vmargin -= relief;
11645 /* Put a margin around the image. */
11646 if (hmargin || vmargin)
11648 if (hmargin == vmargin)
11649 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11650 else
11651 plist = Fplist_put (plist, QCmargin,
11652 Fcons (make_number (hmargin),
11653 make_number (vmargin)));
11656 /* If button is not enabled, and we don't have special images
11657 for the disabled state, make the image appear disabled by
11658 applying an appropriate algorithm to it. */
11659 if (!enabled_p && idx < 0)
11660 plist = Fplist_put (plist, QCconversion, Qdisabled);
11662 /* Put a `display' text property on the string for the image to
11663 display. Put a `menu-item' property on the string that gives
11664 the start of this item's properties in the tool-bar items
11665 vector. */
11666 image = Fcons (Qimage, plist);
11667 props = list4 (Qdisplay, image,
11668 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11670 /* Let the last image hide all remaining spaces in the tool bar
11671 string. The string can be longer than needed when we reuse a
11672 previous string. */
11673 if (i + 1 == f->n_tool_bar_items)
11674 end = SCHARS (f->desired_tool_bar_string);
11675 else
11676 end = i + 1;
11677 Fadd_text_properties (make_number (i), make_number (end),
11678 props, f->desired_tool_bar_string);
11679 #undef PROP
11682 UNGCPRO;
11686 /* Display one line of the tool-bar of frame IT->f.
11688 HEIGHT specifies the desired height of the tool-bar line.
11689 If the actual height of the glyph row is less than HEIGHT, the
11690 row's height is increased to HEIGHT, and the icons are centered
11691 vertically in the new height.
11693 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11694 count a final empty row in case the tool-bar width exactly matches
11695 the window width.
11698 static void
11699 display_tool_bar_line (struct it *it, int height)
11701 struct glyph_row *row = it->glyph_row;
11702 int max_x = it->last_visible_x;
11703 struct glyph *last;
11705 prepare_desired_row (row);
11706 row->y = it->current_y;
11708 /* Note that this isn't made use of if the face hasn't a box,
11709 so there's no need to check the face here. */
11710 it->start_of_box_run_p = 1;
11712 while (it->current_x < max_x)
11714 int x, n_glyphs_before, i, nglyphs;
11715 struct it it_before;
11717 /* Get the next display element. */
11718 if (!get_next_display_element (it))
11720 /* Don't count empty row if we are counting needed tool-bar lines. */
11721 if (height < 0 && !it->hpos)
11722 return;
11723 break;
11726 /* Produce glyphs. */
11727 n_glyphs_before = row->used[TEXT_AREA];
11728 it_before = *it;
11730 PRODUCE_GLYPHS (it);
11732 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11733 i = 0;
11734 x = it_before.current_x;
11735 while (i < nglyphs)
11737 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11739 if (x + glyph->pixel_width > max_x)
11741 /* Glyph doesn't fit on line. Backtrack. */
11742 row->used[TEXT_AREA] = n_glyphs_before;
11743 *it = it_before;
11744 /* If this is the only glyph on this line, it will never fit on the
11745 tool-bar, so skip it. But ensure there is at least one glyph,
11746 so we don't accidentally disable the tool-bar. */
11747 if (n_glyphs_before == 0
11748 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11749 break;
11750 goto out;
11753 ++it->hpos;
11754 x += glyph->pixel_width;
11755 ++i;
11758 /* Stop at line end. */
11759 if (ITERATOR_AT_END_OF_LINE_P (it))
11760 break;
11762 set_iterator_to_next (it, 1);
11765 out:;
11767 row->displays_text_p = row->used[TEXT_AREA] != 0;
11769 /* Use default face for the border below the tool bar.
11771 FIXME: When auto-resize-tool-bars is grow-only, there is
11772 no additional border below the possibly empty tool-bar lines.
11773 So to make the extra empty lines look "normal", we have to
11774 use the tool-bar face for the border too. */
11775 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
11776 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11777 it->face_id = DEFAULT_FACE_ID;
11779 extend_face_to_end_of_line (it);
11780 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11781 last->right_box_line_p = 1;
11782 if (last == row->glyphs[TEXT_AREA])
11783 last->left_box_line_p = 1;
11785 /* Make line the desired height and center it vertically. */
11786 if ((height -= it->max_ascent + it->max_descent) > 0)
11788 /* Don't add more than one line height. */
11789 height %= FRAME_LINE_HEIGHT (it->f);
11790 it->max_ascent += height / 2;
11791 it->max_descent += (height + 1) / 2;
11794 compute_line_metrics (it);
11796 /* If line is empty, make it occupy the rest of the tool-bar. */
11797 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
11799 row->height = row->phys_height = it->last_visible_y - row->y;
11800 row->visible_height = row->height;
11801 row->ascent = row->phys_ascent = 0;
11802 row->extra_line_spacing = 0;
11805 row->full_width_p = 1;
11806 row->continued_p = 0;
11807 row->truncated_on_left_p = 0;
11808 row->truncated_on_right_p = 0;
11810 it->current_x = it->hpos = 0;
11811 it->current_y += row->height;
11812 ++it->vpos;
11813 ++it->glyph_row;
11817 /* Max tool-bar height. */
11819 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11820 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11822 /* Value is the number of screen lines needed to make all tool-bar
11823 items of frame F visible. The number of actual rows needed is
11824 returned in *N_ROWS if non-NULL. */
11826 static int
11827 tool_bar_lines_needed (struct frame *f, int *n_rows)
11829 struct window *w = XWINDOW (f->tool_bar_window);
11830 struct it it;
11831 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11832 the desired matrix, so use (unused) mode-line row as temporary row to
11833 avoid destroying the first tool-bar row. */
11834 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11836 /* Initialize an iterator for iteration over
11837 F->desired_tool_bar_string in the tool-bar window of frame F. */
11838 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11839 it.first_visible_x = 0;
11840 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11841 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11842 it.paragraph_embedding = L2R;
11844 while (!ITERATOR_AT_END_P (&it))
11846 clear_glyph_row (temp_row);
11847 it.glyph_row = temp_row;
11848 display_tool_bar_line (&it, -1);
11850 clear_glyph_row (temp_row);
11852 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11853 if (n_rows)
11854 *n_rows = it.vpos > 0 ? it.vpos : -1;
11856 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11860 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11861 0, 1, 0,
11862 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11863 If FRAME is nil or omitted, use the selected frame. */)
11864 (Lisp_Object frame)
11866 struct frame *f = decode_any_frame (frame);
11867 struct window *w;
11868 int nlines = 0;
11870 if (WINDOWP (f->tool_bar_window)
11871 && (w = XWINDOW (f->tool_bar_window),
11872 WINDOW_TOTAL_LINES (w) > 0))
11874 update_tool_bar (f, 1);
11875 if (f->n_tool_bar_items)
11877 build_desired_tool_bar_string (f);
11878 nlines = tool_bar_lines_needed (f, NULL);
11882 return make_number (nlines);
11886 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11887 height should be changed. */
11889 static int
11890 redisplay_tool_bar (struct frame *f)
11892 struct window *w;
11893 struct it it;
11894 struct glyph_row *row;
11896 #if defined (USE_GTK) || defined (HAVE_NS)
11897 if (FRAME_EXTERNAL_TOOL_BAR (f))
11898 update_frame_tool_bar (f);
11899 return 0;
11900 #endif
11902 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11903 do anything. This means you must start with tool-bar-lines
11904 non-zero to get the auto-sizing effect. Or in other words, you
11905 can turn off tool-bars by specifying tool-bar-lines zero. */
11906 if (!WINDOWP (f->tool_bar_window)
11907 || (w = XWINDOW (f->tool_bar_window),
11908 WINDOW_TOTAL_LINES (w) == 0))
11909 return 0;
11911 /* Set up an iterator for the tool-bar window. */
11912 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11913 it.first_visible_x = 0;
11914 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11915 row = it.glyph_row;
11917 /* Build a string that represents the contents of the tool-bar. */
11918 build_desired_tool_bar_string (f);
11919 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11920 /* FIXME: This should be controlled by a user option. But it
11921 doesn't make sense to have an R2L tool bar if the menu bar cannot
11922 be drawn also R2L, and making the menu bar R2L is tricky due
11923 toolkit-specific code that implements it. If an R2L tool bar is
11924 ever supported, display_tool_bar_line should also be augmented to
11925 call unproduce_glyphs like display_line and display_string
11926 do. */
11927 it.paragraph_embedding = L2R;
11929 if (f->n_tool_bar_rows == 0)
11931 int nlines;
11933 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11934 nlines != WINDOW_TOTAL_LINES (w)))
11936 Lisp_Object frame;
11937 int old_height = WINDOW_TOTAL_LINES (w);
11939 XSETFRAME (frame, f);
11940 Fmodify_frame_parameters (frame,
11941 Fcons (Fcons (Qtool_bar_lines,
11942 make_number (nlines)),
11943 Qnil));
11944 if (WINDOW_TOTAL_LINES (w) != old_height)
11946 clear_glyph_matrix (w->desired_matrix);
11947 fonts_changed_p = 1;
11948 return 1;
11953 /* Display as many lines as needed to display all tool-bar items. */
11955 if (f->n_tool_bar_rows > 0)
11957 int border, rows, height, extra;
11959 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
11960 border = XINT (Vtool_bar_border);
11961 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11962 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11963 else if (EQ (Vtool_bar_border, Qborder_width))
11964 border = f->border_width;
11965 else
11966 border = 0;
11967 if (border < 0)
11968 border = 0;
11970 rows = f->n_tool_bar_rows;
11971 height = max (1, (it.last_visible_y - border) / rows);
11972 extra = it.last_visible_y - border - height * rows;
11974 while (it.current_y < it.last_visible_y)
11976 int h = 0;
11977 if (extra > 0 && rows-- > 0)
11979 h = (extra + rows - 1) / rows;
11980 extra -= h;
11982 display_tool_bar_line (&it, height + h);
11985 else
11987 while (it.current_y < it.last_visible_y)
11988 display_tool_bar_line (&it, 0);
11991 /* It doesn't make much sense to try scrolling in the tool-bar
11992 window, so don't do it. */
11993 w->desired_matrix->no_scrolling_p = 1;
11994 w->must_be_updated_p = 1;
11996 if (!NILP (Vauto_resize_tool_bars))
11998 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
11999 int change_height_p = 0;
12001 /* If we couldn't display everything, change the tool-bar's
12002 height if there is room for more. */
12003 if (IT_STRING_CHARPOS (it) < it.end_charpos
12004 && it.current_y < max_tool_bar_height)
12005 change_height_p = 1;
12007 row = it.glyph_row - 1;
12009 /* If there are blank lines at the end, except for a partially
12010 visible blank line at the end that is smaller than
12011 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12012 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12013 && row->height >= FRAME_LINE_HEIGHT (f))
12014 change_height_p = 1;
12016 /* If row displays tool-bar items, but is partially visible,
12017 change the tool-bar's height. */
12018 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12019 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12020 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12021 change_height_p = 1;
12023 /* Resize windows as needed by changing the `tool-bar-lines'
12024 frame parameter. */
12025 if (change_height_p)
12027 Lisp_Object frame;
12028 int old_height = WINDOW_TOTAL_LINES (w);
12029 int nrows;
12030 int nlines = tool_bar_lines_needed (f, &nrows);
12032 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12033 && !f->minimize_tool_bar_window_p)
12034 ? (nlines > old_height)
12035 : (nlines != old_height));
12036 f->minimize_tool_bar_window_p = 0;
12038 if (change_height_p)
12040 XSETFRAME (frame, f);
12041 Fmodify_frame_parameters (frame,
12042 Fcons (Fcons (Qtool_bar_lines,
12043 make_number (nlines)),
12044 Qnil));
12045 if (WINDOW_TOTAL_LINES (w) != old_height)
12047 clear_glyph_matrix (w->desired_matrix);
12048 f->n_tool_bar_rows = nrows;
12049 fonts_changed_p = 1;
12050 return 1;
12056 f->minimize_tool_bar_window_p = 0;
12057 return 0;
12061 /* Get information about the tool-bar item which is displayed in GLYPH
12062 on frame F. Return in *PROP_IDX the index where tool-bar item
12063 properties start in F->tool_bar_items. Value is zero if
12064 GLYPH doesn't display a tool-bar item. */
12066 static int
12067 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12069 Lisp_Object prop;
12070 int success_p;
12071 int charpos;
12073 /* This function can be called asynchronously, which means we must
12074 exclude any possibility that Fget_text_property signals an
12075 error. */
12076 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12077 charpos = max (0, charpos);
12079 /* Get the text property `menu-item' at pos. The value of that
12080 property is the start index of this item's properties in
12081 F->tool_bar_items. */
12082 prop = Fget_text_property (make_number (charpos),
12083 Qmenu_item, f->current_tool_bar_string);
12084 if (INTEGERP (prop))
12086 *prop_idx = XINT (prop);
12087 success_p = 1;
12089 else
12090 success_p = 0;
12092 return success_p;
12096 /* Get information about the tool-bar item at position X/Y on frame F.
12097 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12098 the current matrix of the tool-bar window of F, or NULL if not
12099 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12100 item in F->tool_bar_items. Value is
12102 -1 if X/Y is not on a tool-bar item
12103 0 if X/Y is on the same item that was highlighted before.
12104 1 otherwise. */
12106 static int
12107 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12108 int *hpos, int *vpos, int *prop_idx)
12110 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12111 struct window *w = XWINDOW (f->tool_bar_window);
12112 int area;
12114 /* Find the glyph under X/Y. */
12115 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12116 if (*glyph == NULL)
12117 return -1;
12119 /* Get the start of this tool-bar item's properties in
12120 f->tool_bar_items. */
12121 if (!tool_bar_item_info (f, *glyph, prop_idx))
12122 return -1;
12124 /* Is mouse on the highlighted item? */
12125 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12126 && *vpos >= hlinfo->mouse_face_beg_row
12127 && *vpos <= hlinfo->mouse_face_end_row
12128 && (*vpos > hlinfo->mouse_face_beg_row
12129 || *hpos >= hlinfo->mouse_face_beg_col)
12130 && (*vpos < hlinfo->mouse_face_end_row
12131 || *hpos < hlinfo->mouse_face_end_col
12132 || hlinfo->mouse_face_past_end))
12133 return 0;
12135 return 1;
12139 /* EXPORT:
12140 Handle mouse button event on the tool-bar of frame F, at
12141 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12142 0 for button release. MODIFIERS is event modifiers for button
12143 release. */
12145 void
12146 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12147 int modifiers)
12149 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12150 struct window *w = XWINDOW (f->tool_bar_window);
12151 int hpos, vpos, prop_idx;
12152 struct glyph *glyph;
12153 Lisp_Object enabled_p;
12154 int ts;
12156 /* If not on the highlighted tool-bar item, and mouse-highlight is
12157 non-nil, return. This is so we generate the tool-bar button
12158 click only when the mouse button is released on the same item as
12159 where it was pressed. However, when mouse-highlight is disabled,
12160 generate the click when the button is released regardless of the
12161 highlight, since tool-bar items are not highlighted in that
12162 case. */
12163 frame_to_window_pixel_xy (w, &x, &y);
12164 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12165 if (ts == -1
12166 || (ts != 0 && !NILP (Vmouse_highlight)))
12167 return;
12169 /* When mouse-highlight is off, generate the click for the item
12170 where the button was pressed, disregarding where it was
12171 released. */
12172 if (NILP (Vmouse_highlight) && !down_p)
12173 prop_idx = last_tool_bar_item;
12175 /* If item is disabled, do nothing. */
12176 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12177 if (NILP (enabled_p))
12178 return;
12180 if (down_p)
12182 /* Show item in pressed state. */
12183 if (!NILP (Vmouse_highlight))
12184 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12185 last_tool_bar_item = prop_idx;
12187 else
12189 Lisp_Object key, frame;
12190 struct input_event event;
12191 EVENT_INIT (event);
12193 /* Show item in released state. */
12194 if (!NILP (Vmouse_highlight))
12195 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12197 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12199 XSETFRAME (frame, f);
12200 event.kind = TOOL_BAR_EVENT;
12201 event.frame_or_window = frame;
12202 event.arg = frame;
12203 kbd_buffer_store_event (&event);
12205 event.kind = TOOL_BAR_EVENT;
12206 event.frame_or_window = frame;
12207 event.arg = key;
12208 event.modifiers = modifiers;
12209 kbd_buffer_store_event (&event);
12210 last_tool_bar_item = -1;
12215 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12216 tool-bar window-relative coordinates X/Y. Called from
12217 note_mouse_highlight. */
12219 static void
12220 note_tool_bar_highlight (struct frame *f, int x, int y)
12222 Lisp_Object window = f->tool_bar_window;
12223 struct window *w = XWINDOW (window);
12224 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12225 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12226 int hpos, vpos;
12227 struct glyph *glyph;
12228 struct glyph_row *row;
12229 int i;
12230 Lisp_Object enabled_p;
12231 int prop_idx;
12232 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12233 int mouse_down_p, rc;
12235 /* Function note_mouse_highlight is called with negative X/Y
12236 values when mouse moves outside of the frame. */
12237 if (x <= 0 || y <= 0)
12239 clear_mouse_face (hlinfo);
12240 return;
12243 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12244 if (rc < 0)
12246 /* Not on tool-bar item. */
12247 clear_mouse_face (hlinfo);
12248 return;
12250 else if (rc == 0)
12251 /* On same tool-bar item as before. */
12252 goto set_help_echo;
12254 clear_mouse_face (hlinfo);
12256 /* Mouse is down, but on different tool-bar item? */
12257 mouse_down_p = (dpyinfo->grabbed
12258 && f == last_mouse_frame
12259 && FRAME_LIVE_P (f));
12260 if (mouse_down_p
12261 && last_tool_bar_item != prop_idx)
12262 return;
12264 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12266 /* If tool-bar item is not enabled, don't highlight it. */
12267 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12268 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12270 /* Compute the x-position of the glyph. In front and past the
12271 image is a space. We include this in the highlighted area. */
12272 row = MATRIX_ROW (w->current_matrix, vpos);
12273 for (i = x = 0; i < hpos; ++i)
12274 x += row->glyphs[TEXT_AREA][i].pixel_width;
12276 /* Record this as the current active region. */
12277 hlinfo->mouse_face_beg_col = hpos;
12278 hlinfo->mouse_face_beg_row = vpos;
12279 hlinfo->mouse_face_beg_x = x;
12280 hlinfo->mouse_face_beg_y = row->y;
12281 hlinfo->mouse_face_past_end = 0;
12283 hlinfo->mouse_face_end_col = hpos + 1;
12284 hlinfo->mouse_face_end_row = vpos;
12285 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12286 hlinfo->mouse_face_end_y = row->y;
12287 hlinfo->mouse_face_window = window;
12288 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12290 /* Display it as active. */
12291 show_mouse_face (hlinfo, draw);
12294 set_help_echo:
12296 /* Set help_echo_string to a help string to display for this tool-bar item.
12297 XTread_socket does the rest. */
12298 help_echo_object = help_echo_window = Qnil;
12299 help_echo_pos = -1;
12300 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12301 if (NILP (help_echo_string))
12302 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12305 #endif /* HAVE_WINDOW_SYSTEM */
12309 /************************************************************************
12310 Horizontal scrolling
12311 ************************************************************************/
12313 static int hscroll_window_tree (Lisp_Object);
12314 static int hscroll_windows (Lisp_Object);
12316 /* For all leaf windows in the window tree rooted at WINDOW, set their
12317 hscroll value so that PT is (i) visible in the window, and (ii) so
12318 that it is not within a certain margin at the window's left and
12319 right border. Value is non-zero if any window's hscroll has been
12320 changed. */
12322 static int
12323 hscroll_window_tree (Lisp_Object window)
12325 int hscrolled_p = 0;
12326 int hscroll_relative_p = FLOATP (Vhscroll_step);
12327 int hscroll_step_abs = 0;
12328 double hscroll_step_rel = 0;
12330 if (hscroll_relative_p)
12332 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12333 if (hscroll_step_rel < 0)
12335 hscroll_relative_p = 0;
12336 hscroll_step_abs = 0;
12339 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12341 hscroll_step_abs = XINT (Vhscroll_step);
12342 if (hscroll_step_abs < 0)
12343 hscroll_step_abs = 0;
12345 else
12346 hscroll_step_abs = 0;
12348 while (WINDOWP (window))
12350 struct window *w = XWINDOW (window);
12352 if (WINDOWP (w->contents))
12353 hscrolled_p |= hscroll_window_tree (w->contents);
12354 else if (w->cursor.vpos >= 0)
12356 int h_margin;
12357 int text_area_width;
12358 struct glyph_row *current_cursor_row
12359 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12360 struct glyph_row *desired_cursor_row
12361 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12362 struct glyph_row *cursor_row
12363 = (desired_cursor_row->enabled_p
12364 ? desired_cursor_row
12365 : current_cursor_row);
12366 int row_r2l_p = cursor_row->reversed_p;
12368 text_area_width = window_box_width (w, TEXT_AREA);
12370 /* Scroll when cursor is inside this scroll margin. */
12371 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12373 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12374 /* For left-to-right rows, hscroll when cursor is either
12375 (i) inside the right hscroll margin, or (ii) if it is
12376 inside the left margin and the window is already
12377 hscrolled. */
12378 && ((!row_r2l_p
12379 && ((w->hscroll
12380 && w->cursor.x <= h_margin)
12381 || (cursor_row->enabled_p
12382 && cursor_row->truncated_on_right_p
12383 && (w->cursor.x >= text_area_width - h_margin))))
12384 /* For right-to-left rows, the logic is similar,
12385 except that rules for scrolling to left and right
12386 are reversed. E.g., if cursor.x <= h_margin, we
12387 need to hscroll "to the right" unconditionally,
12388 and that will scroll the screen to the left so as
12389 to reveal the next portion of the row. */
12390 || (row_r2l_p
12391 && ((cursor_row->enabled_p
12392 /* FIXME: It is confusing to set the
12393 truncated_on_right_p flag when R2L rows
12394 are actually truncated on the left. */
12395 && cursor_row->truncated_on_right_p
12396 && w->cursor.x <= h_margin)
12397 || (w->hscroll
12398 && (w->cursor.x >= text_area_width - h_margin))))))
12400 struct it it;
12401 ptrdiff_t hscroll;
12402 struct buffer *saved_current_buffer;
12403 ptrdiff_t pt;
12404 int wanted_x;
12406 /* Find point in a display of infinite width. */
12407 saved_current_buffer = current_buffer;
12408 current_buffer = XBUFFER (w->contents);
12410 if (w == XWINDOW (selected_window))
12411 pt = PT;
12412 else
12413 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12415 /* Move iterator to pt starting at cursor_row->start in
12416 a line with infinite width. */
12417 init_to_row_start (&it, w, cursor_row);
12418 it.last_visible_x = INFINITY;
12419 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12420 current_buffer = saved_current_buffer;
12422 /* Position cursor in window. */
12423 if (!hscroll_relative_p && hscroll_step_abs == 0)
12424 hscroll = max (0, (it.current_x
12425 - (ITERATOR_AT_END_OF_LINE_P (&it)
12426 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12427 : (text_area_width / 2))))
12428 / FRAME_COLUMN_WIDTH (it.f);
12429 else if ((!row_r2l_p
12430 && w->cursor.x >= text_area_width - h_margin)
12431 || (row_r2l_p && w->cursor.x <= h_margin))
12433 if (hscroll_relative_p)
12434 wanted_x = text_area_width * (1 - hscroll_step_rel)
12435 - h_margin;
12436 else
12437 wanted_x = text_area_width
12438 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12439 - h_margin;
12440 hscroll
12441 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12443 else
12445 if (hscroll_relative_p)
12446 wanted_x = text_area_width * hscroll_step_rel
12447 + h_margin;
12448 else
12449 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12450 + h_margin;
12451 hscroll
12452 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12454 hscroll = max (hscroll, w->min_hscroll);
12456 /* Don't prevent redisplay optimizations if hscroll
12457 hasn't changed, as it will unnecessarily slow down
12458 redisplay. */
12459 if (w->hscroll != hscroll)
12461 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12462 w->hscroll = hscroll;
12463 hscrolled_p = 1;
12468 window = w->next;
12471 /* Value is non-zero if hscroll of any leaf window has been changed. */
12472 return hscrolled_p;
12476 /* Set hscroll so that cursor is visible and not inside horizontal
12477 scroll margins for all windows in the tree rooted at WINDOW. See
12478 also hscroll_window_tree above. Value is non-zero if any window's
12479 hscroll has been changed. If it has, desired matrices on the frame
12480 of WINDOW are cleared. */
12482 static int
12483 hscroll_windows (Lisp_Object window)
12485 int hscrolled_p = hscroll_window_tree (window);
12486 if (hscrolled_p)
12487 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12488 return hscrolled_p;
12493 /************************************************************************
12494 Redisplay
12495 ************************************************************************/
12497 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12498 to a non-zero value. This is sometimes handy to have in a debugger
12499 session. */
12501 #ifdef GLYPH_DEBUG
12503 /* First and last unchanged row for try_window_id. */
12505 static int debug_first_unchanged_at_end_vpos;
12506 static int debug_last_unchanged_at_beg_vpos;
12508 /* Delta vpos and y. */
12510 static int debug_dvpos, debug_dy;
12512 /* Delta in characters and bytes for try_window_id. */
12514 static ptrdiff_t debug_delta, debug_delta_bytes;
12516 /* Values of window_end_pos and window_end_vpos at the end of
12517 try_window_id. */
12519 static ptrdiff_t debug_end_vpos;
12521 /* Append a string to W->desired_matrix->method. FMT is a printf
12522 format string. If trace_redisplay_p is non-zero also printf the
12523 resulting string to stderr. */
12525 static void debug_method_add (struct window *, char const *, ...)
12526 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12528 static void
12529 debug_method_add (struct window *w, char const *fmt, ...)
12531 char *method = w->desired_matrix->method;
12532 int len = strlen (method);
12533 int size = sizeof w->desired_matrix->method;
12534 int remaining = size - len - 1;
12535 va_list ap;
12537 if (len && remaining)
12539 method[len] = '|';
12540 --remaining, ++len;
12543 va_start (ap, fmt);
12544 vsnprintf (method + len, remaining + 1, fmt, ap);
12545 va_end (ap);
12547 if (trace_redisplay_p)
12548 fprintf (stderr, "%p (%s): %s\n",
12550 ((BUFFERP (w->contents)
12551 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12552 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12553 : "no buffer"),
12554 method + len);
12557 #endif /* GLYPH_DEBUG */
12560 /* Value is non-zero if all changes in window W, which displays
12561 current_buffer, are in the text between START and END. START is a
12562 buffer position, END is given as a distance from Z. Used in
12563 redisplay_internal for display optimization. */
12565 static int
12566 text_outside_line_unchanged_p (struct window *w,
12567 ptrdiff_t start, ptrdiff_t end)
12569 int unchanged_p = 1;
12571 /* If text or overlays have changed, see where. */
12572 if (window_outdated (w))
12574 /* Gap in the line? */
12575 if (GPT < start || Z - GPT < end)
12576 unchanged_p = 0;
12578 /* Changes start in front of the line, or end after it? */
12579 if (unchanged_p
12580 && (BEG_UNCHANGED < start - 1
12581 || END_UNCHANGED < end))
12582 unchanged_p = 0;
12584 /* If selective display, can't optimize if changes start at the
12585 beginning of the line. */
12586 if (unchanged_p
12587 && INTEGERP (BVAR (current_buffer, selective_display))
12588 && XINT (BVAR (current_buffer, selective_display)) > 0
12589 && (BEG_UNCHANGED < start || GPT <= start))
12590 unchanged_p = 0;
12592 /* If there are overlays at the start or end of the line, these
12593 may have overlay strings with newlines in them. A change at
12594 START, for instance, may actually concern the display of such
12595 overlay strings as well, and they are displayed on different
12596 lines. So, quickly rule out this case. (For the future, it
12597 might be desirable to implement something more telling than
12598 just BEG/END_UNCHANGED.) */
12599 if (unchanged_p)
12601 if (BEG + BEG_UNCHANGED == start
12602 && overlay_touches_p (start))
12603 unchanged_p = 0;
12604 if (END_UNCHANGED == end
12605 && overlay_touches_p (Z - end))
12606 unchanged_p = 0;
12609 /* Under bidi reordering, adding or deleting a character in the
12610 beginning of a paragraph, before the first strong directional
12611 character, can change the base direction of the paragraph (unless
12612 the buffer specifies a fixed paragraph direction), which will
12613 require to redisplay the whole paragraph. It might be worthwhile
12614 to find the paragraph limits and widen the range of redisplayed
12615 lines to that, but for now just give up this optimization. */
12616 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12617 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12618 unchanged_p = 0;
12621 return unchanged_p;
12625 /* Do a frame update, taking possible shortcuts into account. This is
12626 the main external entry point for redisplay.
12628 If the last redisplay displayed an echo area message and that message
12629 is no longer requested, we clear the echo area or bring back the
12630 mini-buffer if that is in use. */
12632 void
12633 redisplay (void)
12635 redisplay_internal ();
12639 static Lisp_Object
12640 overlay_arrow_string_or_property (Lisp_Object var)
12642 Lisp_Object val;
12644 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12645 return val;
12647 return Voverlay_arrow_string;
12650 /* Return 1 if there are any overlay-arrows in current_buffer. */
12651 static int
12652 overlay_arrow_in_current_buffer_p (void)
12654 Lisp_Object vlist;
12656 for (vlist = Voverlay_arrow_variable_list;
12657 CONSP (vlist);
12658 vlist = XCDR (vlist))
12660 Lisp_Object var = XCAR (vlist);
12661 Lisp_Object val;
12663 if (!SYMBOLP (var))
12664 continue;
12665 val = find_symbol_value (var);
12666 if (MARKERP (val)
12667 && current_buffer == XMARKER (val)->buffer)
12668 return 1;
12670 return 0;
12674 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12675 has changed. */
12677 static int
12678 overlay_arrows_changed_p (void)
12680 Lisp_Object vlist;
12682 for (vlist = Voverlay_arrow_variable_list;
12683 CONSP (vlist);
12684 vlist = XCDR (vlist))
12686 Lisp_Object var = XCAR (vlist);
12687 Lisp_Object val, pstr;
12689 if (!SYMBOLP (var))
12690 continue;
12691 val = find_symbol_value (var);
12692 if (!MARKERP (val))
12693 continue;
12694 if (! EQ (COERCE_MARKER (val),
12695 Fget (var, Qlast_arrow_position))
12696 || ! (pstr = overlay_arrow_string_or_property (var),
12697 EQ (pstr, Fget (var, Qlast_arrow_string))))
12698 return 1;
12700 return 0;
12703 /* Mark overlay arrows to be updated on next redisplay. */
12705 static void
12706 update_overlay_arrows (int up_to_date)
12708 Lisp_Object vlist;
12710 for (vlist = Voverlay_arrow_variable_list;
12711 CONSP (vlist);
12712 vlist = XCDR (vlist))
12714 Lisp_Object var = XCAR (vlist);
12716 if (!SYMBOLP (var))
12717 continue;
12719 if (up_to_date > 0)
12721 Lisp_Object val = find_symbol_value (var);
12722 Fput (var, Qlast_arrow_position,
12723 COERCE_MARKER (val));
12724 Fput (var, Qlast_arrow_string,
12725 overlay_arrow_string_or_property (var));
12727 else if (up_to_date < 0
12728 || !NILP (Fget (var, Qlast_arrow_position)))
12730 Fput (var, Qlast_arrow_position, Qt);
12731 Fput (var, Qlast_arrow_string, Qt);
12737 /* Return overlay arrow string to display at row.
12738 Return integer (bitmap number) for arrow bitmap in left fringe.
12739 Return nil if no overlay arrow. */
12741 static Lisp_Object
12742 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12744 Lisp_Object vlist;
12746 for (vlist = Voverlay_arrow_variable_list;
12747 CONSP (vlist);
12748 vlist = XCDR (vlist))
12750 Lisp_Object var = XCAR (vlist);
12751 Lisp_Object val;
12753 if (!SYMBOLP (var))
12754 continue;
12756 val = find_symbol_value (var);
12758 if (MARKERP (val)
12759 && current_buffer == XMARKER (val)->buffer
12760 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12762 if (FRAME_WINDOW_P (it->f)
12763 /* FIXME: if ROW->reversed_p is set, this should test
12764 the right fringe, not the left one. */
12765 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12767 #ifdef HAVE_WINDOW_SYSTEM
12768 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12770 int fringe_bitmap;
12771 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12772 return make_number (fringe_bitmap);
12774 #endif
12775 return make_number (-1); /* Use default arrow bitmap. */
12777 return overlay_arrow_string_or_property (var);
12781 return Qnil;
12784 /* Return 1 if point moved out of or into a composition. Otherwise
12785 return 0. PREV_BUF and PREV_PT are the last point buffer and
12786 position. BUF and PT are the current point buffer and position. */
12788 static int
12789 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12790 struct buffer *buf, ptrdiff_t pt)
12792 ptrdiff_t start, end;
12793 Lisp_Object prop;
12794 Lisp_Object buffer;
12796 XSETBUFFER (buffer, buf);
12797 /* Check a composition at the last point if point moved within the
12798 same buffer. */
12799 if (prev_buf == buf)
12801 if (prev_pt == pt)
12802 /* Point didn't move. */
12803 return 0;
12805 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12806 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12807 && COMPOSITION_VALID_P (start, end, prop)
12808 && start < prev_pt && end > prev_pt)
12809 /* The last point was within the composition. Return 1 iff
12810 point moved out of the composition. */
12811 return (pt <= start || pt >= end);
12814 /* Check a composition at the current point. */
12815 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12816 && find_composition (pt, -1, &start, &end, &prop, buffer)
12817 && COMPOSITION_VALID_P (start, end, prop)
12818 && start < pt && end > pt);
12822 /* Reconsider the setting of B->clip_changed which is displayed
12823 in window W. */
12825 static void
12826 reconsider_clip_changes (struct window *w, struct buffer *b)
12828 if (b->clip_changed
12829 && w->window_end_valid
12830 && w->current_matrix->buffer == b
12831 && w->current_matrix->zv == BUF_ZV (b)
12832 && w->current_matrix->begv == BUF_BEGV (b))
12833 b->clip_changed = 0;
12835 /* If display wasn't paused, and W is not a tool bar window, see if
12836 point has been moved into or out of a composition. In that case,
12837 we set b->clip_changed to 1 to force updating the screen. If
12838 b->clip_changed has already been set to 1, we can skip this
12839 check. */
12840 if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid)
12842 ptrdiff_t pt;
12844 if (w == XWINDOW (selected_window))
12845 pt = PT;
12846 else
12847 pt = marker_position (w->pointm);
12849 if ((w->current_matrix->buffer != XBUFFER (w->contents)
12850 || pt != w->last_point)
12851 && check_point_in_composition (w->current_matrix->buffer,
12852 w->last_point,
12853 XBUFFER (w->contents), pt))
12854 b->clip_changed = 1;
12859 #define STOP_POLLING \
12860 do { if (! polling_stopped_here) stop_polling (); \
12861 polling_stopped_here = 1; } while (0)
12863 #define RESUME_POLLING \
12864 do { if (polling_stopped_here) start_polling (); \
12865 polling_stopped_here = 0; } while (0)
12868 /* Perhaps in the future avoid recentering windows if it
12869 is not necessary; currently that causes some problems. */
12871 static void
12872 redisplay_internal (void)
12874 struct window *w = XWINDOW (selected_window);
12875 struct window *sw;
12876 struct frame *fr;
12877 int pending;
12878 int must_finish = 0;
12879 struct text_pos tlbufpos, tlendpos;
12880 int number_of_visible_frames;
12881 ptrdiff_t count, count1;
12882 struct frame *sf;
12883 int polling_stopped_here = 0;
12884 Lisp_Object tail, frame;
12886 /* Non-zero means redisplay has to consider all windows on all
12887 frames. Zero means, only selected_window is considered. */
12888 int consider_all_windows_p;
12890 /* Non-zero means redisplay has to redisplay the miniwindow. */
12891 int update_miniwindow_p = 0;
12893 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12895 /* No redisplay if running in batch mode or frame is not yet fully
12896 initialized, or redisplay is explicitly turned off by setting
12897 Vinhibit_redisplay. */
12898 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12899 || !NILP (Vinhibit_redisplay))
12900 return;
12902 /* Don't examine these until after testing Vinhibit_redisplay.
12903 When Emacs is shutting down, perhaps because its connection to
12904 X has dropped, we should not look at them at all. */
12905 fr = XFRAME (w->frame);
12906 sf = SELECTED_FRAME ();
12908 if (!fr->glyphs_initialized_p)
12909 return;
12911 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12912 if (popup_activated ())
12913 return;
12914 #endif
12916 /* I don't think this happens but let's be paranoid. */
12917 if (redisplaying_p)
12918 return;
12920 /* Record a function that clears redisplaying_p
12921 when we leave this function. */
12922 count = SPECPDL_INDEX ();
12923 record_unwind_protect (unwind_redisplay, selected_frame);
12924 redisplaying_p = 1;
12925 specbind (Qinhibit_free_realized_faces, Qnil);
12927 /* Record this function, so it appears on the profiler's backtraces. */
12928 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12930 FOR_EACH_FRAME (tail, frame)
12931 XFRAME (frame)->already_hscrolled_p = 0;
12933 retry:
12934 /* Remember the currently selected window. */
12935 sw = w;
12937 pending = 0;
12938 reconsider_clip_changes (w, current_buffer);
12939 last_escape_glyph_frame = NULL;
12940 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12941 last_glyphless_glyph_frame = NULL;
12942 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12944 /* If new fonts have been loaded that make a glyph matrix adjustment
12945 necessary, do it. */
12946 if (fonts_changed_p)
12948 adjust_glyphs (NULL);
12949 ++windows_or_buffers_changed;
12950 fonts_changed_p = 0;
12953 /* If face_change_count is non-zero, init_iterator will free all
12954 realized faces, which includes the faces referenced from current
12955 matrices. So, we can't reuse current matrices in this case. */
12956 if (face_change_count)
12957 ++windows_or_buffers_changed;
12959 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12960 && FRAME_TTY (sf)->previous_frame != sf)
12962 /* Since frames on a single ASCII terminal share the same
12963 display area, displaying a different frame means redisplay
12964 the whole thing. */
12965 windows_or_buffers_changed++;
12966 SET_FRAME_GARBAGED (sf);
12967 #ifndef DOS_NT
12968 set_tty_color_mode (FRAME_TTY (sf), sf);
12969 #endif
12970 FRAME_TTY (sf)->previous_frame = sf;
12973 /* Set the visible flags for all frames. Do this before checking for
12974 resized or garbaged frames; they want to know if their frames are
12975 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
12976 number_of_visible_frames = 0;
12978 FOR_EACH_FRAME (tail, frame)
12980 struct frame *f = XFRAME (frame);
12982 if (FRAME_VISIBLE_P (f))
12983 ++number_of_visible_frames;
12984 clear_desired_matrices (f);
12987 /* Notice any pending interrupt request to change frame size. */
12988 do_pending_window_change (1);
12990 /* do_pending_window_change could change the selected_window due to
12991 frame resizing which makes the selected window too small. */
12992 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
12994 sw = w;
12995 reconsider_clip_changes (w, current_buffer);
12998 /* Clear frames marked as garbaged. */
12999 clear_garbaged_frames ();
13001 /* Build menubar and tool-bar items. */
13002 if (NILP (Vmemory_full))
13003 prepare_menu_bars ();
13005 if (windows_or_buffers_changed)
13006 update_mode_lines++;
13008 /* Detect case that we need to write or remove a star in the mode line. */
13009 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13011 w->update_mode_line = 1;
13012 if (buffer_shared_and_changed ())
13013 update_mode_lines++;
13016 /* Avoid invocation of point motion hooks by `current_column' below. */
13017 count1 = SPECPDL_INDEX ();
13018 specbind (Qinhibit_point_motion_hooks, Qt);
13020 if (mode_line_update_needed (w))
13021 w->update_mode_line = 1;
13023 unbind_to (count1, Qnil);
13025 consider_all_windows_p = (update_mode_lines
13026 || buffer_shared_and_changed ()
13027 || cursor_type_changed);
13029 /* If specs for an arrow have changed, do thorough redisplay
13030 to ensure we remove any arrow that should no longer exist. */
13031 if (overlay_arrows_changed_p ())
13032 consider_all_windows_p = windows_or_buffers_changed = 1;
13034 /* Normally the message* functions will have already displayed and
13035 updated the echo area, but the frame may have been trashed, or
13036 the update may have been preempted, so display the echo area
13037 again here. Checking message_cleared_p captures the case that
13038 the echo area should be cleared. */
13039 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13040 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13041 || (message_cleared_p
13042 && minibuf_level == 0
13043 /* If the mini-window is currently selected, this means the
13044 echo-area doesn't show through. */
13045 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13047 int window_height_changed_p = echo_area_display (0);
13049 if (message_cleared_p)
13050 update_miniwindow_p = 1;
13052 must_finish = 1;
13054 /* If we don't display the current message, don't clear the
13055 message_cleared_p flag, because, if we did, we wouldn't clear
13056 the echo area in the next redisplay which doesn't preserve
13057 the echo area. */
13058 if (!display_last_displayed_message_p)
13059 message_cleared_p = 0;
13061 if (fonts_changed_p)
13062 goto retry;
13063 else if (window_height_changed_p)
13065 consider_all_windows_p = 1;
13066 ++update_mode_lines;
13067 ++windows_or_buffers_changed;
13069 /* If window configuration was changed, frames may have been
13070 marked garbaged. Clear them or we will experience
13071 surprises wrt scrolling. */
13072 clear_garbaged_frames ();
13075 else if (EQ (selected_window, minibuf_window)
13076 && (current_buffer->clip_changed || window_outdated (w))
13077 && resize_mini_window (w, 0))
13079 /* Resized active mini-window to fit the size of what it is
13080 showing if its contents might have changed. */
13081 must_finish = 1;
13082 /* FIXME: this causes all frames to be updated, which seems unnecessary
13083 since only the current frame needs to be considered. This function
13084 needs to be rewritten with two variables, consider_all_windows and
13085 consider_all_frames. */
13086 consider_all_windows_p = 1;
13087 ++windows_or_buffers_changed;
13088 ++update_mode_lines;
13090 /* If window configuration was changed, frames may have been
13091 marked garbaged. Clear them or we will experience
13092 surprises wrt scrolling. */
13093 clear_garbaged_frames ();
13096 /* If showing the region, and mark has changed, we must redisplay
13097 the whole window. The assignment to this_line_start_pos prevents
13098 the optimization directly below this if-statement. */
13099 if (((!NILP (Vtransient_mark_mode)
13100 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13101 != (w->region_showing > 0))
13102 || (w->region_showing
13103 && w->region_showing
13104 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13105 CHARPOS (this_line_start_pos) = 0;
13107 /* Optimize the case that only the line containing the cursor in the
13108 selected window has changed. Variables starting with this_ are
13109 set in display_line and record information about the line
13110 containing the cursor. */
13111 tlbufpos = this_line_start_pos;
13112 tlendpos = this_line_end_pos;
13113 if (!consider_all_windows_p
13114 && CHARPOS (tlbufpos) > 0
13115 && !w->update_mode_line
13116 && !current_buffer->clip_changed
13117 && !current_buffer->prevent_redisplay_optimizations_p
13118 && FRAME_VISIBLE_P (XFRAME (w->frame))
13119 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13120 /* Make sure recorded data applies to current buffer, etc. */
13121 && this_line_buffer == current_buffer
13122 && current_buffer == XBUFFER (w->contents)
13123 && !w->force_start
13124 && !w->optional_new_start
13125 /* Point must be on the line that we have info recorded about. */
13126 && PT >= CHARPOS (tlbufpos)
13127 && PT <= Z - CHARPOS (tlendpos)
13128 /* All text outside that line, including its final newline,
13129 must be unchanged. */
13130 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13131 CHARPOS (tlendpos)))
13133 if (CHARPOS (tlbufpos) > BEGV
13134 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13135 && (CHARPOS (tlbufpos) == ZV
13136 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13137 /* Former continuation line has disappeared by becoming empty. */
13138 goto cancel;
13139 else if (window_outdated (w) || MINI_WINDOW_P (w))
13141 /* We have to handle the case of continuation around a
13142 wide-column character (see the comment in indent.c around
13143 line 1340).
13145 For instance, in the following case:
13147 -------- Insert --------
13148 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13149 J_I_ ==> J_I_ `^^' are cursors.
13150 ^^ ^^
13151 -------- --------
13153 As we have to redraw the line above, we cannot use this
13154 optimization. */
13156 struct it it;
13157 int line_height_before = this_line_pixel_height;
13159 /* Note that start_display will handle the case that the
13160 line starting at tlbufpos is a continuation line. */
13161 start_display (&it, w, tlbufpos);
13163 /* Implementation note: It this still necessary? */
13164 if (it.current_x != this_line_start_x)
13165 goto cancel;
13167 TRACE ((stderr, "trying display optimization 1\n"));
13168 w->cursor.vpos = -1;
13169 overlay_arrow_seen = 0;
13170 it.vpos = this_line_vpos;
13171 it.current_y = this_line_y;
13172 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13173 display_line (&it);
13175 /* If line contains point, is not continued,
13176 and ends at same distance from eob as before, we win. */
13177 if (w->cursor.vpos >= 0
13178 /* Line is not continued, otherwise this_line_start_pos
13179 would have been set to 0 in display_line. */
13180 && CHARPOS (this_line_start_pos)
13181 /* Line ends as before. */
13182 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13183 /* Line has same height as before. Otherwise other lines
13184 would have to be shifted up or down. */
13185 && this_line_pixel_height == line_height_before)
13187 /* If this is not the window's last line, we must adjust
13188 the charstarts of the lines below. */
13189 if (it.current_y < it.last_visible_y)
13191 struct glyph_row *row
13192 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13193 ptrdiff_t delta, delta_bytes;
13195 /* We used to distinguish between two cases here,
13196 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13197 when the line ends in a newline or the end of the
13198 buffer's accessible portion. But both cases did
13199 the same, so they were collapsed. */
13200 delta = (Z
13201 - CHARPOS (tlendpos)
13202 - MATRIX_ROW_START_CHARPOS (row));
13203 delta_bytes = (Z_BYTE
13204 - BYTEPOS (tlendpos)
13205 - MATRIX_ROW_START_BYTEPOS (row));
13207 increment_matrix_positions (w->current_matrix,
13208 this_line_vpos + 1,
13209 w->current_matrix->nrows,
13210 delta, delta_bytes);
13213 /* If this row displays text now but previously didn't,
13214 or vice versa, w->window_end_vpos may have to be
13215 adjusted. */
13216 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13218 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13219 wset_window_end_vpos (w, make_number (this_line_vpos));
13221 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13222 && this_line_vpos > 0)
13223 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13224 w->window_end_valid = 0;
13226 /* Update hint: No need to try to scroll in update_window. */
13227 w->desired_matrix->no_scrolling_p = 1;
13229 #ifdef GLYPH_DEBUG
13230 *w->desired_matrix->method = 0;
13231 debug_method_add (w, "optimization 1");
13232 #endif
13233 #ifdef HAVE_WINDOW_SYSTEM
13234 update_window_fringes (w, 0);
13235 #endif
13236 goto update;
13238 else
13239 goto cancel;
13241 else if (/* Cursor position hasn't changed. */
13242 PT == w->last_point
13243 /* Make sure the cursor was last displayed
13244 in this window. Otherwise we have to reposition it. */
13245 && 0 <= w->cursor.vpos
13246 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13248 if (!must_finish)
13250 do_pending_window_change (1);
13251 /* If selected_window changed, redisplay again. */
13252 if (WINDOWP (selected_window)
13253 && (w = XWINDOW (selected_window)) != sw)
13254 goto retry;
13256 /* We used to always goto end_of_redisplay here, but this
13257 isn't enough if we have a blinking cursor. */
13258 if (w->cursor_off_p == w->last_cursor_off_p)
13259 goto end_of_redisplay;
13261 goto update;
13263 /* If highlighting the region, or if the cursor is in the echo area,
13264 then we can't just move the cursor. */
13265 else if (! (!NILP (Vtransient_mark_mode)
13266 && !NILP (BVAR (current_buffer, mark_active)))
13267 && (EQ (selected_window,
13268 BVAR (current_buffer, last_selected_window))
13269 || highlight_nonselected_windows)
13270 && !w->region_showing
13271 && NILP (Vshow_trailing_whitespace)
13272 && !cursor_in_echo_area)
13274 struct it it;
13275 struct glyph_row *row;
13277 /* Skip from tlbufpos to PT and see where it is. Note that
13278 PT may be in invisible text. If so, we will end at the
13279 next visible position. */
13280 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13281 NULL, DEFAULT_FACE_ID);
13282 it.current_x = this_line_start_x;
13283 it.current_y = this_line_y;
13284 it.vpos = this_line_vpos;
13286 /* The call to move_it_to stops in front of PT, but
13287 moves over before-strings. */
13288 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13290 if (it.vpos == this_line_vpos
13291 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13292 row->enabled_p))
13294 eassert (this_line_vpos == it.vpos);
13295 eassert (this_line_y == it.current_y);
13296 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13297 #ifdef GLYPH_DEBUG
13298 *w->desired_matrix->method = 0;
13299 debug_method_add (w, "optimization 3");
13300 #endif
13301 goto update;
13303 else
13304 goto cancel;
13307 cancel:
13308 /* Text changed drastically or point moved off of line. */
13309 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13312 CHARPOS (this_line_start_pos) = 0;
13313 consider_all_windows_p |= buffer_shared_and_changed ();
13314 ++clear_face_cache_count;
13315 #ifdef HAVE_WINDOW_SYSTEM
13316 ++clear_image_cache_count;
13317 #endif
13319 /* Build desired matrices, and update the display. If
13320 consider_all_windows_p is non-zero, do it for all windows on all
13321 frames. Otherwise do it for selected_window, only. */
13323 if (consider_all_windows_p)
13325 FOR_EACH_FRAME (tail, frame)
13326 XFRAME (frame)->updated_p = 0;
13328 FOR_EACH_FRAME (tail, frame)
13330 struct frame *f = XFRAME (frame);
13332 /* We don't have to do anything for unselected terminal
13333 frames. */
13334 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13335 && !EQ (FRAME_TTY (f)->top_frame, frame))
13336 continue;
13338 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13340 /* Mark all the scroll bars to be removed; we'll redeem
13341 the ones we want when we redisplay their windows. */
13342 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13343 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13345 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13346 redisplay_windows (FRAME_ROOT_WINDOW (f));
13348 /* The X error handler may have deleted that frame. */
13349 if (!FRAME_LIVE_P (f))
13350 continue;
13352 /* Any scroll bars which redisplay_windows should have
13353 nuked should now go away. */
13354 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13355 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13357 /* If fonts changed, display again. */
13358 /* ??? rms: I suspect it is a mistake to jump all the way
13359 back to retry here. It should just retry this frame. */
13360 if (fonts_changed_p)
13361 goto retry;
13363 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13365 /* See if we have to hscroll. */
13366 if (!f->already_hscrolled_p)
13368 f->already_hscrolled_p = 1;
13369 if (hscroll_windows (f->root_window))
13370 goto retry;
13373 /* Prevent various kinds of signals during display
13374 update. stdio is not robust about handling
13375 signals, which can cause an apparent I/O
13376 error. */
13377 if (interrupt_input)
13378 unrequest_sigio ();
13379 STOP_POLLING;
13381 /* Update the display. */
13382 set_window_update_flags (XWINDOW (f->root_window), 1);
13383 pending |= update_frame (f, 0, 0);
13384 f->updated_p = 1;
13389 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13391 if (!pending)
13393 /* Do the mark_window_display_accurate after all windows have
13394 been redisplayed because this call resets flags in buffers
13395 which are needed for proper redisplay. */
13396 FOR_EACH_FRAME (tail, frame)
13398 struct frame *f = XFRAME (frame);
13399 if (f->updated_p)
13401 mark_window_display_accurate (f->root_window, 1);
13402 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13403 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13408 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13410 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13411 struct frame *mini_frame;
13413 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13414 /* Use list_of_error, not Qerror, so that
13415 we catch only errors and don't run the debugger. */
13416 internal_condition_case_1 (redisplay_window_1, selected_window,
13417 list_of_error,
13418 redisplay_window_error);
13419 if (update_miniwindow_p)
13420 internal_condition_case_1 (redisplay_window_1, mini_window,
13421 list_of_error,
13422 redisplay_window_error);
13424 /* Compare desired and current matrices, perform output. */
13426 update:
13427 /* If fonts changed, display again. */
13428 if (fonts_changed_p)
13429 goto retry;
13431 /* Prevent various kinds of signals during display update.
13432 stdio is not robust about handling signals,
13433 which can cause an apparent I/O error. */
13434 if (interrupt_input)
13435 unrequest_sigio ();
13436 STOP_POLLING;
13438 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13440 if (hscroll_windows (selected_window))
13441 goto retry;
13443 XWINDOW (selected_window)->must_be_updated_p = 1;
13444 pending = update_frame (sf, 0, 0);
13447 /* We may have called echo_area_display at the top of this
13448 function. If the echo area is on another frame, that may
13449 have put text on a frame other than the selected one, so the
13450 above call to update_frame would not have caught it. Catch
13451 it here. */
13452 mini_window = FRAME_MINIBUF_WINDOW (sf);
13453 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13455 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13457 XWINDOW (mini_window)->must_be_updated_p = 1;
13458 pending |= update_frame (mini_frame, 0, 0);
13459 if (!pending && hscroll_windows (mini_window))
13460 goto retry;
13464 /* If display was paused because of pending input, make sure we do a
13465 thorough update the next time. */
13466 if (pending)
13468 /* Prevent the optimization at the beginning of
13469 redisplay_internal that tries a single-line update of the
13470 line containing the cursor in the selected window. */
13471 CHARPOS (this_line_start_pos) = 0;
13473 /* Let the overlay arrow be updated the next time. */
13474 update_overlay_arrows (0);
13476 /* If we pause after scrolling, some rows in the current
13477 matrices of some windows are not valid. */
13478 if (!WINDOW_FULL_WIDTH_P (w)
13479 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13480 update_mode_lines = 1;
13482 else
13484 if (!consider_all_windows_p)
13486 /* This has already been done above if
13487 consider_all_windows_p is set. */
13488 mark_window_display_accurate_1 (w, 1);
13490 /* Say overlay arrows are up to date. */
13491 update_overlay_arrows (1);
13493 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13494 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13497 update_mode_lines = 0;
13498 windows_or_buffers_changed = 0;
13499 cursor_type_changed = 0;
13502 /* Start SIGIO interrupts coming again. Having them off during the
13503 code above makes it less likely one will discard output, but not
13504 impossible, since there might be stuff in the system buffer here.
13505 But it is much hairier to try to do anything about that. */
13506 if (interrupt_input)
13507 request_sigio ();
13508 RESUME_POLLING;
13510 /* If a frame has become visible which was not before, redisplay
13511 again, so that we display it. Expose events for such a frame
13512 (which it gets when becoming visible) don't call the parts of
13513 redisplay constructing glyphs, so simply exposing a frame won't
13514 display anything in this case. So, we have to display these
13515 frames here explicitly. */
13516 if (!pending)
13518 int new_count = 0;
13520 FOR_EACH_FRAME (tail, frame)
13522 int this_is_visible = 0;
13524 if (XFRAME (frame)->visible)
13525 this_is_visible = 1;
13527 if (this_is_visible)
13528 new_count++;
13531 if (new_count != number_of_visible_frames)
13532 windows_or_buffers_changed++;
13535 /* Change frame size now if a change is pending. */
13536 do_pending_window_change (1);
13538 /* If we just did a pending size change, or have additional
13539 visible frames, or selected_window changed, redisplay again. */
13540 if ((windows_or_buffers_changed && !pending)
13541 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13542 goto retry;
13544 /* Clear the face and image caches.
13546 We used to do this only if consider_all_windows_p. But the cache
13547 needs to be cleared if a timer creates images in the current
13548 buffer (e.g. the test case in Bug#6230). */
13550 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13552 clear_face_cache (0);
13553 clear_face_cache_count = 0;
13556 #ifdef HAVE_WINDOW_SYSTEM
13557 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13559 clear_image_caches (Qnil);
13560 clear_image_cache_count = 0;
13562 #endif /* HAVE_WINDOW_SYSTEM */
13564 end_of_redisplay:
13565 unbind_to (count, Qnil);
13566 RESUME_POLLING;
13570 /* Redisplay, but leave alone any recent echo area message unless
13571 another message has been requested in its place.
13573 This is useful in situations where you need to redisplay but no
13574 user action has occurred, making it inappropriate for the message
13575 area to be cleared. See tracking_off and
13576 wait_reading_process_output for examples of these situations.
13578 FROM_WHERE is an integer saying from where this function was
13579 called. This is useful for debugging. */
13581 void
13582 redisplay_preserve_echo_area (int from_where)
13584 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13586 if (!NILP (echo_area_buffer[1]))
13588 /* We have a previously displayed message, but no current
13589 message. Redisplay the previous message. */
13590 display_last_displayed_message_p = 1;
13591 redisplay_internal ();
13592 display_last_displayed_message_p = 0;
13594 else
13595 redisplay_internal ();
13597 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13598 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13599 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13603 /* Function registered with record_unwind_protect in redisplay_internal.
13604 Clear redisplaying_p. Also select the previously selected frame. */
13606 static Lisp_Object
13607 unwind_redisplay (Lisp_Object old_frame)
13609 redisplaying_p = 0;
13610 return Qnil;
13614 /* Mark the display of leaf window W as accurate or inaccurate.
13615 If ACCURATE_P is non-zero mark display of W as accurate. If
13616 ACCURATE_P is zero, arrange for W to be redisplayed the next
13617 time redisplay_internal is called. */
13619 static void
13620 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13622 struct buffer *b = XBUFFER (w->contents);
13624 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13625 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
13626 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13628 if (accurate_p)
13630 b->clip_changed = 0;
13631 b->prevent_redisplay_optimizations_p = 0;
13633 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13634 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13635 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13636 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13638 w->current_matrix->buffer = b;
13639 w->current_matrix->begv = BUF_BEGV (b);
13640 w->current_matrix->zv = BUF_ZV (b);
13642 w->last_cursor = w->cursor;
13643 w->last_cursor_off_p = w->cursor_off_p;
13645 if (w == XWINDOW (selected_window))
13646 w->last_point = BUF_PT (b);
13647 else
13648 w->last_point = marker_position (w->pointm);
13650 w->window_end_valid = 1;
13651 w->update_mode_line = 0;
13656 /* Mark the display of windows in the window tree rooted at WINDOW as
13657 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13658 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13659 be redisplayed the next time redisplay_internal is called. */
13661 void
13662 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13664 struct window *w;
13666 for (; !NILP (window); window = w->next)
13668 w = XWINDOW (window);
13669 if (WINDOWP (w->contents))
13670 mark_window_display_accurate (w->contents, accurate_p);
13671 else
13672 mark_window_display_accurate_1 (w, accurate_p);
13675 if (accurate_p)
13676 update_overlay_arrows (1);
13677 else
13678 /* Force a thorough redisplay the next time by setting
13679 last_arrow_position and last_arrow_string to t, which is
13680 unequal to any useful value of Voverlay_arrow_... */
13681 update_overlay_arrows (-1);
13685 /* Return value in display table DP (Lisp_Char_Table *) for character
13686 C. Since a display table doesn't have any parent, we don't have to
13687 follow parent. Do not call this function directly but use the
13688 macro DISP_CHAR_VECTOR. */
13690 Lisp_Object
13691 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13693 Lisp_Object val;
13695 if (ASCII_CHAR_P (c))
13697 val = dp->ascii;
13698 if (SUB_CHAR_TABLE_P (val))
13699 val = XSUB_CHAR_TABLE (val)->contents[c];
13701 else
13703 Lisp_Object table;
13705 XSETCHAR_TABLE (table, dp);
13706 val = char_table_ref (table, c);
13708 if (NILP (val))
13709 val = dp->defalt;
13710 return val;
13715 /***********************************************************************
13716 Window Redisplay
13717 ***********************************************************************/
13719 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13721 static void
13722 redisplay_windows (Lisp_Object window)
13724 while (!NILP (window))
13726 struct window *w = XWINDOW (window);
13728 if (WINDOWP (w->contents))
13729 redisplay_windows (w->contents);
13730 else if (BUFFERP (w->contents))
13732 displayed_buffer = XBUFFER (w->contents);
13733 /* Use list_of_error, not Qerror, so that
13734 we catch only errors and don't run the debugger. */
13735 internal_condition_case_1 (redisplay_window_0, window,
13736 list_of_error,
13737 redisplay_window_error);
13740 window = w->next;
13744 static Lisp_Object
13745 redisplay_window_error (Lisp_Object ignore)
13747 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13748 return Qnil;
13751 static Lisp_Object
13752 redisplay_window_0 (Lisp_Object window)
13754 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13755 redisplay_window (window, 0);
13756 return Qnil;
13759 static Lisp_Object
13760 redisplay_window_1 (Lisp_Object window)
13762 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13763 redisplay_window (window, 1);
13764 return Qnil;
13768 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13769 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13770 which positions recorded in ROW differ from current buffer
13771 positions.
13773 Return 0 if cursor is not on this row, 1 otherwise. */
13775 static int
13776 set_cursor_from_row (struct window *w, struct glyph_row *row,
13777 struct glyph_matrix *matrix,
13778 ptrdiff_t delta, ptrdiff_t delta_bytes,
13779 int dy, int dvpos)
13781 struct glyph *glyph = row->glyphs[TEXT_AREA];
13782 struct glyph *end = glyph + row->used[TEXT_AREA];
13783 struct glyph *cursor = NULL;
13784 /* The last known character position in row. */
13785 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13786 int x = row->x;
13787 ptrdiff_t pt_old = PT - delta;
13788 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13789 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13790 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13791 /* A glyph beyond the edge of TEXT_AREA which we should never
13792 touch. */
13793 struct glyph *glyphs_end = end;
13794 /* Non-zero means we've found a match for cursor position, but that
13795 glyph has the avoid_cursor_p flag set. */
13796 int match_with_avoid_cursor = 0;
13797 /* Non-zero means we've seen at least one glyph that came from a
13798 display string. */
13799 int string_seen = 0;
13800 /* Largest and smallest buffer positions seen so far during scan of
13801 glyph row. */
13802 ptrdiff_t bpos_max = pos_before;
13803 ptrdiff_t bpos_min = pos_after;
13804 /* Last buffer position covered by an overlay string with an integer
13805 `cursor' property. */
13806 ptrdiff_t bpos_covered = 0;
13807 /* Non-zero means the display string on which to display the cursor
13808 comes from a text property, not from an overlay. */
13809 int string_from_text_prop = 0;
13811 /* Don't even try doing anything if called for a mode-line or
13812 header-line row, since the rest of the code isn't prepared to
13813 deal with such calamities. */
13814 eassert (!row->mode_line_p);
13815 if (row->mode_line_p)
13816 return 0;
13818 /* Skip over glyphs not having an object at the start and the end of
13819 the row. These are special glyphs like truncation marks on
13820 terminal frames. */
13821 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13823 if (!row->reversed_p)
13825 while (glyph < end
13826 && INTEGERP (glyph->object)
13827 && glyph->charpos < 0)
13829 x += glyph->pixel_width;
13830 ++glyph;
13832 while (end > glyph
13833 && INTEGERP ((end - 1)->object)
13834 /* CHARPOS is zero for blanks and stretch glyphs
13835 inserted by extend_face_to_end_of_line. */
13836 && (end - 1)->charpos <= 0)
13837 --end;
13838 glyph_before = glyph - 1;
13839 glyph_after = end;
13841 else
13843 struct glyph *g;
13845 /* If the glyph row is reversed, we need to process it from back
13846 to front, so swap the edge pointers. */
13847 glyphs_end = end = glyph - 1;
13848 glyph += row->used[TEXT_AREA] - 1;
13850 while (glyph > end + 1
13851 && INTEGERP (glyph->object)
13852 && glyph->charpos < 0)
13854 --glyph;
13855 x -= glyph->pixel_width;
13857 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13858 --glyph;
13859 /* By default, in reversed rows we put the cursor on the
13860 rightmost (first in the reading order) glyph. */
13861 for (g = end + 1; g < glyph; g++)
13862 x += g->pixel_width;
13863 while (end < glyph
13864 && INTEGERP ((end + 1)->object)
13865 && (end + 1)->charpos <= 0)
13866 ++end;
13867 glyph_before = glyph + 1;
13868 glyph_after = end;
13871 else if (row->reversed_p)
13873 /* In R2L rows that don't display text, put the cursor on the
13874 rightmost glyph. Case in point: an empty last line that is
13875 part of an R2L paragraph. */
13876 cursor = end - 1;
13877 /* Avoid placing the cursor on the last glyph of the row, where
13878 on terminal frames we hold the vertical border between
13879 adjacent windows. */
13880 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13881 && !WINDOW_RIGHTMOST_P (w)
13882 && cursor == row->glyphs[LAST_AREA] - 1)
13883 cursor--;
13884 x = -1; /* will be computed below, at label compute_x */
13887 /* Step 1: Try to find the glyph whose character position
13888 corresponds to point. If that's not possible, find 2 glyphs
13889 whose character positions are the closest to point, one before
13890 point, the other after it. */
13891 if (!row->reversed_p)
13892 while (/* not marched to end of glyph row */
13893 glyph < end
13894 /* glyph was not inserted by redisplay for internal purposes */
13895 && !INTEGERP (glyph->object))
13897 if (BUFFERP (glyph->object))
13899 ptrdiff_t dpos = glyph->charpos - pt_old;
13901 if (glyph->charpos > bpos_max)
13902 bpos_max = glyph->charpos;
13903 if (glyph->charpos < bpos_min)
13904 bpos_min = glyph->charpos;
13905 if (!glyph->avoid_cursor_p)
13907 /* If we hit point, we've found the glyph on which to
13908 display the cursor. */
13909 if (dpos == 0)
13911 match_with_avoid_cursor = 0;
13912 break;
13914 /* See if we've found a better approximation to
13915 POS_BEFORE or to POS_AFTER. */
13916 if (0 > dpos && dpos > pos_before - pt_old)
13918 pos_before = glyph->charpos;
13919 glyph_before = glyph;
13921 else if (0 < dpos && dpos < pos_after - pt_old)
13923 pos_after = glyph->charpos;
13924 glyph_after = glyph;
13927 else if (dpos == 0)
13928 match_with_avoid_cursor = 1;
13930 else if (STRINGP (glyph->object))
13932 Lisp_Object chprop;
13933 ptrdiff_t glyph_pos = glyph->charpos;
13935 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13936 glyph->object);
13937 if (!NILP (chprop))
13939 /* If the string came from a `display' text property,
13940 look up the buffer position of that property and
13941 use that position to update bpos_max, as if we
13942 actually saw such a position in one of the row's
13943 glyphs. This helps with supporting integer values
13944 of `cursor' property on the display string in
13945 situations where most or all of the row's buffer
13946 text is completely covered by display properties,
13947 so that no glyph with valid buffer positions is
13948 ever seen in the row. */
13949 ptrdiff_t prop_pos =
13950 string_buffer_position_lim (glyph->object, pos_before,
13951 pos_after, 0);
13953 if (prop_pos >= pos_before)
13954 bpos_max = prop_pos - 1;
13956 if (INTEGERP (chprop))
13958 bpos_covered = bpos_max + XINT (chprop);
13959 /* If the `cursor' property covers buffer positions up
13960 to and including point, we should display cursor on
13961 this glyph. Note that, if a `cursor' property on one
13962 of the string's characters has an integer value, we
13963 will break out of the loop below _before_ we get to
13964 the position match above. IOW, integer values of
13965 the `cursor' property override the "exact match for
13966 point" strategy of positioning the cursor. */
13967 /* Implementation note: bpos_max == pt_old when, e.g.,
13968 we are in an empty line, where bpos_max is set to
13969 MATRIX_ROW_START_CHARPOS, see above. */
13970 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13972 cursor = glyph;
13973 break;
13977 string_seen = 1;
13979 x += glyph->pixel_width;
13980 ++glyph;
13982 else if (glyph > end) /* row is reversed */
13983 while (!INTEGERP (glyph->object))
13985 if (BUFFERP (glyph->object))
13987 ptrdiff_t dpos = glyph->charpos - pt_old;
13989 if (glyph->charpos > bpos_max)
13990 bpos_max = glyph->charpos;
13991 if (glyph->charpos < bpos_min)
13992 bpos_min = glyph->charpos;
13993 if (!glyph->avoid_cursor_p)
13995 if (dpos == 0)
13997 match_with_avoid_cursor = 0;
13998 break;
14000 if (0 > dpos && dpos > pos_before - pt_old)
14002 pos_before = glyph->charpos;
14003 glyph_before = glyph;
14005 else if (0 < dpos && dpos < pos_after - pt_old)
14007 pos_after = glyph->charpos;
14008 glyph_after = glyph;
14011 else if (dpos == 0)
14012 match_with_avoid_cursor = 1;
14014 else if (STRINGP (glyph->object))
14016 Lisp_Object chprop;
14017 ptrdiff_t glyph_pos = glyph->charpos;
14019 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14020 glyph->object);
14021 if (!NILP (chprop))
14023 ptrdiff_t prop_pos =
14024 string_buffer_position_lim (glyph->object, pos_before,
14025 pos_after, 0);
14027 if (prop_pos >= pos_before)
14028 bpos_max = prop_pos - 1;
14030 if (INTEGERP (chprop))
14032 bpos_covered = bpos_max + XINT (chprop);
14033 /* If the `cursor' property covers buffer positions up
14034 to and including point, we should display cursor on
14035 this glyph. */
14036 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14038 cursor = glyph;
14039 break;
14042 string_seen = 1;
14044 --glyph;
14045 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14047 x--; /* can't use any pixel_width */
14048 break;
14050 x -= glyph->pixel_width;
14053 /* Step 2: If we didn't find an exact match for point, we need to
14054 look for a proper place to put the cursor among glyphs between
14055 GLYPH_BEFORE and GLYPH_AFTER. */
14056 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14057 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14058 && !(bpos_max < pt_old && pt_old <= bpos_covered))
14060 /* An empty line has a single glyph whose OBJECT is zero and
14061 whose CHARPOS is the position of a newline on that line.
14062 Note that on a TTY, there are more glyphs after that, which
14063 were produced by extend_face_to_end_of_line, but their
14064 CHARPOS is zero or negative. */
14065 int empty_line_p =
14066 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14067 && INTEGERP (glyph->object) && glyph->charpos > 0
14068 /* On a TTY, continued and truncated rows also have a glyph at
14069 their end whose OBJECT is zero and whose CHARPOS is
14070 positive (the continuation and truncation glyphs), but such
14071 rows are obviously not "empty". */
14072 && !(row->continued_p || row->truncated_on_right_p);
14074 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14076 ptrdiff_t ellipsis_pos;
14078 /* Scan back over the ellipsis glyphs. */
14079 if (!row->reversed_p)
14081 ellipsis_pos = (glyph - 1)->charpos;
14082 while (glyph > row->glyphs[TEXT_AREA]
14083 && (glyph - 1)->charpos == ellipsis_pos)
14084 glyph--, x -= glyph->pixel_width;
14085 /* That loop always goes one position too far, including
14086 the glyph before the ellipsis. So scan forward over
14087 that one. */
14088 x += glyph->pixel_width;
14089 glyph++;
14091 else /* row is reversed */
14093 ellipsis_pos = (glyph + 1)->charpos;
14094 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14095 && (glyph + 1)->charpos == ellipsis_pos)
14096 glyph++, x += glyph->pixel_width;
14097 x -= glyph->pixel_width;
14098 glyph--;
14101 else if (match_with_avoid_cursor)
14103 cursor = glyph_after;
14104 x = -1;
14106 else if (string_seen)
14108 int incr = row->reversed_p ? -1 : +1;
14110 /* Need to find the glyph that came out of a string which is
14111 present at point. That glyph is somewhere between
14112 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14113 positioned between POS_BEFORE and POS_AFTER in the
14114 buffer. */
14115 struct glyph *start, *stop;
14116 ptrdiff_t pos = pos_before;
14118 x = -1;
14120 /* If the row ends in a newline from a display string,
14121 reordering could have moved the glyphs belonging to the
14122 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14123 in this case we extend the search to the last glyph in
14124 the row that was not inserted by redisplay. */
14125 if (row->ends_in_newline_from_string_p)
14127 glyph_after = end;
14128 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14131 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14132 correspond to POS_BEFORE and POS_AFTER, respectively. We
14133 need START and STOP in the order that corresponds to the
14134 row's direction as given by its reversed_p flag. If the
14135 directionality of characters between POS_BEFORE and
14136 POS_AFTER is the opposite of the row's base direction,
14137 these characters will have been reordered for display,
14138 and we need to reverse START and STOP. */
14139 if (!row->reversed_p)
14141 start = min (glyph_before, glyph_after);
14142 stop = max (glyph_before, glyph_after);
14144 else
14146 start = max (glyph_before, glyph_after);
14147 stop = min (glyph_before, glyph_after);
14149 for (glyph = start + incr;
14150 row->reversed_p ? glyph > stop : glyph < stop; )
14153 /* Any glyphs that come from the buffer are here because
14154 of bidi reordering. Skip them, and only pay
14155 attention to glyphs that came from some string. */
14156 if (STRINGP (glyph->object))
14158 Lisp_Object str;
14159 ptrdiff_t tem;
14160 /* If the display property covers the newline, we
14161 need to search for it one position farther. */
14162 ptrdiff_t lim = pos_after
14163 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14165 string_from_text_prop = 0;
14166 str = glyph->object;
14167 tem = string_buffer_position_lim (str, pos, lim, 0);
14168 if (tem == 0 /* from overlay */
14169 || pos <= tem)
14171 /* If the string from which this glyph came is
14172 found in the buffer at point, or at position
14173 that is closer to point than pos_after, then
14174 we've found the glyph we've been looking for.
14175 If it comes from an overlay (tem == 0), and
14176 it has the `cursor' property on one of its
14177 glyphs, record that glyph as a candidate for
14178 displaying the cursor. (As in the
14179 unidirectional version, we will display the
14180 cursor on the last candidate we find.) */
14181 if (tem == 0
14182 || tem == pt_old
14183 || (tem - pt_old > 0 && tem < pos_after))
14185 /* The glyphs from this string could have
14186 been reordered. Find the one with the
14187 smallest string position. Or there could
14188 be a character in the string with the
14189 `cursor' property, which means display
14190 cursor on that character's glyph. */
14191 ptrdiff_t strpos = glyph->charpos;
14193 if (tem)
14195 cursor = glyph;
14196 string_from_text_prop = 1;
14198 for ( ;
14199 (row->reversed_p ? glyph > stop : glyph < stop)
14200 && EQ (glyph->object, str);
14201 glyph += incr)
14203 Lisp_Object cprop;
14204 ptrdiff_t gpos = glyph->charpos;
14206 cprop = Fget_char_property (make_number (gpos),
14207 Qcursor,
14208 glyph->object);
14209 if (!NILP (cprop))
14211 cursor = glyph;
14212 break;
14214 if (tem && glyph->charpos < strpos)
14216 strpos = glyph->charpos;
14217 cursor = glyph;
14221 if (tem == pt_old
14222 || (tem - pt_old > 0 && tem < pos_after))
14223 goto compute_x;
14225 if (tem)
14226 pos = tem + 1; /* don't find previous instances */
14228 /* This string is not what we want; skip all of the
14229 glyphs that came from it. */
14230 while ((row->reversed_p ? glyph > stop : glyph < stop)
14231 && EQ (glyph->object, str))
14232 glyph += incr;
14234 else
14235 glyph += incr;
14238 /* If we reached the end of the line, and END was from a string,
14239 the cursor is not on this line. */
14240 if (cursor == NULL
14241 && (row->reversed_p ? glyph <= end : glyph >= end)
14242 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14243 && STRINGP (end->object)
14244 && row->continued_p)
14245 return 0;
14247 /* A truncated row may not include PT among its character positions.
14248 Setting the cursor inside the scroll margin will trigger
14249 recalculation of hscroll in hscroll_window_tree. But if a
14250 display string covers point, defer to the string-handling
14251 code below to figure this out. */
14252 else if (row->truncated_on_left_p && pt_old < bpos_min)
14254 cursor = glyph_before;
14255 x = -1;
14257 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14258 /* Zero-width characters produce no glyphs. */
14259 || (!empty_line_p
14260 && (row->reversed_p
14261 ? glyph_after > glyphs_end
14262 : glyph_after < glyphs_end)))
14264 cursor = glyph_after;
14265 x = -1;
14269 compute_x:
14270 if (cursor != NULL)
14271 glyph = cursor;
14272 else if (glyph == glyphs_end
14273 && pos_before == pos_after
14274 && STRINGP ((row->reversed_p
14275 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14276 : row->glyphs[TEXT_AREA])->object))
14278 /* If all the glyphs of this row came from strings, put the
14279 cursor on the first glyph of the row. This avoids having the
14280 cursor outside of the text area in this very rare and hard
14281 use case. */
14282 glyph =
14283 row->reversed_p
14284 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14285 : row->glyphs[TEXT_AREA];
14287 if (x < 0)
14289 struct glyph *g;
14291 /* Need to compute x that corresponds to GLYPH. */
14292 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14294 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14295 emacs_abort ();
14296 x += g->pixel_width;
14300 /* ROW could be part of a continued line, which, under bidi
14301 reordering, might have other rows whose start and end charpos
14302 occlude point. Only set w->cursor if we found a better
14303 approximation to the cursor position than we have from previously
14304 examined candidate rows belonging to the same continued line. */
14305 if (/* we already have a candidate row */
14306 w->cursor.vpos >= 0
14307 /* that candidate is not the row we are processing */
14308 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14309 /* Make sure cursor.vpos specifies a row whose start and end
14310 charpos occlude point, and it is valid candidate for being a
14311 cursor-row. This is because some callers of this function
14312 leave cursor.vpos at the row where the cursor was displayed
14313 during the last redisplay cycle. */
14314 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14315 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14316 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14318 struct glyph *g1 =
14319 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14321 /* Don't consider glyphs that are outside TEXT_AREA. */
14322 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14323 return 0;
14324 /* Keep the candidate whose buffer position is the closest to
14325 point or has the `cursor' property. */
14326 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14327 w->cursor.hpos >= 0
14328 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14329 && ((BUFFERP (g1->object)
14330 && (g1->charpos == pt_old /* an exact match always wins */
14331 || (BUFFERP (glyph->object)
14332 && eabs (g1->charpos - pt_old)
14333 < eabs (glyph->charpos - pt_old))))
14334 /* previous candidate is a glyph from a string that has
14335 a non-nil `cursor' property */
14336 || (STRINGP (g1->object)
14337 && (!NILP (Fget_char_property (make_number (g1->charpos),
14338 Qcursor, g1->object))
14339 /* previous candidate is from the same display
14340 string as this one, and the display string
14341 came from a text property */
14342 || (EQ (g1->object, glyph->object)
14343 && string_from_text_prop)
14344 /* this candidate is from newline and its
14345 position is not an exact match */
14346 || (INTEGERP (glyph->object)
14347 && glyph->charpos != pt_old)))))
14348 return 0;
14349 /* If this candidate gives an exact match, use that. */
14350 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14351 /* If this candidate is a glyph created for the
14352 terminating newline of a line, and point is on that
14353 newline, it wins because it's an exact match. */
14354 || (!row->continued_p
14355 && INTEGERP (glyph->object)
14356 && glyph->charpos == 0
14357 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14358 /* Otherwise, keep the candidate that comes from a row
14359 spanning less buffer positions. This may win when one or
14360 both candidate positions are on glyphs that came from
14361 display strings, for which we cannot compare buffer
14362 positions. */
14363 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14364 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14365 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14366 return 0;
14368 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14369 w->cursor.x = x;
14370 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14371 w->cursor.y = row->y + dy;
14373 if (w == XWINDOW (selected_window))
14375 if (!row->continued_p
14376 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14377 && row->x == 0)
14379 this_line_buffer = XBUFFER (w->contents);
14381 CHARPOS (this_line_start_pos)
14382 = MATRIX_ROW_START_CHARPOS (row) + delta;
14383 BYTEPOS (this_line_start_pos)
14384 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14386 CHARPOS (this_line_end_pos)
14387 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14388 BYTEPOS (this_line_end_pos)
14389 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14391 this_line_y = w->cursor.y;
14392 this_line_pixel_height = row->height;
14393 this_line_vpos = w->cursor.vpos;
14394 this_line_start_x = row->x;
14396 else
14397 CHARPOS (this_line_start_pos) = 0;
14400 return 1;
14404 /* Run window scroll functions, if any, for WINDOW with new window
14405 start STARTP. Sets the window start of WINDOW to that position.
14407 We assume that the window's buffer is really current. */
14409 static struct text_pos
14410 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14412 struct window *w = XWINDOW (window);
14413 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14415 if (current_buffer != XBUFFER (w->contents))
14416 emacs_abort ();
14418 if (!NILP (Vwindow_scroll_functions))
14420 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14421 make_number (CHARPOS (startp)));
14422 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14423 /* In case the hook functions switch buffers. */
14424 set_buffer_internal (XBUFFER (w->contents));
14427 return startp;
14431 /* Make sure the line containing the cursor is fully visible.
14432 A value of 1 means there is nothing to be done.
14433 (Either the line is fully visible, or it cannot be made so,
14434 or we cannot tell.)
14436 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14437 is higher than window.
14439 A value of 0 means the caller should do scrolling
14440 as if point had gone off the screen. */
14442 static int
14443 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14445 struct glyph_matrix *matrix;
14446 struct glyph_row *row;
14447 int window_height;
14449 if (!make_cursor_line_fully_visible_p)
14450 return 1;
14452 /* It's not always possible to find the cursor, e.g, when a window
14453 is full of overlay strings. Don't do anything in that case. */
14454 if (w->cursor.vpos < 0)
14455 return 1;
14457 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14458 row = MATRIX_ROW (matrix, w->cursor.vpos);
14460 /* If the cursor row is not partially visible, there's nothing to do. */
14461 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14462 return 1;
14464 /* If the row the cursor is in is taller than the window's height,
14465 it's not clear what to do, so do nothing. */
14466 window_height = window_box_height (w);
14467 if (row->height >= window_height)
14469 if (!force_p || MINI_WINDOW_P (w)
14470 || w->vscroll || w->cursor.vpos == 0)
14471 return 1;
14473 return 0;
14477 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14478 non-zero means only WINDOW is redisplayed in redisplay_internal.
14479 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14480 in redisplay_window to bring a partially visible line into view in
14481 the case that only the cursor has moved.
14483 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14484 last screen line's vertical height extends past the end of the screen.
14486 Value is
14488 1 if scrolling succeeded
14490 0 if scrolling didn't find point.
14492 -1 if new fonts have been loaded so that we must interrupt
14493 redisplay, adjust glyph matrices, and try again. */
14495 enum
14497 SCROLLING_SUCCESS,
14498 SCROLLING_FAILED,
14499 SCROLLING_NEED_LARGER_MATRICES
14502 /* If scroll-conservatively is more than this, never recenter.
14504 If you change this, don't forget to update the doc string of
14505 `scroll-conservatively' and the Emacs manual. */
14506 #define SCROLL_LIMIT 100
14508 static int
14509 try_scrolling (Lisp_Object window, int just_this_one_p,
14510 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14511 int temp_scroll_step, int last_line_misfit)
14513 struct window *w = XWINDOW (window);
14514 struct frame *f = XFRAME (w->frame);
14515 struct text_pos pos, startp;
14516 struct it it;
14517 int this_scroll_margin, scroll_max, rc, height;
14518 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14519 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14520 Lisp_Object aggressive;
14521 /* We will never try scrolling more than this number of lines. */
14522 int scroll_limit = SCROLL_LIMIT;
14524 #ifdef GLYPH_DEBUG
14525 debug_method_add (w, "try_scrolling");
14526 #endif
14528 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14530 /* Compute scroll margin height in pixels. We scroll when point is
14531 within this distance from the top or bottom of the window. */
14532 if (scroll_margin > 0)
14533 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14534 * FRAME_LINE_HEIGHT (f);
14535 else
14536 this_scroll_margin = 0;
14538 /* Force arg_scroll_conservatively to have a reasonable value, to
14539 avoid scrolling too far away with slow move_it_* functions. Note
14540 that the user can supply scroll-conservatively equal to
14541 `most-positive-fixnum', which can be larger than INT_MAX. */
14542 if (arg_scroll_conservatively > scroll_limit)
14544 arg_scroll_conservatively = scroll_limit + 1;
14545 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14547 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14548 /* Compute how much we should try to scroll maximally to bring
14549 point into view. */
14550 scroll_max = (max (scroll_step,
14551 max (arg_scroll_conservatively, temp_scroll_step))
14552 * FRAME_LINE_HEIGHT (f));
14553 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14554 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14555 /* We're trying to scroll because of aggressive scrolling but no
14556 scroll_step is set. Choose an arbitrary one. */
14557 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14558 else
14559 scroll_max = 0;
14561 too_near_end:
14563 /* Decide whether to scroll down. */
14564 if (PT > CHARPOS (startp))
14566 int scroll_margin_y;
14568 /* Compute the pixel ypos of the scroll margin, then move IT to
14569 either that ypos or PT, whichever comes first. */
14570 start_display (&it, w, startp);
14571 scroll_margin_y = it.last_visible_y - this_scroll_margin
14572 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14573 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14574 (MOVE_TO_POS | MOVE_TO_Y));
14576 if (PT > CHARPOS (it.current.pos))
14578 int y0 = line_bottom_y (&it);
14579 /* Compute how many pixels below window bottom to stop searching
14580 for PT. This avoids costly search for PT that is far away if
14581 the user limited scrolling by a small number of lines, but
14582 always finds PT if scroll_conservatively is set to a large
14583 number, such as most-positive-fixnum. */
14584 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14585 int y_to_move = it.last_visible_y + slack;
14587 /* Compute the distance from the scroll margin to PT or to
14588 the scroll limit, whichever comes first. This should
14589 include the height of the cursor line, to make that line
14590 fully visible. */
14591 move_it_to (&it, PT, -1, y_to_move,
14592 -1, MOVE_TO_POS | MOVE_TO_Y);
14593 dy = line_bottom_y (&it) - y0;
14595 if (dy > scroll_max)
14596 return SCROLLING_FAILED;
14598 if (dy > 0)
14599 scroll_down_p = 1;
14603 if (scroll_down_p)
14605 /* Point is in or below the bottom scroll margin, so move the
14606 window start down. If scrolling conservatively, move it just
14607 enough down to make point visible. If scroll_step is set,
14608 move it down by scroll_step. */
14609 if (arg_scroll_conservatively)
14610 amount_to_scroll
14611 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14612 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14613 else if (scroll_step || temp_scroll_step)
14614 amount_to_scroll = scroll_max;
14615 else
14617 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14618 height = WINDOW_BOX_TEXT_HEIGHT (w);
14619 if (NUMBERP (aggressive))
14621 double float_amount = XFLOATINT (aggressive) * height;
14622 int aggressive_scroll = float_amount;
14623 if (aggressive_scroll == 0 && float_amount > 0)
14624 aggressive_scroll = 1;
14625 /* Don't let point enter the scroll margin near top of
14626 the window. This could happen if the value of
14627 scroll_up_aggressively is too large and there are
14628 non-zero margins, because scroll_up_aggressively
14629 means put point that fraction of window height
14630 _from_the_bottom_margin_. */
14631 if (aggressive_scroll + 2*this_scroll_margin > height)
14632 aggressive_scroll = height - 2*this_scroll_margin;
14633 amount_to_scroll = dy + aggressive_scroll;
14637 if (amount_to_scroll <= 0)
14638 return SCROLLING_FAILED;
14640 start_display (&it, w, startp);
14641 if (arg_scroll_conservatively <= scroll_limit)
14642 move_it_vertically (&it, amount_to_scroll);
14643 else
14645 /* Extra precision for users who set scroll-conservatively
14646 to a large number: make sure the amount we scroll
14647 the window start is never less than amount_to_scroll,
14648 which was computed as distance from window bottom to
14649 point. This matters when lines at window top and lines
14650 below window bottom have different height. */
14651 struct it it1;
14652 void *it1data = NULL;
14653 /* We use a temporary it1 because line_bottom_y can modify
14654 its argument, if it moves one line down; see there. */
14655 int start_y;
14657 SAVE_IT (it1, it, it1data);
14658 start_y = line_bottom_y (&it1);
14659 do {
14660 RESTORE_IT (&it, &it, it1data);
14661 move_it_by_lines (&it, 1);
14662 SAVE_IT (it1, it, it1data);
14663 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14666 /* If STARTP is unchanged, move it down another screen line. */
14667 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14668 move_it_by_lines (&it, 1);
14669 startp = it.current.pos;
14671 else
14673 struct text_pos scroll_margin_pos = startp;
14674 int y_offset = 0;
14676 /* See if point is inside the scroll margin at the top of the
14677 window. */
14678 if (this_scroll_margin)
14680 int y_start;
14682 start_display (&it, w, startp);
14683 y_start = it.current_y;
14684 move_it_vertically (&it, this_scroll_margin);
14685 scroll_margin_pos = it.current.pos;
14686 /* If we didn't move enough before hitting ZV, request
14687 additional amount of scroll, to move point out of the
14688 scroll margin. */
14689 if (IT_CHARPOS (it) == ZV
14690 && it.current_y - y_start < this_scroll_margin)
14691 y_offset = this_scroll_margin - (it.current_y - y_start);
14694 if (PT < CHARPOS (scroll_margin_pos))
14696 /* Point is in the scroll margin at the top of the window or
14697 above what is displayed in the window. */
14698 int y0, y_to_move;
14700 /* Compute the vertical distance from PT to the scroll
14701 margin position. Move as far as scroll_max allows, or
14702 one screenful, or 10 screen lines, whichever is largest.
14703 Give up if distance is greater than scroll_max or if we
14704 didn't reach the scroll margin position. */
14705 SET_TEXT_POS (pos, PT, PT_BYTE);
14706 start_display (&it, w, pos);
14707 y0 = it.current_y;
14708 y_to_move = max (it.last_visible_y,
14709 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14710 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14711 y_to_move, -1,
14712 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14713 dy = it.current_y - y0;
14714 if (dy > scroll_max
14715 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14716 return SCROLLING_FAILED;
14718 /* Additional scroll for when ZV was too close to point. */
14719 dy += y_offset;
14721 /* Compute new window start. */
14722 start_display (&it, w, startp);
14724 if (arg_scroll_conservatively)
14725 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14726 max (scroll_step, temp_scroll_step));
14727 else if (scroll_step || temp_scroll_step)
14728 amount_to_scroll = scroll_max;
14729 else
14731 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14732 height = WINDOW_BOX_TEXT_HEIGHT (w);
14733 if (NUMBERP (aggressive))
14735 double float_amount = XFLOATINT (aggressive) * height;
14736 int aggressive_scroll = float_amount;
14737 if (aggressive_scroll == 0 && float_amount > 0)
14738 aggressive_scroll = 1;
14739 /* Don't let point enter the scroll margin near
14740 bottom of the window, if the value of
14741 scroll_down_aggressively happens to be too
14742 large. */
14743 if (aggressive_scroll + 2*this_scroll_margin > height)
14744 aggressive_scroll = height - 2*this_scroll_margin;
14745 amount_to_scroll = dy + aggressive_scroll;
14749 if (amount_to_scroll <= 0)
14750 return SCROLLING_FAILED;
14752 move_it_vertically_backward (&it, amount_to_scroll);
14753 startp = it.current.pos;
14757 /* Run window scroll functions. */
14758 startp = run_window_scroll_functions (window, startp);
14760 /* Display the window. Give up if new fonts are loaded, or if point
14761 doesn't appear. */
14762 if (!try_window (window, startp, 0))
14763 rc = SCROLLING_NEED_LARGER_MATRICES;
14764 else if (w->cursor.vpos < 0)
14766 clear_glyph_matrix (w->desired_matrix);
14767 rc = SCROLLING_FAILED;
14769 else
14771 /* Maybe forget recorded base line for line number display. */
14772 if (!just_this_one_p
14773 || current_buffer->clip_changed
14774 || BEG_UNCHANGED < CHARPOS (startp))
14775 w->base_line_number = 0;
14777 /* If cursor ends up on a partially visible line,
14778 treat that as being off the bottom of the screen. */
14779 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14780 /* It's possible that the cursor is on the first line of the
14781 buffer, which is partially obscured due to a vscroll
14782 (Bug#7537). In that case, avoid looping forever . */
14783 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14785 clear_glyph_matrix (w->desired_matrix);
14786 ++extra_scroll_margin_lines;
14787 goto too_near_end;
14789 rc = SCROLLING_SUCCESS;
14792 return rc;
14796 /* Compute a suitable window start for window W if display of W starts
14797 on a continuation line. Value is non-zero if a new window start
14798 was computed.
14800 The new window start will be computed, based on W's width, starting
14801 from the start of the continued line. It is the start of the
14802 screen line with the minimum distance from the old start W->start. */
14804 static int
14805 compute_window_start_on_continuation_line (struct window *w)
14807 struct text_pos pos, start_pos;
14808 int window_start_changed_p = 0;
14810 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14812 /* If window start is on a continuation line... Window start may be
14813 < BEGV in case there's invisible text at the start of the
14814 buffer (M-x rmail, for example). */
14815 if (CHARPOS (start_pos) > BEGV
14816 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14818 struct it it;
14819 struct glyph_row *row;
14821 /* Handle the case that the window start is out of range. */
14822 if (CHARPOS (start_pos) < BEGV)
14823 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14824 else if (CHARPOS (start_pos) > ZV)
14825 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14827 /* Find the start of the continued line. This should be fast
14828 because find_newline is fast (newline cache). */
14829 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14830 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14831 row, DEFAULT_FACE_ID);
14832 reseat_at_previous_visible_line_start (&it);
14834 /* If the line start is "too far" away from the window start,
14835 say it takes too much time to compute a new window start. */
14836 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14837 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14839 int min_distance, distance;
14841 /* Move forward by display lines to find the new window
14842 start. If window width was enlarged, the new start can
14843 be expected to be > the old start. If window width was
14844 decreased, the new window start will be < the old start.
14845 So, we're looking for the display line start with the
14846 minimum distance from the old window start. */
14847 pos = it.current.pos;
14848 min_distance = INFINITY;
14849 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14850 distance < min_distance)
14852 min_distance = distance;
14853 pos = it.current.pos;
14854 move_it_by_lines (&it, 1);
14857 /* Set the window start there. */
14858 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14859 window_start_changed_p = 1;
14863 return window_start_changed_p;
14867 /* Try cursor movement in case text has not changed in window WINDOW,
14868 with window start STARTP. Value is
14870 CURSOR_MOVEMENT_SUCCESS if successful
14872 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14874 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14875 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14876 we want to scroll as if scroll-step were set to 1. See the code.
14878 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14879 which case we have to abort this redisplay, and adjust matrices
14880 first. */
14882 enum
14884 CURSOR_MOVEMENT_SUCCESS,
14885 CURSOR_MOVEMENT_CANNOT_BE_USED,
14886 CURSOR_MOVEMENT_MUST_SCROLL,
14887 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14890 static int
14891 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14893 struct window *w = XWINDOW (window);
14894 struct frame *f = XFRAME (w->frame);
14895 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14897 #ifdef GLYPH_DEBUG
14898 if (inhibit_try_cursor_movement)
14899 return rc;
14900 #endif
14902 /* Previously, there was a check for Lisp integer in the
14903 if-statement below. Now, this field is converted to
14904 ptrdiff_t, thus zero means invalid position in a buffer. */
14905 eassert (w->last_point > 0);
14907 /* Handle case where text has not changed, only point, and it has
14908 not moved off the frame. */
14909 if (/* Point may be in this window. */
14910 PT >= CHARPOS (startp)
14911 /* Selective display hasn't changed. */
14912 && !current_buffer->clip_changed
14913 /* Function force-mode-line-update is used to force a thorough
14914 redisplay. It sets either windows_or_buffers_changed or
14915 update_mode_lines. So don't take a shortcut here for these
14916 cases. */
14917 && !update_mode_lines
14918 && !windows_or_buffers_changed
14919 && !cursor_type_changed
14920 /* Can't use this case if highlighting a region. When a
14921 region exists, cursor movement has to do more than just
14922 set the cursor. */
14923 && markpos_of_region () < 0
14924 && !w->region_showing
14925 && NILP (Vshow_trailing_whitespace)
14926 /* This code is not used for mini-buffer for the sake of the case
14927 of redisplaying to replace an echo area message; since in
14928 that case the mini-buffer contents per se are usually
14929 unchanged. This code is of no real use in the mini-buffer
14930 since the handling of this_line_start_pos, etc., in redisplay
14931 handles the same cases. */
14932 && !EQ (window, minibuf_window)
14933 /* When splitting windows or for new windows, it happens that
14934 redisplay is called with a nil window_end_vpos or one being
14935 larger than the window. This should really be fixed in
14936 window.c. I don't have this on my list, now, so we do
14937 approximately the same as the old redisplay code. --gerd. */
14938 && INTEGERP (w->window_end_vpos)
14939 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14940 && (FRAME_WINDOW_P (f)
14941 || !overlay_arrow_in_current_buffer_p ()))
14943 int this_scroll_margin, top_scroll_margin;
14944 struct glyph_row *row = NULL;
14946 #ifdef GLYPH_DEBUG
14947 debug_method_add (w, "cursor movement");
14948 #endif
14950 /* Scroll if point within this distance from the top or bottom
14951 of the window. This is a pixel value. */
14952 if (scroll_margin > 0)
14954 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14955 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14957 else
14958 this_scroll_margin = 0;
14960 top_scroll_margin = this_scroll_margin;
14961 if (WINDOW_WANTS_HEADER_LINE_P (w))
14962 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14964 /* Start with the row the cursor was displayed during the last
14965 not paused redisplay. Give up if that row is not valid. */
14966 if (w->last_cursor.vpos < 0
14967 || w->last_cursor.vpos >= w->current_matrix->nrows)
14968 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14969 else
14971 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
14972 if (row->mode_line_p)
14973 ++row;
14974 if (!row->enabled_p)
14975 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14978 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
14980 int scroll_p = 0, must_scroll = 0;
14981 int last_y = window_text_bottom_y (w) - this_scroll_margin;
14983 if (PT > w->last_point)
14985 /* Point has moved forward. */
14986 while (MATRIX_ROW_END_CHARPOS (row) < PT
14987 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
14989 eassert (row->enabled_p);
14990 ++row;
14993 /* If the end position of a row equals the start
14994 position of the next row, and PT is at that position,
14995 we would rather display cursor in the next line. */
14996 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14997 && MATRIX_ROW_END_CHARPOS (row) == PT
14998 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
14999 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15000 && !cursor_row_p (row))
15001 ++row;
15003 /* If within the scroll margin, scroll. Note that
15004 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15005 the next line would be drawn, and that
15006 this_scroll_margin can be zero. */
15007 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15008 || PT > MATRIX_ROW_END_CHARPOS (row)
15009 /* Line is completely visible last line in window
15010 and PT is to be set in the next line. */
15011 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15012 && PT == MATRIX_ROW_END_CHARPOS (row)
15013 && !row->ends_at_zv_p
15014 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15015 scroll_p = 1;
15017 else if (PT < w->last_point)
15019 /* Cursor has to be moved backward. Note that PT >=
15020 CHARPOS (startp) because of the outer if-statement. */
15021 while (!row->mode_line_p
15022 && (MATRIX_ROW_START_CHARPOS (row) > PT
15023 || (MATRIX_ROW_START_CHARPOS (row) == PT
15024 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15025 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15026 row > w->current_matrix->rows
15027 && (row-1)->ends_in_newline_from_string_p))))
15028 && (row->y > top_scroll_margin
15029 || CHARPOS (startp) == BEGV))
15031 eassert (row->enabled_p);
15032 --row;
15035 /* Consider the following case: Window starts at BEGV,
15036 there is invisible, intangible text at BEGV, so that
15037 display starts at some point START > BEGV. It can
15038 happen that we are called with PT somewhere between
15039 BEGV and START. Try to handle that case. */
15040 if (row < w->current_matrix->rows
15041 || row->mode_line_p)
15043 row = w->current_matrix->rows;
15044 if (row->mode_line_p)
15045 ++row;
15048 /* Due to newlines in overlay strings, we may have to
15049 skip forward over overlay strings. */
15050 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15051 && MATRIX_ROW_END_CHARPOS (row) == PT
15052 && !cursor_row_p (row))
15053 ++row;
15055 /* If within the scroll margin, scroll. */
15056 if (row->y < top_scroll_margin
15057 && CHARPOS (startp) != BEGV)
15058 scroll_p = 1;
15060 else
15062 /* Cursor did not move. So don't scroll even if cursor line
15063 is partially visible, as it was so before. */
15064 rc = CURSOR_MOVEMENT_SUCCESS;
15067 if (PT < MATRIX_ROW_START_CHARPOS (row)
15068 || PT > MATRIX_ROW_END_CHARPOS (row))
15070 /* if PT is not in the glyph row, give up. */
15071 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15072 must_scroll = 1;
15074 else if (rc != CURSOR_MOVEMENT_SUCCESS
15075 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15077 struct glyph_row *row1;
15079 /* If rows are bidi-reordered and point moved, back up
15080 until we find a row that does not belong to a
15081 continuation line. This is because we must consider
15082 all rows of a continued line as candidates for the
15083 new cursor positioning, since row start and end
15084 positions change non-linearly with vertical position
15085 in such rows. */
15086 /* FIXME: Revisit this when glyph ``spilling'' in
15087 continuation lines' rows is implemented for
15088 bidi-reordered rows. */
15089 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15090 MATRIX_ROW_CONTINUATION_LINE_P (row);
15091 --row)
15093 /* If we hit the beginning of the displayed portion
15094 without finding the first row of a continued
15095 line, give up. */
15096 if (row <= row1)
15098 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15099 break;
15101 eassert (row->enabled_p);
15104 if (must_scroll)
15106 else if (rc != CURSOR_MOVEMENT_SUCCESS
15107 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15108 /* Make sure this isn't a header line by any chance, since
15109 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15110 && !row->mode_line_p
15111 && make_cursor_line_fully_visible_p)
15113 if (PT == MATRIX_ROW_END_CHARPOS (row)
15114 && !row->ends_at_zv_p
15115 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15116 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15117 else if (row->height > window_box_height (w))
15119 /* If we end up in a partially visible line, let's
15120 make it fully visible, except when it's taller
15121 than the window, in which case we can't do much
15122 about it. */
15123 *scroll_step = 1;
15124 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15126 else
15128 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15129 if (!cursor_row_fully_visible_p (w, 0, 1))
15130 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15131 else
15132 rc = CURSOR_MOVEMENT_SUCCESS;
15135 else if (scroll_p)
15136 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15137 else if (rc != CURSOR_MOVEMENT_SUCCESS
15138 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15140 /* With bidi-reordered rows, there could be more than
15141 one candidate row whose start and end positions
15142 occlude point. We need to let set_cursor_from_row
15143 find the best candidate. */
15144 /* FIXME: Revisit this when glyph ``spilling'' in
15145 continuation lines' rows is implemented for
15146 bidi-reordered rows. */
15147 int rv = 0;
15151 int at_zv_p = 0, exact_match_p = 0;
15153 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15154 && PT <= MATRIX_ROW_END_CHARPOS (row)
15155 && cursor_row_p (row))
15156 rv |= set_cursor_from_row (w, row, w->current_matrix,
15157 0, 0, 0, 0);
15158 /* As soon as we've found the exact match for point,
15159 or the first suitable row whose ends_at_zv_p flag
15160 is set, we are done. */
15161 at_zv_p =
15162 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15163 if (rv && !at_zv_p
15164 && w->cursor.hpos >= 0
15165 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15166 w->cursor.vpos))
15168 struct glyph_row *candidate =
15169 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15170 struct glyph *g =
15171 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15172 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15174 exact_match_p =
15175 (BUFFERP (g->object) && g->charpos == PT)
15176 || (INTEGERP (g->object)
15177 && (g->charpos == PT
15178 || (g->charpos == 0 && endpos - 1 == PT)));
15180 if (rv && (at_zv_p || exact_match_p))
15182 rc = CURSOR_MOVEMENT_SUCCESS;
15183 break;
15185 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15186 break;
15187 ++row;
15189 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15190 || row->continued_p)
15191 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15192 || (MATRIX_ROW_START_CHARPOS (row) == PT
15193 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15194 /* If we didn't find any candidate rows, or exited the
15195 loop before all the candidates were examined, signal
15196 to the caller that this method failed. */
15197 if (rc != CURSOR_MOVEMENT_SUCCESS
15198 && !(rv
15199 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15200 && !row->continued_p))
15201 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15202 else if (rv)
15203 rc = CURSOR_MOVEMENT_SUCCESS;
15205 else
15209 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15211 rc = CURSOR_MOVEMENT_SUCCESS;
15212 break;
15214 ++row;
15216 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15217 && MATRIX_ROW_START_CHARPOS (row) == PT
15218 && cursor_row_p (row));
15223 return rc;
15226 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15227 static
15228 #endif
15229 void
15230 set_vertical_scroll_bar (struct window *w)
15232 ptrdiff_t start, end, whole;
15234 /* Calculate the start and end positions for the current window.
15235 At some point, it would be nice to choose between scrollbars
15236 which reflect the whole buffer size, with special markers
15237 indicating narrowing, and scrollbars which reflect only the
15238 visible region.
15240 Note that mini-buffers sometimes aren't displaying any text. */
15241 if (!MINI_WINDOW_P (w)
15242 || (w == XWINDOW (minibuf_window)
15243 && NILP (echo_area_buffer[0])))
15245 struct buffer *buf = XBUFFER (w->contents);
15246 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15247 start = marker_position (w->start) - BUF_BEGV (buf);
15248 /* I don't think this is guaranteed to be right. For the
15249 moment, we'll pretend it is. */
15250 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15252 if (end < start)
15253 end = start;
15254 if (whole < (end - start))
15255 whole = end - start;
15257 else
15258 start = end = whole = 0;
15260 /* Indicate what this scroll bar ought to be displaying now. */
15261 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15262 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15263 (w, end - start, whole, start);
15267 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15268 selected_window is redisplayed.
15270 We can return without actually redisplaying the window if
15271 fonts_changed_p. In that case, redisplay_internal will
15272 retry. */
15274 static void
15275 redisplay_window (Lisp_Object window, int just_this_one_p)
15277 struct window *w = XWINDOW (window);
15278 struct frame *f = XFRAME (w->frame);
15279 struct buffer *buffer = XBUFFER (w->contents);
15280 struct buffer *old = current_buffer;
15281 struct text_pos lpoint, opoint, startp;
15282 int update_mode_line;
15283 int tem;
15284 struct it it;
15285 /* Record it now because it's overwritten. */
15286 int current_matrix_up_to_date_p = 0;
15287 int used_current_matrix_p = 0;
15288 /* This is less strict than current_matrix_up_to_date_p.
15289 It indicates that the buffer contents and narrowing are unchanged. */
15290 int buffer_unchanged_p = 0;
15291 int temp_scroll_step = 0;
15292 ptrdiff_t count = SPECPDL_INDEX ();
15293 int rc;
15294 int centering_position = -1;
15295 int last_line_misfit = 0;
15296 ptrdiff_t beg_unchanged, end_unchanged;
15298 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15299 opoint = lpoint;
15301 #ifdef GLYPH_DEBUG
15302 *w->desired_matrix->method = 0;
15303 #endif
15305 /* Make sure that both W's markers are valid. */
15306 eassert (XMARKER (w->start)->buffer == buffer);
15307 eassert (XMARKER (w->pointm)->buffer == buffer);
15309 restart:
15310 reconsider_clip_changes (w, buffer);
15312 /* Has the mode line to be updated? */
15313 update_mode_line = (w->update_mode_line
15314 || update_mode_lines
15315 || buffer->clip_changed
15316 || buffer->prevent_redisplay_optimizations_p);
15318 if (MINI_WINDOW_P (w))
15320 if (w == XWINDOW (echo_area_window)
15321 && !NILP (echo_area_buffer[0]))
15323 if (update_mode_line)
15324 /* We may have to update a tty frame's menu bar or a
15325 tool-bar. Example `M-x C-h C-h C-g'. */
15326 goto finish_menu_bars;
15327 else
15328 /* We've already displayed the echo area glyphs in this window. */
15329 goto finish_scroll_bars;
15331 else if ((w != XWINDOW (minibuf_window)
15332 || minibuf_level == 0)
15333 /* When buffer is nonempty, redisplay window normally. */
15334 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15335 /* Quail displays non-mini buffers in minibuffer window.
15336 In that case, redisplay the window normally. */
15337 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15339 /* W is a mini-buffer window, but it's not active, so clear
15340 it. */
15341 int yb = window_text_bottom_y (w);
15342 struct glyph_row *row;
15343 int y;
15345 for (y = 0, row = w->desired_matrix->rows;
15346 y < yb;
15347 y += row->height, ++row)
15348 blank_row (w, row, y);
15349 goto finish_scroll_bars;
15352 clear_glyph_matrix (w->desired_matrix);
15355 /* Otherwise set up data on this window; select its buffer and point
15356 value. */
15357 /* Really select the buffer, for the sake of buffer-local
15358 variables. */
15359 set_buffer_internal_1 (XBUFFER (w->contents));
15361 current_matrix_up_to_date_p
15362 = (w->window_end_valid
15363 && !current_buffer->clip_changed
15364 && !current_buffer->prevent_redisplay_optimizations_p
15365 && !window_outdated (w));
15367 /* Run the window-bottom-change-functions
15368 if it is possible that the text on the screen has changed
15369 (either due to modification of the text, or any other reason). */
15370 if (!current_matrix_up_to_date_p
15371 && !NILP (Vwindow_text_change_functions))
15373 safe_run_hooks (Qwindow_text_change_functions);
15374 goto restart;
15377 beg_unchanged = BEG_UNCHANGED;
15378 end_unchanged = END_UNCHANGED;
15380 SET_TEXT_POS (opoint, PT, PT_BYTE);
15382 specbind (Qinhibit_point_motion_hooks, Qt);
15384 buffer_unchanged_p
15385 = (w->window_end_valid
15386 && !current_buffer->clip_changed
15387 && !window_outdated (w));
15389 /* When windows_or_buffers_changed is non-zero, we can't rely on
15390 the window end being valid, so set it to nil there. */
15391 if (windows_or_buffers_changed)
15393 /* If window starts on a continuation line, maybe adjust the
15394 window start in case the window's width changed. */
15395 if (XMARKER (w->start)->buffer == current_buffer)
15396 compute_window_start_on_continuation_line (w);
15398 w->window_end_valid = 0;
15401 /* Some sanity checks. */
15402 CHECK_WINDOW_END (w);
15403 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15404 emacs_abort ();
15405 if (BYTEPOS (opoint) < CHARPOS (opoint))
15406 emacs_abort ();
15408 if (mode_line_update_needed (w))
15409 update_mode_line = 1;
15411 /* Point refers normally to the selected window. For any other
15412 window, set up appropriate value. */
15413 if (!EQ (window, selected_window))
15415 ptrdiff_t new_pt = marker_position (w->pointm);
15416 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15417 if (new_pt < BEGV)
15419 new_pt = BEGV;
15420 new_pt_byte = BEGV_BYTE;
15421 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15423 else if (new_pt > (ZV - 1))
15425 new_pt = ZV;
15426 new_pt_byte = ZV_BYTE;
15427 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15430 /* We don't use SET_PT so that the point-motion hooks don't run. */
15431 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15434 /* If any of the character widths specified in the display table
15435 have changed, invalidate the width run cache. It's true that
15436 this may be a bit late to catch such changes, but the rest of
15437 redisplay goes (non-fatally) haywire when the display table is
15438 changed, so why should we worry about doing any better? */
15439 if (current_buffer->width_run_cache)
15441 struct Lisp_Char_Table *disptab = buffer_display_table ();
15443 if (! disptab_matches_widthtab
15444 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15446 invalidate_region_cache (current_buffer,
15447 current_buffer->width_run_cache,
15448 BEG, Z);
15449 recompute_width_table (current_buffer, disptab);
15453 /* If window-start is screwed up, choose a new one. */
15454 if (XMARKER (w->start)->buffer != current_buffer)
15455 goto recenter;
15457 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15459 /* If someone specified a new starting point but did not insist,
15460 check whether it can be used. */
15461 if (w->optional_new_start
15462 && CHARPOS (startp) >= BEGV
15463 && CHARPOS (startp) <= ZV)
15465 w->optional_new_start = 0;
15466 start_display (&it, w, startp);
15467 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15468 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15469 if (IT_CHARPOS (it) == PT)
15470 w->force_start = 1;
15471 /* IT may overshoot PT if text at PT is invisible. */
15472 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15473 w->force_start = 1;
15476 force_start:
15478 /* Handle case where place to start displaying has been specified,
15479 unless the specified location is outside the accessible range. */
15480 if (w->force_start || w->frozen_window_start_p)
15482 /* We set this later on if we have to adjust point. */
15483 int new_vpos = -1;
15485 w->force_start = 0;
15486 w->vscroll = 0;
15487 w->window_end_valid = 0;
15489 /* Forget any recorded base line for line number display. */
15490 if (!buffer_unchanged_p)
15491 w->base_line_number = 0;
15493 /* Redisplay the mode line. Select the buffer properly for that.
15494 Also, run the hook window-scroll-functions
15495 because we have scrolled. */
15496 /* Note, we do this after clearing force_start because
15497 if there's an error, it is better to forget about force_start
15498 than to get into an infinite loop calling the hook functions
15499 and having them get more errors. */
15500 if (!update_mode_line
15501 || ! NILP (Vwindow_scroll_functions))
15503 update_mode_line = 1;
15504 w->update_mode_line = 1;
15505 startp = run_window_scroll_functions (window, startp);
15508 w->last_modified = 0;
15509 w->last_overlay_modified = 0;
15510 if (CHARPOS (startp) < BEGV)
15511 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15512 else if (CHARPOS (startp) > ZV)
15513 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15515 /* Redisplay, then check if cursor has been set during the
15516 redisplay. Give up if new fonts were loaded. */
15517 /* We used to issue a CHECK_MARGINS argument to try_window here,
15518 but this causes scrolling to fail when point begins inside
15519 the scroll margin (bug#148) -- cyd */
15520 if (!try_window (window, startp, 0))
15522 w->force_start = 1;
15523 clear_glyph_matrix (w->desired_matrix);
15524 goto need_larger_matrices;
15527 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15529 /* If point does not appear, try to move point so it does
15530 appear. The desired matrix has been built above, so we
15531 can use it here. */
15532 new_vpos = window_box_height (w) / 2;
15535 if (!cursor_row_fully_visible_p (w, 0, 0))
15537 /* Point does appear, but on a line partly visible at end of window.
15538 Move it back to a fully-visible line. */
15539 new_vpos = window_box_height (w);
15541 else if (w->cursor.vpos >=0)
15543 /* Some people insist on not letting point enter the scroll
15544 margin, even though this part handles windows that didn't
15545 scroll at all. */
15546 int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15547 int pixel_margin = margin * FRAME_LINE_HEIGHT (f);
15548 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15550 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15551 below, which finds the row to move point to, advances by
15552 the Y coordinate of the _next_ row, see the definition of
15553 MATRIX_ROW_BOTTOM_Y. */
15554 if (w->cursor.vpos < margin + header_line)
15555 new_vpos
15556 = pixel_margin + (header_line
15557 ? CURRENT_HEADER_LINE_HEIGHT (w)
15558 : 0) + FRAME_LINE_HEIGHT (f);
15559 else
15561 int window_height = window_box_height (w);
15563 if (header_line)
15564 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15565 if (w->cursor.y >= window_height - pixel_margin)
15566 new_vpos = window_height - pixel_margin;
15570 /* If we need to move point for either of the above reasons,
15571 now actually do it. */
15572 if (new_vpos >= 0)
15574 struct glyph_row *row;
15576 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15577 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15578 ++row;
15580 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15581 MATRIX_ROW_START_BYTEPOS (row));
15583 if (w != XWINDOW (selected_window))
15584 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15585 else if (current_buffer == old)
15586 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15588 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15590 /* If we are highlighting the region, then we just changed
15591 the region, so redisplay to show it. */
15592 if (markpos_of_region () >= 0)
15594 clear_glyph_matrix (w->desired_matrix);
15595 if (!try_window (window, startp, 0))
15596 goto need_larger_matrices;
15600 #ifdef GLYPH_DEBUG
15601 debug_method_add (w, "forced window start");
15602 #endif
15603 goto done;
15606 /* Handle case where text has not changed, only point, and it has
15607 not moved off the frame, and we are not retrying after hscroll.
15608 (current_matrix_up_to_date_p is nonzero when retrying.) */
15609 if (current_matrix_up_to_date_p
15610 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15611 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15613 switch (rc)
15615 case CURSOR_MOVEMENT_SUCCESS:
15616 used_current_matrix_p = 1;
15617 goto done;
15619 case CURSOR_MOVEMENT_MUST_SCROLL:
15620 goto try_to_scroll;
15622 default:
15623 emacs_abort ();
15626 /* If current starting point was originally the beginning of a line
15627 but no longer is, find a new starting point. */
15628 else if (w->start_at_line_beg
15629 && !(CHARPOS (startp) <= BEGV
15630 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15632 #ifdef GLYPH_DEBUG
15633 debug_method_add (w, "recenter 1");
15634 #endif
15635 goto recenter;
15638 /* Try scrolling with try_window_id. Value is > 0 if update has
15639 been done, it is -1 if we know that the same window start will
15640 not work. It is 0 if unsuccessful for some other reason. */
15641 else if ((tem = try_window_id (w)) != 0)
15643 #ifdef GLYPH_DEBUG
15644 debug_method_add (w, "try_window_id %d", tem);
15645 #endif
15647 if (fonts_changed_p)
15648 goto need_larger_matrices;
15649 if (tem > 0)
15650 goto done;
15652 /* Otherwise try_window_id has returned -1 which means that we
15653 don't want the alternative below this comment to execute. */
15655 else if (CHARPOS (startp) >= BEGV
15656 && CHARPOS (startp) <= ZV
15657 && PT >= CHARPOS (startp)
15658 && (CHARPOS (startp) < ZV
15659 /* Avoid starting at end of buffer. */
15660 || CHARPOS (startp) == BEGV
15661 || !window_outdated (w)))
15663 int d1, d2, d3, d4, d5, d6;
15665 /* If first window line is a continuation line, and window start
15666 is inside the modified region, but the first change is before
15667 current window start, we must select a new window start.
15669 However, if this is the result of a down-mouse event (e.g. by
15670 extending the mouse-drag-overlay), we don't want to select a
15671 new window start, since that would change the position under
15672 the mouse, resulting in an unwanted mouse-movement rather
15673 than a simple mouse-click. */
15674 if (!w->start_at_line_beg
15675 && NILP (do_mouse_tracking)
15676 && CHARPOS (startp) > BEGV
15677 && CHARPOS (startp) > BEG + beg_unchanged
15678 && CHARPOS (startp) <= Z - end_unchanged
15679 /* Even if w->start_at_line_beg is nil, a new window may
15680 start at a line_beg, since that's how set_buffer_window
15681 sets it. So, we need to check the return value of
15682 compute_window_start_on_continuation_line. (See also
15683 bug#197). */
15684 && XMARKER (w->start)->buffer == current_buffer
15685 && compute_window_start_on_continuation_line (w)
15686 /* It doesn't make sense to force the window start like we
15687 do at label force_start if it is already known that point
15688 will not be visible in the resulting window, because
15689 doing so will move point from its correct position
15690 instead of scrolling the window to bring point into view.
15691 See bug#9324. */
15692 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15694 w->force_start = 1;
15695 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15696 goto force_start;
15699 #ifdef GLYPH_DEBUG
15700 debug_method_add (w, "same window start");
15701 #endif
15703 /* Try to redisplay starting at same place as before.
15704 If point has not moved off frame, accept the results. */
15705 if (!current_matrix_up_to_date_p
15706 /* Don't use try_window_reusing_current_matrix in this case
15707 because a window scroll function can have changed the
15708 buffer. */
15709 || !NILP (Vwindow_scroll_functions)
15710 || MINI_WINDOW_P (w)
15711 || !(used_current_matrix_p
15712 = try_window_reusing_current_matrix (w)))
15714 IF_DEBUG (debug_method_add (w, "1"));
15715 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15716 /* -1 means we need to scroll.
15717 0 means we need new matrices, but fonts_changed_p
15718 is set in that case, so we will detect it below. */
15719 goto try_to_scroll;
15722 if (fonts_changed_p)
15723 goto need_larger_matrices;
15725 if (w->cursor.vpos >= 0)
15727 if (!just_this_one_p
15728 || current_buffer->clip_changed
15729 || BEG_UNCHANGED < CHARPOS (startp))
15730 /* Forget any recorded base line for line number display. */
15731 w->base_line_number = 0;
15733 if (!cursor_row_fully_visible_p (w, 1, 0))
15735 clear_glyph_matrix (w->desired_matrix);
15736 last_line_misfit = 1;
15738 /* Drop through and scroll. */
15739 else
15740 goto done;
15742 else
15743 clear_glyph_matrix (w->desired_matrix);
15746 try_to_scroll:
15748 w->last_modified = 0;
15749 w->last_overlay_modified = 0;
15751 /* Redisplay the mode line. Select the buffer properly for that. */
15752 if (!update_mode_line)
15754 update_mode_line = 1;
15755 w->update_mode_line = 1;
15758 /* Try to scroll by specified few lines. */
15759 if ((scroll_conservatively
15760 || emacs_scroll_step
15761 || temp_scroll_step
15762 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15763 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15764 && CHARPOS (startp) >= BEGV
15765 && CHARPOS (startp) <= ZV)
15767 /* The function returns -1 if new fonts were loaded, 1 if
15768 successful, 0 if not successful. */
15769 int ss = try_scrolling (window, just_this_one_p,
15770 scroll_conservatively,
15771 emacs_scroll_step,
15772 temp_scroll_step, last_line_misfit);
15773 switch (ss)
15775 case SCROLLING_SUCCESS:
15776 goto done;
15778 case SCROLLING_NEED_LARGER_MATRICES:
15779 goto need_larger_matrices;
15781 case SCROLLING_FAILED:
15782 break;
15784 default:
15785 emacs_abort ();
15789 /* Finally, just choose a place to start which positions point
15790 according to user preferences. */
15792 recenter:
15794 #ifdef GLYPH_DEBUG
15795 debug_method_add (w, "recenter");
15796 #endif
15798 /* Forget any previously recorded base line for line number display. */
15799 if (!buffer_unchanged_p)
15800 w->base_line_number = 0;
15802 /* Determine the window start relative to point. */
15803 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15804 it.current_y = it.last_visible_y;
15805 if (centering_position < 0)
15807 int margin =
15808 scroll_margin > 0
15809 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15810 : 0;
15811 ptrdiff_t margin_pos = CHARPOS (startp);
15812 Lisp_Object aggressive;
15813 int scrolling_up;
15815 /* If there is a scroll margin at the top of the window, find
15816 its character position. */
15817 if (margin
15818 /* Cannot call start_display if startp is not in the
15819 accessible region of the buffer. This can happen when we
15820 have just switched to a different buffer and/or changed
15821 its restriction. In that case, startp is initialized to
15822 the character position 1 (BEGV) because we did not yet
15823 have chance to display the buffer even once. */
15824 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15826 struct it it1;
15827 void *it1data = NULL;
15829 SAVE_IT (it1, it, it1data);
15830 start_display (&it1, w, startp);
15831 move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
15832 margin_pos = IT_CHARPOS (it1);
15833 RESTORE_IT (&it, &it, it1data);
15835 scrolling_up = PT > margin_pos;
15836 aggressive =
15837 scrolling_up
15838 ? BVAR (current_buffer, scroll_up_aggressively)
15839 : BVAR (current_buffer, scroll_down_aggressively);
15841 if (!MINI_WINDOW_P (w)
15842 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15844 int pt_offset = 0;
15846 /* Setting scroll-conservatively overrides
15847 scroll-*-aggressively. */
15848 if (!scroll_conservatively && NUMBERP (aggressive))
15850 double float_amount = XFLOATINT (aggressive);
15852 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15853 if (pt_offset == 0 && float_amount > 0)
15854 pt_offset = 1;
15855 if (pt_offset && margin > 0)
15856 margin -= 1;
15858 /* Compute how much to move the window start backward from
15859 point so that point will be displayed where the user
15860 wants it. */
15861 if (scrolling_up)
15863 centering_position = it.last_visible_y;
15864 if (pt_offset)
15865 centering_position -= pt_offset;
15866 centering_position -=
15867 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15868 + WINDOW_HEADER_LINE_HEIGHT (w);
15869 /* Don't let point enter the scroll margin near top of
15870 the window. */
15871 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15872 centering_position = margin * FRAME_LINE_HEIGHT (f);
15874 else
15875 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15877 else
15878 /* Set the window start half the height of the window backward
15879 from point. */
15880 centering_position = window_box_height (w) / 2;
15882 move_it_vertically_backward (&it, centering_position);
15884 eassert (IT_CHARPOS (it) >= BEGV);
15886 /* The function move_it_vertically_backward may move over more
15887 than the specified y-distance. If it->w is small, e.g. a
15888 mini-buffer window, we may end up in front of the window's
15889 display area. Start displaying at the start of the line
15890 containing PT in this case. */
15891 if (it.current_y <= 0)
15893 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15894 move_it_vertically_backward (&it, 0);
15895 it.current_y = 0;
15898 it.current_x = it.hpos = 0;
15900 /* Set the window start position here explicitly, to avoid an
15901 infinite loop in case the functions in window-scroll-functions
15902 get errors. */
15903 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15905 /* Run scroll hooks. */
15906 startp = run_window_scroll_functions (window, it.current.pos);
15908 /* Redisplay the window. */
15909 if (!current_matrix_up_to_date_p
15910 || windows_or_buffers_changed
15911 || cursor_type_changed
15912 /* Don't use try_window_reusing_current_matrix in this case
15913 because it can have changed the buffer. */
15914 || !NILP (Vwindow_scroll_functions)
15915 || !just_this_one_p
15916 || MINI_WINDOW_P (w)
15917 || !(used_current_matrix_p
15918 = try_window_reusing_current_matrix (w)))
15919 try_window (window, startp, 0);
15921 /* If new fonts have been loaded (due to fontsets), give up. We
15922 have to start a new redisplay since we need to re-adjust glyph
15923 matrices. */
15924 if (fonts_changed_p)
15925 goto need_larger_matrices;
15927 /* If cursor did not appear assume that the middle of the window is
15928 in the first line of the window. Do it again with the next line.
15929 (Imagine a window of height 100, displaying two lines of height
15930 60. Moving back 50 from it->last_visible_y will end in the first
15931 line.) */
15932 if (w->cursor.vpos < 0)
15934 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
15936 clear_glyph_matrix (w->desired_matrix);
15937 move_it_by_lines (&it, 1);
15938 try_window (window, it.current.pos, 0);
15940 else if (PT < IT_CHARPOS (it))
15942 clear_glyph_matrix (w->desired_matrix);
15943 move_it_by_lines (&it, -1);
15944 try_window (window, it.current.pos, 0);
15946 else
15948 /* Not much we can do about it. */
15952 /* Consider the following case: Window starts at BEGV, there is
15953 invisible, intangible text at BEGV, so that display starts at
15954 some point START > BEGV. It can happen that we are called with
15955 PT somewhere between BEGV and START. Try to handle that case. */
15956 if (w->cursor.vpos < 0)
15958 struct glyph_row *row = w->current_matrix->rows;
15959 if (row->mode_line_p)
15960 ++row;
15961 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15964 if (!cursor_row_fully_visible_p (w, 0, 0))
15966 /* If vscroll is enabled, disable it and try again. */
15967 if (w->vscroll)
15969 w->vscroll = 0;
15970 clear_glyph_matrix (w->desired_matrix);
15971 goto recenter;
15974 /* Users who set scroll-conservatively to a large number want
15975 point just above/below the scroll margin. If we ended up
15976 with point's row partially visible, move the window start to
15977 make that row fully visible and out of the margin. */
15978 if (scroll_conservatively > SCROLL_LIMIT)
15980 int margin =
15981 scroll_margin > 0
15982 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15983 : 0;
15984 int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
15986 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
15987 clear_glyph_matrix (w->desired_matrix);
15988 if (1 == try_window (window, it.current.pos,
15989 TRY_WINDOW_CHECK_MARGINS))
15990 goto done;
15993 /* If centering point failed to make the whole line visible,
15994 put point at the top instead. That has to make the whole line
15995 visible, if it can be done. */
15996 if (centering_position == 0)
15997 goto done;
15999 clear_glyph_matrix (w->desired_matrix);
16000 centering_position = 0;
16001 goto recenter;
16004 done:
16006 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16007 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16008 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16010 /* Display the mode line, if we must. */
16011 if ((update_mode_line
16012 /* If window not full width, must redo its mode line
16013 if (a) the window to its side is being redone and
16014 (b) we do a frame-based redisplay. This is a consequence
16015 of how inverted lines are drawn in frame-based redisplay. */
16016 || (!just_this_one_p
16017 && !FRAME_WINDOW_P (f)
16018 && !WINDOW_FULL_WIDTH_P (w))
16019 /* Line number to display. */
16020 || w->base_line_pos > 0
16021 /* Column number is displayed and different from the one displayed. */
16022 || (w->column_number_displayed != -1
16023 && (w->column_number_displayed != current_column ())))
16024 /* This means that the window has a mode line. */
16025 && (WINDOW_WANTS_MODELINE_P (w)
16026 || WINDOW_WANTS_HEADER_LINE_P (w)))
16028 display_mode_lines (w);
16030 /* If mode line height has changed, arrange for a thorough
16031 immediate redisplay using the correct mode line height. */
16032 if (WINDOW_WANTS_MODELINE_P (w)
16033 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16035 fonts_changed_p = 1;
16036 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16037 = DESIRED_MODE_LINE_HEIGHT (w);
16040 /* If header line height has changed, arrange for a thorough
16041 immediate redisplay using the correct header line height. */
16042 if (WINDOW_WANTS_HEADER_LINE_P (w)
16043 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16045 fonts_changed_p = 1;
16046 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16047 = DESIRED_HEADER_LINE_HEIGHT (w);
16050 if (fonts_changed_p)
16051 goto need_larger_matrices;
16054 if (!line_number_displayed && w->base_line_pos != -1)
16056 w->base_line_pos = 0;
16057 w->base_line_number = 0;
16060 finish_menu_bars:
16062 /* When we reach a frame's selected window, redo the frame's menu bar. */
16063 if (update_mode_line
16064 && EQ (FRAME_SELECTED_WINDOW (f), window))
16066 int redisplay_menu_p = 0;
16068 if (FRAME_WINDOW_P (f))
16070 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16071 || defined (HAVE_NS) || defined (USE_GTK)
16072 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16073 #else
16074 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16075 #endif
16077 else
16078 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16080 if (redisplay_menu_p)
16081 display_menu_bar (w);
16083 #ifdef HAVE_WINDOW_SYSTEM
16084 if (FRAME_WINDOW_P (f))
16086 #if defined (USE_GTK) || defined (HAVE_NS)
16087 if (FRAME_EXTERNAL_TOOL_BAR (f))
16088 redisplay_tool_bar (f);
16089 #else
16090 if (WINDOWP (f->tool_bar_window)
16091 && (FRAME_TOOL_BAR_LINES (f) > 0
16092 || !NILP (Vauto_resize_tool_bars))
16093 && redisplay_tool_bar (f))
16094 ignore_mouse_drag_p = 1;
16095 #endif
16097 #endif
16100 #ifdef HAVE_WINDOW_SYSTEM
16101 if (FRAME_WINDOW_P (f)
16102 && update_window_fringes (w, (just_this_one_p
16103 || (!used_current_matrix_p && !overlay_arrow_seen)
16104 || w->pseudo_window_p)))
16106 update_begin (f);
16107 block_input ();
16108 if (draw_window_fringes (w, 1))
16109 x_draw_vertical_border (w);
16110 unblock_input ();
16111 update_end (f);
16113 #endif /* HAVE_WINDOW_SYSTEM */
16115 /* We go to this label, with fonts_changed_p set,
16116 if it is necessary to try again using larger glyph matrices.
16117 We have to redeem the scroll bar even in this case,
16118 because the loop in redisplay_internal expects that. */
16119 need_larger_matrices:
16121 finish_scroll_bars:
16123 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16125 /* Set the thumb's position and size. */
16126 set_vertical_scroll_bar (w);
16128 /* Note that we actually used the scroll bar attached to this
16129 window, so it shouldn't be deleted at the end of redisplay. */
16130 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16131 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16134 /* Restore current_buffer and value of point in it. The window
16135 update may have changed the buffer, so first make sure `opoint'
16136 is still valid (Bug#6177). */
16137 if (CHARPOS (opoint) < BEGV)
16138 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16139 else if (CHARPOS (opoint) > ZV)
16140 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16141 else
16142 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16144 set_buffer_internal_1 (old);
16145 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16146 shorter. This can be caused by log truncation in *Messages*. */
16147 if (CHARPOS (lpoint) <= ZV)
16148 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16150 unbind_to (count, Qnil);
16154 /* Build the complete desired matrix of WINDOW with a window start
16155 buffer position POS.
16157 Value is 1 if successful. It is zero if fonts were loaded during
16158 redisplay which makes re-adjusting glyph matrices necessary, and -1
16159 if point would appear in the scroll margins.
16160 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16161 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16162 set in FLAGS.) */
16165 try_window (Lisp_Object window, struct text_pos pos, int flags)
16167 struct window *w = XWINDOW (window);
16168 struct it it;
16169 struct glyph_row *last_text_row = NULL;
16170 struct frame *f = XFRAME (w->frame);
16172 /* Make POS the new window start. */
16173 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16175 /* Mark cursor position as unknown. No overlay arrow seen. */
16176 w->cursor.vpos = -1;
16177 overlay_arrow_seen = 0;
16179 /* Initialize iterator and info to start at POS. */
16180 start_display (&it, w, pos);
16182 /* Display all lines of W. */
16183 while (it.current_y < it.last_visible_y)
16185 if (display_line (&it))
16186 last_text_row = it.glyph_row - 1;
16187 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16188 return 0;
16191 /* Don't let the cursor end in the scroll margins. */
16192 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16193 && !MINI_WINDOW_P (w))
16195 int this_scroll_margin;
16197 if (scroll_margin > 0)
16199 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
16200 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
16202 else
16203 this_scroll_margin = 0;
16205 if ((w->cursor.y >= 0 /* not vscrolled */
16206 && w->cursor.y < this_scroll_margin
16207 && CHARPOS (pos) > BEGV
16208 && IT_CHARPOS (it) < ZV)
16209 /* rms: considering make_cursor_line_fully_visible_p here
16210 seems to give wrong results. We don't want to recenter
16211 when the last line is partly visible, we want to allow
16212 that case to be handled in the usual way. */
16213 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16215 w->cursor.vpos = -1;
16216 clear_glyph_matrix (w->desired_matrix);
16217 return -1;
16221 /* If bottom moved off end of frame, change mode line percentage. */
16222 if (XFASTINT (w->window_end_pos) <= 0
16223 && Z != IT_CHARPOS (it))
16224 w->update_mode_line = 1;
16226 /* Set window_end_pos to the offset of the last character displayed
16227 on the window from the end of current_buffer. Set
16228 window_end_vpos to its row number. */
16229 if (last_text_row)
16231 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16232 w->window_end_bytepos
16233 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16234 wset_window_end_pos
16235 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16236 wset_window_end_vpos
16237 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16238 eassert
16239 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16240 XFASTINT (w->window_end_vpos))));
16242 else
16244 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16245 wset_window_end_pos (w, make_number (Z - ZV));
16246 wset_window_end_vpos (w, make_number (0));
16249 /* But that is not valid info until redisplay finishes. */
16250 w->window_end_valid = 0;
16251 return 1;
16256 /************************************************************************
16257 Window redisplay reusing current matrix when buffer has not changed
16258 ************************************************************************/
16260 /* Try redisplay of window W showing an unchanged buffer with a
16261 different window start than the last time it was displayed by
16262 reusing its current matrix. Value is non-zero if successful.
16263 W->start is the new window start. */
16265 static int
16266 try_window_reusing_current_matrix (struct window *w)
16268 struct frame *f = XFRAME (w->frame);
16269 struct glyph_row *bottom_row;
16270 struct it it;
16271 struct run run;
16272 struct text_pos start, new_start;
16273 int nrows_scrolled, i;
16274 struct glyph_row *last_text_row;
16275 struct glyph_row *last_reused_text_row;
16276 struct glyph_row *start_row;
16277 int start_vpos, min_y, max_y;
16279 #ifdef GLYPH_DEBUG
16280 if (inhibit_try_window_reusing)
16281 return 0;
16282 #endif
16284 if (/* This function doesn't handle terminal frames. */
16285 !FRAME_WINDOW_P (f)
16286 /* Don't try to reuse the display if windows have been split
16287 or such. */
16288 || windows_or_buffers_changed
16289 || cursor_type_changed)
16290 return 0;
16292 /* Can't do this if region may have changed. */
16293 if (markpos_of_region () >= 0
16294 || w->region_showing
16295 || !NILP (Vshow_trailing_whitespace))
16296 return 0;
16298 /* If top-line visibility has changed, give up. */
16299 if (WINDOW_WANTS_HEADER_LINE_P (w)
16300 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16301 return 0;
16303 /* Give up if old or new display is scrolled vertically. We could
16304 make this function handle this, but right now it doesn't. */
16305 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16306 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16307 return 0;
16309 /* The variable new_start now holds the new window start. The old
16310 start `start' can be determined from the current matrix. */
16311 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16312 start = start_row->minpos;
16313 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16315 /* Clear the desired matrix for the display below. */
16316 clear_glyph_matrix (w->desired_matrix);
16318 if (CHARPOS (new_start) <= CHARPOS (start))
16320 /* Don't use this method if the display starts with an ellipsis
16321 displayed for invisible text. It's not easy to handle that case
16322 below, and it's certainly not worth the effort since this is
16323 not a frequent case. */
16324 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16325 return 0;
16327 IF_DEBUG (debug_method_add (w, "twu1"));
16329 /* Display up to a row that can be reused. The variable
16330 last_text_row is set to the last row displayed that displays
16331 text. Note that it.vpos == 0 if or if not there is a
16332 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16333 start_display (&it, w, new_start);
16334 w->cursor.vpos = -1;
16335 last_text_row = last_reused_text_row = NULL;
16337 while (it.current_y < it.last_visible_y
16338 && !fonts_changed_p)
16340 /* If we have reached into the characters in the START row,
16341 that means the line boundaries have changed. So we
16342 can't start copying with the row START. Maybe it will
16343 work to start copying with the following row. */
16344 while (IT_CHARPOS (it) > CHARPOS (start))
16346 /* Advance to the next row as the "start". */
16347 start_row++;
16348 start = start_row->minpos;
16349 /* If there are no more rows to try, or just one, give up. */
16350 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16351 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16352 || CHARPOS (start) == ZV)
16354 clear_glyph_matrix (w->desired_matrix);
16355 return 0;
16358 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16360 /* If we have reached alignment, we can copy the rest of the
16361 rows. */
16362 if (IT_CHARPOS (it) == CHARPOS (start)
16363 /* Don't accept "alignment" inside a display vector,
16364 since start_row could have started in the middle of
16365 that same display vector (thus their character
16366 positions match), and we have no way of telling if
16367 that is the case. */
16368 && it.current.dpvec_index < 0)
16369 break;
16371 if (display_line (&it))
16372 last_text_row = it.glyph_row - 1;
16376 /* A value of current_y < last_visible_y means that we stopped
16377 at the previous window start, which in turn means that we
16378 have at least one reusable row. */
16379 if (it.current_y < it.last_visible_y)
16381 struct glyph_row *row;
16383 /* IT.vpos always starts from 0; it counts text lines. */
16384 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16386 /* Find PT if not already found in the lines displayed. */
16387 if (w->cursor.vpos < 0)
16389 int dy = it.current_y - start_row->y;
16391 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16392 row = row_containing_pos (w, PT, row, NULL, dy);
16393 if (row)
16394 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16395 dy, nrows_scrolled);
16396 else
16398 clear_glyph_matrix (w->desired_matrix);
16399 return 0;
16403 /* Scroll the display. Do it before the current matrix is
16404 changed. The problem here is that update has not yet
16405 run, i.e. part of the current matrix is not up to date.
16406 scroll_run_hook will clear the cursor, and use the
16407 current matrix to get the height of the row the cursor is
16408 in. */
16409 run.current_y = start_row->y;
16410 run.desired_y = it.current_y;
16411 run.height = it.last_visible_y - it.current_y;
16413 if (run.height > 0 && run.current_y != run.desired_y)
16415 update_begin (f);
16416 FRAME_RIF (f)->update_window_begin_hook (w);
16417 FRAME_RIF (f)->clear_window_mouse_face (w);
16418 FRAME_RIF (f)->scroll_run_hook (w, &run);
16419 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16420 update_end (f);
16423 /* Shift current matrix down by nrows_scrolled lines. */
16424 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16425 rotate_matrix (w->current_matrix,
16426 start_vpos,
16427 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16428 nrows_scrolled);
16430 /* Disable lines that must be updated. */
16431 for (i = 0; i < nrows_scrolled; ++i)
16432 (start_row + i)->enabled_p = 0;
16434 /* Re-compute Y positions. */
16435 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16436 max_y = it.last_visible_y;
16437 for (row = start_row + nrows_scrolled;
16438 row < bottom_row;
16439 ++row)
16441 row->y = it.current_y;
16442 row->visible_height = row->height;
16444 if (row->y < min_y)
16445 row->visible_height -= min_y - row->y;
16446 if (row->y + row->height > max_y)
16447 row->visible_height -= row->y + row->height - max_y;
16448 if (row->fringe_bitmap_periodic_p)
16449 row->redraw_fringe_bitmaps_p = 1;
16451 it.current_y += row->height;
16453 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16454 last_reused_text_row = row;
16455 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16456 break;
16459 /* Disable lines in the current matrix which are now
16460 below the window. */
16461 for (++row; row < bottom_row; ++row)
16462 row->enabled_p = row->mode_line_p = 0;
16465 /* Update window_end_pos etc.; last_reused_text_row is the last
16466 reused row from the current matrix containing text, if any.
16467 The value of last_text_row is the last displayed line
16468 containing text. */
16469 if (last_reused_text_row)
16471 w->window_end_bytepos
16472 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16473 wset_window_end_pos
16474 (w, make_number (Z
16475 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16476 wset_window_end_vpos
16477 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16478 w->current_matrix)));
16480 else if (last_text_row)
16482 w->window_end_bytepos
16483 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16484 wset_window_end_pos
16485 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16486 wset_window_end_vpos
16487 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16488 w->desired_matrix)));
16490 else
16492 /* This window must be completely empty. */
16493 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16494 wset_window_end_pos (w, make_number (Z - ZV));
16495 wset_window_end_vpos (w, make_number (0));
16497 w->window_end_valid = 0;
16499 /* Update hint: don't try scrolling again in update_window. */
16500 w->desired_matrix->no_scrolling_p = 1;
16502 #ifdef GLYPH_DEBUG
16503 debug_method_add (w, "try_window_reusing_current_matrix 1");
16504 #endif
16505 return 1;
16507 else if (CHARPOS (new_start) > CHARPOS (start))
16509 struct glyph_row *pt_row, *row;
16510 struct glyph_row *first_reusable_row;
16511 struct glyph_row *first_row_to_display;
16512 int dy;
16513 int yb = window_text_bottom_y (w);
16515 /* Find the row starting at new_start, if there is one. Don't
16516 reuse a partially visible line at the end. */
16517 first_reusable_row = start_row;
16518 while (first_reusable_row->enabled_p
16519 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16520 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16521 < CHARPOS (new_start)))
16522 ++first_reusable_row;
16524 /* Give up if there is no row to reuse. */
16525 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16526 || !first_reusable_row->enabled_p
16527 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16528 != CHARPOS (new_start)))
16529 return 0;
16531 /* We can reuse fully visible rows beginning with
16532 first_reusable_row to the end of the window. Set
16533 first_row_to_display to the first row that cannot be reused.
16534 Set pt_row to the row containing point, if there is any. */
16535 pt_row = NULL;
16536 for (first_row_to_display = first_reusable_row;
16537 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16538 ++first_row_to_display)
16540 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16541 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16542 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16543 && first_row_to_display->ends_at_zv_p
16544 && pt_row == NULL)))
16545 pt_row = first_row_to_display;
16548 /* Start displaying at the start of first_row_to_display. */
16549 eassert (first_row_to_display->y < yb);
16550 init_to_row_start (&it, w, first_row_to_display);
16552 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16553 - start_vpos);
16554 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16555 - nrows_scrolled);
16556 it.current_y = (first_row_to_display->y - first_reusable_row->y
16557 + WINDOW_HEADER_LINE_HEIGHT (w));
16559 /* Display lines beginning with first_row_to_display in the
16560 desired matrix. Set last_text_row to the last row displayed
16561 that displays text. */
16562 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16563 if (pt_row == NULL)
16564 w->cursor.vpos = -1;
16565 last_text_row = NULL;
16566 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16567 if (display_line (&it))
16568 last_text_row = it.glyph_row - 1;
16570 /* If point is in a reused row, adjust y and vpos of the cursor
16571 position. */
16572 if (pt_row)
16574 w->cursor.vpos -= nrows_scrolled;
16575 w->cursor.y -= first_reusable_row->y - start_row->y;
16578 /* Give up if point isn't in a row displayed or reused. (This
16579 also handles the case where w->cursor.vpos < nrows_scrolled
16580 after the calls to display_line, which can happen with scroll
16581 margins. See bug#1295.) */
16582 if (w->cursor.vpos < 0)
16584 clear_glyph_matrix (w->desired_matrix);
16585 return 0;
16588 /* Scroll the display. */
16589 run.current_y = first_reusable_row->y;
16590 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16591 run.height = it.last_visible_y - run.current_y;
16592 dy = run.current_y - run.desired_y;
16594 if (run.height)
16596 update_begin (f);
16597 FRAME_RIF (f)->update_window_begin_hook (w);
16598 FRAME_RIF (f)->clear_window_mouse_face (w);
16599 FRAME_RIF (f)->scroll_run_hook (w, &run);
16600 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16601 update_end (f);
16604 /* Adjust Y positions of reused rows. */
16605 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16606 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16607 max_y = it.last_visible_y;
16608 for (row = first_reusable_row; row < first_row_to_display; ++row)
16610 row->y -= dy;
16611 row->visible_height = row->height;
16612 if (row->y < min_y)
16613 row->visible_height -= min_y - row->y;
16614 if (row->y + row->height > max_y)
16615 row->visible_height -= row->y + row->height - max_y;
16616 if (row->fringe_bitmap_periodic_p)
16617 row->redraw_fringe_bitmaps_p = 1;
16620 /* Scroll the current matrix. */
16621 eassert (nrows_scrolled > 0);
16622 rotate_matrix (w->current_matrix,
16623 start_vpos,
16624 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16625 -nrows_scrolled);
16627 /* Disable rows not reused. */
16628 for (row -= nrows_scrolled; row < bottom_row; ++row)
16629 row->enabled_p = 0;
16631 /* Point may have moved to a different line, so we cannot assume that
16632 the previous cursor position is valid; locate the correct row. */
16633 if (pt_row)
16635 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16636 row < bottom_row
16637 && PT >= MATRIX_ROW_END_CHARPOS (row)
16638 && !row->ends_at_zv_p;
16639 row++)
16641 w->cursor.vpos++;
16642 w->cursor.y = row->y;
16644 if (row < bottom_row)
16646 /* Can't simply scan the row for point with
16647 bidi-reordered glyph rows. Let set_cursor_from_row
16648 figure out where to put the cursor, and if it fails,
16649 give up. */
16650 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16652 if (!set_cursor_from_row (w, row, w->current_matrix,
16653 0, 0, 0, 0))
16655 clear_glyph_matrix (w->desired_matrix);
16656 return 0;
16659 else
16661 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16662 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16664 for (; glyph < end
16665 && (!BUFFERP (glyph->object)
16666 || glyph->charpos < PT);
16667 glyph++)
16669 w->cursor.hpos++;
16670 w->cursor.x += glyph->pixel_width;
16676 /* Adjust window end. A null value of last_text_row means that
16677 the window end is in reused rows which in turn means that
16678 only its vpos can have changed. */
16679 if (last_text_row)
16681 w->window_end_bytepos
16682 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16683 wset_window_end_pos
16684 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16685 wset_window_end_vpos
16686 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16687 w->desired_matrix)));
16689 else
16691 wset_window_end_vpos
16692 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16695 w->window_end_valid = 0;
16696 w->desired_matrix->no_scrolling_p = 1;
16698 #ifdef GLYPH_DEBUG
16699 debug_method_add (w, "try_window_reusing_current_matrix 2");
16700 #endif
16701 return 1;
16704 return 0;
16709 /************************************************************************
16710 Window redisplay reusing current matrix when buffer has changed
16711 ************************************************************************/
16713 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16714 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16715 ptrdiff_t *, ptrdiff_t *);
16716 static struct glyph_row *
16717 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16718 struct glyph_row *);
16721 /* Return the last row in MATRIX displaying text. If row START is
16722 non-null, start searching with that row. IT gives the dimensions
16723 of the display. Value is null if matrix is empty; otherwise it is
16724 a pointer to the row found. */
16726 static struct glyph_row *
16727 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16728 struct glyph_row *start)
16730 struct glyph_row *row, *row_found;
16732 /* Set row_found to the last row in IT->w's current matrix
16733 displaying text. The loop looks funny but think of partially
16734 visible lines. */
16735 row_found = NULL;
16736 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16737 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16739 eassert (row->enabled_p);
16740 row_found = row;
16741 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16742 break;
16743 ++row;
16746 return row_found;
16750 /* Return the last row in the current matrix of W that is not affected
16751 by changes at the start of current_buffer that occurred since W's
16752 current matrix was built. Value is null if no such row exists.
16754 BEG_UNCHANGED us the number of characters unchanged at the start of
16755 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16756 first changed character in current_buffer. Characters at positions <
16757 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16758 when the current matrix was built. */
16760 static struct glyph_row *
16761 find_last_unchanged_at_beg_row (struct window *w)
16763 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16764 struct glyph_row *row;
16765 struct glyph_row *row_found = NULL;
16766 int yb = window_text_bottom_y (w);
16768 /* Find the last row displaying unchanged text. */
16769 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16770 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16771 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16772 ++row)
16774 if (/* If row ends before first_changed_pos, it is unchanged,
16775 except in some case. */
16776 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16777 /* When row ends in ZV and we write at ZV it is not
16778 unchanged. */
16779 && !row->ends_at_zv_p
16780 /* When first_changed_pos is the end of a continued line,
16781 row is not unchanged because it may be no longer
16782 continued. */
16783 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16784 && (row->continued_p
16785 || row->exact_window_width_line_p))
16786 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16787 needs to be recomputed, so don't consider this row as
16788 unchanged. This happens when the last line was
16789 bidi-reordered and was killed immediately before this
16790 redisplay cycle. In that case, ROW->end stores the
16791 buffer position of the first visual-order character of
16792 the killed text, which is now beyond ZV. */
16793 && CHARPOS (row->end.pos) <= ZV)
16794 row_found = row;
16796 /* Stop if last visible row. */
16797 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16798 break;
16801 return row_found;
16805 /* Find the first glyph row in the current matrix of W that is not
16806 affected by changes at the end of current_buffer since the
16807 time W's current matrix was built.
16809 Return in *DELTA the number of chars by which buffer positions in
16810 unchanged text at the end of current_buffer must be adjusted.
16812 Return in *DELTA_BYTES the corresponding number of bytes.
16814 Value is null if no such row exists, i.e. all rows are affected by
16815 changes. */
16817 static struct glyph_row *
16818 find_first_unchanged_at_end_row (struct window *w,
16819 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16821 struct glyph_row *row;
16822 struct glyph_row *row_found = NULL;
16824 *delta = *delta_bytes = 0;
16826 /* Display must not have been paused, otherwise the current matrix
16827 is not up to date. */
16828 eassert (w->window_end_valid);
16830 /* A value of window_end_pos >= END_UNCHANGED means that the window
16831 end is in the range of changed text. If so, there is no
16832 unchanged row at the end of W's current matrix. */
16833 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16834 return NULL;
16836 /* Set row to the last row in W's current matrix displaying text. */
16837 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16839 /* If matrix is entirely empty, no unchanged row exists. */
16840 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16842 /* The value of row is the last glyph row in the matrix having a
16843 meaningful buffer position in it. The end position of row
16844 corresponds to window_end_pos. This allows us to translate
16845 buffer positions in the current matrix to current buffer
16846 positions for characters not in changed text. */
16847 ptrdiff_t Z_old =
16848 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16849 ptrdiff_t Z_BYTE_old =
16850 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16851 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16852 struct glyph_row *first_text_row
16853 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16855 *delta = Z - Z_old;
16856 *delta_bytes = Z_BYTE - Z_BYTE_old;
16858 /* Set last_unchanged_pos to the buffer position of the last
16859 character in the buffer that has not been changed. Z is the
16860 index + 1 of the last character in current_buffer, i.e. by
16861 subtracting END_UNCHANGED we get the index of the last
16862 unchanged character, and we have to add BEG to get its buffer
16863 position. */
16864 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16865 last_unchanged_pos_old = last_unchanged_pos - *delta;
16867 /* Search backward from ROW for a row displaying a line that
16868 starts at a minimum position >= last_unchanged_pos_old. */
16869 for (; row > first_text_row; --row)
16871 /* This used to abort, but it can happen.
16872 It is ok to just stop the search instead here. KFS. */
16873 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16874 break;
16876 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16877 row_found = row;
16881 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16883 return row_found;
16887 /* Make sure that glyph rows in the current matrix of window W
16888 reference the same glyph memory as corresponding rows in the
16889 frame's frame matrix. This function is called after scrolling W's
16890 current matrix on a terminal frame in try_window_id and
16891 try_window_reusing_current_matrix. */
16893 static void
16894 sync_frame_with_window_matrix_rows (struct window *w)
16896 struct frame *f = XFRAME (w->frame);
16897 struct glyph_row *window_row, *window_row_end, *frame_row;
16899 /* Preconditions: W must be a leaf window and full-width. Its frame
16900 must have a frame matrix. */
16901 eassert (BUFFERP (w->contents));
16902 eassert (WINDOW_FULL_WIDTH_P (w));
16903 eassert (!FRAME_WINDOW_P (f));
16905 /* If W is a full-width window, glyph pointers in W's current matrix
16906 have, by definition, to be the same as glyph pointers in the
16907 corresponding frame matrix. Note that frame matrices have no
16908 marginal areas (see build_frame_matrix). */
16909 window_row = w->current_matrix->rows;
16910 window_row_end = window_row + w->current_matrix->nrows;
16911 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16912 while (window_row < window_row_end)
16914 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16915 struct glyph *end = window_row->glyphs[LAST_AREA];
16917 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16918 frame_row->glyphs[TEXT_AREA] = start;
16919 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16920 frame_row->glyphs[LAST_AREA] = end;
16922 /* Disable frame rows whose corresponding window rows have
16923 been disabled in try_window_id. */
16924 if (!window_row->enabled_p)
16925 frame_row->enabled_p = 0;
16927 ++window_row, ++frame_row;
16932 /* Find the glyph row in window W containing CHARPOS. Consider all
16933 rows between START and END (not inclusive). END null means search
16934 all rows to the end of the display area of W. Value is the row
16935 containing CHARPOS or null. */
16937 struct glyph_row *
16938 row_containing_pos (struct window *w, ptrdiff_t charpos,
16939 struct glyph_row *start, struct glyph_row *end, int dy)
16941 struct glyph_row *row = start;
16942 struct glyph_row *best_row = NULL;
16943 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
16944 int last_y;
16946 /* If we happen to start on a header-line, skip that. */
16947 if (row->mode_line_p)
16948 ++row;
16950 if ((end && row >= end) || !row->enabled_p)
16951 return NULL;
16953 last_y = window_text_bottom_y (w) - dy;
16955 while (1)
16957 /* Give up if we have gone too far. */
16958 if (end && row >= end)
16959 return NULL;
16960 /* This formerly returned if they were equal.
16961 I think that both quantities are of a "last plus one" type;
16962 if so, when they are equal, the row is within the screen. -- rms. */
16963 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16964 return NULL;
16966 /* If it is in this row, return this row. */
16967 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16968 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16969 /* The end position of a row equals the start
16970 position of the next row. If CHARPOS is there, we
16971 would rather consider it displayed in the next
16972 line, except when this line ends in ZV. */
16973 && !row_for_charpos_p (row, charpos)))
16974 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16976 struct glyph *g;
16978 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
16979 || (!best_row && !row->continued_p))
16980 return row;
16981 /* In bidi-reordered rows, there could be several rows whose
16982 edges surround CHARPOS, all of these rows belonging to
16983 the same continued line. We need to find the row which
16984 fits CHARPOS the best. */
16985 for (g = row->glyphs[TEXT_AREA];
16986 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16987 g++)
16989 if (!STRINGP (g->object))
16991 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
16993 mindif = eabs (g->charpos - charpos);
16994 best_row = row;
16995 /* Exact match always wins. */
16996 if (mindif == 0)
16997 return best_row;
17002 else if (best_row && !row->continued_p)
17003 return best_row;
17004 ++row;
17009 /* Try to redisplay window W by reusing its existing display. W's
17010 current matrix must be up to date when this function is called,
17011 i.e. window_end_valid must be nonzero.
17013 Value is
17015 1 if display has been updated
17016 0 if otherwise unsuccessful
17017 -1 if redisplay with same window start is known not to succeed
17019 The following steps are performed:
17021 1. Find the last row in the current matrix of W that is not
17022 affected by changes at the start of current_buffer. If no such row
17023 is found, give up.
17025 2. Find the first row in W's current matrix that is not affected by
17026 changes at the end of current_buffer. Maybe there is no such row.
17028 3. Display lines beginning with the row + 1 found in step 1 to the
17029 row found in step 2 or, if step 2 didn't find a row, to the end of
17030 the window.
17032 4. If cursor is not known to appear on the window, give up.
17034 5. If display stopped at the row found in step 2, scroll the
17035 display and current matrix as needed.
17037 6. Maybe display some lines at the end of W, if we must. This can
17038 happen under various circumstances, like a partially visible line
17039 becoming fully visible, or because newly displayed lines are displayed
17040 in smaller font sizes.
17042 7. Update W's window end information. */
17044 static int
17045 try_window_id (struct window *w)
17047 struct frame *f = XFRAME (w->frame);
17048 struct glyph_matrix *current_matrix = w->current_matrix;
17049 struct glyph_matrix *desired_matrix = w->desired_matrix;
17050 struct glyph_row *last_unchanged_at_beg_row;
17051 struct glyph_row *first_unchanged_at_end_row;
17052 struct glyph_row *row;
17053 struct glyph_row *bottom_row;
17054 int bottom_vpos;
17055 struct it it;
17056 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17057 int dvpos, dy;
17058 struct text_pos start_pos;
17059 struct run run;
17060 int first_unchanged_at_end_vpos = 0;
17061 struct glyph_row *last_text_row, *last_text_row_at_end;
17062 struct text_pos start;
17063 ptrdiff_t first_changed_charpos, last_changed_charpos;
17065 #ifdef GLYPH_DEBUG
17066 if (inhibit_try_window_id)
17067 return 0;
17068 #endif
17070 /* This is handy for debugging. */
17071 #if 0
17072 #define GIVE_UP(X) \
17073 do { \
17074 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17075 return 0; \
17076 } while (0)
17077 #else
17078 #define GIVE_UP(X) return 0
17079 #endif
17081 SET_TEXT_POS_FROM_MARKER (start, w->start);
17083 /* Don't use this for mini-windows because these can show
17084 messages and mini-buffers, and we don't handle that here. */
17085 if (MINI_WINDOW_P (w))
17086 GIVE_UP (1);
17088 /* This flag is used to prevent redisplay optimizations. */
17089 if (windows_or_buffers_changed || cursor_type_changed)
17090 GIVE_UP (2);
17092 /* Verify that narrowing has not changed.
17093 Also verify that we were not told to prevent redisplay optimizations.
17094 It would be nice to further
17095 reduce the number of cases where this prevents try_window_id. */
17096 if (current_buffer->clip_changed
17097 || current_buffer->prevent_redisplay_optimizations_p)
17098 GIVE_UP (3);
17100 /* Window must either use window-based redisplay or be full width. */
17101 if (!FRAME_WINDOW_P (f)
17102 && (!FRAME_LINE_INS_DEL_OK (f)
17103 || !WINDOW_FULL_WIDTH_P (w)))
17104 GIVE_UP (4);
17106 /* Give up if point is known NOT to appear in W. */
17107 if (PT < CHARPOS (start))
17108 GIVE_UP (5);
17110 /* Another way to prevent redisplay optimizations. */
17111 if (w->last_modified == 0)
17112 GIVE_UP (6);
17114 /* Verify that window is not hscrolled. */
17115 if (w->hscroll != 0)
17116 GIVE_UP (7);
17118 /* Verify that display wasn't paused. */
17119 if (!w->window_end_valid)
17120 GIVE_UP (8);
17122 /* Can't use this if highlighting a region because a cursor movement
17123 will do more than just set the cursor. */
17124 if (markpos_of_region () >= 0)
17125 GIVE_UP (9);
17127 /* Likewise if highlighting trailing whitespace. */
17128 if (!NILP (Vshow_trailing_whitespace))
17129 GIVE_UP (11);
17131 /* Likewise if showing a region. */
17132 if (w->region_showing)
17133 GIVE_UP (10);
17135 /* Can't use this if overlay arrow position and/or string have
17136 changed. */
17137 if (overlay_arrows_changed_p ())
17138 GIVE_UP (12);
17140 /* When word-wrap is on, adding a space to the first word of a
17141 wrapped line can change the wrap position, altering the line
17142 above it. It might be worthwhile to handle this more
17143 intelligently, but for now just redisplay from scratch. */
17144 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17145 GIVE_UP (21);
17147 /* Under bidi reordering, adding or deleting a character in the
17148 beginning of a paragraph, before the first strong directional
17149 character, can change the base direction of the paragraph (unless
17150 the buffer specifies a fixed paragraph direction), which will
17151 require to redisplay the whole paragraph. It might be worthwhile
17152 to find the paragraph limits and widen the range of redisplayed
17153 lines to that, but for now just give up this optimization and
17154 redisplay from scratch. */
17155 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17156 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17157 GIVE_UP (22);
17159 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17160 only if buffer has really changed. The reason is that the gap is
17161 initially at Z for freshly visited files. The code below would
17162 set end_unchanged to 0 in that case. */
17163 if (MODIFF > SAVE_MODIFF
17164 /* This seems to happen sometimes after saving a buffer. */
17165 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17167 if (GPT - BEG < BEG_UNCHANGED)
17168 BEG_UNCHANGED = GPT - BEG;
17169 if (Z - GPT < END_UNCHANGED)
17170 END_UNCHANGED = Z - GPT;
17173 /* The position of the first and last character that has been changed. */
17174 first_changed_charpos = BEG + BEG_UNCHANGED;
17175 last_changed_charpos = Z - END_UNCHANGED;
17177 /* If window starts after a line end, and the last change is in
17178 front of that newline, then changes don't affect the display.
17179 This case happens with stealth-fontification. Note that although
17180 the display is unchanged, glyph positions in the matrix have to
17181 be adjusted, of course. */
17182 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17183 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17184 && ((last_changed_charpos < CHARPOS (start)
17185 && CHARPOS (start) == BEGV)
17186 || (last_changed_charpos < CHARPOS (start) - 1
17187 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17189 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17190 struct glyph_row *r0;
17192 /* Compute how many chars/bytes have been added to or removed
17193 from the buffer. */
17194 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17195 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17196 Z_delta = Z - Z_old;
17197 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17199 /* Give up if PT is not in the window. Note that it already has
17200 been checked at the start of try_window_id that PT is not in
17201 front of the window start. */
17202 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17203 GIVE_UP (13);
17205 /* If window start is unchanged, we can reuse the whole matrix
17206 as is, after adjusting glyph positions. No need to compute
17207 the window end again, since its offset from Z hasn't changed. */
17208 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17209 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17210 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17211 /* PT must not be in a partially visible line. */
17212 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17213 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17215 /* Adjust positions in the glyph matrix. */
17216 if (Z_delta || Z_delta_bytes)
17218 struct glyph_row *r1
17219 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17220 increment_matrix_positions (w->current_matrix,
17221 MATRIX_ROW_VPOS (r0, current_matrix),
17222 MATRIX_ROW_VPOS (r1, current_matrix),
17223 Z_delta, Z_delta_bytes);
17226 /* Set the cursor. */
17227 row = row_containing_pos (w, PT, r0, NULL, 0);
17228 if (row)
17229 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17230 else
17231 emacs_abort ();
17232 return 1;
17236 /* Handle the case that changes are all below what is displayed in
17237 the window, and that PT is in the window. This shortcut cannot
17238 be taken if ZV is visible in the window, and text has been added
17239 there that is visible in the window. */
17240 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17241 /* ZV is not visible in the window, or there are no
17242 changes at ZV, actually. */
17243 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17244 || first_changed_charpos == last_changed_charpos))
17246 struct glyph_row *r0;
17248 /* Give up if PT is not in the window. Note that it already has
17249 been checked at the start of try_window_id that PT is not in
17250 front of the window start. */
17251 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17252 GIVE_UP (14);
17254 /* If window start is unchanged, we can reuse the whole matrix
17255 as is, without changing glyph positions since no text has
17256 been added/removed in front of the window end. */
17257 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17258 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17259 /* PT must not be in a partially visible line. */
17260 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17261 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17263 /* We have to compute the window end anew since text
17264 could have been added/removed after it. */
17265 wset_window_end_pos
17266 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17267 w->window_end_bytepos
17268 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17270 /* Set the cursor. */
17271 row = row_containing_pos (w, PT, r0, NULL, 0);
17272 if (row)
17273 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17274 else
17275 emacs_abort ();
17276 return 2;
17280 /* Give up if window start is in the changed area.
17282 The condition used to read
17284 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17286 but why that was tested escapes me at the moment. */
17287 if (CHARPOS (start) >= first_changed_charpos
17288 && CHARPOS (start) <= last_changed_charpos)
17289 GIVE_UP (15);
17291 /* Check that window start agrees with the start of the first glyph
17292 row in its current matrix. Check this after we know the window
17293 start is not in changed text, otherwise positions would not be
17294 comparable. */
17295 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17296 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17297 GIVE_UP (16);
17299 /* Give up if the window ends in strings. Overlay strings
17300 at the end are difficult to handle, so don't try. */
17301 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17302 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17303 GIVE_UP (20);
17305 /* Compute the position at which we have to start displaying new
17306 lines. Some of the lines at the top of the window might be
17307 reusable because they are not displaying changed text. Find the
17308 last row in W's current matrix not affected by changes at the
17309 start of current_buffer. Value is null if changes start in the
17310 first line of window. */
17311 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17312 if (last_unchanged_at_beg_row)
17314 /* Avoid starting to display in the middle of a character, a TAB
17315 for instance. This is easier than to set up the iterator
17316 exactly, and it's not a frequent case, so the additional
17317 effort wouldn't really pay off. */
17318 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17319 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17320 && last_unchanged_at_beg_row > w->current_matrix->rows)
17321 --last_unchanged_at_beg_row;
17323 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17324 GIVE_UP (17);
17326 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17327 GIVE_UP (18);
17328 start_pos = it.current.pos;
17330 /* Start displaying new lines in the desired matrix at the same
17331 vpos we would use in the current matrix, i.e. below
17332 last_unchanged_at_beg_row. */
17333 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17334 current_matrix);
17335 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17336 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17338 eassert (it.hpos == 0 && it.current_x == 0);
17340 else
17342 /* There are no reusable lines at the start of the window.
17343 Start displaying in the first text line. */
17344 start_display (&it, w, start);
17345 it.vpos = it.first_vpos;
17346 start_pos = it.current.pos;
17349 /* Find the first row that is not affected by changes at the end of
17350 the buffer. Value will be null if there is no unchanged row, in
17351 which case we must redisplay to the end of the window. delta
17352 will be set to the value by which buffer positions beginning with
17353 first_unchanged_at_end_row have to be adjusted due to text
17354 changes. */
17355 first_unchanged_at_end_row
17356 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17357 IF_DEBUG (debug_delta = delta);
17358 IF_DEBUG (debug_delta_bytes = delta_bytes);
17360 /* Set stop_pos to the buffer position up to which we will have to
17361 display new lines. If first_unchanged_at_end_row != NULL, this
17362 is the buffer position of the start of the line displayed in that
17363 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17364 that we don't stop at a buffer position. */
17365 stop_pos = 0;
17366 if (first_unchanged_at_end_row)
17368 eassert (last_unchanged_at_beg_row == NULL
17369 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17371 /* If this is a continuation line, move forward to the next one
17372 that isn't. Changes in lines above affect this line.
17373 Caution: this may move first_unchanged_at_end_row to a row
17374 not displaying text. */
17375 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17376 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17377 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17378 < it.last_visible_y))
17379 ++first_unchanged_at_end_row;
17381 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17382 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17383 >= it.last_visible_y))
17384 first_unchanged_at_end_row = NULL;
17385 else
17387 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17388 + delta);
17389 first_unchanged_at_end_vpos
17390 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17391 eassert (stop_pos >= Z - END_UNCHANGED);
17394 else if (last_unchanged_at_beg_row == NULL)
17395 GIVE_UP (19);
17398 #ifdef GLYPH_DEBUG
17400 /* Either there is no unchanged row at the end, or the one we have
17401 now displays text. This is a necessary condition for the window
17402 end pos calculation at the end of this function. */
17403 eassert (first_unchanged_at_end_row == NULL
17404 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17406 debug_last_unchanged_at_beg_vpos
17407 = (last_unchanged_at_beg_row
17408 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17409 : -1);
17410 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17412 #endif /* GLYPH_DEBUG */
17415 /* Display new lines. Set last_text_row to the last new line
17416 displayed which has text on it, i.e. might end up as being the
17417 line where the window_end_vpos is. */
17418 w->cursor.vpos = -1;
17419 last_text_row = NULL;
17420 overlay_arrow_seen = 0;
17421 while (it.current_y < it.last_visible_y
17422 && !fonts_changed_p
17423 && (first_unchanged_at_end_row == NULL
17424 || IT_CHARPOS (it) < stop_pos))
17426 if (display_line (&it))
17427 last_text_row = it.glyph_row - 1;
17430 if (fonts_changed_p)
17431 return -1;
17434 /* Compute differences in buffer positions, y-positions etc. for
17435 lines reused at the bottom of the window. Compute what we can
17436 scroll. */
17437 if (first_unchanged_at_end_row
17438 /* No lines reused because we displayed everything up to the
17439 bottom of the window. */
17440 && it.current_y < it.last_visible_y)
17442 dvpos = (it.vpos
17443 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17444 current_matrix));
17445 dy = it.current_y - first_unchanged_at_end_row->y;
17446 run.current_y = first_unchanged_at_end_row->y;
17447 run.desired_y = run.current_y + dy;
17448 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17450 else
17452 delta = delta_bytes = dvpos = dy
17453 = run.current_y = run.desired_y = run.height = 0;
17454 first_unchanged_at_end_row = NULL;
17456 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17459 /* Find the cursor if not already found. We have to decide whether
17460 PT will appear on this window (it sometimes doesn't, but this is
17461 not a very frequent case.) This decision has to be made before
17462 the current matrix is altered. A value of cursor.vpos < 0 means
17463 that PT is either in one of the lines beginning at
17464 first_unchanged_at_end_row or below the window. Don't care for
17465 lines that might be displayed later at the window end; as
17466 mentioned, this is not a frequent case. */
17467 if (w->cursor.vpos < 0)
17469 /* Cursor in unchanged rows at the top? */
17470 if (PT < CHARPOS (start_pos)
17471 && last_unchanged_at_beg_row)
17473 row = row_containing_pos (w, PT,
17474 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17475 last_unchanged_at_beg_row + 1, 0);
17476 if (row)
17477 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17480 /* Start from first_unchanged_at_end_row looking for PT. */
17481 else if (first_unchanged_at_end_row)
17483 row = row_containing_pos (w, PT - delta,
17484 first_unchanged_at_end_row, NULL, 0);
17485 if (row)
17486 set_cursor_from_row (w, row, w->current_matrix, delta,
17487 delta_bytes, dy, dvpos);
17490 /* Give up if cursor was not found. */
17491 if (w->cursor.vpos < 0)
17493 clear_glyph_matrix (w->desired_matrix);
17494 return -1;
17498 /* Don't let the cursor end in the scroll margins. */
17500 int this_scroll_margin, cursor_height;
17502 this_scroll_margin =
17503 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17504 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17505 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17507 if ((w->cursor.y < this_scroll_margin
17508 && CHARPOS (start) > BEGV)
17509 /* Old redisplay didn't take scroll margin into account at the bottom,
17510 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17511 || (w->cursor.y + (make_cursor_line_fully_visible_p
17512 ? cursor_height + this_scroll_margin
17513 : 1)) > it.last_visible_y)
17515 w->cursor.vpos = -1;
17516 clear_glyph_matrix (w->desired_matrix);
17517 return -1;
17521 /* Scroll the display. Do it before changing the current matrix so
17522 that xterm.c doesn't get confused about where the cursor glyph is
17523 found. */
17524 if (dy && run.height)
17526 update_begin (f);
17528 if (FRAME_WINDOW_P (f))
17530 FRAME_RIF (f)->update_window_begin_hook (w);
17531 FRAME_RIF (f)->clear_window_mouse_face (w);
17532 FRAME_RIF (f)->scroll_run_hook (w, &run);
17533 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17535 else
17537 /* Terminal frame. In this case, dvpos gives the number of
17538 lines to scroll by; dvpos < 0 means scroll up. */
17539 int from_vpos
17540 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17541 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17542 int end = (WINDOW_TOP_EDGE_LINE (w)
17543 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17544 + window_internal_height (w));
17546 #if defined (HAVE_GPM) || defined (MSDOS)
17547 x_clear_window_mouse_face (w);
17548 #endif
17549 /* Perform the operation on the screen. */
17550 if (dvpos > 0)
17552 /* Scroll last_unchanged_at_beg_row to the end of the
17553 window down dvpos lines. */
17554 set_terminal_window (f, end);
17556 /* On dumb terminals delete dvpos lines at the end
17557 before inserting dvpos empty lines. */
17558 if (!FRAME_SCROLL_REGION_OK (f))
17559 ins_del_lines (f, end - dvpos, -dvpos);
17561 /* Insert dvpos empty lines in front of
17562 last_unchanged_at_beg_row. */
17563 ins_del_lines (f, from, dvpos);
17565 else if (dvpos < 0)
17567 /* Scroll up last_unchanged_at_beg_vpos to the end of
17568 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17569 set_terminal_window (f, end);
17571 /* Delete dvpos lines in front of
17572 last_unchanged_at_beg_vpos. ins_del_lines will set
17573 the cursor to the given vpos and emit |dvpos| delete
17574 line sequences. */
17575 ins_del_lines (f, from + dvpos, dvpos);
17577 /* On a dumb terminal insert dvpos empty lines at the
17578 end. */
17579 if (!FRAME_SCROLL_REGION_OK (f))
17580 ins_del_lines (f, end + dvpos, -dvpos);
17583 set_terminal_window (f, 0);
17586 update_end (f);
17589 /* Shift reused rows of the current matrix to the right position.
17590 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17591 text. */
17592 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17593 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17594 if (dvpos < 0)
17596 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17597 bottom_vpos, dvpos);
17598 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17599 bottom_vpos);
17601 else if (dvpos > 0)
17603 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17604 bottom_vpos, dvpos);
17605 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17606 first_unchanged_at_end_vpos + dvpos);
17609 /* For frame-based redisplay, make sure that current frame and window
17610 matrix are in sync with respect to glyph memory. */
17611 if (!FRAME_WINDOW_P (f))
17612 sync_frame_with_window_matrix_rows (w);
17614 /* Adjust buffer positions in reused rows. */
17615 if (delta || delta_bytes)
17616 increment_matrix_positions (current_matrix,
17617 first_unchanged_at_end_vpos + dvpos,
17618 bottom_vpos, delta, delta_bytes);
17620 /* Adjust Y positions. */
17621 if (dy)
17622 shift_glyph_matrix (w, current_matrix,
17623 first_unchanged_at_end_vpos + dvpos,
17624 bottom_vpos, dy);
17626 if (first_unchanged_at_end_row)
17628 first_unchanged_at_end_row += dvpos;
17629 if (first_unchanged_at_end_row->y >= it.last_visible_y
17630 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17631 first_unchanged_at_end_row = NULL;
17634 /* If scrolling up, there may be some lines to display at the end of
17635 the window. */
17636 last_text_row_at_end = NULL;
17637 if (dy < 0)
17639 /* Scrolling up can leave for example a partially visible line
17640 at the end of the window to be redisplayed. */
17641 /* Set last_row to the glyph row in the current matrix where the
17642 window end line is found. It has been moved up or down in
17643 the matrix by dvpos. */
17644 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17645 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17647 /* If last_row is the window end line, it should display text. */
17648 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
17650 /* If window end line was partially visible before, begin
17651 displaying at that line. Otherwise begin displaying with the
17652 line following it. */
17653 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17655 init_to_row_start (&it, w, last_row);
17656 it.vpos = last_vpos;
17657 it.current_y = last_row->y;
17659 else
17661 init_to_row_end (&it, w, last_row);
17662 it.vpos = 1 + last_vpos;
17663 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17664 ++last_row;
17667 /* We may start in a continuation line. If so, we have to
17668 get the right continuation_lines_width and current_x. */
17669 it.continuation_lines_width = last_row->continuation_lines_width;
17670 it.hpos = it.current_x = 0;
17672 /* Display the rest of the lines at the window end. */
17673 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17674 while (it.current_y < it.last_visible_y
17675 && !fonts_changed_p)
17677 /* Is it always sure that the display agrees with lines in
17678 the current matrix? I don't think so, so we mark rows
17679 displayed invalid in the current matrix by setting their
17680 enabled_p flag to zero. */
17681 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17682 if (display_line (&it))
17683 last_text_row_at_end = it.glyph_row - 1;
17687 /* Update window_end_pos and window_end_vpos. */
17688 if (first_unchanged_at_end_row
17689 && !last_text_row_at_end)
17691 /* Window end line if one of the preserved rows from the current
17692 matrix. Set row to the last row displaying text in current
17693 matrix starting at first_unchanged_at_end_row, after
17694 scrolling. */
17695 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17696 row = find_last_row_displaying_text (w->current_matrix, &it,
17697 first_unchanged_at_end_row);
17698 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17700 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17701 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17702 wset_window_end_vpos
17703 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17704 eassert (w->window_end_bytepos >= 0);
17705 IF_DEBUG (debug_method_add (w, "A"));
17707 else if (last_text_row_at_end)
17709 wset_window_end_pos
17710 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17711 w->window_end_bytepos
17712 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17713 wset_window_end_vpos
17714 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17715 desired_matrix)));
17716 eassert (w->window_end_bytepos >= 0);
17717 IF_DEBUG (debug_method_add (w, "B"));
17719 else if (last_text_row)
17721 /* We have displayed either to the end of the window or at the
17722 end of the window, i.e. the last row with text is to be found
17723 in the desired matrix. */
17724 wset_window_end_pos
17725 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17726 w->window_end_bytepos
17727 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17728 wset_window_end_vpos
17729 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17730 eassert (w->window_end_bytepos >= 0);
17732 else if (first_unchanged_at_end_row == NULL
17733 && last_text_row == NULL
17734 && last_text_row_at_end == NULL)
17736 /* Displayed to end of window, but no line containing text was
17737 displayed. Lines were deleted at the end of the window. */
17738 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17739 int vpos = XFASTINT (w->window_end_vpos);
17740 struct glyph_row *current_row = current_matrix->rows + vpos;
17741 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17743 for (row = NULL;
17744 row == NULL && vpos >= first_vpos;
17745 --vpos, --current_row, --desired_row)
17747 if (desired_row->enabled_p)
17749 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
17750 row = desired_row;
17752 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
17753 row = current_row;
17756 eassert (row != NULL);
17757 wset_window_end_vpos (w, make_number (vpos + 1));
17758 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17759 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17760 eassert (w->window_end_bytepos >= 0);
17761 IF_DEBUG (debug_method_add (w, "C"));
17763 else
17764 emacs_abort ();
17766 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17767 debug_end_vpos = XFASTINT (w->window_end_vpos));
17769 /* Record that display has not been completed. */
17770 w->window_end_valid = 0;
17771 w->desired_matrix->no_scrolling_p = 1;
17772 return 3;
17774 #undef GIVE_UP
17779 /***********************************************************************
17780 More debugging support
17781 ***********************************************************************/
17783 #ifdef GLYPH_DEBUG
17785 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17786 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17787 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17790 /* Dump the contents of glyph matrix MATRIX on stderr.
17792 GLYPHS 0 means don't show glyph contents.
17793 GLYPHS 1 means show glyphs in short form
17794 GLYPHS > 1 means show glyphs in long form. */
17796 void
17797 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17799 int i;
17800 for (i = 0; i < matrix->nrows; ++i)
17801 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17805 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17806 the glyph row and area where the glyph comes from. */
17808 void
17809 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17811 if (glyph->type == CHAR_GLYPH
17812 || glyph->type == GLYPHLESS_GLYPH)
17814 fprintf (stderr,
17815 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17816 glyph - row->glyphs[TEXT_AREA],
17817 (glyph->type == CHAR_GLYPH
17818 ? 'C'
17819 : 'G'),
17820 glyph->charpos,
17821 (BUFFERP (glyph->object)
17822 ? 'B'
17823 : (STRINGP (glyph->object)
17824 ? 'S'
17825 : (INTEGERP (glyph->object)
17826 ? '0'
17827 : '-'))),
17828 glyph->pixel_width,
17829 glyph->u.ch,
17830 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17831 ? glyph->u.ch
17832 : '.'),
17833 glyph->face_id,
17834 glyph->left_box_line_p,
17835 glyph->right_box_line_p);
17837 else if (glyph->type == STRETCH_GLYPH)
17839 fprintf (stderr,
17840 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17841 glyph - row->glyphs[TEXT_AREA],
17842 'S',
17843 glyph->charpos,
17844 (BUFFERP (glyph->object)
17845 ? 'B'
17846 : (STRINGP (glyph->object)
17847 ? 'S'
17848 : (INTEGERP (glyph->object)
17849 ? '0'
17850 : '-'))),
17851 glyph->pixel_width,
17853 ' ',
17854 glyph->face_id,
17855 glyph->left_box_line_p,
17856 glyph->right_box_line_p);
17858 else if (glyph->type == IMAGE_GLYPH)
17860 fprintf (stderr,
17861 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
17862 glyph - row->glyphs[TEXT_AREA],
17863 'I',
17864 glyph->charpos,
17865 (BUFFERP (glyph->object)
17866 ? 'B'
17867 : (STRINGP (glyph->object)
17868 ? 'S'
17869 : (INTEGERP (glyph->object)
17870 ? '0'
17871 : '-'))),
17872 glyph->pixel_width,
17873 glyph->u.img_id,
17874 '.',
17875 glyph->face_id,
17876 glyph->left_box_line_p,
17877 glyph->right_box_line_p);
17879 else if (glyph->type == COMPOSITE_GLYPH)
17881 fprintf (stderr,
17882 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
17883 glyph - row->glyphs[TEXT_AREA],
17884 '+',
17885 glyph->charpos,
17886 (BUFFERP (glyph->object)
17887 ? 'B'
17888 : (STRINGP (glyph->object)
17889 ? 'S'
17890 : (INTEGERP (glyph->object)
17891 ? '0'
17892 : '-'))),
17893 glyph->pixel_width,
17894 glyph->u.cmp.id);
17895 if (glyph->u.cmp.automatic)
17896 fprintf (stderr,
17897 "[%d-%d]",
17898 glyph->slice.cmp.from, glyph->slice.cmp.to);
17899 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17900 glyph->face_id,
17901 glyph->left_box_line_p,
17902 glyph->right_box_line_p);
17907 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17908 GLYPHS 0 means don't show glyph contents.
17909 GLYPHS 1 means show glyphs in short form
17910 GLYPHS > 1 means show glyphs in long form. */
17912 void
17913 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17915 if (glyphs != 1)
17917 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17918 fprintf (stderr, "==============================================================================\n");
17920 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17921 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17922 vpos,
17923 MATRIX_ROW_START_CHARPOS (row),
17924 MATRIX_ROW_END_CHARPOS (row),
17925 row->used[TEXT_AREA],
17926 row->contains_overlapping_glyphs_p,
17927 row->enabled_p,
17928 row->truncated_on_left_p,
17929 row->truncated_on_right_p,
17930 row->continued_p,
17931 MATRIX_ROW_CONTINUATION_LINE_P (row),
17932 MATRIX_ROW_DISPLAYS_TEXT_P (row),
17933 row->ends_at_zv_p,
17934 row->fill_line_p,
17935 row->ends_in_middle_of_char_p,
17936 row->starts_in_middle_of_char_p,
17937 row->mouse_face_p,
17938 row->x,
17939 row->y,
17940 row->pixel_width,
17941 row->height,
17942 row->visible_height,
17943 row->ascent,
17944 row->phys_ascent);
17945 /* The next 3 lines should align to "Start" in the header. */
17946 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
17947 row->end.overlay_string_index,
17948 row->continuation_lines_width);
17949 fprintf (stderr, " %9"pI"d %9"pI"d\n",
17950 CHARPOS (row->start.string_pos),
17951 CHARPOS (row->end.string_pos));
17952 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
17953 row->end.dpvec_index);
17956 if (glyphs > 1)
17958 int area;
17960 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17962 struct glyph *glyph = row->glyphs[area];
17963 struct glyph *glyph_end = glyph + row->used[area];
17965 /* Glyph for a line end in text. */
17966 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17967 ++glyph_end;
17969 if (glyph < glyph_end)
17970 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
17972 for (; glyph < glyph_end; ++glyph)
17973 dump_glyph (row, glyph, area);
17976 else if (glyphs == 1)
17978 int area;
17980 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17982 char *s = alloca (row->used[area] + 4);
17983 int i;
17985 for (i = 0; i < row->used[area]; ++i)
17987 struct glyph *glyph = row->glyphs[area] + i;
17988 if (i == row->used[area] - 1
17989 && area == TEXT_AREA
17990 && INTEGERP (glyph->object)
17991 && glyph->type == CHAR_GLYPH
17992 && glyph->u.ch == ' ')
17994 strcpy (&s[i], "[\\n]");
17995 i += 4;
17997 else if (glyph->type == CHAR_GLYPH
17998 && glyph->u.ch < 0x80
17999 && glyph->u.ch >= ' ')
18000 s[i] = glyph->u.ch;
18001 else
18002 s[i] = '.';
18005 s[i] = '\0';
18006 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18012 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18013 Sdump_glyph_matrix, 0, 1, "p",
18014 doc: /* Dump the current matrix of the selected window to stderr.
18015 Shows contents of glyph row structures. With non-nil
18016 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18017 glyphs in short form, otherwise show glyphs in long form. */)
18018 (Lisp_Object glyphs)
18020 struct window *w = XWINDOW (selected_window);
18021 struct buffer *buffer = XBUFFER (w->contents);
18023 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18024 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18025 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18026 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18027 fprintf (stderr, "=============================================\n");
18028 dump_glyph_matrix (w->current_matrix,
18029 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18030 return Qnil;
18034 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18035 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18036 (void)
18038 struct frame *f = XFRAME (selected_frame);
18039 dump_glyph_matrix (f->current_matrix, 1);
18040 return Qnil;
18044 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18045 doc: /* Dump glyph row ROW to stderr.
18046 GLYPH 0 means don't dump glyphs.
18047 GLYPH 1 means dump glyphs in short form.
18048 GLYPH > 1 or omitted means dump glyphs in long form. */)
18049 (Lisp_Object row, Lisp_Object glyphs)
18051 struct glyph_matrix *matrix;
18052 EMACS_INT vpos;
18054 CHECK_NUMBER (row);
18055 matrix = XWINDOW (selected_window)->current_matrix;
18056 vpos = XINT (row);
18057 if (vpos >= 0 && vpos < matrix->nrows)
18058 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18059 vpos,
18060 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18061 return Qnil;
18065 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18066 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18067 GLYPH 0 means don't dump glyphs.
18068 GLYPH 1 means dump glyphs in short form.
18069 GLYPH > 1 or omitted means dump glyphs in long form. */)
18070 (Lisp_Object row, Lisp_Object glyphs)
18072 struct frame *sf = SELECTED_FRAME ();
18073 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18074 EMACS_INT vpos;
18076 CHECK_NUMBER (row);
18077 vpos = XINT (row);
18078 if (vpos >= 0 && vpos < m->nrows)
18079 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18080 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18081 return Qnil;
18085 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18086 doc: /* Toggle tracing of redisplay.
18087 With ARG, turn tracing on if and only if ARG is positive. */)
18088 (Lisp_Object arg)
18090 if (NILP (arg))
18091 trace_redisplay_p = !trace_redisplay_p;
18092 else
18094 arg = Fprefix_numeric_value (arg);
18095 trace_redisplay_p = XINT (arg) > 0;
18098 return Qnil;
18102 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18103 doc: /* Like `format', but print result to stderr.
18104 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18105 (ptrdiff_t nargs, Lisp_Object *args)
18107 Lisp_Object s = Fformat (nargs, args);
18108 fprintf (stderr, "%s", SDATA (s));
18109 return Qnil;
18112 #endif /* GLYPH_DEBUG */
18116 /***********************************************************************
18117 Building Desired Matrix Rows
18118 ***********************************************************************/
18120 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18121 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18123 static struct glyph_row *
18124 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18126 struct frame *f = XFRAME (WINDOW_FRAME (w));
18127 struct buffer *buffer = XBUFFER (w->contents);
18128 struct buffer *old = current_buffer;
18129 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18130 int arrow_len = SCHARS (overlay_arrow_string);
18131 const unsigned char *arrow_end = arrow_string + arrow_len;
18132 const unsigned char *p;
18133 struct it it;
18134 bool multibyte_p;
18135 int n_glyphs_before;
18137 set_buffer_temp (buffer);
18138 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18139 it.glyph_row->used[TEXT_AREA] = 0;
18140 SET_TEXT_POS (it.position, 0, 0);
18142 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18143 p = arrow_string;
18144 while (p < arrow_end)
18146 Lisp_Object face, ilisp;
18148 /* Get the next character. */
18149 if (multibyte_p)
18150 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18151 else
18153 it.c = it.char_to_display = *p, it.len = 1;
18154 if (! ASCII_CHAR_P (it.c))
18155 it.char_to_display = BYTE8_TO_CHAR (it.c);
18157 p += it.len;
18159 /* Get its face. */
18160 ilisp = make_number (p - arrow_string);
18161 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18162 it.face_id = compute_char_face (f, it.char_to_display, face);
18164 /* Compute its width, get its glyphs. */
18165 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18166 SET_TEXT_POS (it.position, -1, -1);
18167 PRODUCE_GLYPHS (&it);
18169 /* If this character doesn't fit any more in the line, we have
18170 to remove some glyphs. */
18171 if (it.current_x > it.last_visible_x)
18173 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18174 break;
18178 set_buffer_temp (old);
18179 return it.glyph_row;
18183 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18184 glyphs to insert is determined by produce_special_glyphs. */
18186 static void
18187 insert_left_trunc_glyphs (struct it *it)
18189 struct it truncate_it;
18190 struct glyph *from, *end, *to, *toend;
18192 eassert (!FRAME_WINDOW_P (it->f)
18193 || (!it->glyph_row->reversed_p
18194 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18195 || (it->glyph_row->reversed_p
18196 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18198 /* Get the truncation glyphs. */
18199 truncate_it = *it;
18200 truncate_it.current_x = 0;
18201 truncate_it.face_id = DEFAULT_FACE_ID;
18202 truncate_it.glyph_row = &scratch_glyph_row;
18203 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18204 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18205 truncate_it.object = make_number (0);
18206 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18208 /* Overwrite glyphs from IT with truncation glyphs. */
18209 if (!it->glyph_row->reversed_p)
18211 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18213 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18214 end = from + tused;
18215 to = it->glyph_row->glyphs[TEXT_AREA];
18216 toend = to + it->glyph_row->used[TEXT_AREA];
18217 if (FRAME_WINDOW_P (it->f))
18219 /* On GUI frames, when variable-size fonts are displayed,
18220 the truncation glyphs may need more pixels than the row's
18221 glyphs they overwrite. We overwrite more glyphs to free
18222 enough screen real estate, and enlarge the stretch glyph
18223 on the right (see display_line), if there is one, to
18224 preserve the screen position of the truncation glyphs on
18225 the right. */
18226 int w = 0;
18227 struct glyph *g = to;
18228 short used;
18230 /* The first glyph could be partially visible, in which case
18231 it->glyph_row->x will be negative. But we want the left
18232 truncation glyphs to be aligned at the left margin of the
18233 window, so we override the x coordinate at which the row
18234 will begin. */
18235 it->glyph_row->x = 0;
18236 while (g < toend && w < it->truncation_pixel_width)
18238 w += g->pixel_width;
18239 ++g;
18241 if (g - to - tused > 0)
18243 memmove (to + tused, g, (toend - g) * sizeof(*g));
18244 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18246 used = it->glyph_row->used[TEXT_AREA];
18247 if (it->glyph_row->truncated_on_right_p
18248 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18249 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18250 == STRETCH_GLYPH)
18252 int extra = w - it->truncation_pixel_width;
18254 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18258 while (from < end)
18259 *to++ = *from++;
18261 /* There may be padding glyphs left over. Overwrite them too. */
18262 if (!FRAME_WINDOW_P (it->f))
18264 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18266 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18267 while (from < end)
18268 *to++ = *from++;
18272 if (to > toend)
18273 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18275 else
18277 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18279 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18280 that back to front. */
18281 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18282 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18283 toend = it->glyph_row->glyphs[TEXT_AREA];
18284 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18285 if (FRAME_WINDOW_P (it->f))
18287 int w = 0;
18288 struct glyph *g = to;
18290 while (g >= toend && w < it->truncation_pixel_width)
18292 w += g->pixel_width;
18293 --g;
18295 if (to - g - tused > 0)
18296 to = g + tused;
18297 if (it->glyph_row->truncated_on_right_p
18298 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18299 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18301 int extra = w - it->truncation_pixel_width;
18303 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18307 while (from >= end && to >= toend)
18308 *to-- = *from--;
18309 if (!FRAME_WINDOW_P (it->f))
18311 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18313 from =
18314 truncate_it.glyph_row->glyphs[TEXT_AREA]
18315 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18316 while (from >= end && to >= toend)
18317 *to-- = *from--;
18320 if (from >= end)
18322 /* Need to free some room before prepending additional
18323 glyphs. */
18324 int move_by = from - end + 1;
18325 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18326 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18328 for ( ; g >= g0; g--)
18329 g[move_by] = *g;
18330 while (from >= end)
18331 *to-- = *from--;
18332 it->glyph_row->used[TEXT_AREA] += move_by;
18337 /* Compute the hash code for ROW. */
18338 unsigned
18339 row_hash (struct glyph_row *row)
18341 int area, k;
18342 unsigned hashval = 0;
18344 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18345 for (k = 0; k < row->used[area]; ++k)
18346 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18347 + row->glyphs[area][k].u.val
18348 + row->glyphs[area][k].face_id
18349 + row->glyphs[area][k].padding_p
18350 + (row->glyphs[area][k].type << 2));
18352 return hashval;
18355 /* Compute the pixel height and width of IT->glyph_row.
18357 Most of the time, ascent and height of a display line will be equal
18358 to the max_ascent and max_height values of the display iterator
18359 structure. This is not the case if
18361 1. We hit ZV without displaying anything. In this case, max_ascent
18362 and max_height will be zero.
18364 2. We have some glyphs that don't contribute to the line height.
18365 (The glyph row flag contributes_to_line_height_p is for future
18366 pixmap extensions).
18368 The first case is easily covered by using default values because in
18369 these cases, the line height does not really matter, except that it
18370 must not be zero. */
18372 static void
18373 compute_line_metrics (struct it *it)
18375 struct glyph_row *row = it->glyph_row;
18377 if (FRAME_WINDOW_P (it->f))
18379 int i, min_y, max_y;
18381 /* The line may consist of one space only, that was added to
18382 place the cursor on it. If so, the row's height hasn't been
18383 computed yet. */
18384 if (row->height == 0)
18386 if (it->max_ascent + it->max_descent == 0)
18387 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18388 row->ascent = it->max_ascent;
18389 row->height = it->max_ascent + it->max_descent;
18390 row->phys_ascent = it->max_phys_ascent;
18391 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18392 row->extra_line_spacing = it->max_extra_line_spacing;
18395 /* Compute the width of this line. */
18396 row->pixel_width = row->x;
18397 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18398 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18400 eassert (row->pixel_width >= 0);
18401 eassert (row->ascent >= 0 && row->height > 0);
18403 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18404 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18406 /* If first line's physical ascent is larger than its logical
18407 ascent, use the physical ascent, and make the row taller.
18408 This makes accented characters fully visible. */
18409 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18410 && row->phys_ascent > row->ascent)
18412 row->height += row->phys_ascent - row->ascent;
18413 row->ascent = row->phys_ascent;
18416 /* Compute how much of the line is visible. */
18417 row->visible_height = row->height;
18419 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18420 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18422 if (row->y < min_y)
18423 row->visible_height -= min_y - row->y;
18424 if (row->y + row->height > max_y)
18425 row->visible_height -= row->y + row->height - max_y;
18427 else
18429 row->pixel_width = row->used[TEXT_AREA];
18430 if (row->continued_p)
18431 row->pixel_width -= it->continuation_pixel_width;
18432 else if (row->truncated_on_right_p)
18433 row->pixel_width -= it->truncation_pixel_width;
18434 row->ascent = row->phys_ascent = 0;
18435 row->height = row->phys_height = row->visible_height = 1;
18436 row->extra_line_spacing = 0;
18439 /* Compute a hash code for this row. */
18440 row->hash = row_hash (row);
18442 it->max_ascent = it->max_descent = 0;
18443 it->max_phys_ascent = it->max_phys_descent = 0;
18447 /* Append one space to the glyph row of iterator IT if doing a
18448 window-based redisplay. The space has the same face as
18449 IT->face_id. Value is non-zero if a space was added.
18451 This function is called to make sure that there is always one glyph
18452 at the end of a glyph row that the cursor can be set on under
18453 window-systems. (If there weren't such a glyph we would not know
18454 how wide and tall a box cursor should be displayed).
18456 At the same time this space let's a nicely handle clearing to the
18457 end of the line if the row ends in italic text. */
18459 static int
18460 append_space_for_newline (struct it *it, int default_face_p)
18462 if (FRAME_WINDOW_P (it->f))
18464 int n = it->glyph_row->used[TEXT_AREA];
18466 if (it->glyph_row->glyphs[TEXT_AREA] + n
18467 < it->glyph_row->glyphs[1 + TEXT_AREA])
18469 /* Save some values that must not be changed.
18470 Must save IT->c and IT->len because otherwise
18471 ITERATOR_AT_END_P wouldn't work anymore after
18472 append_space_for_newline has been called. */
18473 enum display_element_type saved_what = it->what;
18474 int saved_c = it->c, saved_len = it->len;
18475 int saved_char_to_display = it->char_to_display;
18476 int saved_x = it->current_x;
18477 int saved_face_id = it->face_id;
18478 int saved_box_end = it->end_of_box_run_p;
18479 struct text_pos saved_pos;
18480 Lisp_Object saved_object;
18481 struct face *face;
18483 saved_object = it->object;
18484 saved_pos = it->position;
18486 it->what = IT_CHARACTER;
18487 memset (&it->position, 0, sizeof it->position);
18488 it->object = make_number (0);
18489 it->c = it->char_to_display = ' ';
18490 it->len = 1;
18492 /* If the default face was remapped, be sure to use the
18493 remapped face for the appended newline. */
18494 if (default_face_p)
18495 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18496 else if (it->face_before_selective_p)
18497 it->face_id = it->saved_face_id;
18498 face = FACE_FROM_ID (it->f, it->face_id);
18499 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18500 /* In R2L rows, we will prepend a stretch glyph that will
18501 have the end_of_box_run_p flag set for it, so there's no
18502 need for the appended newline glyph to have that flag
18503 set. */
18504 if (it->glyph_row->reversed_p
18505 /* But if the appended newline glyph goes all the way to
18506 the end of the row, there will be no stretch glyph,
18507 so leave the box flag set. */
18508 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
18509 it->end_of_box_run_p = 0;
18511 PRODUCE_GLYPHS (it);
18513 it->override_ascent = -1;
18514 it->constrain_row_ascent_descent_p = 0;
18515 it->current_x = saved_x;
18516 it->object = saved_object;
18517 it->position = saved_pos;
18518 it->what = saved_what;
18519 it->face_id = saved_face_id;
18520 it->len = saved_len;
18521 it->c = saved_c;
18522 it->char_to_display = saved_char_to_display;
18523 it->end_of_box_run_p = saved_box_end;
18524 return 1;
18528 return 0;
18532 /* Extend the face of the last glyph in the text area of IT->glyph_row
18533 to the end of the display line. Called from display_line. If the
18534 glyph row is empty, add a space glyph to it so that we know the
18535 face to draw. Set the glyph row flag fill_line_p. If the glyph
18536 row is R2L, prepend a stretch glyph to cover the empty space to the
18537 left of the leftmost glyph. */
18539 static void
18540 extend_face_to_end_of_line (struct it *it)
18542 struct face *face, *default_face;
18543 struct frame *f = it->f;
18545 /* If line is already filled, do nothing. Non window-system frames
18546 get a grace of one more ``pixel'' because their characters are
18547 1-``pixel'' wide, so they hit the equality too early. This grace
18548 is needed only for R2L rows that are not continued, to produce
18549 one extra blank where we could display the cursor. */
18550 if (it->current_x >= it->last_visible_x
18551 + (!FRAME_WINDOW_P (f)
18552 && it->glyph_row->reversed_p
18553 && !it->glyph_row->continued_p))
18554 return;
18556 /* The default face, possibly remapped. */
18557 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18559 /* Face extension extends the background and box of IT->face_id
18560 to the end of the line. If the background equals the background
18561 of the frame, we don't have to do anything. */
18562 if (it->face_before_selective_p)
18563 face = FACE_FROM_ID (f, it->saved_face_id);
18564 else
18565 face = FACE_FROM_ID (f, it->face_id);
18567 if (FRAME_WINDOW_P (f)
18568 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
18569 && face->box == FACE_NO_BOX
18570 && face->background == FRAME_BACKGROUND_PIXEL (f)
18571 && !face->stipple
18572 && !it->glyph_row->reversed_p)
18573 return;
18575 /* Set the glyph row flag indicating that the face of the last glyph
18576 in the text area has to be drawn to the end of the text area. */
18577 it->glyph_row->fill_line_p = 1;
18579 /* If current character of IT is not ASCII, make sure we have the
18580 ASCII face. This will be automatically undone the next time
18581 get_next_display_element returns a multibyte character. Note
18582 that the character will always be single byte in unibyte
18583 text. */
18584 if (!ASCII_CHAR_P (it->c))
18586 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18589 if (FRAME_WINDOW_P (f))
18591 /* If the row is empty, add a space with the current face of IT,
18592 so that we know which face to draw. */
18593 if (it->glyph_row->used[TEXT_AREA] == 0)
18595 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18596 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18597 it->glyph_row->used[TEXT_AREA] = 1;
18599 #ifdef HAVE_WINDOW_SYSTEM
18600 if (it->glyph_row->reversed_p)
18602 /* Prepend a stretch glyph to the row, such that the
18603 rightmost glyph will be drawn flushed all the way to the
18604 right margin of the window. The stretch glyph that will
18605 occupy the empty space, if any, to the left of the
18606 glyphs. */
18607 struct font *font = face->font ? face->font : FRAME_FONT (f);
18608 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18609 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18610 struct glyph *g;
18611 int row_width, stretch_ascent, stretch_width;
18612 struct text_pos saved_pos;
18613 int saved_face_id, saved_avoid_cursor, saved_box_start;
18615 for (row_width = 0, g = row_start; g < row_end; g++)
18616 row_width += g->pixel_width;
18617 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18618 if (stretch_width > 0)
18620 stretch_ascent =
18621 (((it->ascent + it->descent)
18622 * FONT_BASE (font)) / FONT_HEIGHT (font));
18623 saved_pos = it->position;
18624 memset (&it->position, 0, sizeof it->position);
18625 saved_avoid_cursor = it->avoid_cursor_p;
18626 it->avoid_cursor_p = 1;
18627 saved_face_id = it->face_id;
18628 saved_box_start = it->start_of_box_run_p;
18629 /* The last row's stretch glyph should get the default
18630 face, to avoid painting the rest of the window with
18631 the region face, if the region ends at ZV. */
18632 if (it->glyph_row->ends_at_zv_p)
18633 it->face_id = default_face->id;
18634 else
18635 it->face_id = face->id;
18636 it->start_of_box_run_p = 0;
18637 append_stretch_glyph (it, make_number (0), stretch_width,
18638 it->ascent + it->descent, stretch_ascent);
18639 it->position = saved_pos;
18640 it->avoid_cursor_p = saved_avoid_cursor;
18641 it->face_id = saved_face_id;
18642 it->start_of_box_run_p = saved_box_start;
18645 #endif /* HAVE_WINDOW_SYSTEM */
18647 else
18649 /* Save some values that must not be changed. */
18650 int saved_x = it->current_x;
18651 struct text_pos saved_pos;
18652 Lisp_Object saved_object;
18653 enum display_element_type saved_what = it->what;
18654 int saved_face_id = it->face_id;
18656 saved_object = it->object;
18657 saved_pos = it->position;
18659 it->what = IT_CHARACTER;
18660 memset (&it->position, 0, sizeof it->position);
18661 it->object = make_number (0);
18662 it->c = it->char_to_display = ' ';
18663 it->len = 1;
18664 /* The last row's blank glyphs should get the default face, to
18665 avoid painting the rest of the window with the region face,
18666 if the region ends at ZV. */
18667 if (it->glyph_row->ends_at_zv_p)
18668 it->face_id = default_face->id;
18669 else
18670 it->face_id = face->id;
18672 PRODUCE_GLYPHS (it);
18674 while (it->current_x <= it->last_visible_x)
18675 PRODUCE_GLYPHS (it);
18677 /* Don't count these blanks really. It would let us insert a left
18678 truncation glyph below and make us set the cursor on them, maybe. */
18679 it->current_x = saved_x;
18680 it->object = saved_object;
18681 it->position = saved_pos;
18682 it->what = saved_what;
18683 it->face_id = saved_face_id;
18688 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18689 trailing whitespace. */
18691 static int
18692 trailing_whitespace_p (ptrdiff_t charpos)
18694 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18695 int c = 0;
18697 while (bytepos < ZV_BYTE
18698 && (c = FETCH_CHAR (bytepos),
18699 c == ' ' || c == '\t'))
18700 ++bytepos;
18702 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18704 if (bytepos != PT_BYTE)
18705 return 1;
18707 return 0;
18711 /* Highlight trailing whitespace, if any, in ROW. */
18713 static void
18714 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18716 int used = row->used[TEXT_AREA];
18718 if (used)
18720 struct glyph *start = row->glyphs[TEXT_AREA];
18721 struct glyph *glyph = start + used - 1;
18723 if (row->reversed_p)
18725 /* Right-to-left rows need to be processed in the opposite
18726 direction, so swap the edge pointers. */
18727 glyph = start;
18728 start = row->glyphs[TEXT_AREA] + used - 1;
18731 /* Skip over glyphs inserted to display the cursor at the
18732 end of a line, for extending the face of the last glyph
18733 to the end of the line on terminals, and for truncation
18734 and continuation glyphs. */
18735 if (!row->reversed_p)
18737 while (glyph >= start
18738 && glyph->type == CHAR_GLYPH
18739 && INTEGERP (glyph->object))
18740 --glyph;
18742 else
18744 while (glyph <= start
18745 && glyph->type == CHAR_GLYPH
18746 && INTEGERP (glyph->object))
18747 ++glyph;
18750 /* If last glyph is a space or stretch, and it's trailing
18751 whitespace, set the face of all trailing whitespace glyphs in
18752 IT->glyph_row to `trailing-whitespace'. */
18753 if ((row->reversed_p ? glyph <= start : glyph >= start)
18754 && BUFFERP (glyph->object)
18755 && (glyph->type == STRETCH_GLYPH
18756 || (glyph->type == CHAR_GLYPH
18757 && glyph->u.ch == ' '))
18758 && trailing_whitespace_p (glyph->charpos))
18760 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18761 if (face_id < 0)
18762 return;
18764 if (!row->reversed_p)
18766 while (glyph >= start
18767 && BUFFERP (glyph->object)
18768 && (glyph->type == STRETCH_GLYPH
18769 || (glyph->type == CHAR_GLYPH
18770 && glyph->u.ch == ' ')))
18771 (glyph--)->face_id = face_id;
18773 else
18775 while (glyph <= start
18776 && BUFFERP (glyph->object)
18777 && (glyph->type == STRETCH_GLYPH
18778 || (glyph->type == CHAR_GLYPH
18779 && glyph->u.ch == ' ')))
18780 (glyph++)->face_id = face_id;
18787 /* Value is non-zero if glyph row ROW should be
18788 considered to hold the buffer position CHARPOS. */
18790 static int
18791 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18793 int result = 1;
18795 if (charpos == CHARPOS (row->end.pos)
18796 || charpos == MATRIX_ROW_END_CHARPOS (row))
18798 /* Suppose the row ends on a string.
18799 Unless the row is continued, that means it ends on a newline
18800 in the string. If it's anything other than a display string
18801 (e.g., a before-string from an overlay), we don't want the
18802 cursor there. (This heuristic seems to give the optimal
18803 behavior for the various types of multi-line strings.)
18804 One exception: if the string has `cursor' property on one of
18805 its characters, we _do_ want the cursor there. */
18806 if (CHARPOS (row->end.string_pos) >= 0)
18808 if (row->continued_p)
18809 result = 1;
18810 else
18812 /* Check for `display' property. */
18813 struct glyph *beg = row->glyphs[TEXT_AREA];
18814 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18815 struct glyph *glyph;
18817 result = 0;
18818 for (glyph = end; glyph >= beg; --glyph)
18819 if (STRINGP (glyph->object))
18821 Lisp_Object prop
18822 = Fget_char_property (make_number (charpos),
18823 Qdisplay, Qnil);
18824 result =
18825 (!NILP (prop)
18826 && display_prop_string_p (prop, glyph->object));
18827 /* If there's a `cursor' property on one of the
18828 string's characters, this row is a cursor row,
18829 even though this is not a display string. */
18830 if (!result)
18832 Lisp_Object s = glyph->object;
18834 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18836 ptrdiff_t gpos = glyph->charpos;
18838 if (!NILP (Fget_char_property (make_number (gpos),
18839 Qcursor, s)))
18841 result = 1;
18842 break;
18846 break;
18850 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18852 /* If the row ends in middle of a real character,
18853 and the line is continued, we want the cursor here.
18854 That's because CHARPOS (ROW->end.pos) would equal
18855 PT if PT is before the character. */
18856 if (!row->ends_in_ellipsis_p)
18857 result = row->continued_p;
18858 else
18859 /* If the row ends in an ellipsis, then
18860 CHARPOS (ROW->end.pos) will equal point after the
18861 invisible text. We want that position to be displayed
18862 after the ellipsis. */
18863 result = 0;
18865 /* If the row ends at ZV, display the cursor at the end of that
18866 row instead of at the start of the row below. */
18867 else if (row->ends_at_zv_p)
18868 result = 1;
18869 else
18870 result = 0;
18873 return result;
18876 /* Value is non-zero if glyph row ROW should be
18877 used to hold the cursor. */
18879 static int
18880 cursor_row_p (struct glyph_row *row)
18882 return row_for_charpos_p (row, PT);
18887 /* Push the property PROP so that it will be rendered at the current
18888 position in IT. Return 1 if PROP was successfully pushed, 0
18889 otherwise. Called from handle_line_prefix to handle the
18890 `line-prefix' and `wrap-prefix' properties. */
18892 static int
18893 push_prefix_prop (struct it *it, Lisp_Object prop)
18895 struct text_pos pos =
18896 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18898 eassert (it->method == GET_FROM_BUFFER
18899 || it->method == GET_FROM_DISPLAY_VECTOR
18900 || it->method == GET_FROM_STRING);
18902 /* We need to save the current buffer/string position, so it will be
18903 restored by pop_it, because iterate_out_of_display_property
18904 depends on that being set correctly, but some situations leave
18905 it->position not yet set when this function is called. */
18906 push_it (it, &pos);
18908 if (STRINGP (prop))
18910 if (SCHARS (prop) == 0)
18912 pop_it (it);
18913 return 0;
18916 it->string = prop;
18917 it->string_from_prefix_prop_p = 1;
18918 it->multibyte_p = STRING_MULTIBYTE (it->string);
18919 it->current.overlay_string_index = -1;
18920 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18921 it->end_charpos = it->string_nchars = SCHARS (it->string);
18922 it->method = GET_FROM_STRING;
18923 it->stop_charpos = 0;
18924 it->prev_stop = 0;
18925 it->base_level_stop = 0;
18927 /* Force paragraph direction to be that of the parent
18928 buffer/string. */
18929 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18930 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18931 else
18932 it->paragraph_embedding = L2R;
18934 /* Set up the bidi iterator for this display string. */
18935 if (it->bidi_p)
18937 it->bidi_it.string.lstring = it->string;
18938 it->bidi_it.string.s = NULL;
18939 it->bidi_it.string.schars = it->end_charpos;
18940 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18941 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18942 it->bidi_it.string.unibyte = !it->multibyte_p;
18943 it->bidi_it.w = it->w;
18944 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18947 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18949 it->method = GET_FROM_STRETCH;
18950 it->object = prop;
18952 #ifdef HAVE_WINDOW_SYSTEM
18953 else if (IMAGEP (prop))
18955 it->what = IT_IMAGE;
18956 it->image_id = lookup_image (it->f, prop);
18957 it->method = GET_FROM_IMAGE;
18959 #endif /* HAVE_WINDOW_SYSTEM */
18960 else
18962 pop_it (it); /* bogus display property, give up */
18963 return 0;
18966 return 1;
18969 /* Return the character-property PROP at the current position in IT. */
18971 static Lisp_Object
18972 get_it_property (struct it *it, Lisp_Object prop)
18974 Lisp_Object position, object = it->object;
18976 if (STRINGP (object))
18977 position = make_number (IT_STRING_CHARPOS (*it));
18978 else if (BUFFERP (object))
18980 position = make_number (IT_CHARPOS (*it));
18981 XSETWINDOW (object, it->w);
18983 else
18984 return Qnil;
18986 return Fget_char_property (position, prop, object);
18989 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18991 static void
18992 handle_line_prefix (struct it *it)
18994 Lisp_Object prefix;
18996 if (it->continuation_lines_width > 0)
18998 prefix = get_it_property (it, Qwrap_prefix);
18999 if (NILP (prefix))
19000 prefix = Vwrap_prefix;
19002 else
19004 prefix = get_it_property (it, Qline_prefix);
19005 if (NILP (prefix))
19006 prefix = Vline_prefix;
19008 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19010 /* If the prefix is wider than the window, and we try to wrap
19011 it, it would acquire its own wrap prefix, and so on till the
19012 iterator stack overflows. So, don't wrap the prefix. */
19013 it->line_wrap = TRUNCATE;
19014 it->avoid_cursor_p = 1;
19020 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19021 only for R2L lines from display_line and display_string, when they
19022 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19023 the line/string needs to be continued on the next glyph row. */
19024 static void
19025 unproduce_glyphs (struct it *it, int n)
19027 struct glyph *glyph, *end;
19029 eassert (it->glyph_row);
19030 eassert (it->glyph_row->reversed_p);
19031 eassert (it->area == TEXT_AREA);
19032 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19034 if (n > it->glyph_row->used[TEXT_AREA])
19035 n = it->glyph_row->used[TEXT_AREA];
19036 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19037 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19038 for ( ; glyph < end; glyph++)
19039 glyph[-n] = *glyph;
19042 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19043 and ROW->maxpos. */
19044 static void
19045 find_row_edges (struct it *it, struct glyph_row *row,
19046 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19047 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19049 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19050 lines' rows is implemented for bidi-reordered rows. */
19052 /* ROW->minpos is the value of min_pos, the minimal buffer position
19053 we have in ROW, or ROW->start.pos if that is smaller. */
19054 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19055 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19056 else
19057 /* We didn't find buffer positions smaller than ROW->start, or
19058 didn't find _any_ valid buffer positions in any of the glyphs,
19059 so we must trust the iterator's computed positions. */
19060 row->minpos = row->start.pos;
19061 if (max_pos <= 0)
19063 max_pos = CHARPOS (it->current.pos);
19064 max_bpos = BYTEPOS (it->current.pos);
19067 /* Here are the various use-cases for ending the row, and the
19068 corresponding values for ROW->maxpos:
19070 Line ends in a newline from buffer eol_pos + 1
19071 Line is continued from buffer max_pos + 1
19072 Line is truncated on right it->current.pos
19073 Line ends in a newline from string max_pos + 1(*)
19074 (*) + 1 only when line ends in a forward scan
19075 Line is continued from string max_pos
19076 Line is continued from display vector max_pos
19077 Line is entirely from a string min_pos == max_pos
19078 Line is entirely from a display vector min_pos == max_pos
19079 Line that ends at ZV ZV
19081 If you discover other use-cases, please add them here as
19082 appropriate. */
19083 if (row->ends_at_zv_p)
19084 row->maxpos = it->current.pos;
19085 else if (row->used[TEXT_AREA])
19087 int seen_this_string = 0;
19088 struct glyph_row *r1 = row - 1;
19090 /* Did we see the same display string on the previous row? */
19091 if (STRINGP (it->object)
19092 /* this is not the first row */
19093 && row > it->w->desired_matrix->rows
19094 /* previous row is not the header line */
19095 && !r1->mode_line_p
19096 /* previous row also ends in a newline from a string */
19097 && r1->ends_in_newline_from_string_p)
19099 struct glyph *start, *end;
19101 /* Search for the last glyph of the previous row that came
19102 from buffer or string. Depending on whether the row is
19103 L2R or R2L, we need to process it front to back or the
19104 other way round. */
19105 if (!r1->reversed_p)
19107 start = r1->glyphs[TEXT_AREA];
19108 end = start + r1->used[TEXT_AREA];
19109 /* Glyphs inserted by redisplay have an integer (zero)
19110 as their object. */
19111 while (end > start
19112 && INTEGERP ((end - 1)->object)
19113 && (end - 1)->charpos <= 0)
19114 --end;
19115 if (end > start)
19117 if (EQ ((end - 1)->object, it->object))
19118 seen_this_string = 1;
19120 else
19121 /* If all the glyphs of the previous row were inserted
19122 by redisplay, it means the previous row was
19123 produced from a single newline, which is only
19124 possible if that newline came from the same string
19125 as the one which produced this ROW. */
19126 seen_this_string = 1;
19128 else
19130 end = r1->glyphs[TEXT_AREA] - 1;
19131 start = end + r1->used[TEXT_AREA];
19132 while (end < start
19133 && INTEGERP ((end + 1)->object)
19134 && (end + 1)->charpos <= 0)
19135 ++end;
19136 if (end < start)
19138 if (EQ ((end + 1)->object, it->object))
19139 seen_this_string = 1;
19141 else
19142 seen_this_string = 1;
19145 /* Take note of each display string that covers a newline only
19146 once, the first time we see it. This is for when a display
19147 string includes more than one newline in it. */
19148 if (row->ends_in_newline_from_string_p && !seen_this_string)
19150 /* If we were scanning the buffer forward when we displayed
19151 the string, we want to account for at least one buffer
19152 position that belongs to this row (position covered by
19153 the display string), so that cursor positioning will
19154 consider this row as a candidate when point is at the end
19155 of the visual line represented by this row. This is not
19156 required when scanning back, because max_pos will already
19157 have a much larger value. */
19158 if (CHARPOS (row->end.pos) > max_pos)
19159 INC_BOTH (max_pos, max_bpos);
19160 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19162 else if (CHARPOS (it->eol_pos) > 0)
19163 SET_TEXT_POS (row->maxpos,
19164 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19165 else if (row->continued_p)
19167 /* If max_pos is different from IT's current position, it
19168 means IT->method does not belong to the display element
19169 at max_pos. However, it also means that the display
19170 element at max_pos was displayed in its entirety on this
19171 line, which is equivalent to saying that the next line
19172 starts at the next buffer position. */
19173 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19174 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19175 else
19177 INC_BOTH (max_pos, max_bpos);
19178 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19181 else if (row->truncated_on_right_p)
19182 /* display_line already called reseat_at_next_visible_line_start,
19183 which puts the iterator at the beginning of the next line, in
19184 the logical order. */
19185 row->maxpos = it->current.pos;
19186 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19187 /* A line that is entirely from a string/image/stretch... */
19188 row->maxpos = row->minpos;
19189 else
19190 emacs_abort ();
19192 else
19193 row->maxpos = it->current.pos;
19196 /* Construct the glyph row IT->glyph_row in the desired matrix of
19197 IT->w from text at the current position of IT. See dispextern.h
19198 for an overview of struct it. Value is non-zero if
19199 IT->glyph_row displays text, as opposed to a line displaying ZV
19200 only. */
19202 static int
19203 display_line (struct it *it)
19205 struct glyph_row *row = it->glyph_row;
19206 Lisp_Object overlay_arrow_string;
19207 struct it wrap_it;
19208 void *wrap_data = NULL;
19209 int may_wrap = 0, wrap_x IF_LINT (= 0);
19210 int wrap_row_used = -1;
19211 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19212 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19213 int wrap_row_extra_line_spacing IF_LINT (= 0);
19214 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19215 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19216 int cvpos;
19217 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19218 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19220 /* We always start displaying at hpos zero even if hscrolled. */
19221 eassert (it->hpos == 0 && it->current_x == 0);
19223 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19224 >= it->w->desired_matrix->nrows)
19226 it->w->nrows_scale_factor++;
19227 fonts_changed_p = 1;
19228 return 0;
19231 /* Is IT->w showing the region? */
19232 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19234 /* Clear the result glyph row and enable it. */
19235 prepare_desired_row (row);
19237 row->y = it->current_y;
19238 row->start = it->start;
19239 row->continuation_lines_width = it->continuation_lines_width;
19240 row->displays_text_p = 1;
19241 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19242 it->starts_in_middle_of_char_p = 0;
19244 /* Arrange the overlays nicely for our purposes. Usually, we call
19245 display_line on only one line at a time, in which case this
19246 can't really hurt too much, or we call it on lines which appear
19247 one after another in the buffer, in which case all calls to
19248 recenter_overlay_lists but the first will be pretty cheap. */
19249 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19251 /* Move over display elements that are not visible because we are
19252 hscrolled. This may stop at an x-position < IT->first_visible_x
19253 if the first glyph is partially visible or if we hit a line end. */
19254 if (it->current_x < it->first_visible_x)
19256 enum move_it_result move_result;
19258 this_line_min_pos = row->start.pos;
19259 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19260 MOVE_TO_POS | MOVE_TO_X);
19261 /* If we are under a large hscroll, move_it_in_display_line_to
19262 could hit the end of the line without reaching
19263 it->first_visible_x. Pretend that we did reach it. This is
19264 especially important on a TTY, where we will call
19265 extend_face_to_end_of_line, which needs to know how many
19266 blank glyphs to produce. */
19267 if (it->current_x < it->first_visible_x
19268 && (move_result == MOVE_NEWLINE_OR_CR
19269 || move_result == MOVE_POS_MATCH_OR_ZV))
19270 it->current_x = it->first_visible_x;
19272 /* Record the smallest positions seen while we moved over
19273 display elements that are not visible. This is needed by
19274 redisplay_internal for optimizing the case where the cursor
19275 stays inside the same line. The rest of this function only
19276 considers positions that are actually displayed, so
19277 RECORD_MAX_MIN_POS will not otherwise record positions that
19278 are hscrolled to the left of the left edge of the window. */
19279 min_pos = CHARPOS (this_line_min_pos);
19280 min_bpos = BYTEPOS (this_line_min_pos);
19282 else
19284 /* We only do this when not calling `move_it_in_display_line_to'
19285 above, because move_it_in_display_line_to calls
19286 handle_line_prefix itself. */
19287 handle_line_prefix (it);
19290 /* Get the initial row height. This is either the height of the
19291 text hscrolled, if there is any, or zero. */
19292 row->ascent = it->max_ascent;
19293 row->height = it->max_ascent + it->max_descent;
19294 row->phys_ascent = it->max_phys_ascent;
19295 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19296 row->extra_line_spacing = it->max_extra_line_spacing;
19298 /* Utility macro to record max and min buffer positions seen until now. */
19299 #define RECORD_MAX_MIN_POS(IT) \
19300 do \
19302 int composition_p = !STRINGP ((IT)->string) \
19303 && ((IT)->what == IT_COMPOSITION); \
19304 ptrdiff_t current_pos = \
19305 composition_p ? (IT)->cmp_it.charpos \
19306 : IT_CHARPOS (*(IT)); \
19307 ptrdiff_t current_bpos = \
19308 composition_p ? CHAR_TO_BYTE (current_pos) \
19309 : IT_BYTEPOS (*(IT)); \
19310 if (current_pos < min_pos) \
19312 min_pos = current_pos; \
19313 min_bpos = current_bpos; \
19315 if (IT_CHARPOS (*it) > max_pos) \
19317 max_pos = IT_CHARPOS (*it); \
19318 max_bpos = IT_BYTEPOS (*it); \
19321 while (0)
19323 /* Loop generating characters. The loop is left with IT on the next
19324 character to display. */
19325 while (1)
19327 int n_glyphs_before, hpos_before, x_before;
19328 int x, nglyphs;
19329 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19331 /* Retrieve the next thing to display. Value is zero if end of
19332 buffer reached. */
19333 if (!get_next_display_element (it))
19335 /* Maybe add a space at the end of this line that is used to
19336 display the cursor there under X. Set the charpos of the
19337 first glyph of blank lines not corresponding to any text
19338 to -1. */
19339 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19340 row->exact_window_width_line_p = 1;
19341 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19342 || row->used[TEXT_AREA] == 0)
19344 row->glyphs[TEXT_AREA]->charpos = -1;
19345 row->displays_text_p = 0;
19347 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19348 && (!MINI_WINDOW_P (it->w)
19349 || (minibuf_level && EQ (it->window, minibuf_window))))
19350 row->indicate_empty_line_p = 1;
19353 it->continuation_lines_width = 0;
19354 row->ends_at_zv_p = 1;
19355 /* A row that displays right-to-left text must always have
19356 its last face extended all the way to the end of line,
19357 even if this row ends in ZV, because we still write to
19358 the screen left to right. We also need to extend the
19359 last face if the default face is remapped to some
19360 different face, otherwise the functions that clear
19361 portions of the screen will clear with the default face's
19362 background color. */
19363 if (row->reversed_p
19364 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19365 extend_face_to_end_of_line (it);
19366 break;
19369 /* Now, get the metrics of what we want to display. This also
19370 generates glyphs in `row' (which is IT->glyph_row). */
19371 n_glyphs_before = row->used[TEXT_AREA];
19372 x = it->current_x;
19374 /* Remember the line height so far in case the next element doesn't
19375 fit on the line. */
19376 if (it->line_wrap != TRUNCATE)
19378 ascent = it->max_ascent;
19379 descent = it->max_descent;
19380 phys_ascent = it->max_phys_ascent;
19381 phys_descent = it->max_phys_descent;
19383 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19385 if (IT_DISPLAYING_WHITESPACE (it))
19386 may_wrap = 1;
19387 else if (may_wrap)
19389 SAVE_IT (wrap_it, *it, wrap_data);
19390 wrap_x = x;
19391 wrap_row_used = row->used[TEXT_AREA];
19392 wrap_row_ascent = row->ascent;
19393 wrap_row_height = row->height;
19394 wrap_row_phys_ascent = row->phys_ascent;
19395 wrap_row_phys_height = row->phys_height;
19396 wrap_row_extra_line_spacing = row->extra_line_spacing;
19397 wrap_row_min_pos = min_pos;
19398 wrap_row_min_bpos = min_bpos;
19399 wrap_row_max_pos = max_pos;
19400 wrap_row_max_bpos = max_bpos;
19401 may_wrap = 0;
19406 PRODUCE_GLYPHS (it);
19408 /* If this display element was in marginal areas, continue with
19409 the next one. */
19410 if (it->area != TEXT_AREA)
19412 row->ascent = max (row->ascent, it->max_ascent);
19413 row->height = max (row->height, it->max_ascent + it->max_descent);
19414 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19415 row->phys_height = max (row->phys_height,
19416 it->max_phys_ascent + it->max_phys_descent);
19417 row->extra_line_spacing = max (row->extra_line_spacing,
19418 it->max_extra_line_spacing);
19419 set_iterator_to_next (it, 1);
19420 continue;
19423 /* Does the display element fit on the line? If we truncate
19424 lines, we should draw past the right edge of the window. If
19425 we don't truncate, we want to stop so that we can display the
19426 continuation glyph before the right margin. If lines are
19427 continued, there are two possible strategies for characters
19428 resulting in more than 1 glyph (e.g. tabs): Display as many
19429 glyphs as possible in this line and leave the rest for the
19430 continuation line, or display the whole element in the next
19431 line. Original redisplay did the former, so we do it also. */
19432 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19433 hpos_before = it->hpos;
19434 x_before = x;
19436 if (/* Not a newline. */
19437 nglyphs > 0
19438 /* Glyphs produced fit entirely in the line. */
19439 && it->current_x < it->last_visible_x)
19441 it->hpos += nglyphs;
19442 row->ascent = max (row->ascent, it->max_ascent);
19443 row->height = max (row->height, it->max_ascent + it->max_descent);
19444 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19445 row->phys_height = max (row->phys_height,
19446 it->max_phys_ascent + it->max_phys_descent);
19447 row->extra_line_spacing = max (row->extra_line_spacing,
19448 it->max_extra_line_spacing);
19449 if (it->current_x - it->pixel_width < it->first_visible_x)
19450 row->x = x - it->first_visible_x;
19451 /* Record the maximum and minimum buffer positions seen so
19452 far in glyphs that will be displayed by this row. */
19453 if (it->bidi_p)
19454 RECORD_MAX_MIN_POS (it);
19456 else
19458 int i, new_x;
19459 struct glyph *glyph;
19461 for (i = 0; i < nglyphs; ++i, x = new_x)
19463 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19464 new_x = x + glyph->pixel_width;
19466 if (/* Lines are continued. */
19467 it->line_wrap != TRUNCATE
19468 && (/* Glyph doesn't fit on the line. */
19469 new_x > it->last_visible_x
19470 /* Or it fits exactly on a window system frame. */
19471 || (new_x == it->last_visible_x
19472 && FRAME_WINDOW_P (it->f)
19473 && (row->reversed_p
19474 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19475 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19477 /* End of a continued line. */
19479 if (it->hpos == 0
19480 || (new_x == it->last_visible_x
19481 && FRAME_WINDOW_P (it->f)
19482 && (row->reversed_p
19483 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19484 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19486 /* Current glyph is the only one on the line or
19487 fits exactly on the line. We must continue
19488 the line because we can't draw the cursor
19489 after the glyph. */
19490 row->continued_p = 1;
19491 it->current_x = new_x;
19492 it->continuation_lines_width += new_x;
19493 ++it->hpos;
19494 if (i == nglyphs - 1)
19496 /* If line-wrap is on, check if a previous
19497 wrap point was found. */
19498 if (wrap_row_used > 0
19499 /* Even if there is a previous wrap
19500 point, continue the line here as
19501 usual, if (i) the previous character
19502 was a space or tab AND (ii) the
19503 current character is not. */
19504 && (!may_wrap
19505 || IT_DISPLAYING_WHITESPACE (it)))
19506 goto back_to_wrap;
19508 /* Record the maximum and minimum buffer
19509 positions seen so far in glyphs that will be
19510 displayed by this row. */
19511 if (it->bidi_p)
19512 RECORD_MAX_MIN_POS (it);
19513 set_iterator_to_next (it, 1);
19514 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19516 if (!get_next_display_element (it))
19518 row->exact_window_width_line_p = 1;
19519 it->continuation_lines_width = 0;
19520 row->continued_p = 0;
19521 row->ends_at_zv_p = 1;
19523 else if (ITERATOR_AT_END_OF_LINE_P (it))
19525 row->continued_p = 0;
19526 row->exact_window_width_line_p = 1;
19530 else if (it->bidi_p)
19531 RECORD_MAX_MIN_POS (it);
19533 else if (CHAR_GLYPH_PADDING_P (*glyph)
19534 && !FRAME_WINDOW_P (it->f))
19536 /* A padding glyph that doesn't fit on this line.
19537 This means the whole character doesn't fit
19538 on the line. */
19539 if (row->reversed_p)
19540 unproduce_glyphs (it, row->used[TEXT_AREA]
19541 - n_glyphs_before);
19542 row->used[TEXT_AREA] = n_glyphs_before;
19544 /* Fill the rest of the row with continuation
19545 glyphs like in 20.x. */
19546 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19547 < row->glyphs[1 + TEXT_AREA])
19548 produce_special_glyphs (it, IT_CONTINUATION);
19550 row->continued_p = 1;
19551 it->current_x = x_before;
19552 it->continuation_lines_width += x_before;
19554 /* Restore the height to what it was before the
19555 element not fitting on the line. */
19556 it->max_ascent = ascent;
19557 it->max_descent = descent;
19558 it->max_phys_ascent = phys_ascent;
19559 it->max_phys_descent = phys_descent;
19561 else if (wrap_row_used > 0)
19563 back_to_wrap:
19564 if (row->reversed_p)
19565 unproduce_glyphs (it,
19566 row->used[TEXT_AREA] - wrap_row_used);
19567 RESTORE_IT (it, &wrap_it, wrap_data);
19568 it->continuation_lines_width += wrap_x;
19569 row->used[TEXT_AREA] = wrap_row_used;
19570 row->ascent = wrap_row_ascent;
19571 row->height = wrap_row_height;
19572 row->phys_ascent = wrap_row_phys_ascent;
19573 row->phys_height = wrap_row_phys_height;
19574 row->extra_line_spacing = wrap_row_extra_line_spacing;
19575 min_pos = wrap_row_min_pos;
19576 min_bpos = wrap_row_min_bpos;
19577 max_pos = wrap_row_max_pos;
19578 max_bpos = wrap_row_max_bpos;
19579 row->continued_p = 1;
19580 row->ends_at_zv_p = 0;
19581 row->exact_window_width_line_p = 0;
19582 it->continuation_lines_width += x;
19584 /* Make sure that a non-default face is extended
19585 up to the right margin of the window. */
19586 extend_face_to_end_of_line (it);
19588 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19590 /* A TAB that extends past the right edge of the
19591 window. This produces a single glyph on
19592 window system frames. We leave the glyph in
19593 this row and let it fill the row, but don't
19594 consume the TAB. */
19595 if ((row->reversed_p
19596 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19597 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19598 produce_special_glyphs (it, IT_CONTINUATION);
19599 it->continuation_lines_width += it->last_visible_x;
19600 row->ends_in_middle_of_char_p = 1;
19601 row->continued_p = 1;
19602 glyph->pixel_width = it->last_visible_x - x;
19603 it->starts_in_middle_of_char_p = 1;
19605 else
19607 /* Something other than a TAB that draws past
19608 the right edge of the window. Restore
19609 positions to values before the element. */
19610 if (row->reversed_p)
19611 unproduce_glyphs (it, row->used[TEXT_AREA]
19612 - (n_glyphs_before + i));
19613 row->used[TEXT_AREA] = n_glyphs_before + i;
19615 /* Display continuation glyphs. */
19616 it->current_x = x_before;
19617 it->continuation_lines_width += x;
19618 if (!FRAME_WINDOW_P (it->f)
19619 || (row->reversed_p
19620 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19621 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19622 produce_special_glyphs (it, IT_CONTINUATION);
19623 row->continued_p = 1;
19625 extend_face_to_end_of_line (it);
19627 if (nglyphs > 1 && i > 0)
19629 row->ends_in_middle_of_char_p = 1;
19630 it->starts_in_middle_of_char_p = 1;
19633 /* Restore the height to what it was before the
19634 element not fitting on the line. */
19635 it->max_ascent = ascent;
19636 it->max_descent = descent;
19637 it->max_phys_ascent = phys_ascent;
19638 it->max_phys_descent = phys_descent;
19641 break;
19643 else if (new_x > it->first_visible_x)
19645 /* Increment number of glyphs actually displayed. */
19646 ++it->hpos;
19648 /* Record the maximum and minimum buffer positions
19649 seen so far in glyphs that will be displayed by
19650 this row. */
19651 if (it->bidi_p)
19652 RECORD_MAX_MIN_POS (it);
19654 if (x < it->first_visible_x)
19655 /* Glyph is partially visible, i.e. row starts at
19656 negative X position. */
19657 row->x = x - it->first_visible_x;
19659 else
19661 /* Glyph is completely off the left margin of the
19662 window. This should not happen because of the
19663 move_it_in_display_line at the start of this
19664 function, unless the text display area of the
19665 window is empty. */
19666 eassert (it->first_visible_x <= it->last_visible_x);
19669 /* Even if this display element produced no glyphs at all,
19670 we want to record its position. */
19671 if (it->bidi_p && nglyphs == 0)
19672 RECORD_MAX_MIN_POS (it);
19674 row->ascent = max (row->ascent, it->max_ascent);
19675 row->height = max (row->height, it->max_ascent + it->max_descent);
19676 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19677 row->phys_height = max (row->phys_height,
19678 it->max_phys_ascent + it->max_phys_descent);
19679 row->extra_line_spacing = max (row->extra_line_spacing,
19680 it->max_extra_line_spacing);
19682 /* End of this display line if row is continued. */
19683 if (row->continued_p || row->ends_at_zv_p)
19684 break;
19687 at_end_of_line:
19688 /* Is this a line end? If yes, we're also done, after making
19689 sure that a non-default face is extended up to the right
19690 margin of the window. */
19691 if (ITERATOR_AT_END_OF_LINE_P (it))
19693 int used_before = row->used[TEXT_AREA];
19695 row->ends_in_newline_from_string_p = STRINGP (it->object);
19697 /* Add a space at the end of the line that is used to
19698 display the cursor there. */
19699 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19700 append_space_for_newline (it, 0);
19702 /* Extend the face to the end of the line. */
19703 extend_face_to_end_of_line (it);
19705 /* Make sure we have the position. */
19706 if (used_before == 0)
19707 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19709 /* Record the position of the newline, for use in
19710 find_row_edges. */
19711 it->eol_pos = it->current.pos;
19713 /* Consume the line end. This skips over invisible lines. */
19714 set_iterator_to_next (it, 1);
19715 it->continuation_lines_width = 0;
19716 break;
19719 /* Proceed with next display element. Note that this skips
19720 over lines invisible because of selective display. */
19721 set_iterator_to_next (it, 1);
19723 /* If we truncate lines, we are done when the last displayed
19724 glyphs reach past the right margin of the window. */
19725 if (it->line_wrap == TRUNCATE
19726 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19727 ? (it->current_x >= it->last_visible_x)
19728 : (it->current_x > it->last_visible_x)))
19730 /* Maybe add truncation glyphs. */
19731 if (!FRAME_WINDOW_P (it->f)
19732 || (row->reversed_p
19733 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19734 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19736 int i, n;
19738 if (!row->reversed_p)
19740 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19741 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19742 break;
19744 else
19746 for (i = 0; i < row->used[TEXT_AREA]; i++)
19747 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19748 break;
19749 /* Remove any padding glyphs at the front of ROW, to
19750 make room for the truncation glyphs we will be
19751 adding below. The loop below always inserts at
19752 least one truncation glyph, so also remove the
19753 last glyph added to ROW. */
19754 unproduce_glyphs (it, i + 1);
19755 /* Adjust i for the loop below. */
19756 i = row->used[TEXT_AREA] - (i + 1);
19759 it->current_x = x_before;
19760 if (!FRAME_WINDOW_P (it->f))
19762 for (n = row->used[TEXT_AREA]; i < n; ++i)
19764 row->used[TEXT_AREA] = i;
19765 produce_special_glyphs (it, IT_TRUNCATION);
19768 else
19770 row->used[TEXT_AREA] = i;
19771 produce_special_glyphs (it, IT_TRUNCATION);
19774 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19776 /* Don't truncate if we can overflow newline into fringe. */
19777 if (!get_next_display_element (it))
19779 it->continuation_lines_width = 0;
19780 row->ends_at_zv_p = 1;
19781 row->exact_window_width_line_p = 1;
19782 break;
19784 if (ITERATOR_AT_END_OF_LINE_P (it))
19786 row->exact_window_width_line_p = 1;
19787 goto at_end_of_line;
19789 it->current_x = x_before;
19792 row->truncated_on_right_p = 1;
19793 it->continuation_lines_width = 0;
19794 reseat_at_next_visible_line_start (it, 0);
19795 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19796 it->hpos = hpos_before;
19797 break;
19801 if (wrap_data)
19802 bidi_unshelve_cache (wrap_data, 1);
19804 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19805 at the left window margin. */
19806 if (it->first_visible_x
19807 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19809 if (!FRAME_WINDOW_P (it->f)
19810 || (row->reversed_p
19811 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19812 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19813 insert_left_trunc_glyphs (it);
19814 row->truncated_on_left_p = 1;
19817 /* Remember the position at which this line ends.
19819 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19820 cannot be before the call to find_row_edges below, since that is
19821 where these positions are determined. */
19822 row->end = it->current;
19823 if (!it->bidi_p)
19825 row->minpos = row->start.pos;
19826 row->maxpos = row->end.pos;
19828 else
19830 /* ROW->minpos and ROW->maxpos must be the smallest and
19831 `1 + the largest' buffer positions in ROW. But if ROW was
19832 bidi-reordered, these two positions can be anywhere in the
19833 row, so we must determine them now. */
19834 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19837 /* If the start of this line is the overlay arrow-position, then
19838 mark this glyph row as the one containing the overlay arrow.
19839 This is clearly a mess with variable size fonts. It would be
19840 better to let it be displayed like cursors under X. */
19841 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19842 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19843 !NILP (overlay_arrow_string)))
19845 /* Overlay arrow in window redisplay is a fringe bitmap. */
19846 if (STRINGP (overlay_arrow_string))
19848 struct glyph_row *arrow_row
19849 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19850 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19851 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19852 struct glyph *p = row->glyphs[TEXT_AREA];
19853 struct glyph *p2, *end;
19855 /* Copy the arrow glyphs. */
19856 while (glyph < arrow_end)
19857 *p++ = *glyph++;
19859 /* Throw away padding glyphs. */
19860 p2 = p;
19861 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19862 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19863 ++p2;
19864 if (p2 > p)
19866 while (p2 < end)
19867 *p++ = *p2++;
19868 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19871 else
19873 eassert (INTEGERP (overlay_arrow_string));
19874 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19876 overlay_arrow_seen = 1;
19879 /* Highlight trailing whitespace. */
19880 if (!NILP (Vshow_trailing_whitespace))
19881 highlight_trailing_whitespace (it->f, it->glyph_row);
19883 /* Compute pixel dimensions of this line. */
19884 compute_line_metrics (it);
19886 /* Implementation note: No changes in the glyphs of ROW or in their
19887 faces can be done past this point, because compute_line_metrics
19888 computes ROW's hash value and stores it within the glyph_row
19889 structure. */
19891 /* Record whether this row ends inside an ellipsis. */
19892 row->ends_in_ellipsis_p
19893 = (it->method == GET_FROM_DISPLAY_VECTOR
19894 && it->ellipsis_p);
19896 /* Save fringe bitmaps in this row. */
19897 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19898 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19899 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19900 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19902 it->left_user_fringe_bitmap = 0;
19903 it->left_user_fringe_face_id = 0;
19904 it->right_user_fringe_bitmap = 0;
19905 it->right_user_fringe_face_id = 0;
19907 /* Maybe set the cursor. */
19908 cvpos = it->w->cursor.vpos;
19909 if ((cvpos < 0
19910 /* In bidi-reordered rows, keep checking for proper cursor
19911 position even if one has been found already, because buffer
19912 positions in such rows change non-linearly with ROW->VPOS,
19913 when a line is continued. One exception: when we are at ZV,
19914 display cursor on the first suitable glyph row, since all
19915 the empty rows after that also have their position set to ZV. */
19916 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19917 lines' rows is implemented for bidi-reordered rows. */
19918 || (it->bidi_p
19919 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19920 && PT >= MATRIX_ROW_START_CHARPOS (row)
19921 && PT <= MATRIX_ROW_END_CHARPOS (row)
19922 && cursor_row_p (row))
19923 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19925 /* Prepare for the next line. This line starts horizontally at (X
19926 HPOS) = (0 0). Vertical positions are incremented. As a
19927 convenience for the caller, IT->glyph_row is set to the next
19928 row to be used. */
19929 it->current_x = it->hpos = 0;
19930 it->current_y += row->height;
19931 SET_TEXT_POS (it->eol_pos, 0, 0);
19932 ++it->vpos;
19933 ++it->glyph_row;
19934 /* The next row should by default use the same value of the
19935 reversed_p flag as this one. set_iterator_to_next decides when
19936 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19937 the flag accordingly. */
19938 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19939 it->glyph_row->reversed_p = row->reversed_p;
19940 it->start = row->end;
19941 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
19943 #undef RECORD_MAX_MIN_POS
19946 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19947 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19948 doc: /* Return paragraph direction at point in BUFFER.
19949 Value is either `left-to-right' or `right-to-left'.
19950 If BUFFER is omitted or nil, it defaults to the current buffer.
19952 Paragraph direction determines how the text in the paragraph is displayed.
19953 In left-to-right paragraphs, text begins at the left margin of the window
19954 and the reading direction is generally left to right. In right-to-left
19955 paragraphs, text begins at the right margin and is read from right to left.
19957 See also `bidi-paragraph-direction'. */)
19958 (Lisp_Object buffer)
19960 struct buffer *buf = current_buffer;
19961 struct buffer *old = buf;
19963 if (! NILP (buffer))
19965 CHECK_BUFFER (buffer);
19966 buf = XBUFFER (buffer);
19969 if (NILP (BVAR (buf, bidi_display_reordering))
19970 || NILP (BVAR (buf, enable_multibyte_characters))
19971 /* When we are loading loadup.el, the character property tables
19972 needed for bidi iteration are not yet available. */
19973 || !NILP (Vpurify_flag))
19974 return Qleft_to_right;
19975 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19976 return BVAR (buf, bidi_paragraph_direction);
19977 else
19979 /* Determine the direction from buffer text. We could try to
19980 use current_matrix if it is up to date, but this seems fast
19981 enough as it is. */
19982 struct bidi_it itb;
19983 ptrdiff_t pos = BUF_PT (buf);
19984 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
19985 int c;
19986 void *itb_data = bidi_shelve_cache ();
19988 set_buffer_temp (buf);
19989 /* bidi_paragraph_init finds the base direction of the paragraph
19990 by searching forward from paragraph start. We need the base
19991 direction of the current or _previous_ paragraph, so we need
19992 to make sure we are within that paragraph. To that end, find
19993 the previous non-empty line. */
19994 if (pos >= ZV && pos > BEGV)
19995 DEC_BOTH (pos, bytepos);
19996 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19997 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
19999 while ((c = FETCH_BYTE (bytepos)) == '\n'
20000 || c == ' ' || c == '\t' || c == '\f')
20002 if (bytepos <= BEGV_BYTE)
20003 break;
20004 bytepos--;
20005 pos--;
20007 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20008 bytepos--;
20010 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20011 itb.paragraph_dir = NEUTRAL_DIR;
20012 itb.string.s = NULL;
20013 itb.string.lstring = Qnil;
20014 itb.string.bufpos = 0;
20015 itb.string.unibyte = 0;
20016 itb.w = XWINDOW (selected_window);
20017 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20018 bidi_unshelve_cache (itb_data, 0);
20019 set_buffer_temp (old);
20020 switch (itb.paragraph_dir)
20022 case L2R:
20023 return Qleft_to_right;
20024 break;
20025 case R2L:
20026 return Qright_to_left;
20027 break;
20028 default:
20029 emacs_abort ();
20036 /***********************************************************************
20037 Menu Bar
20038 ***********************************************************************/
20040 /* Redisplay the menu bar in the frame for window W.
20042 The menu bar of X frames that don't have X toolkit support is
20043 displayed in a special window W->frame->menu_bar_window.
20045 The menu bar of terminal frames is treated specially as far as
20046 glyph matrices are concerned. Menu bar lines are not part of
20047 windows, so the update is done directly on the frame matrix rows
20048 for the menu bar. */
20050 static void
20051 display_menu_bar (struct window *w)
20053 struct frame *f = XFRAME (WINDOW_FRAME (w));
20054 struct it it;
20055 Lisp_Object items;
20056 int i;
20058 /* Don't do all this for graphical frames. */
20059 #ifdef HAVE_NTGUI
20060 if (FRAME_W32_P (f))
20061 return;
20062 #endif
20063 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20064 if (FRAME_X_P (f))
20065 return;
20066 #endif
20068 #ifdef HAVE_NS
20069 if (FRAME_NS_P (f))
20070 return;
20071 #endif /* HAVE_NS */
20073 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20074 eassert (!FRAME_WINDOW_P (f));
20075 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20076 it.first_visible_x = 0;
20077 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20078 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20079 if (FRAME_WINDOW_P (f))
20081 /* Menu bar lines are displayed in the desired matrix of the
20082 dummy window menu_bar_window. */
20083 struct window *menu_w;
20084 menu_w = XWINDOW (f->menu_bar_window);
20085 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20086 MENU_FACE_ID);
20087 it.first_visible_x = 0;
20088 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20090 else
20091 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20093 /* This is a TTY frame, i.e. character hpos/vpos are used as
20094 pixel x/y. */
20095 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20096 MENU_FACE_ID);
20097 it.first_visible_x = 0;
20098 it.last_visible_x = FRAME_COLS (f);
20101 /* FIXME: This should be controlled by a user option. See the
20102 comments in redisplay_tool_bar and display_mode_line about
20103 this. */
20104 it.paragraph_embedding = L2R;
20106 /* Clear all rows of the menu bar. */
20107 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20109 struct glyph_row *row = it.glyph_row + i;
20110 clear_glyph_row (row);
20111 row->enabled_p = 1;
20112 row->full_width_p = 1;
20115 /* Display all items of the menu bar. */
20116 items = FRAME_MENU_BAR_ITEMS (it.f);
20117 for (i = 0; i < ASIZE (items); i += 4)
20119 Lisp_Object string;
20121 /* Stop at nil string. */
20122 string = AREF (items, i + 1);
20123 if (NILP (string))
20124 break;
20126 /* Remember where item was displayed. */
20127 ASET (items, i + 3, make_number (it.hpos));
20129 /* Display the item, pad with one space. */
20130 if (it.current_x < it.last_visible_x)
20131 display_string (NULL, string, Qnil, 0, 0, &it,
20132 SCHARS (string) + 1, 0, 0, -1);
20135 /* Fill out the line with spaces. */
20136 if (it.current_x < it.last_visible_x)
20137 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20139 /* Compute the total height of the lines. */
20140 compute_line_metrics (&it);
20145 /***********************************************************************
20146 Mode Line
20147 ***********************************************************************/
20149 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20150 FORCE is non-zero, redisplay mode lines unconditionally.
20151 Otherwise, redisplay only mode lines that are garbaged. Value is
20152 the number of windows whose mode lines were redisplayed. */
20154 static int
20155 redisplay_mode_lines (Lisp_Object window, int force)
20157 int nwindows = 0;
20159 while (!NILP (window))
20161 struct window *w = XWINDOW (window);
20163 if (WINDOWP (w->contents))
20164 nwindows += redisplay_mode_lines (w->contents, force);
20165 else if (force
20166 || FRAME_GARBAGED_P (XFRAME (w->frame))
20167 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20169 struct text_pos lpoint;
20170 struct buffer *old = current_buffer;
20172 /* Set the window's buffer for the mode line display. */
20173 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20174 set_buffer_internal_1 (XBUFFER (w->contents));
20176 /* Point refers normally to the selected window. For any
20177 other window, set up appropriate value. */
20178 if (!EQ (window, selected_window))
20180 struct text_pos pt;
20182 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20183 if (CHARPOS (pt) < BEGV)
20184 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20185 else if (CHARPOS (pt) > (ZV - 1))
20186 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20187 else
20188 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20191 /* Display mode lines. */
20192 clear_glyph_matrix (w->desired_matrix);
20193 if (display_mode_lines (w))
20195 ++nwindows;
20196 w->must_be_updated_p = 1;
20199 /* Restore old settings. */
20200 set_buffer_internal_1 (old);
20201 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20204 window = w->next;
20207 return nwindows;
20211 /* Display the mode and/or header line of window W. Value is the
20212 sum number of mode lines and header lines displayed. */
20214 static int
20215 display_mode_lines (struct window *w)
20217 Lisp_Object old_selected_window = selected_window;
20218 Lisp_Object old_selected_frame = selected_frame;
20219 Lisp_Object new_frame = w->frame;
20220 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20221 int n = 0;
20223 selected_frame = new_frame;
20224 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20225 or window's point, then we'd need select_window_1 here as well. */
20226 XSETWINDOW (selected_window, w);
20227 XFRAME (new_frame)->selected_window = selected_window;
20229 /* These will be set while the mode line specs are processed. */
20230 line_number_displayed = 0;
20231 w->column_number_displayed = -1;
20233 if (WINDOW_WANTS_MODELINE_P (w))
20235 struct window *sel_w = XWINDOW (old_selected_window);
20237 /* Select mode line face based on the real selected window. */
20238 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20239 BVAR (current_buffer, mode_line_format));
20240 ++n;
20243 if (WINDOW_WANTS_HEADER_LINE_P (w))
20245 display_mode_line (w, HEADER_LINE_FACE_ID,
20246 BVAR (current_buffer, header_line_format));
20247 ++n;
20250 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20251 selected_frame = old_selected_frame;
20252 selected_window = old_selected_window;
20253 return n;
20257 /* Display mode or header line of window W. FACE_ID specifies which
20258 line to display; it is either MODE_LINE_FACE_ID or
20259 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20260 display. Value is the pixel height of the mode/header line
20261 displayed. */
20263 static int
20264 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20266 struct it it;
20267 struct face *face;
20268 ptrdiff_t count = SPECPDL_INDEX ();
20270 init_iterator (&it, w, -1, -1, NULL, face_id);
20271 /* Don't extend on a previously drawn mode-line.
20272 This may happen if called from pos_visible_p. */
20273 it.glyph_row->enabled_p = 0;
20274 prepare_desired_row (it.glyph_row);
20276 it.glyph_row->mode_line_p = 1;
20278 /* FIXME: This should be controlled by a user option. But
20279 supporting such an option is not trivial, since the mode line is
20280 made up of many separate strings. */
20281 it.paragraph_embedding = L2R;
20283 record_unwind_protect (unwind_format_mode_line,
20284 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20286 mode_line_target = MODE_LINE_DISPLAY;
20288 /* Temporarily make frame's keyboard the current kboard so that
20289 kboard-local variables in the mode_line_format will get the right
20290 values. */
20291 push_kboard (FRAME_KBOARD (it.f));
20292 record_unwind_save_match_data ();
20293 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20294 pop_kboard ();
20296 unbind_to (count, Qnil);
20298 /* Fill up with spaces. */
20299 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20301 compute_line_metrics (&it);
20302 it.glyph_row->full_width_p = 1;
20303 it.glyph_row->continued_p = 0;
20304 it.glyph_row->truncated_on_left_p = 0;
20305 it.glyph_row->truncated_on_right_p = 0;
20307 /* Make a 3D mode-line have a shadow at its right end. */
20308 face = FACE_FROM_ID (it.f, face_id);
20309 extend_face_to_end_of_line (&it);
20310 if (face->box != FACE_NO_BOX)
20312 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20313 + it.glyph_row->used[TEXT_AREA] - 1);
20314 last->right_box_line_p = 1;
20317 return it.glyph_row->height;
20320 /* Move element ELT in LIST to the front of LIST.
20321 Return the updated list. */
20323 static Lisp_Object
20324 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20326 register Lisp_Object tail, prev;
20327 register Lisp_Object tem;
20329 tail = list;
20330 prev = Qnil;
20331 while (CONSP (tail))
20333 tem = XCAR (tail);
20335 if (EQ (elt, tem))
20337 /* Splice out the link TAIL. */
20338 if (NILP (prev))
20339 list = XCDR (tail);
20340 else
20341 Fsetcdr (prev, XCDR (tail));
20343 /* Now make it the first. */
20344 Fsetcdr (tail, list);
20345 return tail;
20347 else
20348 prev = tail;
20349 tail = XCDR (tail);
20350 QUIT;
20353 /* Not found--return unchanged LIST. */
20354 return list;
20357 /* Contribute ELT to the mode line for window IT->w. How it
20358 translates into text depends on its data type.
20360 IT describes the display environment in which we display, as usual.
20362 DEPTH is the depth in recursion. It is used to prevent
20363 infinite recursion here.
20365 FIELD_WIDTH is the number of characters the display of ELT should
20366 occupy in the mode line, and PRECISION is the maximum number of
20367 characters to display from ELT's representation. See
20368 display_string for details.
20370 Returns the hpos of the end of the text generated by ELT.
20372 PROPS is a property list to add to any string we encounter.
20374 If RISKY is nonzero, remove (disregard) any properties in any string
20375 we encounter, and ignore :eval and :propertize.
20377 The global variable `mode_line_target' determines whether the
20378 output is passed to `store_mode_line_noprop',
20379 `store_mode_line_string', or `display_string'. */
20381 static int
20382 display_mode_element (struct it *it, int depth, int field_width, int precision,
20383 Lisp_Object elt, Lisp_Object props, int risky)
20385 int n = 0, field, prec;
20386 int literal = 0;
20388 tail_recurse:
20389 if (depth > 100)
20390 elt = build_string ("*too-deep*");
20392 depth++;
20394 switch (XTYPE (elt))
20396 case Lisp_String:
20398 /* A string: output it and check for %-constructs within it. */
20399 unsigned char c;
20400 ptrdiff_t offset = 0;
20402 if (SCHARS (elt) > 0
20403 && (!NILP (props) || risky))
20405 Lisp_Object oprops, aelt;
20406 oprops = Ftext_properties_at (make_number (0), elt);
20408 /* If the starting string's properties are not what
20409 we want, translate the string. Also, if the string
20410 is risky, do that anyway. */
20412 if (NILP (Fequal (props, oprops)) || risky)
20414 /* If the starting string has properties,
20415 merge the specified ones onto the existing ones. */
20416 if (! NILP (oprops) && !risky)
20418 Lisp_Object tem;
20420 oprops = Fcopy_sequence (oprops);
20421 tem = props;
20422 while (CONSP (tem))
20424 oprops = Fplist_put (oprops, XCAR (tem),
20425 XCAR (XCDR (tem)));
20426 tem = XCDR (XCDR (tem));
20428 props = oprops;
20431 aelt = Fassoc (elt, mode_line_proptrans_alist);
20432 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20434 /* AELT is what we want. Move it to the front
20435 without consing. */
20436 elt = XCAR (aelt);
20437 mode_line_proptrans_alist
20438 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20440 else
20442 Lisp_Object tem;
20444 /* If AELT has the wrong props, it is useless.
20445 so get rid of it. */
20446 if (! NILP (aelt))
20447 mode_line_proptrans_alist
20448 = Fdelq (aelt, mode_line_proptrans_alist);
20450 elt = Fcopy_sequence (elt);
20451 Fset_text_properties (make_number (0), Flength (elt),
20452 props, elt);
20453 /* Add this item to mode_line_proptrans_alist. */
20454 mode_line_proptrans_alist
20455 = Fcons (Fcons (elt, props),
20456 mode_line_proptrans_alist);
20457 /* Truncate mode_line_proptrans_alist
20458 to at most 50 elements. */
20459 tem = Fnthcdr (make_number (50),
20460 mode_line_proptrans_alist);
20461 if (! NILP (tem))
20462 XSETCDR (tem, Qnil);
20467 offset = 0;
20469 if (literal)
20471 prec = precision - n;
20472 switch (mode_line_target)
20474 case MODE_LINE_NOPROP:
20475 case MODE_LINE_TITLE:
20476 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20477 break;
20478 case MODE_LINE_STRING:
20479 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20480 break;
20481 case MODE_LINE_DISPLAY:
20482 n += display_string (NULL, elt, Qnil, 0, 0, it,
20483 0, prec, 0, STRING_MULTIBYTE (elt));
20484 break;
20487 break;
20490 /* Handle the non-literal case. */
20492 while ((precision <= 0 || n < precision)
20493 && SREF (elt, offset) != 0
20494 && (mode_line_target != MODE_LINE_DISPLAY
20495 || it->current_x < it->last_visible_x))
20497 ptrdiff_t last_offset = offset;
20499 /* Advance to end of string or next format specifier. */
20500 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20503 if (offset - 1 != last_offset)
20505 ptrdiff_t nchars, nbytes;
20507 /* Output to end of string or up to '%'. Field width
20508 is length of string. Don't output more than
20509 PRECISION allows us. */
20510 offset--;
20512 prec = c_string_width (SDATA (elt) + last_offset,
20513 offset - last_offset, precision - n,
20514 &nchars, &nbytes);
20516 switch (mode_line_target)
20518 case MODE_LINE_NOPROP:
20519 case MODE_LINE_TITLE:
20520 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20521 break;
20522 case MODE_LINE_STRING:
20524 ptrdiff_t bytepos = last_offset;
20525 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20526 ptrdiff_t endpos = (precision <= 0
20527 ? string_byte_to_char (elt, offset)
20528 : charpos + nchars);
20530 n += store_mode_line_string (NULL,
20531 Fsubstring (elt, make_number (charpos),
20532 make_number (endpos)),
20533 0, 0, 0, Qnil);
20535 break;
20536 case MODE_LINE_DISPLAY:
20538 ptrdiff_t bytepos = last_offset;
20539 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20541 if (precision <= 0)
20542 nchars = string_byte_to_char (elt, offset) - charpos;
20543 n += display_string (NULL, elt, Qnil, 0, charpos,
20544 it, 0, nchars, 0,
20545 STRING_MULTIBYTE (elt));
20547 break;
20550 else /* c == '%' */
20552 ptrdiff_t percent_position = offset;
20554 /* Get the specified minimum width. Zero means
20555 don't pad. */
20556 field = 0;
20557 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20558 field = field * 10 + c - '0';
20560 /* Don't pad beyond the total padding allowed. */
20561 if (field_width - n > 0 && field > field_width - n)
20562 field = field_width - n;
20564 /* Note that either PRECISION <= 0 or N < PRECISION. */
20565 prec = precision - n;
20567 if (c == 'M')
20568 n += display_mode_element (it, depth, field, prec,
20569 Vglobal_mode_string, props,
20570 risky);
20571 else if (c != 0)
20573 bool multibyte;
20574 ptrdiff_t bytepos, charpos;
20575 const char *spec;
20576 Lisp_Object string;
20578 bytepos = percent_position;
20579 charpos = (STRING_MULTIBYTE (elt)
20580 ? string_byte_to_char (elt, bytepos)
20581 : bytepos);
20582 spec = decode_mode_spec (it->w, c, field, &string);
20583 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20585 switch (mode_line_target)
20587 case MODE_LINE_NOPROP:
20588 case MODE_LINE_TITLE:
20589 n += store_mode_line_noprop (spec, field, prec);
20590 break;
20591 case MODE_LINE_STRING:
20593 Lisp_Object tem = build_string (spec);
20594 props = Ftext_properties_at (make_number (charpos), elt);
20595 /* Should only keep face property in props */
20596 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20598 break;
20599 case MODE_LINE_DISPLAY:
20601 int nglyphs_before, nwritten;
20603 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20604 nwritten = display_string (spec, string, elt,
20605 charpos, 0, it,
20606 field, prec, 0,
20607 multibyte);
20609 /* Assign to the glyphs written above the
20610 string where the `%x' came from, position
20611 of the `%'. */
20612 if (nwritten > 0)
20614 struct glyph *glyph
20615 = (it->glyph_row->glyphs[TEXT_AREA]
20616 + nglyphs_before);
20617 int i;
20619 for (i = 0; i < nwritten; ++i)
20621 glyph[i].object = elt;
20622 glyph[i].charpos = charpos;
20625 n += nwritten;
20628 break;
20631 else /* c == 0 */
20632 break;
20636 break;
20638 case Lisp_Symbol:
20639 /* A symbol: process the value of the symbol recursively
20640 as if it appeared here directly. Avoid error if symbol void.
20641 Special case: if value of symbol is a string, output the string
20642 literally. */
20644 register Lisp_Object tem;
20646 /* If the variable is not marked as risky to set
20647 then its contents are risky to use. */
20648 if (NILP (Fget (elt, Qrisky_local_variable)))
20649 risky = 1;
20651 tem = Fboundp (elt);
20652 if (!NILP (tem))
20654 tem = Fsymbol_value (elt);
20655 /* If value is a string, output that string literally:
20656 don't check for % within it. */
20657 if (STRINGP (tem))
20658 literal = 1;
20660 if (!EQ (tem, elt))
20662 /* Give up right away for nil or t. */
20663 elt = tem;
20664 goto tail_recurse;
20668 break;
20670 case Lisp_Cons:
20672 register Lisp_Object car, tem;
20674 /* A cons cell: five distinct cases.
20675 If first element is :eval or :propertize, do something special.
20676 If first element is a string or a cons, process all the elements
20677 and effectively concatenate them.
20678 If first element is a negative number, truncate displaying cdr to
20679 at most that many characters. If positive, pad (with spaces)
20680 to at least that many characters.
20681 If first element is a symbol, process the cadr or caddr recursively
20682 according to whether the symbol's value is non-nil or nil. */
20683 car = XCAR (elt);
20684 if (EQ (car, QCeval))
20686 /* An element of the form (:eval FORM) means evaluate FORM
20687 and use the result as mode line elements. */
20689 if (risky)
20690 break;
20692 if (CONSP (XCDR (elt)))
20694 Lisp_Object spec;
20695 spec = safe_eval (XCAR (XCDR (elt)));
20696 n += display_mode_element (it, depth, field_width - n,
20697 precision - n, spec, props,
20698 risky);
20701 else if (EQ (car, QCpropertize))
20703 /* An element of the form (:propertize ELT PROPS...)
20704 means display ELT but applying properties PROPS. */
20706 if (risky)
20707 break;
20709 if (CONSP (XCDR (elt)))
20710 n += display_mode_element (it, depth, field_width - n,
20711 precision - n, XCAR (XCDR (elt)),
20712 XCDR (XCDR (elt)), risky);
20714 else if (SYMBOLP (car))
20716 tem = Fboundp (car);
20717 elt = XCDR (elt);
20718 if (!CONSP (elt))
20719 goto invalid;
20720 /* elt is now the cdr, and we know it is a cons cell.
20721 Use its car if CAR has a non-nil value. */
20722 if (!NILP (tem))
20724 tem = Fsymbol_value (car);
20725 if (!NILP (tem))
20727 elt = XCAR (elt);
20728 goto tail_recurse;
20731 /* Symbol's value is nil (or symbol is unbound)
20732 Get the cddr of the original list
20733 and if possible find the caddr and use that. */
20734 elt = XCDR (elt);
20735 if (NILP (elt))
20736 break;
20737 else if (!CONSP (elt))
20738 goto invalid;
20739 elt = XCAR (elt);
20740 goto tail_recurse;
20742 else if (INTEGERP (car))
20744 register int lim = XINT (car);
20745 elt = XCDR (elt);
20746 if (lim < 0)
20748 /* Negative int means reduce maximum width. */
20749 if (precision <= 0)
20750 precision = -lim;
20751 else
20752 precision = min (precision, -lim);
20754 else if (lim > 0)
20756 /* Padding specified. Don't let it be more than
20757 current maximum. */
20758 if (precision > 0)
20759 lim = min (precision, lim);
20761 /* If that's more padding than already wanted, queue it.
20762 But don't reduce padding already specified even if
20763 that is beyond the current truncation point. */
20764 field_width = max (lim, field_width);
20766 goto tail_recurse;
20768 else if (STRINGP (car) || CONSP (car))
20770 Lisp_Object halftail = elt;
20771 int len = 0;
20773 while (CONSP (elt)
20774 && (precision <= 0 || n < precision))
20776 n += display_mode_element (it, depth,
20777 /* Do padding only after the last
20778 element in the list. */
20779 (! CONSP (XCDR (elt))
20780 ? field_width - n
20781 : 0),
20782 precision - n, XCAR (elt),
20783 props, risky);
20784 elt = XCDR (elt);
20785 len++;
20786 if ((len & 1) == 0)
20787 halftail = XCDR (halftail);
20788 /* Check for cycle. */
20789 if (EQ (halftail, elt))
20790 break;
20794 break;
20796 default:
20797 invalid:
20798 elt = build_string ("*invalid*");
20799 goto tail_recurse;
20802 /* Pad to FIELD_WIDTH. */
20803 if (field_width > 0 && n < field_width)
20805 switch (mode_line_target)
20807 case MODE_LINE_NOPROP:
20808 case MODE_LINE_TITLE:
20809 n += store_mode_line_noprop ("", field_width - n, 0);
20810 break;
20811 case MODE_LINE_STRING:
20812 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20813 break;
20814 case MODE_LINE_DISPLAY:
20815 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20816 0, 0, 0);
20817 break;
20821 return n;
20824 /* Store a mode-line string element in mode_line_string_list.
20826 If STRING is non-null, display that C string. Otherwise, the Lisp
20827 string LISP_STRING is displayed.
20829 FIELD_WIDTH is the minimum number of output glyphs to produce.
20830 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20831 with spaces. FIELD_WIDTH <= 0 means don't pad.
20833 PRECISION is the maximum number of characters to output from
20834 STRING. PRECISION <= 0 means don't truncate the string.
20836 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20837 properties to the string.
20839 PROPS are the properties to add to the string.
20840 The mode_line_string_face face property is always added to the string.
20843 static int
20844 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20845 int field_width, int precision, Lisp_Object props)
20847 ptrdiff_t len;
20848 int n = 0;
20850 if (string != NULL)
20852 len = strlen (string);
20853 if (precision > 0 && len > precision)
20854 len = precision;
20855 lisp_string = make_string (string, len);
20856 if (NILP (props))
20857 props = mode_line_string_face_prop;
20858 else if (!NILP (mode_line_string_face))
20860 Lisp_Object face = Fplist_get (props, Qface);
20861 props = Fcopy_sequence (props);
20862 if (NILP (face))
20863 face = mode_line_string_face;
20864 else
20865 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20866 props = Fplist_put (props, Qface, face);
20868 Fadd_text_properties (make_number (0), make_number (len),
20869 props, lisp_string);
20871 else
20873 len = XFASTINT (Flength (lisp_string));
20874 if (precision > 0 && len > precision)
20876 len = precision;
20877 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20878 precision = -1;
20880 if (!NILP (mode_line_string_face))
20882 Lisp_Object face;
20883 if (NILP (props))
20884 props = Ftext_properties_at (make_number (0), lisp_string);
20885 face = Fplist_get (props, Qface);
20886 if (NILP (face))
20887 face = mode_line_string_face;
20888 else
20889 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20890 props = Fcons (Qface, Fcons (face, Qnil));
20891 if (copy_string)
20892 lisp_string = Fcopy_sequence (lisp_string);
20894 if (!NILP (props))
20895 Fadd_text_properties (make_number (0), make_number (len),
20896 props, lisp_string);
20899 if (len > 0)
20901 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20902 n += len;
20905 if (field_width > len)
20907 field_width -= len;
20908 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20909 if (!NILP (props))
20910 Fadd_text_properties (make_number (0), make_number (field_width),
20911 props, lisp_string);
20912 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20913 n += field_width;
20916 return n;
20920 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20921 1, 4, 0,
20922 doc: /* Format a string out of a mode line format specification.
20923 First arg FORMAT specifies the mode line format (see `mode-line-format'
20924 for details) to use.
20926 By default, the format is evaluated for the currently selected window.
20928 Optional second arg FACE specifies the face property to put on all
20929 characters for which no face is specified. The value nil means the
20930 default face. The value t means whatever face the window's mode line
20931 currently uses (either `mode-line' or `mode-line-inactive',
20932 depending on whether the window is the selected window or not).
20933 An integer value means the value string has no text
20934 properties.
20936 Optional third and fourth args WINDOW and BUFFER specify the window
20937 and buffer to use as the context for the formatting (defaults
20938 are the selected window and the WINDOW's buffer). */)
20939 (Lisp_Object format, Lisp_Object face,
20940 Lisp_Object window, Lisp_Object buffer)
20942 struct it it;
20943 int len;
20944 struct window *w;
20945 struct buffer *old_buffer = NULL;
20946 int face_id;
20947 int no_props = INTEGERP (face);
20948 ptrdiff_t count = SPECPDL_INDEX ();
20949 Lisp_Object str;
20950 int string_start = 0;
20952 w = decode_any_window (window);
20953 XSETWINDOW (window, w);
20955 if (NILP (buffer))
20956 buffer = w->contents;
20957 CHECK_BUFFER (buffer);
20959 /* Make formatting the modeline a non-op when noninteractive, otherwise
20960 there will be problems later caused by a partially initialized frame. */
20961 if (NILP (format) || noninteractive)
20962 return empty_unibyte_string;
20964 if (no_props)
20965 face = Qnil;
20967 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20968 : EQ (face, Qt) ? (EQ (window, selected_window)
20969 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20970 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20971 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20972 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20973 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20974 : DEFAULT_FACE_ID;
20976 old_buffer = current_buffer;
20978 /* Save things including mode_line_proptrans_alist,
20979 and set that to nil so that we don't alter the outer value. */
20980 record_unwind_protect (unwind_format_mode_line,
20981 format_mode_line_unwind_data
20982 (XFRAME (WINDOW_FRAME (w)),
20983 old_buffer, selected_window, 1));
20984 mode_line_proptrans_alist = Qnil;
20986 Fselect_window (window, Qt);
20987 set_buffer_internal_1 (XBUFFER (buffer));
20989 init_iterator (&it, w, -1, -1, NULL, face_id);
20991 if (no_props)
20993 mode_line_target = MODE_LINE_NOPROP;
20994 mode_line_string_face_prop = Qnil;
20995 mode_line_string_list = Qnil;
20996 string_start = MODE_LINE_NOPROP_LEN (0);
20998 else
21000 mode_line_target = MODE_LINE_STRING;
21001 mode_line_string_list = Qnil;
21002 mode_line_string_face = face;
21003 mode_line_string_face_prop
21004 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
21007 push_kboard (FRAME_KBOARD (it.f));
21008 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21009 pop_kboard ();
21011 if (no_props)
21013 len = MODE_LINE_NOPROP_LEN (string_start);
21014 str = make_string (mode_line_noprop_buf + string_start, len);
21016 else
21018 mode_line_string_list = Fnreverse (mode_line_string_list);
21019 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21020 empty_unibyte_string);
21023 unbind_to (count, Qnil);
21024 return str;
21027 /* Write a null-terminated, right justified decimal representation of
21028 the positive integer D to BUF using a minimal field width WIDTH. */
21030 static void
21031 pint2str (register char *buf, register int width, register ptrdiff_t d)
21033 register char *p = buf;
21035 if (d <= 0)
21036 *p++ = '0';
21037 else
21039 while (d > 0)
21041 *p++ = d % 10 + '0';
21042 d /= 10;
21046 for (width -= (int) (p - buf); width > 0; --width)
21047 *p++ = ' ';
21048 *p-- = '\0';
21049 while (p > buf)
21051 d = *buf;
21052 *buf++ = *p;
21053 *p-- = d;
21057 /* Write a null-terminated, right justified decimal and "human
21058 readable" representation of the nonnegative integer D to BUF using
21059 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21061 static const char power_letter[] =
21063 0, /* no letter */
21064 'k', /* kilo */
21065 'M', /* mega */
21066 'G', /* giga */
21067 'T', /* tera */
21068 'P', /* peta */
21069 'E', /* exa */
21070 'Z', /* zetta */
21071 'Y' /* yotta */
21074 static void
21075 pint2hrstr (char *buf, int width, ptrdiff_t d)
21077 /* We aim to represent the nonnegative integer D as
21078 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21079 ptrdiff_t quotient = d;
21080 int remainder = 0;
21081 /* -1 means: do not use TENTHS. */
21082 int tenths = -1;
21083 int exponent = 0;
21085 /* Length of QUOTIENT.TENTHS as a string. */
21086 int length;
21088 char * psuffix;
21089 char * p;
21091 if (quotient >= 1000)
21093 /* Scale to the appropriate EXPONENT. */
21096 remainder = quotient % 1000;
21097 quotient /= 1000;
21098 exponent++;
21100 while (quotient >= 1000);
21102 /* Round to nearest and decide whether to use TENTHS or not. */
21103 if (quotient <= 9)
21105 tenths = remainder / 100;
21106 if (remainder % 100 >= 50)
21108 if (tenths < 9)
21109 tenths++;
21110 else
21112 quotient++;
21113 if (quotient == 10)
21114 tenths = -1;
21115 else
21116 tenths = 0;
21120 else
21121 if (remainder >= 500)
21123 if (quotient < 999)
21124 quotient++;
21125 else
21127 quotient = 1;
21128 exponent++;
21129 tenths = 0;
21134 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21135 if (tenths == -1 && quotient <= 99)
21136 if (quotient <= 9)
21137 length = 1;
21138 else
21139 length = 2;
21140 else
21141 length = 3;
21142 p = psuffix = buf + max (width, length);
21144 /* Print EXPONENT. */
21145 *psuffix++ = power_letter[exponent];
21146 *psuffix = '\0';
21148 /* Print TENTHS. */
21149 if (tenths >= 0)
21151 *--p = '0' + tenths;
21152 *--p = '.';
21155 /* Print QUOTIENT. */
21158 int digit = quotient % 10;
21159 *--p = '0' + digit;
21161 while ((quotient /= 10) != 0);
21163 /* Print leading spaces. */
21164 while (buf < p)
21165 *--p = ' ';
21168 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21169 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21170 type of CODING_SYSTEM. Return updated pointer into BUF. */
21172 static unsigned char invalid_eol_type[] = "(*invalid*)";
21174 static char *
21175 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21177 Lisp_Object val;
21178 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21179 const unsigned char *eol_str;
21180 int eol_str_len;
21181 /* The EOL conversion we are using. */
21182 Lisp_Object eoltype;
21184 val = CODING_SYSTEM_SPEC (coding_system);
21185 eoltype = Qnil;
21187 if (!VECTORP (val)) /* Not yet decided. */
21189 *buf++ = multibyte ? '-' : ' ';
21190 if (eol_flag)
21191 eoltype = eol_mnemonic_undecided;
21192 /* Don't mention EOL conversion if it isn't decided. */
21194 else
21196 Lisp_Object attrs;
21197 Lisp_Object eolvalue;
21199 attrs = AREF (val, 0);
21200 eolvalue = AREF (val, 2);
21202 *buf++ = multibyte
21203 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21204 : ' ';
21206 if (eol_flag)
21208 /* The EOL conversion that is normal on this system. */
21210 if (NILP (eolvalue)) /* Not yet decided. */
21211 eoltype = eol_mnemonic_undecided;
21212 else if (VECTORP (eolvalue)) /* Not yet decided. */
21213 eoltype = eol_mnemonic_undecided;
21214 else /* eolvalue is Qunix, Qdos, or Qmac. */
21215 eoltype = (EQ (eolvalue, Qunix)
21216 ? eol_mnemonic_unix
21217 : (EQ (eolvalue, Qdos) == 1
21218 ? eol_mnemonic_dos : eol_mnemonic_mac));
21222 if (eol_flag)
21224 /* Mention the EOL conversion if it is not the usual one. */
21225 if (STRINGP (eoltype))
21227 eol_str = SDATA (eoltype);
21228 eol_str_len = SBYTES (eoltype);
21230 else if (CHARACTERP (eoltype))
21232 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21233 int c = XFASTINT (eoltype);
21234 eol_str_len = CHAR_STRING (c, tmp);
21235 eol_str = tmp;
21237 else
21239 eol_str = invalid_eol_type;
21240 eol_str_len = sizeof (invalid_eol_type) - 1;
21242 memcpy (buf, eol_str, eol_str_len);
21243 buf += eol_str_len;
21246 return buf;
21249 /* Return a string for the output of a mode line %-spec for window W,
21250 generated by character C. FIELD_WIDTH > 0 means pad the string
21251 returned with spaces to that value. Return a Lisp string in
21252 *STRING if the resulting string is taken from that Lisp string.
21254 Note we operate on the current buffer for most purposes. */
21256 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21258 static const char *
21259 decode_mode_spec (struct window *w, register int c, int field_width,
21260 Lisp_Object *string)
21262 Lisp_Object obj;
21263 struct frame *f = XFRAME (WINDOW_FRAME (w));
21264 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21265 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21266 produce strings from numerical values, so limit preposterously
21267 large values of FIELD_WIDTH to avoid overrunning the buffer's
21268 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21269 bytes plus the terminating null. */
21270 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21271 struct buffer *b = current_buffer;
21273 obj = Qnil;
21274 *string = Qnil;
21276 switch (c)
21278 case '*':
21279 if (!NILP (BVAR (b, read_only)))
21280 return "%";
21281 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21282 return "*";
21283 return "-";
21285 case '+':
21286 /* This differs from %* only for a modified read-only buffer. */
21287 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21288 return "*";
21289 if (!NILP (BVAR (b, read_only)))
21290 return "%";
21291 return "-";
21293 case '&':
21294 /* This differs from %* in ignoring read-only-ness. */
21295 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21296 return "*";
21297 return "-";
21299 case '%':
21300 return "%";
21302 case '[':
21304 int i;
21305 char *p;
21307 if (command_loop_level > 5)
21308 return "[[[... ";
21309 p = decode_mode_spec_buf;
21310 for (i = 0; i < command_loop_level; i++)
21311 *p++ = '[';
21312 *p = 0;
21313 return decode_mode_spec_buf;
21316 case ']':
21318 int i;
21319 char *p;
21321 if (command_loop_level > 5)
21322 return " ...]]]";
21323 p = decode_mode_spec_buf;
21324 for (i = 0; i < command_loop_level; i++)
21325 *p++ = ']';
21326 *p = 0;
21327 return decode_mode_spec_buf;
21330 case '-':
21332 register int i;
21334 /* Let lots_of_dashes be a string of infinite length. */
21335 if (mode_line_target == MODE_LINE_NOPROP
21336 || mode_line_target == MODE_LINE_STRING)
21337 return "--";
21338 if (field_width <= 0
21339 || field_width > sizeof (lots_of_dashes))
21341 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21342 decode_mode_spec_buf[i] = '-';
21343 decode_mode_spec_buf[i] = '\0';
21344 return decode_mode_spec_buf;
21346 else
21347 return lots_of_dashes;
21350 case 'b':
21351 obj = BVAR (b, name);
21352 break;
21354 case 'c':
21355 /* %c and %l are ignored in `frame-title-format'.
21356 (In redisplay_internal, the frame title is drawn _before_ the
21357 windows are updated, so the stuff which depends on actual
21358 window contents (such as %l) may fail to render properly, or
21359 even crash emacs.) */
21360 if (mode_line_target == MODE_LINE_TITLE)
21361 return "";
21362 else
21364 ptrdiff_t col = current_column ();
21365 w->column_number_displayed = col;
21366 pint2str (decode_mode_spec_buf, width, col);
21367 return decode_mode_spec_buf;
21370 case 'e':
21371 #ifndef SYSTEM_MALLOC
21373 if (NILP (Vmemory_full))
21374 return "";
21375 else
21376 return "!MEM FULL! ";
21378 #else
21379 return "";
21380 #endif
21382 case 'F':
21383 /* %F displays the frame name. */
21384 if (!NILP (f->title))
21385 return SSDATA (f->title);
21386 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21387 return SSDATA (f->name);
21388 return "Emacs";
21390 case 'f':
21391 obj = BVAR (b, filename);
21392 break;
21394 case 'i':
21396 ptrdiff_t size = ZV - BEGV;
21397 pint2str (decode_mode_spec_buf, width, size);
21398 return decode_mode_spec_buf;
21401 case 'I':
21403 ptrdiff_t size = ZV - BEGV;
21404 pint2hrstr (decode_mode_spec_buf, width, size);
21405 return decode_mode_spec_buf;
21408 case 'l':
21410 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21411 ptrdiff_t topline, nlines, height;
21412 ptrdiff_t junk;
21414 /* %c and %l are ignored in `frame-title-format'. */
21415 if (mode_line_target == MODE_LINE_TITLE)
21416 return "";
21418 startpos = marker_position (w->start);
21419 startpos_byte = marker_byte_position (w->start);
21420 height = WINDOW_TOTAL_LINES (w);
21422 /* If we decided that this buffer isn't suitable for line numbers,
21423 don't forget that too fast. */
21424 if (w->base_line_pos == -1)
21425 goto no_value;
21427 /* If the buffer is very big, don't waste time. */
21428 if (INTEGERP (Vline_number_display_limit)
21429 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21431 w->base_line_pos = 0;
21432 w->base_line_number = 0;
21433 goto no_value;
21436 if (w->base_line_number > 0
21437 && w->base_line_pos > 0
21438 && w->base_line_pos <= startpos)
21440 line = w->base_line_number;
21441 linepos = w->base_line_pos;
21442 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21444 else
21446 line = 1;
21447 linepos = BUF_BEGV (b);
21448 linepos_byte = BUF_BEGV_BYTE (b);
21451 /* Count lines from base line to window start position. */
21452 nlines = display_count_lines (linepos_byte,
21453 startpos_byte,
21454 startpos, &junk);
21456 topline = nlines + line;
21458 /* Determine a new base line, if the old one is too close
21459 or too far away, or if we did not have one.
21460 "Too close" means it's plausible a scroll-down would
21461 go back past it. */
21462 if (startpos == BUF_BEGV (b))
21464 w->base_line_number = topline;
21465 w->base_line_pos = BUF_BEGV (b);
21467 else if (nlines < height + 25 || nlines > height * 3 + 50
21468 || linepos == BUF_BEGV (b))
21470 ptrdiff_t limit = BUF_BEGV (b);
21471 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21472 ptrdiff_t position;
21473 ptrdiff_t distance =
21474 (height * 2 + 30) * line_number_display_limit_width;
21476 if (startpos - distance > limit)
21478 limit = startpos - distance;
21479 limit_byte = CHAR_TO_BYTE (limit);
21482 nlines = display_count_lines (startpos_byte,
21483 limit_byte,
21484 - (height * 2 + 30),
21485 &position);
21486 /* If we couldn't find the lines we wanted within
21487 line_number_display_limit_width chars per line,
21488 give up on line numbers for this window. */
21489 if (position == limit_byte && limit == startpos - distance)
21491 w->base_line_pos = -1;
21492 w->base_line_number = 0;
21493 goto no_value;
21496 w->base_line_number = topline - nlines;
21497 w->base_line_pos = BYTE_TO_CHAR (position);
21500 /* Now count lines from the start pos to point. */
21501 nlines = display_count_lines (startpos_byte,
21502 PT_BYTE, PT, &junk);
21504 /* Record that we did display the line number. */
21505 line_number_displayed = 1;
21507 /* Make the string to show. */
21508 pint2str (decode_mode_spec_buf, width, topline + nlines);
21509 return decode_mode_spec_buf;
21510 no_value:
21512 char* p = decode_mode_spec_buf;
21513 int pad = width - 2;
21514 while (pad-- > 0)
21515 *p++ = ' ';
21516 *p++ = '?';
21517 *p++ = '?';
21518 *p = '\0';
21519 return decode_mode_spec_buf;
21522 break;
21524 case 'm':
21525 obj = BVAR (b, mode_name);
21526 break;
21528 case 'n':
21529 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21530 return " Narrow";
21531 break;
21533 case 'p':
21535 ptrdiff_t pos = marker_position (w->start);
21536 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21538 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21540 if (pos <= BUF_BEGV (b))
21541 return "All";
21542 else
21543 return "Bottom";
21545 else if (pos <= BUF_BEGV (b))
21546 return "Top";
21547 else
21549 if (total > 1000000)
21550 /* Do it differently for a large value, to avoid overflow. */
21551 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21552 else
21553 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21554 /* We can't normally display a 3-digit number,
21555 so get us a 2-digit number that is close. */
21556 if (total == 100)
21557 total = 99;
21558 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21559 return decode_mode_spec_buf;
21563 /* Display percentage of size above the bottom of the screen. */
21564 case 'P':
21566 ptrdiff_t toppos = marker_position (w->start);
21567 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21568 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21570 if (botpos >= BUF_ZV (b))
21572 if (toppos <= BUF_BEGV (b))
21573 return "All";
21574 else
21575 return "Bottom";
21577 else
21579 if (total > 1000000)
21580 /* Do it differently for a large value, to avoid overflow. */
21581 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21582 else
21583 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21584 /* We can't normally display a 3-digit number,
21585 so get us a 2-digit number that is close. */
21586 if (total == 100)
21587 total = 99;
21588 if (toppos <= BUF_BEGV (b))
21589 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
21590 else
21591 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21592 return decode_mode_spec_buf;
21596 case 's':
21597 /* status of process */
21598 obj = Fget_buffer_process (Fcurrent_buffer ());
21599 if (NILP (obj))
21600 return "no process";
21601 #ifndef MSDOS
21602 obj = Fsymbol_name (Fprocess_status (obj));
21603 #endif
21604 break;
21606 case '@':
21608 ptrdiff_t count = inhibit_garbage_collection ();
21609 Lisp_Object val = call1 (intern ("file-remote-p"),
21610 BVAR (current_buffer, directory));
21611 unbind_to (count, Qnil);
21613 if (NILP (val))
21614 return "-";
21615 else
21616 return "@";
21619 case 'z':
21620 /* coding-system (not including end-of-line format) */
21621 case 'Z':
21622 /* coding-system (including end-of-line type) */
21624 int eol_flag = (c == 'Z');
21625 char *p = decode_mode_spec_buf;
21627 if (! FRAME_WINDOW_P (f))
21629 /* No need to mention EOL here--the terminal never needs
21630 to do EOL conversion. */
21631 p = decode_mode_spec_coding (CODING_ID_NAME
21632 (FRAME_KEYBOARD_CODING (f)->id),
21633 p, 0);
21634 p = decode_mode_spec_coding (CODING_ID_NAME
21635 (FRAME_TERMINAL_CODING (f)->id),
21636 p, 0);
21638 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21639 p, eol_flag);
21641 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21642 #ifdef subprocesses
21643 obj = Fget_buffer_process (Fcurrent_buffer ());
21644 if (PROCESSP (obj))
21646 p = decode_mode_spec_coding
21647 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
21648 p = decode_mode_spec_coding
21649 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
21651 #endif /* subprocesses */
21652 #endif /* 0 */
21653 *p = 0;
21654 return decode_mode_spec_buf;
21658 if (STRINGP (obj))
21660 *string = obj;
21661 return SSDATA (obj);
21663 else
21664 return "";
21668 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
21669 means count lines back from START_BYTE. But don't go beyond
21670 LIMIT_BYTE. Return the number of lines thus found (always
21671 nonnegative).
21673 Set *BYTE_POS_PTR to the byte position where we stopped. This is
21674 either the position COUNT lines after/before START_BYTE, if we
21675 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
21676 COUNT lines. */
21678 static ptrdiff_t
21679 display_count_lines (ptrdiff_t start_byte,
21680 ptrdiff_t limit_byte, ptrdiff_t count,
21681 ptrdiff_t *byte_pos_ptr)
21683 register unsigned char *cursor;
21684 unsigned char *base;
21686 register ptrdiff_t ceiling;
21687 register unsigned char *ceiling_addr;
21688 ptrdiff_t orig_count = count;
21690 /* If we are not in selective display mode,
21691 check only for newlines. */
21692 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21693 && !INTEGERP (BVAR (current_buffer, selective_display)));
21695 if (count > 0)
21697 while (start_byte < limit_byte)
21699 ceiling = BUFFER_CEILING_OF (start_byte);
21700 ceiling = min (limit_byte - 1, ceiling);
21701 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21702 base = (cursor = BYTE_POS_ADDR (start_byte));
21706 if (selective_display)
21708 while (*cursor != '\n' && *cursor != 015
21709 && ++cursor != ceiling_addr)
21710 continue;
21711 if (cursor == ceiling_addr)
21712 break;
21714 else
21716 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
21717 if (! cursor)
21718 break;
21721 cursor++;
21723 if (--count == 0)
21725 start_byte += cursor - base;
21726 *byte_pos_ptr = start_byte;
21727 return orig_count;
21730 while (cursor < ceiling_addr);
21732 start_byte += ceiling_addr - base;
21735 else
21737 while (start_byte > limit_byte)
21739 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21740 ceiling = max (limit_byte, ceiling);
21741 ceiling_addr = BYTE_POS_ADDR (ceiling);
21742 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21743 while (1)
21745 if (selective_display)
21747 while (--cursor >= ceiling_addr
21748 && *cursor != '\n' && *cursor != 015)
21749 continue;
21750 if (cursor < ceiling_addr)
21751 break;
21753 else
21755 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
21756 if (! cursor)
21757 break;
21760 if (++count == 0)
21762 start_byte += cursor - base + 1;
21763 *byte_pos_ptr = start_byte;
21764 /* When scanning backwards, we should
21765 not count the newline posterior to which we stop. */
21766 return - orig_count - 1;
21769 start_byte += ceiling_addr - base;
21773 *byte_pos_ptr = limit_byte;
21775 if (count < 0)
21776 return - orig_count + count;
21777 return orig_count - count;
21783 /***********************************************************************
21784 Displaying strings
21785 ***********************************************************************/
21787 /* Display a NUL-terminated string, starting with index START.
21789 If STRING is non-null, display that C string. Otherwise, the Lisp
21790 string LISP_STRING is displayed. There's a case that STRING is
21791 non-null and LISP_STRING is not nil. It means STRING is a string
21792 data of LISP_STRING. In that case, we display LISP_STRING while
21793 ignoring its text properties.
21795 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21796 FACE_STRING. Display STRING or LISP_STRING with the face at
21797 FACE_STRING_POS in FACE_STRING:
21799 Display the string in the environment given by IT, but use the
21800 standard display table, temporarily.
21802 FIELD_WIDTH is the minimum number of output glyphs to produce.
21803 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21804 with spaces. If STRING has more characters, more than FIELD_WIDTH
21805 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21807 PRECISION is the maximum number of characters to output from
21808 STRING. PRECISION < 0 means don't truncate the string.
21810 This is roughly equivalent to printf format specifiers:
21812 FIELD_WIDTH PRECISION PRINTF
21813 ----------------------------------------
21814 -1 -1 %s
21815 -1 10 %.10s
21816 10 -1 %10s
21817 20 10 %20.10s
21819 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21820 display them, and < 0 means obey the current buffer's value of
21821 enable_multibyte_characters.
21823 Value is the number of columns displayed. */
21825 static int
21826 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21827 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
21828 int field_width, int precision, int max_x, int multibyte)
21830 int hpos_at_start = it->hpos;
21831 int saved_face_id = it->face_id;
21832 struct glyph_row *row = it->glyph_row;
21833 ptrdiff_t it_charpos;
21835 /* Initialize the iterator IT for iteration over STRING beginning
21836 with index START. */
21837 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21838 precision, field_width, multibyte);
21839 if (string && STRINGP (lisp_string))
21840 /* LISP_STRING is the one returned by decode_mode_spec. We should
21841 ignore its text properties. */
21842 it->stop_charpos = it->end_charpos;
21844 /* If displaying STRING, set up the face of the iterator from
21845 FACE_STRING, if that's given. */
21846 if (STRINGP (face_string))
21848 ptrdiff_t endptr;
21849 struct face *face;
21851 it->face_id
21852 = face_at_string_position (it->w, face_string, face_string_pos,
21853 0, it->region_beg_charpos,
21854 it->region_end_charpos,
21855 &endptr, it->base_face_id, 0);
21856 face = FACE_FROM_ID (it->f, it->face_id);
21857 it->face_box_p = face->box != FACE_NO_BOX;
21860 /* Set max_x to the maximum allowed X position. Don't let it go
21861 beyond the right edge of the window. */
21862 if (max_x <= 0)
21863 max_x = it->last_visible_x;
21864 else
21865 max_x = min (max_x, it->last_visible_x);
21867 /* Skip over display elements that are not visible. because IT->w is
21868 hscrolled. */
21869 if (it->current_x < it->first_visible_x)
21870 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21871 MOVE_TO_POS | MOVE_TO_X);
21873 row->ascent = it->max_ascent;
21874 row->height = it->max_ascent + it->max_descent;
21875 row->phys_ascent = it->max_phys_ascent;
21876 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21877 row->extra_line_spacing = it->max_extra_line_spacing;
21879 if (STRINGP (it->string))
21880 it_charpos = IT_STRING_CHARPOS (*it);
21881 else
21882 it_charpos = IT_CHARPOS (*it);
21884 /* This condition is for the case that we are called with current_x
21885 past last_visible_x. */
21886 while (it->current_x < max_x)
21888 int x_before, x, n_glyphs_before, i, nglyphs;
21890 /* Get the next display element. */
21891 if (!get_next_display_element (it))
21892 break;
21894 /* Produce glyphs. */
21895 x_before = it->current_x;
21896 n_glyphs_before = row->used[TEXT_AREA];
21897 PRODUCE_GLYPHS (it);
21899 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21900 i = 0;
21901 x = x_before;
21902 while (i < nglyphs)
21904 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21906 if (it->line_wrap != TRUNCATE
21907 && x + glyph->pixel_width > max_x)
21909 /* End of continued line or max_x reached. */
21910 if (CHAR_GLYPH_PADDING_P (*glyph))
21912 /* A wide character is unbreakable. */
21913 if (row->reversed_p)
21914 unproduce_glyphs (it, row->used[TEXT_AREA]
21915 - n_glyphs_before);
21916 row->used[TEXT_AREA] = n_glyphs_before;
21917 it->current_x = x_before;
21919 else
21921 if (row->reversed_p)
21922 unproduce_glyphs (it, row->used[TEXT_AREA]
21923 - (n_glyphs_before + i));
21924 row->used[TEXT_AREA] = n_glyphs_before + i;
21925 it->current_x = x;
21927 break;
21929 else if (x + glyph->pixel_width >= it->first_visible_x)
21931 /* Glyph is at least partially visible. */
21932 ++it->hpos;
21933 if (x < it->first_visible_x)
21934 row->x = x - it->first_visible_x;
21936 else
21938 /* Glyph is off the left margin of the display area.
21939 Should not happen. */
21940 emacs_abort ();
21943 row->ascent = max (row->ascent, it->max_ascent);
21944 row->height = max (row->height, it->max_ascent + it->max_descent);
21945 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21946 row->phys_height = max (row->phys_height,
21947 it->max_phys_ascent + it->max_phys_descent);
21948 row->extra_line_spacing = max (row->extra_line_spacing,
21949 it->max_extra_line_spacing);
21950 x += glyph->pixel_width;
21951 ++i;
21954 /* Stop if max_x reached. */
21955 if (i < nglyphs)
21956 break;
21958 /* Stop at line ends. */
21959 if (ITERATOR_AT_END_OF_LINE_P (it))
21961 it->continuation_lines_width = 0;
21962 break;
21965 set_iterator_to_next (it, 1);
21966 if (STRINGP (it->string))
21967 it_charpos = IT_STRING_CHARPOS (*it);
21968 else
21969 it_charpos = IT_CHARPOS (*it);
21971 /* Stop if truncating at the right edge. */
21972 if (it->line_wrap == TRUNCATE
21973 && it->current_x >= it->last_visible_x)
21975 /* Add truncation mark, but don't do it if the line is
21976 truncated at a padding space. */
21977 if (it_charpos < it->string_nchars)
21979 if (!FRAME_WINDOW_P (it->f))
21981 int ii, n;
21983 if (it->current_x > it->last_visible_x)
21985 if (!row->reversed_p)
21987 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21988 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21989 break;
21991 else
21993 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21994 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21995 break;
21996 unproduce_glyphs (it, ii + 1);
21997 ii = row->used[TEXT_AREA] - (ii + 1);
21999 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22001 row->used[TEXT_AREA] = ii;
22002 produce_special_glyphs (it, IT_TRUNCATION);
22005 produce_special_glyphs (it, IT_TRUNCATION);
22007 row->truncated_on_right_p = 1;
22009 break;
22013 /* Maybe insert a truncation at the left. */
22014 if (it->first_visible_x
22015 && it_charpos > 0)
22017 if (!FRAME_WINDOW_P (it->f)
22018 || (row->reversed_p
22019 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22020 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22021 insert_left_trunc_glyphs (it);
22022 row->truncated_on_left_p = 1;
22025 it->face_id = saved_face_id;
22027 /* Value is number of columns displayed. */
22028 return it->hpos - hpos_at_start;
22033 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22034 appears as an element of LIST or as the car of an element of LIST.
22035 If PROPVAL is a list, compare each element against LIST in that
22036 way, and return 1/2 if any element of PROPVAL is found in LIST.
22037 Otherwise return 0. This function cannot quit.
22038 The return value is 2 if the text is invisible but with an ellipsis
22039 and 1 if it's invisible and without an ellipsis. */
22042 invisible_p (register Lisp_Object propval, Lisp_Object list)
22044 register Lisp_Object tail, proptail;
22046 for (tail = list; CONSP (tail); tail = XCDR (tail))
22048 register Lisp_Object tem;
22049 tem = XCAR (tail);
22050 if (EQ (propval, tem))
22051 return 1;
22052 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22053 return NILP (XCDR (tem)) ? 1 : 2;
22056 if (CONSP (propval))
22058 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22060 Lisp_Object propelt;
22061 propelt = XCAR (proptail);
22062 for (tail = list; CONSP (tail); tail = XCDR (tail))
22064 register Lisp_Object tem;
22065 tem = XCAR (tail);
22066 if (EQ (propelt, tem))
22067 return 1;
22068 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22069 return NILP (XCDR (tem)) ? 1 : 2;
22074 return 0;
22077 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22078 doc: /* Non-nil if the property makes the text invisible.
22079 POS-OR-PROP can be a marker or number, in which case it is taken to be
22080 a position in the current buffer and the value of the `invisible' property
22081 is checked; or it can be some other value, which is then presumed to be the
22082 value of the `invisible' property of the text of interest.
22083 The non-nil value returned can be t for truly invisible text or something
22084 else if the text is replaced by an ellipsis. */)
22085 (Lisp_Object pos_or_prop)
22087 Lisp_Object prop
22088 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22089 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22090 : pos_or_prop);
22091 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22092 return (invis == 0 ? Qnil
22093 : invis == 1 ? Qt
22094 : make_number (invis));
22097 /* Calculate a width or height in pixels from a specification using
22098 the following elements:
22100 SPEC ::=
22101 NUM - a (fractional) multiple of the default font width/height
22102 (NUM) - specifies exactly NUM pixels
22103 UNIT - a fixed number of pixels, see below.
22104 ELEMENT - size of a display element in pixels, see below.
22105 (NUM . SPEC) - equals NUM * SPEC
22106 (+ SPEC SPEC ...) - add pixel values
22107 (- SPEC SPEC ...) - subtract pixel values
22108 (- SPEC) - negate pixel value
22110 NUM ::=
22111 INT or FLOAT - a number constant
22112 SYMBOL - use symbol's (buffer local) variable binding.
22114 UNIT ::=
22115 in - pixels per inch *)
22116 mm - pixels per 1/1000 meter *)
22117 cm - pixels per 1/100 meter *)
22118 width - width of current font in pixels.
22119 height - height of current font in pixels.
22121 *) using the ratio(s) defined in display-pixels-per-inch.
22123 ELEMENT ::=
22125 left-fringe - left fringe width in pixels
22126 right-fringe - right fringe width in pixels
22128 left-margin - left margin width in pixels
22129 right-margin - right margin width in pixels
22131 scroll-bar - scroll-bar area width in pixels
22133 Examples:
22135 Pixels corresponding to 5 inches:
22136 (5 . in)
22138 Total width of non-text areas on left side of window (if scroll-bar is on left):
22139 '(space :width (+ left-fringe left-margin scroll-bar))
22141 Align to first text column (in header line):
22142 '(space :align-to 0)
22144 Align to middle of text area minus half the width of variable `my-image'
22145 containing a loaded image:
22146 '(space :align-to (0.5 . (- text my-image)))
22148 Width of left margin minus width of 1 character in the default font:
22149 '(space :width (- left-margin 1))
22151 Width of left margin minus width of 2 characters in the current font:
22152 '(space :width (- left-margin (2 . width)))
22154 Center 1 character over left-margin (in header line):
22155 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22157 Different ways to express width of left fringe plus left margin minus one pixel:
22158 '(space :width (- (+ left-fringe left-margin) (1)))
22159 '(space :width (+ left-fringe left-margin (- (1))))
22160 '(space :width (+ left-fringe left-margin (-1)))
22164 static int
22165 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22166 struct font *font, int width_p, int *align_to)
22168 double pixels;
22170 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22171 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22173 if (NILP (prop))
22174 return OK_PIXELS (0);
22176 eassert (FRAME_LIVE_P (it->f));
22178 if (SYMBOLP (prop))
22180 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22182 char *unit = SSDATA (SYMBOL_NAME (prop));
22184 if (unit[0] == 'i' && unit[1] == 'n')
22185 pixels = 1.0;
22186 else if (unit[0] == 'm' && unit[1] == 'm')
22187 pixels = 25.4;
22188 else if (unit[0] == 'c' && unit[1] == 'm')
22189 pixels = 2.54;
22190 else
22191 pixels = 0;
22192 if (pixels > 0)
22194 double ppi = (width_p ? FRAME_RES_X (it->f)
22195 : FRAME_RES_Y (it->f));
22197 if (ppi > 0)
22198 return OK_PIXELS (ppi / pixels);
22199 return 0;
22203 #ifdef HAVE_WINDOW_SYSTEM
22204 if (EQ (prop, Qheight))
22205 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22206 if (EQ (prop, Qwidth))
22207 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22208 #else
22209 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22210 return OK_PIXELS (1);
22211 #endif
22213 if (EQ (prop, Qtext))
22214 return OK_PIXELS (width_p
22215 ? window_box_width (it->w, TEXT_AREA)
22216 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22218 if (align_to && *align_to < 0)
22220 *res = 0;
22221 if (EQ (prop, Qleft))
22222 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22223 if (EQ (prop, Qright))
22224 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22225 if (EQ (prop, Qcenter))
22226 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22227 + window_box_width (it->w, TEXT_AREA) / 2);
22228 if (EQ (prop, Qleft_fringe))
22229 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22230 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22231 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22232 if (EQ (prop, Qright_fringe))
22233 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22234 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22235 : window_box_right_offset (it->w, TEXT_AREA));
22236 if (EQ (prop, Qleft_margin))
22237 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22238 if (EQ (prop, Qright_margin))
22239 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22240 if (EQ (prop, Qscroll_bar))
22241 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22243 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22244 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22245 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22246 : 0)));
22248 else
22250 if (EQ (prop, Qleft_fringe))
22251 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22252 if (EQ (prop, Qright_fringe))
22253 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22254 if (EQ (prop, Qleft_margin))
22255 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22256 if (EQ (prop, Qright_margin))
22257 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22258 if (EQ (prop, Qscroll_bar))
22259 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22262 prop = buffer_local_value_1 (prop, it->w->contents);
22263 if (EQ (prop, Qunbound))
22264 prop = Qnil;
22267 if (INTEGERP (prop) || FLOATP (prop))
22269 int base_unit = (width_p
22270 ? FRAME_COLUMN_WIDTH (it->f)
22271 : FRAME_LINE_HEIGHT (it->f));
22272 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22275 if (CONSP (prop))
22277 Lisp_Object car = XCAR (prop);
22278 Lisp_Object cdr = XCDR (prop);
22280 if (SYMBOLP (car))
22282 #ifdef HAVE_WINDOW_SYSTEM
22283 if (FRAME_WINDOW_P (it->f)
22284 && valid_image_p (prop))
22286 ptrdiff_t id = lookup_image (it->f, prop);
22287 struct image *img = IMAGE_FROM_ID (it->f, id);
22289 return OK_PIXELS (width_p ? img->width : img->height);
22291 #endif
22292 if (EQ (car, Qplus) || EQ (car, Qminus))
22294 int first = 1;
22295 double px;
22297 pixels = 0;
22298 while (CONSP (cdr))
22300 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22301 font, width_p, align_to))
22302 return 0;
22303 if (first)
22304 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22305 else
22306 pixels += px;
22307 cdr = XCDR (cdr);
22309 if (EQ (car, Qminus))
22310 pixels = -pixels;
22311 return OK_PIXELS (pixels);
22314 car = buffer_local_value_1 (car, it->w->contents);
22315 if (EQ (car, Qunbound))
22316 car = Qnil;
22319 if (INTEGERP (car) || FLOATP (car))
22321 double fact;
22322 pixels = XFLOATINT (car);
22323 if (NILP (cdr))
22324 return OK_PIXELS (pixels);
22325 if (calc_pixel_width_or_height (&fact, it, cdr,
22326 font, width_p, align_to))
22327 return OK_PIXELS (pixels * fact);
22328 return 0;
22331 return 0;
22334 return 0;
22338 /***********************************************************************
22339 Glyph Display
22340 ***********************************************************************/
22342 #ifdef HAVE_WINDOW_SYSTEM
22344 #ifdef GLYPH_DEBUG
22346 void
22347 dump_glyph_string (struct glyph_string *s)
22349 fprintf (stderr, "glyph string\n");
22350 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22351 s->x, s->y, s->width, s->height);
22352 fprintf (stderr, " ybase = %d\n", s->ybase);
22353 fprintf (stderr, " hl = %d\n", s->hl);
22354 fprintf (stderr, " left overhang = %d, right = %d\n",
22355 s->left_overhang, s->right_overhang);
22356 fprintf (stderr, " nchars = %d\n", s->nchars);
22357 fprintf (stderr, " extends to end of line = %d\n",
22358 s->extends_to_end_of_line_p);
22359 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22360 fprintf (stderr, " bg width = %d\n", s->background_width);
22363 #endif /* GLYPH_DEBUG */
22365 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22366 of XChar2b structures for S; it can't be allocated in
22367 init_glyph_string because it must be allocated via `alloca'. W
22368 is the window on which S is drawn. ROW and AREA are the glyph row
22369 and area within the row from which S is constructed. START is the
22370 index of the first glyph structure covered by S. HL is a
22371 face-override for drawing S. */
22373 #ifdef HAVE_NTGUI
22374 #define OPTIONAL_HDC(hdc) HDC hdc,
22375 #define DECLARE_HDC(hdc) HDC hdc;
22376 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22377 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22378 #endif
22380 #ifndef OPTIONAL_HDC
22381 #define OPTIONAL_HDC(hdc)
22382 #define DECLARE_HDC(hdc)
22383 #define ALLOCATE_HDC(hdc, f)
22384 #define RELEASE_HDC(hdc, f)
22385 #endif
22387 static void
22388 init_glyph_string (struct glyph_string *s,
22389 OPTIONAL_HDC (hdc)
22390 XChar2b *char2b, struct window *w, struct glyph_row *row,
22391 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22393 memset (s, 0, sizeof *s);
22394 s->w = w;
22395 s->f = XFRAME (w->frame);
22396 #ifdef HAVE_NTGUI
22397 s->hdc = hdc;
22398 #endif
22399 s->display = FRAME_X_DISPLAY (s->f);
22400 s->window = FRAME_X_WINDOW (s->f);
22401 s->char2b = char2b;
22402 s->hl = hl;
22403 s->row = row;
22404 s->area = area;
22405 s->first_glyph = row->glyphs[area] + start;
22406 s->height = row->height;
22407 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22408 s->ybase = s->y + row->ascent;
22412 /* Append the list of glyph strings with head H and tail T to the list
22413 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22415 static void
22416 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22417 struct glyph_string *h, struct glyph_string *t)
22419 if (h)
22421 if (*head)
22422 (*tail)->next = h;
22423 else
22424 *head = h;
22425 h->prev = *tail;
22426 *tail = t;
22431 /* Prepend the list of glyph strings with head H and tail T to the
22432 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22433 result. */
22435 static void
22436 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22437 struct glyph_string *h, struct glyph_string *t)
22439 if (h)
22441 if (*head)
22442 (*head)->prev = t;
22443 else
22444 *tail = t;
22445 t->next = *head;
22446 *head = h;
22451 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22452 Set *HEAD and *TAIL to the resulting list. */
22454 static void
22455 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22456 struct glyph_string *s)
22458 s->next = s->prev = NULL;
22459 append_glyph_string_lists (head, tail, s, s);
22463 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22464 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22465 make sure that X resources for the face returned are allocated.
22466 Value is a pointer to a realized face that is ready for display if
22467 DISPLAY_P is non-zero. */
22469 static struct face *
22470 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22471 XChar2b *char2b, int display_p)
22473 struct face *face = FACE_FROM_ID (f, face_id);
22474 unsigned code = 0;
22476 if (face->font)
22478 code = face->font->driver->encode_char (face->font, c);
22480 if (code == FONT_INVALID_CODE)
22481 code = 0;
22483 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22485 /* Make sure X resources of the face are allocated. */
22486 #ifdef HAVE_X_WINDOWS
22487 if (display_p)
22488 #endif
22490 eassert (face != NULL);
22491 PREPARE_FACE_FOR_DISPLAY (f, face);
22494 return face;
22498 /* Get face and two-byte form of character glyph GLYPH on frame F.
22499 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22500 a pointer to a realized face that is ready for display. */
22502 static struct face *
22503 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22504 XChar2b *char2b, int *two_byte_p)
22506 struct face *face;
22507 unsigned code = 0;
22509 eassert (glyph->type == CHAR_GLYPH);
22510 face = FACE_FROM_ID (f, glyph->face_id);
22512 /* Make sure X resources of the face are allocated. */
22513 eassert (face != NULL);
22514 PREPARE_FACE_FOR_DISPLAY (f, face);
22516 if (two_byte_p)
22517 *two_byte_p = 0;
22519 if (face->font)
22521 if (CHAR_BYTE8_P (glyph->u.ch))
22522 code = CHAR_TO_BYTE8 (glyph->u.ch);
22523 else
22524 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22526 if (code == FONT_INVALID_CODE)
22527 code = 0;
22530 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22531 return face;
22535 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22536 Return 1 if FONT has a glyph for C, otherwise return 0. */
22538 static int
22539 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22541 unsigned code;
22543 if (CHAR_BYTE8_P (c))
22544 code = CHAR_TO_BYTE8 (c);
22545 else
22546 code = font->driver->encode_char (font, c);
22548 if (code == FONT_INVALID_CODE)
22549 return 0;
22550 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22551 return 1;
22555 /* Fill glyph string S with composition components specified by S->cmp.
22557 BASE_FACE is the base face of the composition.
22558 S->cmp_from is the index of the first component for S.
22560 OVERLAPS non-zero means S should draw the foreground only, and use
22561 its physical height for clipping. See also draw_glyphs.
22563 Value is the index of a component not in S. */
22565 static int
22566 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22567 int overlaps)
22569 int i;
22570 /* For all glyphs of this composition, starting at the offset
22571 S->cmp_from, until we reach the end of the definition or encounter a
22572 glyph that requires the different face, add it to S. */
22573 struct face *face;
22575 eassert (s);
22577 s->for_overlaps = overlaps;
22578 s->face = NULL;
22579 s->font = NULL;
22580 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22582 int c = COMPOSITION_GLYPH (s->cmp, i);
22584 /* TAB in a composition means display glyphs with padding space
22585 on the left or right. */
22586 if (c != '\t')
22588 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22589 -1, Qnil);
22591 face = get_char_face_and_encoding (s->f, c, face_id,
22592 s->char2b + i, 1);
22593 if (face)
22595 if (! s->face)
22597 s->face = face;
22598 s->font = s->face->font;
22600 else if (s->face != face)
22601 break;
22604 ++s->nchars;
22606 s->cmp_to = i;
22608 if (s->face == NULL)
22610 s->face = base_face->ascii_face;
22611 s->font = s->face->font;
22614 /* All glyph strings for the same composition has the same width,
22615 i.e. the width set for the first component of the composition. */
22616 s->width = s->first_glyph->pixel_width;
22618 /* If the specified font could not be loaded, use the frame's
22619 default font, but record the fact that we couldn't load it in
22620 the glyph string so that we can draw rectangles for the
22621 characters of the glyph string. */
22622 if (s->font == NULL)
22624 s->font_not_found_p = 1;
22625 s->font = FRAME_FONT (s->f);
22628 /* Adjust base line for subscript/superscript text. */
22629 s->ybase += s->first_glyph->voffset;
22631 /* This glyph string must always be drawn with 16-bit functions. */
22632 s->two_byte_p = 1;
22634 return s->cmp_to;
22637 static int
22638 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22639 int start, int end, int overlaps)
22641 struct glyph *glyph, *last;
22642 Lisp_Object lgstring;
22643 int i;
22645 s->for_overlaps = overlaps;
22646 glyph = s->row->glyphs[s->area] + start;
22647 last = s->row->glyphs[s->area] + end;
22648 s->cmp_id = glyph->u.cmp.id;
22649 s->cmp_from = glyph->slice.cmp.from;
22650 s->cmp_to = glyph->slice.cmp.to + 1;
22651 s->face = FACE_FROM_ID (s->f, face_id);
22652 lgstring = composition_gstring_from_id (s->cmp_id);
22653 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22654 glyph++;
22655 while (glyph < last
22656 && glyph->u.cmp.automatic
22657 && glyph->u.cmp.id == s->cmp_id
22658 && s->cmp_to == glyph->slice.cmp.from)
22659 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22661 for (i = s->cmp_from; i < s->cmp_to; i++)
22663 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22664 unsigned code = LGLYPH_CODE (lglyph);
22666 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22668 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22669 return glyph - s->row->glyphs[s->area];
22673 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22674 See the comment of fill_glyph_string for arguments.
22675 Value is the index of the first glyph not in S. */
22678 static int
22679 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22680 int start, int end, int overlaps)
22682 struct glyph *glyph, *last;
22683 int voffset;
22685 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22686 s->for_overlaps = overlaps;
22687 glyph = s->row->glyphs[s->area] + start;
22688 last = s->row->glyphs[s->area] + end;
22689 voffset = glyph->voffset;
22690 s->face = FACE_FROM_ID (s->f, face_id);
22691 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
22692 s->nchars = 1;
22693 s->width = glyph->pixel_width;
22694 glyph++;
22695 while (glyph < last
22696 && glyph->type == GLYPHLESS_GLYPH
22697 && glyph->voffset == voffset
22698 && glyph->face_id == face_id)
22700 s->nchars++;
22701 s->width += glyph->pixel_width;
22702 glyph++;
22704 s->ybase += voffset;
22705 return glyph - s->row->glyphs[s->area];
22709 /* Fill glyph string S from a sequence of character glyphs.
22711 FACE_ID is the face id of the string. START is the index of the
22712 first glyph to consider, END is the index of the last + 1.
22713 OVERLAPS non-zero means S should draw the foreground only, and use
22714 its physical height for clipping. See also draw_glyphs.
22716 Value is the index of the first glyph not in S. */
22718 static int
22719 fill_glyph_string (struct glyph_string *s, int face_id,
22720 int start, int end, int overlaps)
22722 struct glyph *glyph, *last;
22723 int voffset;
22724 int glyph_not_available_p;
22726 eassert (s->f == XFRAME (s->w->frame));
22727 eassert (s->nchars == 0);
22728 eassert (start >= 0 && end > start);
22730 s->for_overlaps = overlaps;
22731 glyph = s->row->glyphs[s->area] + start;
22732 last = s->row->glyphs[s->area] + end;
22733 voffset = glyph->voffset;
22734 s->padding_p = glyph->padding_p;
22735 glyph_not_available_p = glyph->glyph_not_available_p;
22737 while (glyph < last
22738 && glyph->type == CHAR_GLYPH
22739 && glyph->voffset == voffset
22740 /* Same face id implies same font, nowadays. */
22741 && glyph->face_id == face_id
22742 && glyph->glyph_not_available_p == glyph_not_available_p)
22744 int two_byte_p;
22746 s->face = get_glyph_face_and_encoding (s->f, glyph,
22747 s->char2b + s->nchars,
22748 &two_byte_p);
22749 s->two_byte_p = two_byte_p;
22750 ++s->nchars;
22751 eassert (s->nchars <= end - start);
22752 s->width += glyph->pixel_width;
22753 if (glyph++->padding_p != s->padding_p)
22754 break;
22757 s->font = s->face->font;
22759 /* If the specified font could not be loaded, use the frame's font,
22760 but record the fact that we couldn't load it in
22761 S->font_not_found_p so that we can draw rectangles for the
22762 characters of the glyph string. */
22763 if (s->font == NULL || glyph_not_available_p)
22765 s->font_not_found_p = 1;
22766 s->font = FRAME_FONT (s->f);
22769 /* Adjust base line for subscript/superscript text. */
22770 s->ybase += voffset;
22772 eassert (s->face && s->face->gc);
22773 return glyph - s->row->glyphs[s->area];
22777 /* Fill glyph string S from image glyph S->first_glyph. */
22779 static void
22780 fill_image_glyph_string (struct glyph_string *s)
22782 eassert (s->first_glyph->type == IMAGE_GLYPH);
22783 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22784 eassert (s->img);
22785 s->slice = s->first_glyph->slice.img;
22786 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22787 s->font = s->face->font;
22788 s->width = s->first_glyph->pixel_width;
22790 /* Adjust base line for subscript/superscript text. */
22791 s->ybase += s->first_glyph->voffset;
22795 /* Fill glyph string S from a sequence of stretch glyphs.
22797 START is the index of the first glyph to consider,
22798 END is the index of the last + 1.
22800 Value is the index of the first glyph not in S. */
22802 static int
22803 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22805 struct glyph *glyph, *last;
22806 int voffset, face_id;
22808 eassert (s->first_glyph->type == STRETCH_GLYPH);
22810 glyph = s->row->glyphs[s->area] + start;
22811 last = s->row->glyphs[s->area] + end;
22812 face_id = glyph->face_id;
22813 s->face = FACE_FROM_ID (s->f, face_id);
22814 s->font = s->face->font;
22815 s->width = glyph->pixel_width;
22816 s->nchars = 1;
22817 voffset = glyph->voffset;
22819 for (++glyph;
22820 (glyph < last
22821 && glyph->type == STRETCH_GLYPH
22822 && glyph->voffset == voffset
22823 && glyph->face_id == face_id);
22824 ++glyph)
22825 s->width += glyph->pixel_width;
22827 /* Adjust base line for subscript/superscript text. */
22828 s->ybase += voffset;
22830 /* The case that face->gc == 0 is handled when drawing the glyph
22831 string by calling PREPARE_FACE_FOR_DISPLAY. */
22832 eassert (s->face);
22833 return glyph - s->row->glyphs[s->area];
22836 static struct font_metrics *
22837 get_per_char_metric (struct font *font, XChar2b *char2b)
22839 static struct font_metrics metrics;
22840 unsigned code;
22842 if (! font)
22843 return NULL;
22844 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22845 if (code == FONT_INVALID_CODE)
22846 return NULL;
22847 font->driver->text_extents (font, &code, 1, &metrics);
22848 return &metrics;
22851 /* EXPORT for RIF:
22852 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22853 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22854 assumed to be zero. */
22856 void
22857 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22859 *left = *right = 0;
22861 if (glyph->type == CHAR_GLYPH)
22863 struct face *face;
22864 XChar2b char2b;
22865 struct font_metrics *pcm;
22867 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22868 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22870 if (pcm->rbearing > pcm->width)
22871 *right = pcm->rbearing - pcm->width;
22872 if (pcm->lbearing < 0)
22873 *left = -pcm->lbearing;
22876 else if (glyph->type == COMPOSITE_GLYPH)
22878 if (! glyph->u.cmp.automatic)
22880 struct composition *cmp = composition_table[glyph->u.cmp.id];
22882 if (cmp->rbearing > cmp->pixel_width)
22883 *right = cmp->rbearing - cmp->pixel_width;
22884 if (cmp->lbearing < 0)
22885 *left = - cmp->lbearing;
22887 else
22889 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22890 struct font_metrics metrics;
22892 composition_gstring_width (gstring, glyph->slice.cmp.from,
22893 glyph->slice.cmp.to + 1, &metrics);
22894 if (metrics.rbearing > metrics.width)
22895 *right = metrics.rbearing - metrics.width;
22896 if (metrics.lbearing < 0)
22897 *left = - metrics.lbearing;
22903 /* Return the index of the first glyph preceding glyph string S that
22904 is overwritten by S because of S's left overhang. Value is -1
22905 if no glyphs are overwritten. */
22907 static int
22908 left_overwritten (struct glyph_string *s)
22910 int k;
22912 if (s->left_overhang)
22914 int x = 0, i;
22915 struct glyph *glyphs = s->row->glyphs[s->area];
22916 int first = s->first_glyph - glyphs;
22918 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22919 x -= glyphs[i].pixel_width;
22921 k = i + 1;
22923 else
22924 k = -1;
22926 return k;
22930 /* Return the index of the first glyph preceding glyph string S that
22931 is overwriting S because of its right overhang. Value is -1 if no
22932 glyph in front of S overwrites S. */
22934 static int
22935 left_overwriting (struct glyph_string *s)
22937 int i, k, x;
22938 struct glyph *glyphs = s->row->glyphs[s->area];
22939 int first = s->first_glyph - glyphs;
22941 k = -1;
22942 x = 0;
22943 for (i = first - 1; i >= 0; --i)
22945 int left, right;
22946 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22947 if (x + right > 0)
22948 k = i;
22949 x -= glyphs[i].pixel_width;
22952 return k;
22956 /* Return the index of the last glyph following glyph string S that is
22957 overwritten by S because of S's right overhang. Value is -1 if
22958 no such glyph is found. */
22960 static int
22961 right_overwritten (struct glyph_string *s)
22963 int k = -1;
22965 if (s->right_overhang)
22967 int x = 0, i;
22968 struct glyph *glyphs = s->row->glyphs[s->area];
22969 int first = (s->first_glyph - glyphs
22970 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22971 int end = s->row->used[s->area];
22973 for (i = first; i < end && s->right_overhang > x; ++i)
22974 x += glyphs[i].pixel_width;
22976 k = i;
22979 return k;
22983 /* Return the index of the last glyph following glyph string S that
22984 overwrites S because of its left overhang. Value is negative
22985 if no such glyph is found. */
22987 static int
22988 right_overwriting (struct glyph_string *s)
22990 int i, k, x;
22991 int end = s->row->used[s->area];
22992 struct glyph *glyphs = s->row->glyphs[s->area];
22993 int first = (s->first_glyph - glyphs
22994 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22996 k = -1;
22997 x = 0;
22998 for (i = first; i < end; ++i)
23000 int left, right;
23001 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23002 if (x - left < 0)
23003 k = i;
23004 x += glyphs[i].pixel_width;
23007 return k;
23011 /* Set background width of glyph string S. START is the index of the
23012 first glyph following S. LAST_X is the right-most x-position + 1
23013 in the drawing area. */
23015 static void
23016 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23018 /* If the face of this glyph string has to be drawn to the end of
23019 the drawing area, set S->extends_to_end_of_line_p. */
23021 if (start == s->row->used[s->area]
23022 && s->area == TEXT_AREA
23023 && ((s->row->fill_line_p
23024 && (s->hl == DRAW_NORMAL_TEXT
23025 || s->hl == DRAW_IMAGE_RAISED
23026 || s->hl == DRAW_IMAGE_SUNKEN))
23027 || s->hl == DRAW_MOUSE_FACE))
23028 s->extends_to_end_of_line_p = 1;
23030 /* If S extends its face to the end of the line, set its
23031 background_width to the distance to the right edge of the drawing
23032 area. */
23033 if (s->extends_to_end_of_line_p)
23034 s->background_width = last_x - s->x + 1;
23035 else
23036 s->background_width = s->width;
23040 /* Compute overhangs and x-positions for glyph string S and its
23041 predecessors, or successors. X is the starting x-position for S.
23042 BACKWARD_P non-zero means process predecessors. */
23044 static void
23045 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23047 if (backward_p)
23049 while (s)
23051 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23052 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23053 x -= s->width;
23054 s->x = x;
23055 s = s->prev;
23058 else
23060 while (s)
23062 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23063 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23064 s->x = x;
23065 x += s->width;
23066 s = s->next;
23073 /* The following macros are only called from draw_glyphs below.
23074 They reference the following parameters of that function directly:
23075 `w', `row', `area', and `overlap_p'
23076 as well as the following local variables:
23077 `s', `f', and `hdc' (in W32) */
23079 #ifdef HAVE_NTGUI
23080 /* On W32, silently add local `hdc' variable to argument list of
23081 init_glyph_string. */
23082 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23083 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23084 #else
23085 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23086 init_glyph_string (s, char2b, w, row, area, start, hl)
23087 #endif
23089 /* Add a glyph string for a stretch glyph to the list of strings
23090 between HEAD and TAIL. START is the index of the stretch glyph in
23091 row area AREA of glyph row ROW. END is the index of the last glyph
23092 in that glyph row area. X is the current output position assigned
23093 to the new glyph string constructed. HL overrides that face of the
23094 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23095 is the right-most x-position of the drawing area. */
23097 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23098 and below -- keep them on one line. */
23099 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23100 do \
23102 s = alloca (sizeof *s); \
23103 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23104 START = fill_stretch_glyph_string (s, START, END); \
23105 append_glyph_string (&HEAD, &TAIL, s); \
23106 s->x = (X); \
23108 while (0)
23111 /* Add a glyph string for an image glyph to the list of strings
23112 between HEAD and TAIL. START is the index of the image glyph in
23113 row area AREA of glyph row ROW. END is the index of the last glyph
23114 in that glyph row area. X is the current output position assigned
23115 to the new glyph string constructed. HL overrides that face of the
23116 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23117 is the right-most x-position of the drawing area. */
23119 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23120 do \
23122 s = alloca (sizeof *s); \
23123 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23124 fill_image_glyph_string (s); \
23125 append_glyph_string (&HEAD, &TAIL, s); \
23126 ++START; \
23127 s->x = (X); \
23129 while (0)
23132 /* Add a glyph string for a sequence of character glyphs to the list
23133 of strings between HEAD and TAIL. START is the index of the first
23134 glyph in row area AREA of glyph row ROW that is part of the new
23135 glyph string. END is the index of the last glyph in that glyph row
23136 area. X is the current output position assigned to the new glyph
23137 string constructed. HL overrides that face of the glyph; e.g. it
23138 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23139 right-most x-position of the drawing area. */
23141 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23142 do \
23144 int face_id; \
23145 XChar2b *char2b; \
23147 face_id = (row)->glyphs[area][START].face_id; \
23149 s = alloca (sizeof *s); \
23150 char2b = alloca ((END - START) * sizeof *char2b); \
23151 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23152 append_glyph_string (&HEAD, &TAIL, s); \
23153 s->x = (X); \
23154 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23156 while (0)
23159 /* Add a glyph string for a composite sequence to the list of strings
23160 between HEAD and TAIL. START is the index of the first glyph in
23161 row area AREA of glyph row ROW that is part of the new glyph
23162 string. END is the index of the last glyph in that glyph row area.
23163 X is the current output position assigned to the new glyph string
23164 constructed. HL overrides that face of the glyph; e.g. it is
23165 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23166 x-position of the drawing area. */
23168 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23169 do { \
23170 int face_id = (row)->glyphs[area][START].face_id; \
23171 struct face *base_face = FACE_FROM_ID (f, face_id); \
23172 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23173 struct composition *cmp = composition_table[cmp_id]; \
23174 XChar2b *char2b; \
23175 struct glyph_string *first_s = NULL; \
23176 int n; \
23178 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23180 /* Make glyph_strings for each glyph sequence that is drawable by \
23181 the same face, and append them to HEAD/TAIL. */ \
23182 for (n = 0; n < cmp->glyph_len;) \
23184 s = alloca (sizeof *s); \
23185 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23186 append_glyph_string (&(HEAD), &(TAIL), s); \
23187 s->cmp = cmp; \
23188 s->cmp_from = n; \
23189 s->x = (X); \
23190 if (n == 0) \
23191 first_s = s; \
23192 n = fill_composite_glyph_string (s, base_face, overlaps); \
23195 ++START; \
23196 s = first_s; \
23197 } while (0)
23200 /* Add a glyph string for a glyph-string sequence to the list of strings
23201 between HEAD and TAIL. */
23203 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23204 do { \
23205 int face_id; \
23206 XChar2b *char2b; \
23207 Lisp_Object gstring; \
23209 face_id = (row)->glyphs[area][START].face_id; \
23210 gstring = (composition_gstring_from_id \
23211 ((row)->glyphs[area][START].u.cmp.id)); \
23212 s = alloca (sizeof *s); \
23213 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23214 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23215 append_glyph_string (&(HEAD), &(TAIL), s); \
23216 s->x = (X); \
23217 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23218 } while (0)
23221 /* Add a glyph string for a sequence of glyphless character's glyphs
23222 to the list of strings between HEAD and TAIL. The meanings of
23223 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23225 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23226 do \
23228 int face_id; \
23230 face_id = (row)->glyphs[area][START].face_id; \
23232 s = alloca (sizeof *s); \
23233 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23234 append_glyph_string (&HEAD, &TAIL, s); \
23235 s->x = (X); \
23236 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23237 overlaps); \
23239 while (0)
23242 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23243 of AREA of glyph row ROW on window W between indices START and END.
23244 HL overrides the face for drawing glyph strings, e.g. it is
23245 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23246 x-positions of the drawing area.
23248 This is an ugly monster macro construct because we must use alloca
23249 to allocate glyph strings (because draw_glyphs can be called
23250 asynchronously). */
23252 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23253 do \
23255 HEAD = TAIL = NULL; \
23256 while (START < END) \
23258 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23259 switch (first_glyph->type) \
23261 case CHAR_GLYPH: \
23262 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23263 HL, X, LAST_X); \
23264 break; \
23266 case COMPOSITE_GLYPH: \
23267 if (first_glyph->u.cmp.automatic) \
23268 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23269 HL, X, LAST_X); \
23270 else \
23271 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23272 HL, X, LAST_X); \
23273 break; \
23275 case STRETCH_GLYPH: \
23276 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23277 HL, X, LAST_X); \
23278 break; \
23280 case IMAGE_GLYPH: \
23281 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23282 HL, X, LAST_X); \
23283 break; \
23285 case GLYPHLESS_GLYPH: \
23286 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23287 HL, X, LAST_X); \
23288 break; \
23290 default: \
23291 emacs_abort (); \
23294 if (s) \
23296 set_glyph_string_background_width (s, START, LAST_X); \
23297 (X) += s->width; \
23300 } while (0)
23303 /* Draw glyphs between START and END in AREA of ROW on window W,
23304 starting at x-position X. X is relative to AREA in W. HL is a
23305 face-override with the following meaning:
23307 DRAW_NORMAL_TEXT draw normally
23308 DRAW_CURSOR draw in cursor face
23309 DRAW_MOUSE_FACE draw in mouse face.
23310 DRAW_INVERSE_VIDEO draw in mode line face
23311 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23312 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23314 If OVERLAPS is non-zero, draw only the foreground of characters and
23315 clip to the physical height of ROW. Non-zero value also defines
23316 the overlapping part to be drawn:
23318 OVERLAPS_PRED overlap with preceding rows
23319 OVERLAPS_SUCC overlap with succeeding rows
23320 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23321 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23323 Value is the x-position reached, relative to AREA of W. */
23325 static int
23326 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23327 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23328 enum draw_glyphs_face hl, int overlaps)
23330 struct glyph_string *head, *tail;
23331 struct glyph_string *s;
23332 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23333 int i, j, x_reached, last_x, area_left = 0;
23334 struct frame *f = XFRAME (WINDOW_FRAME (w));
23335 DECLARE_HDC (hdc);
23337 ALLOCATE_HDC (hdc, f);
23339 /* Let's rather be paranoid than getting a SEGV. */
23340 end = min (end, row->used[area]);
23341 start = clip_to_bounds (0, start, end);
23343 /* Translate X to frame coordinates. Set last_x to the right
23344 end of the drawing area. */
23345 if (row->full_width_p)
23347 /* X is relative to the left edge of W, without scroll bars
23348 or fringes. */
23349 area_left = WINDOW_LEFT_EDGE_X (w);
23350 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23352 else
23354 area_left = window_box_left (w, area);
23355 last_x = area_left + window_box_width (w, area);
23357 x += area_left;
23359 /* Build a doubly-linked list of glyph_string structures between
23360 head and tail from what we have to draw. Note that the macro
23361 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23362 the reason we use a separate variable `i'. */
23363 i = start;
23364 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23365 if (tail)
23366 x_reached = tail->x + tail->background_width;
23367 else
23368 x_reached = x;
23370 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23371 the row, redraw some glyphs in front or following the glyph
23372 strings built above. */
23373 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23375 struct glyph_string *h, *t;
23376 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23377 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23378 int check_mouse_face = 0;
23379 int dummy_x = 0;
23381 /* If mouse highlighting is on, we may need to draw adjacent
23382 glyphs using mouse-face highlighting. */
23383 if (area == TEXT_AREA && row->mouse_face_p
23384 && hlinfo->mouse_face_beg_row >= 0
23385 && hlinfo->mouse_face_end_row >= 0)
23387 struct glyph_row *mouse_beg_row, *mouse_end_row;
23389 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23390 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23392 if (row >= mouse_beg_row && row <= mouse_end_row)
23394 check_mouse_face = 1;
23395 mouse_beg_col = (row == mouse_beg_row)
23396 ? hlinfo->mouse_face_beg_col : 0;
23397 mouse_end_col = (row == mouse_end_row)
23398 ? hlinfo->mouse_face_end_col
23399 : row->used[TEXT_AREA];
23403 /* Compute overhangs for all glyph strings. */
23404 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23405 for (s = head; s; s = s->next)
23406 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23408 /* Prepend glyph strings for glyphs in front of the first glyph
23409 string that are overwritten because of the first glyph
23410 string's left overhang. The background of all strings
23411 prepended must be drawn because the first glyph string
23412 draws over it. */
23413 i = left_overwritten (head);
23414 if (i >= 0)
23416 enum draw_glyphs_face overlap_hl;
23418 /* If this row contains mouse highlighting, attempt to draw
23419 the overlapped glyphs with the correct highlight. This
23420 code fails if the overlap encompasses more than one glyph
23421 and mouse-highlight spans only some of these glyphs.
23422 However, making it work perfectly involves a lot more
23423 code, and I don't know if the pathological case occurs in
23424 practice, so we'll stick to this for now. --- cyd */
23425 if (check_mouse_face
23426 && mouse_beg_col < start && mouse_end_col > i)
23427 overlap_hl = DRAW_MOUSE_FACE;
23428 else
23429 overlap_hl = DRAW_NORMAL_TEXT;
23431 j = i;
23432 BUILD_GLYPH_STRINGS (j, start, h, t,
23433 overlap_hl, dummy_x, last_x);
23434 start = i;
23435 compute_overhangs_and_x (t, head->x, 1);
23436 prepend_glyph_string_lists (&head, &tail, h, t);
23437 clip_head = head;
23440 /* Prepend glyph strings for glyphs in front of the first glyph
23441 string that overwrite that glyph string because of their
23442 right overhang. For these strings, only the foreground must
23443 be drawn, because it draws over the glyph string at `head'.
23444 The background must not be drawn because this would overwrite
23445 right overhangs of preceding glyphs for which no glyph
23446 strings exist. */
23447 i = left_overwriting (head);
23448 if (i >= 0)
23450 enum draw_glyphs_face overlap_hl;
23452 if (check_mouse_face
23453 && mouse_beg_col < start && mouse_end_col > i)
23454 overlap_hl = DRAW_MOUSE_FACE;
23455 else
23456 overlap_hl = DRAW_NORMAL_TEXT;
23458 clip_head = head;
23459 BUILD_GLYPH_STRINGS (i, start, h, t,
23460 overlap_hl, dummy_x, last_x);
23461 for (s = h; s; s = s->next)
23462 s->background_filled_p = 1;
23463 compute_overhangs_and_x (t, head->x, 1);
23464 prepend_glyph_string_lists (&head, &tail, h, t);
23467 /* Append glyphs strings for glyphs following the last glyph
23468 string tail that are overwritten by tail. The background of
23469 these strings has to be drawn because tail's foreground draws
23470 over it. */
23471 i = right_overwritten (tail);
23472 if (i >= 0)
23474 enum draw_glyphs_face overlap_hl;
23476 if (check_mouse_face
23477 && mouse_beg_col < i && mouse_end_col > end)
23478 overlap_hl = DRAW_MOUSE_FACE;
23479 else
23480 overlap_hl = DRAW_NORMAL_TEXT;
23482 BUILD_GLYPH_STRINGS (end, i, h, t,
23483 overlap_hl, x, last_x);
23484 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23485 we don't have `end = i;' here. */
23486 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23487 append_glyph_string_lists (&head, &tail, h, t);
23488 clip_tail = tail;
23491 /* Append glyph strings for glyphs following the last glyph
23492 string tail that overwrite tail. The foreground of such
23493 glyphs has to be drawn because it writes into the background
23494 of tail. The background must not be drawn because it could
23495 paint over the foreground of following glyphs. */
23496 i = right_overwriting (tail);
23497 if (i >= 0)
23499 enum draw_glyphs_face overlap_hl;
23500 if (check_mouse_face
23501 && mouse_beg_col < i && mouse_end_col > end)
23502 overlap_hl = DRAW_MOUSE_FACE;
23503 else
23504 overlap_hl = DRAW_NORMAL_TEXT;
23506 clip_tail = tail;
23507 i++; /* We must include the Ith glyph. */
23508 BUILD_GLYPH_STRINGS (end, i, h, t,
23509 overlap_hl, x, last_x);
23510 for (s = h; s; s = s->next)
23511 s->background_filled_p = 1;
23512 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23513 append_glyph_string_lists (&head, &tail, h, t);
23515 if (clip_head || clip_tail)
23516 for (s = head; s; s = s->next)
23518 s->clip_head = clip_head;
23519 s->clip_tail = clip_tail;
23523 /* Draw all strings. */
23524 for (s = head; s; s = s->next)
23525 FRAME_RIF (f)->draw_glyph_string (s);
23527 #ifndef HAVE_NS
23528 /* When focus a sole frame and move horizontally, this sets on_p to 0
23529 causing a failure to erase prev cursor position. */
23530 if (area == TEXT_AREA
23531 && !row->full_width_p
23532 /* When drawing overlapping rows, only the glyph strings'
23533 foreground is drawn, which doesn't erase a cursor
23534 completely. */
23535 && !overlaps)
23537 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23538 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23539 : (tail ? tail->x + tail->background_width : x));
23540 x0 -= area_left;
23541 x1 -= area_left;
23543 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23544 row->y, MATRIX_ROW_BOTTOM_Y (row));
23546 #endif
23548 /* Value is the x-position up to which drawn, relative to AREA of W.
23549 This doesn't include parts drawn because of overhangs. */
23550 if (row->full_width_p)
23551 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23552 else
23553 x_reached -= area_left;
23555 RELEASE_HDC (hdc, f);
23557 return x_reached;
23560 /* Expand row matrix if too narrow. Don't expand if area
23561 is not present. */
23563 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23565 if (!fonts_changed_p \
23566 && (it->glyph_row->glyphs[area] \
23567 < it->glyph_row->glyphs[area + 1])) \
23569 it->w->ncols_scale_factor++; \
23570 fonts_changed_p = 1; \
23574 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23575 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23577 static void
23578 append_glyph (struct it *it)
23580 struct glyph *glyph;
23581 enum glyph_row_area area = it->area;
23583 eassert (it->glyph_row);
23584 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23586 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23587 if (glyph < it->glyph_row->glyphs[area + 1])
23589 /* If the glyph row is reversed, we need to prepend the glyph
23590 rather than append it. */
23591 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23593 struct glyph *g;
23595 /* Make room for the additional glyph. */
23596 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23597 g[1] = *g;
23598 glyph = it->glyph_row->glyphs[area];
23600 glyph->charpos = CHARPOS (it->position);
23601 glyph->object = it->object;
23602 if (it->pixel_width > 0)
23604 glyph->pixel_width = it->pixel_width;
23605 glyph->padding_p = 0;
23607 else
23609 /* Assure at least 1-pixel width. Otherwise, cursor can't
23610 be displayed correctly. */
23611 glyph->pixel_width = 1;
23612 glyph->padding_p = 1;
23614 glyph->ascent = it->ascent;
23615 glyph->descent = it->descent;
23616 glyph->voffset = it->voffset;
23617 glyph->type = CHAR_GLYPH;
23618 glyph->avoid_cursor_p = it->avoid_cursor_p;
23619 glyph->multibyte_p = it->multibyte_p;
23620 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23622 /* In R2L rows, the left and the right box edges need to be
23623 drawn in reverse direction. */
23624 glyph->right_box_line_p = it->start_of_box_run_p;
23625 glyph->left_box_line_p = it->end_of_box_run_p;
23627 else
23629 glyph->left_box_line_p = it->start_of_box_run_p;
23630 glyph->right_box_line_p = it->end_of_box_run_p;
23632 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23633 || it->phys_descent > it->descent);
23634 glyph->glyph_not_available_p = it->glyph_not_available_p;
23635 glyph->face_id = it->face_id;
23636 glyph->u.ch = it->char_to_display;
23637 glyph->slice.img = null_glyph_slice;
23638 glyph->font_type = FONT_TYPE_UNKNOWN;
23639 if (it->bidi_p)
23641 glyph->resolved_level = it->bidi_it.resolved_level;
23642 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23643 emacs_abort ();
23644 glyph->bidi_type = it->bidi_it.type;
23646 else
23648 glyph->resolved_level = 0;
23649 glyph->bidi_type = UNKNOWN_BT;
23651 ++it->glyph_row->used[area];
23653 else
23654 IT_EXPAND_MATRIX_WIDTH (it, area);
23657 /* Store one glyph for the composition IT->cmp_it.id in
23658 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23659 non-null. */
23661 static void
23662 append_composite_glyph (struct it *it)
23664 struct glyph *glyph;
23665 enum glyph_row_area area = it->area;
23667 eassert (it->glyph_row);
23669 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23670 if (glyph < it->glyph_row->glyphs[area + 1])
23672 /* If the glyph row is reversed, we need to prepend the glyph
23673 rather than append it. */
23674 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23676 struct glyph *g;
23678 /* Make room for the new glyph. */
23679 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23680 g[1] = *g;
23681 glyph = it->glyph_row->glyphs[it->area];
23683 glyph->charpos = it->cmp_it.charpos;
23684 glyph->object = it->object;
23685 glyph->pixel_width = it->pixel_width;
23686 glyph->ascent = it->ascent;
23687 glyph->descent = it->descent;
23688 glyph->voffset = it->voffset;
23689 glyph->type = COMPOSITE_GLYPH;
23690 if (it->cmp_it.ch < 0)
23692 glyph->u.cmp.automatic = 0;
23693 glyph->u.cmp.id = it->cmp_it.id;
23694 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23696 else
23698 glyph->u.cmp.automatic = 1;
23699 glyph->u.cmp.id = it->cmp_it.id;
23700 glyph->slice.cmp.from = it->cmp_it.from;
23701 glyph->slice.cmp.to = it->cmp_it.to - 1;
23703 glyph->avoid_cursor_p = it->avoid_cursor_p;
23704 glyph->multibyte_p = it->multibyte_p;
23705 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23707 /* In R2L rows, the left and the right box edges need to be
23708 drawn in reverse direction. */
23709 glyph->right_box_line_p = it->start_of_box_run_p;
23710 glyph->left_box_line_p = it->end_of_box_run_p;
23712 else
23714 glyph->left_box_line_p = it->start_of_box_run_p;
23715 glyph->right_box_line_p = it->end_of_box_run_p;
23717 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23718 || it->phys_descent > it->descent);
23719 glyph->padding_p = 0;
23720 glyph->glyph_not_available_p = 0;
23721 glyph->face_id = it->face_id;
23722 glyph->font_type = FONT_TYPE_UNKNOWN;
23723 if (it->bidi_p)
23725 glyph->resolved_level = it->bidi_it.resolved_level;
23726 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23727 emacs_abort ();
23728 glyph->bidi_type = it->bidi_it.type;
23730 ++it->glyph_row->used[area];
23732 else
23733 IT_EXPAND_MATRIX_WIDTH (it, area);
23737 /* Change IT->ascent and IT->height according to the setting of
23738 IT->voffset. */
23740 static void
23741 take_vertical_position_into_account (struct it *it)
23743 if (it->voffset)
23745 if (it->voffset < 0)
23746 /* Increase the ascent so that we can display the text higher
23747 in the line. */
23748 it->ascent -= it->voffset;
23749 else
23750 /* Increase the descent so that we can display the text lower
23751 in the line. */
23752 it->descent += it->voffset;
23757 /* Produce glyphs/get display metrics for the image IT is loaded with.
23758 See the description of struct display_iterator in dispextern.h for
23759 an overview of struct display_iterator. */
23761 static void
23762 produce_image_glyph (struct it *it)
23764 struct image *img;
23765 struct face *face;
23766 int glyph_ascent, crop;
23767 struct glyph_slice slice;
23769 eassert (it->what == IT_IMAGE);
23771 face = FACE_FROM_ID (it->f, it->face_id);
23772 eassert (face);
23773 /* Make sure X resources of the face is loaded. */
23774 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23776 if (it->image_id < 0)
23778 /* Fringe bitmap. */
23779 it->ascent = it->phys_ascent = 0;
23780 it->descent = it->phys_descent = 0;
23781 it->pixel_width = 0;
23782 it->nglyphs = 0;
23783 return;
23786 img = IMAGE_FROM_ID (it->f, it->image_id);
23787 eassert (img);
23788 /* Make sure X resources of the image is loaded. */
23789 prepare_image_for_display (it->f, img);
23791 slice.x = slice.y = 0;
23792 slice.width = img->width;
23793 slice.height = img->height;
23795 if (INTEGERP (it->slice.x))
23796 slice.x = XINT (it->slice.x);
23797 else if (FLOATP (it->slice.x))
23798 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23800 if (INTEGERP (it->slice.y))
23801 slice.y = XINT (it->slice.y);
23802 else if (FLOATP (it->slice.y))
23803 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23805 if (INTEGERP (it->slice.width))
23806 slice.width = XINT (it->slice.width);
23807 else if (FLOATP (it->slice.width))
23808 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23810 if (INTEGERP (it->slice.height))
23811 slice.height = XINT (it->slice.height);
23812 else if (FLOATP (it->slice.height))
23813 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23815 if (slice.x >= img->width)
23816 slice.x = img->width;
23817 if (slice.y >= img->height)
23818 slice.y = img->height;
23819 if (slice.x + slice.width >= img->width)
23820 slice.width = img->width - slice.x;
23821 if (slice.y + slice.height > img->height)
23822 slice.height = img->height - slice.y;
23824 if (slice.width == 0 || slice.height == 0)
23825 return;
23827 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23829 it->descent = slice.height - glyph_ascent;
23830 if (slice.y == 0)
23831 it->descent += img->vmargin;
23832 if (slice.y + slice.height == img->height)
23833 it->descent += img->vmargin;
23834 it->phys_descent = it->descent;
23836 it->pixel_width = slice.width;
23837 if (slice.x == 0)
23838 it->pixel_width += img->hmargin;
23839 if (slice.x + slice.width == img->width)
23840 it->pixel_width += img->hmargin;
23842 /* It's quite possible for images to have an ascent greater than
23843 their height, so don't get confused in that case. */
23844 if (it->descent < 0)
23845 it->descent = 0;
23847 it->nglyphs = 1;
23849 if (face->box != FACE_NO_BOX)
23851 if (face->box_line_width > 0)
23853 if (slice.y == 0)
23854 it->ascent += face->box_line_width;
23855 if (slice.y + slice.height == img->height)
23856 it->descent += face->box_line_width;
23859 if (it->start_of_box_run_p && slice.x == 0)
23860 it->pixel_width += eabs (face->box_line_width);
23861 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23862 it->pixel_width += eabs (face->box_line_width);
23865 take_vertical_position_into_account (it);
23867 /* Automatically crop wide image glyphs at right edge so we can
23868 draw the cursor on same display row. */
23869 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23870 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23872 it->pixel_width -= crop;
23873 slice.width -= crop;
23876 if (it->glyph_row)
23878 struct glyph *glyph;
23879 enum glyph_row_area area = it->area;
23881 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23882 if (glyph < it->glyph_row->glyphs[area + 1])
23884 glyph->charpos = CHARPOS (it->position);
23885 glyph->object = it->object;
23886 glyph->pixel_width = it->pixel_width;
23887 glyph->ascent = glyph_ascent;
23888 glyph->descent = it->descent;
23889 glyph->voffset = it->voffset;
23890 glyph->type = IMAGE_GLYPH;
23891 glyph->avoid_cursor_p = it->avoid_cursor_p;
23892 glyph->multibyte_p = it->multibyte_p;
23893 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23895 /* In R2L rows, the left and the right box edges need to be
23896 drawn in reverse direction. */
23897 glyph->right_box_line_p = it->start_of_box_run_p;
23898 glyph->left_box_line_p = it->end_of_box_run_p;
23900 else
23902 glyph->left_box_line_p = it->start_of_box_run_p;
23903 glyph->right_box_line_p = it->end_of_box_run_p;
23905 glyph->overlaps_vertically_p = 0;
23906 glyph->padding_p = 0;
23907 glyph->glyph_not_available_p = 0;
23908 glyph->face_id = it->face_id;
23909 glyph->u.img_id = img->id;
23910 glyph->slice.img = slice;
23911 glyph->font_type = FONT_TYPE_UNKNOWN;
23912 if (it->bidi_p)
23914 glyph->resolved_level = it->bidi_it.resolved_level;
23915 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23916 emacs_abort ();
23917 glyph->bidi_type = it->bidi_it.type;
23919 ++it->glyph_row->used[area];
23921 else
23922 IT_EXPAND_MATRIX_WIDTH (it, area);
23927 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23928 of the glyph, WIDTH and HEIGHT are the width and height of the
23929 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23931 static void
23932 append_stretch_glyph (struct it *it, Lisp_Object object,
23933 int width, int height, int ascent)
23935 struct glyph *glyph;
23936 enum glyph_row_area area = it->area;
23938 eassert (ascent >= 0 && ascent <= height);
23940 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23941 if (glyph < it->glyph_row->glyphs[area + 1])
23943 /* If the glyph row is reversed, we need to prepend the glyph
23944 rather than append it. */
23945 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23947 struct glyph *g;
23949 /* Make room for the additional glyph. */
23950 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23951 g[1] = *g;
23952 glyph = it->glyph_row->glyphs[area];
23954 glyph->charpos = CHARPOS (it->position);
23955 glyph->object = object;
23956 glyph->pixel_width = width;
23957 glyph->ascent = ascent;
23958 glyph->descent = height - ascent;
23959 glyph->voffset = it->voffset;
23960 glyph->type = STRETCH_GLYPH;
23961 glyph->avoid_cursor_p = it->avoid_cursor_p;
23962 glyph->multibyte_p = it->multibyte_p;
23963 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23965 /* In R2L rows, the left and the right box edges need to be
23966 drawn in reverse direction. */
23967 glyph->right_box_line_p = it->start_of_box_run_p;
23968 glyph->left_box_line_p = it->end_of_box_run_p;
23970 else
23972 glyph->left_box_line_p = it->start_of_box_run_p;
23973 glyph->right_box_line_p = it->end_of_box_run_p;
23975 glyph->overlaps_vertically_p = 0;
23976 glyph->padding_p = 0;
23977 glyph->glyph_not_available_p = 0;
23978 glyph->face_id = it->face_id;
23979 glyph->u.stretch.ascent = ascent;
23980 glyph->u.stretch.height = height;
23981 glyph->slice.img = null_glyph_slice;
23982 glyph->font_type = FONT_TYPE_UNKNOWN;
23983 if (it->bidi_p)
23985 glyph->resolved_level = it->bidi_it.resolved_level;
23986 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23987 emacs_abort ();
23988 glyph->bidi_type = it->bidi_it.type;
23990 else
23992 glyph->resolved_level = 0;
23993 glyph->bidi_type = UNKNOWN_BT;
23995 ++it->glyph_row->used[area];
23997 else
23998 IT_EXPAND_MATRIX_WIDTH (it, area);
24001 #endif /* HAVE_WINDOW_SYSTEM */
24003 /* Produce a stretch glyph for iterator IT. IT->object is the value
24004 of the glyph property displayed. The value must be a list
24005 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24006 being recognized:
24008 1. `:width WIDTH' specifies that the space should be WIDTH *
24009 canonical char width wide. WIDTH may be an integer or floating
24010 point number.
24012 2. `:relative-width FACTOR' specifies that the width of the stretch
24013 should be computed from the width of the first character having the
24014 `glyph' property, and should be FACTOR times that width.
24016 3. `:align-to HPOS' specifies that the space should be wide enough
24017 to reach HPOS, a value in canonical character units.
24019 Exactly one of the above pairs must be present.
24021 4. `:height HEIGHT' specifies that the height of the stretch produced
24022 should be HEIGHT, measured in canonical character units.
24024 5. `:relative-height FACTOR' specifies that the height of the
24025 stretch should be FACTOR times the height of the characters having
24026 the glyph property.
24028 Either none or exactly one of 4 or 5 must be present.
24030 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24031 of the stretch should be used for the ascent of the stretch.
24032 ASCENT must be in the range 0 <= ASCENT <= 100. */
24034 void
24035 produce_stretch_glyph (struct it *it)
24037 /* (space :width WIDTH :height HEIGHT ...) */
24038 Lisp_Object prop, plist;
24039 int width = 0, height = 0, align_to = -1;
24040 int zero_width_ok_p = 0;
24041 double tem;
24042 struct font *font = NULL;
24044 #ifdef HAVE_WINDOW_SYSTEM
24045 int ascent = 0;
24046 int zero_height_ok_p = 0;
24048 if (FRAME_WINDOW_P (it->f))
24050 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24051 font = face->font ? face->font : FRAME_FONT (it->f);
24052 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24054 #endif
24056 /* List should start with `space'. */
24057 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24058 plist = XCDR (it->object);
24060 /* Compute the width of the stretch. */
24061 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24062 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24064 /* Absolute width `:width WIDTH' specified and valid. */
24065 zero_width_ok_p = 1;
24066 width = (int)tem;
24068 #ifdef HAVE_WINDOW_SYSTEM
24069 else if (FRAME_WINDOW_P (it->f)
24070 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24072 /* Relative width `:relative-width FACTOR' specified and valid.
24073 Compute the width of the characters having the `glyph'
24074 property. */
24075 struct it it2;
24076 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24078 it2 = *it;
24079 if (it->multibyte_p)
24080 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24081 else
24083 it2.c = it2.char_to_display = *p, it2.len = 1;
24084 if (! ASCII_CHAR_P (it2.c))
24085 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24088 it2.glyph_row = NULL;
24089 it2.what = IT_CHARACTER;
24090 x_produce_glyphs (&it2);
24091 width = NUMVAL (prop) * it2.pixel_width;
24093 #endif /* HAVE_WINDOW_SYSTEM */
24094 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24095 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24097 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24098 align_to = (align_to < 0
24100 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24101 else if (align_to < 0)
24102 align_to = window_box_left_offset (it->w, TEXT_AREA);
24103 width = max (0, (int)tem + align_to - it->current_x);
24104 zero_width_ok_p = 1;
24106 else
24107 /* Nothing specified -> width defaults to canonical char width. */
24108 width = FRAME_COLUMN_WIDTH (it->f);
24110 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24111 width = 1;
24113 #ifdef HAVE_WINDOW_SYSTEM
24114 /* Compute height. */
24115 if (FRAME_WINDOW_P (it->f))
24117 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24118 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24120 height = (int)tem;
24121 zero_height_ok_p = 1;
24123 else if (prop = Fplist_get (plist, QCrelative_height),
24124 NUMVAL (prop) > 0)
24125 height = FONT_HEIGHT (font) * NUMVAL (prop);
24126 else
24127 height = FONT_HEIGHT (font);
24129 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24130 height = 1;
24132 /* Compute percentage of height used for ascent. If
24133 `:ascent ASCENT' is present and valid, use that. Otherwise,
24134 derive the ascent from the font in use. */
24135 if (prop = Fplist_get (plist, QCascent),
24136 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24137 ascent = height * NUMVAL (prop) / 100.0;
24138 else if (!NILP (prop)
24139 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24140 ascent = min (max (0, (int)tem), height);
24141 else
24142 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24144 else
24145 #endif /* HAVE_WINDOW_SYSTEM */
24146 height = 1;
24148 if (width > 0 && it->line_wrap != TRUNCATE
24149 && it->current_x + width > it->last_visible_x)
24151 width = it->last_visible_x - it->current_x;
24152 #ifdef HAVE_WINDOW_SYSTEM
24153 /* Subtract one more pixel from the stretch width, but only on
24154 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24155 width -= FRAME_WINDOW_P (it->f);
24156 #endif
24159 if (width > 0 && height > 0 && it->glyph_row)
24161 Lisp_Object o_object = it->object;
24162 Lisp_Object object = it->stack[it->sp - 1].string;
24163 int n = width;
24165 if (!STRINGP (object))
24166 object = it->w->contents;
24167 #ifdef HAVE_WINDOW_SYSTEM
24168 if (FRAME_WINDOW_P (it->f))
24169 append_stretch_glyph (it, object, width, height, ascent);
24170 else
24171 #endif
24173 it->object = object;
24174 it->char_to_display = ' ';
24175 it->pixel_width = it->len = 1;
24176 while (n--)
24177 tty_append_glyph (it);
24178 it->object = o_object;
24182 it->pixel_width = width;
24183 #ifdef HAVE_WINDOW_SYSTEM
24184 if (FRAME_WINDOW_P (it->f))
24186 it->ascent = it->phys_ascent = ascent;
24187 it->descent = it->phys_descent = height - it->ascent;
24188 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24189 take_vertical_position_into_account (it);
24191 else
24192 #endif
24193 it->nglyphs = width;
24196 /* Get information about special display element WHAT in an
24197 environment described by IT. WHAT is one of IT_TRUNCATION or
24198 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24199 non-null glyph_row member. This function ensures that fields like
24200 face_id, c, len of IT are left untouched. */
24202 static void
24203 produce_special_glyphs (struct it *it, enum display_element_type what)
24205 struct it temp_it;
24206 Lisp_Object gc;
24207 GLYPH glyph;
24209 temp_it = *it;
24210 temp_it.object = make_number (0);
24211 memset (&temp_it.current, 0, sizeof temp_it.current);
24213 if (what == IT_CONTINUATION)
24215 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24216 if (it->bidi_it.paragraph_dir == R2L)
24217 SET_GLYPH_FROM_CHAR (glyph, '/');
24218 else
24219 SET_GLYPH_FROM_CHAR (glyph, '\\');
24220 if (it->dp
24221 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24223 /* FIXME: Should we mirror GC for R2L lines? */
24224 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24225 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24228 else if (what == IT_TRUNCATION)
24230 /* Truncation glyph. */
24231 SET_GLYPH_FROM_CHAR (glyph, '$');
24232 if (it->dp
24233 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24235 /* FIXME: Should we mirror GC for R2L lines? */
24236 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24237 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24240 else
24241 emacs_abort ();
24243 #ifdef HAVE_WINDOW_SYSTEM
24244 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24245 is turned off, we precede the truncation/continuation glyphs by a
24246 stretch glyph whose width is computed such that these special
24247 glyphs are aligned at the window margin, even when very different
24248 fonts are used in different glyph rows. */
24249 if (FRAME_WINDOW_P (temp_it.f)
24250 /* init_iterator calls this with it->glyph_row == NULL, and it
24251 wants only the pixel width of the truncation/continuation
24252 glyphs. */
24253 && temp_it.glyph_row
24254 /* insert_left_trunc_glyphs calls us at the beginning of the
24255 row, and it has its own calculation of the stretch glyph
24256 width. */
24257 && temp_it.glyph_row->used[TEXT_AREA] > 0
24258 && (temp_it.glyph_row->reversed_p
24259 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24260 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24262 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24264 if (stretch_width > 0)
24266 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24267 struct font *font =
24268 face->font ? face->font : FRAME_FONT (temp_it.f);
24269 int stretch_ascent =
24270 (((temp_it.ascent + temp_it.descent)
24271 * FONT_BASE (font)) / FONT_HEIGHT (font));
24273 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24274 temp_it.ascent + temp_it.descent,
24275 stretch_ascent);
24278 #endif
24280 temp_it.dp = NULL;
24281 temp_it.what = IT_CHARACTER;
24282 temp_it.len = 1;
24283 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24284 temp_it.face_id = GLYPH_FACE (glyph);
24285 temp_it.len = CHAR_BYTES (temp_it.c);
24287 PRODUCE_GLYPHS (&temp_it);
24288 it->pixel_width = temp_it.pixel_width;
24289 it->nglyphs = temp_it.pixel_width;
24292 #ifdef HAVE_WINDOW_SYSTEM
24294 /* Calculate line-height and line-spacing properties.
24295 An integer value specifies explicit pixel value.
24296 A float value specifies relative value to current face height.
24297 A cons (float . face-name) specifies relative value to
24298 height of specified face font.
24300 Returns height in pixels, or nil. */
24303 static Lisp_Object
24304 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24305 int boff, int override)
24307 Lisp_Object face_name = Qnil;
24308 int ascent, descent, height;
24310 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24311 return val;
24313 if (CONSP (val))
24315 face_name = XCAR (val);
24316 val = XCDR (val);
24317 if (!NUMBERP (val))
24318 val = make_number (1);
24319 if (NILP (face_name))
24321 height = it->ascent + it->descent;
24322 goto scale;
24326 if (NILP (face_name))
24328 font = FRAME_FONT (it->f);
24329 boff = FRAME_BASELINE_OFFSET (it->f);
24331 else if (EQ (face_name, Qt))
24333 override = 0;
24335 else
24337 int face_id;
24338 struct face *face;
24340 face_id = lookup_named_face (it->f, face_name, 0);
24341 if (face_id < 0)
24342 return make_number (-1);
24344 face = FACE_FROM_ID (it->f, face_id);
24345 font = face->font;
24346 if (font == NULL)
24347 return make_number (-1);
24348 boff = font->baseline_offset;
24349 if (font->vertical_centering)
24350 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24353 ascent = FONT_BASE (font) + boff;
24354 descent = FONT_DESCENT (font) - boff;
24356 if (override)
24358 it->override_ascent = ascent;
24359 it->override_descent = descent;
24360 it->override_boff = boff;
24363 height = ascent + descent;
24365 scale:
24366 if (FLOATP (val))
24367 height = (int)(XFLOAT_DATA (val) * height);
24368 else if (INTEGERP (val))
24369 height *= XINT (val);
24371 return make_number (height);
24375 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24376 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24377 and only if this is for a character for which no font was found.
24379 If the display method (it->glyphless_method) is
24380 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24381 length of the acronym or the hexadecimal string, UPPER_XOFF and
24382 UPPER_YOFF are pixel offsets for the upper part of the string,
24383 LOWER_XOFF and LOWER_YOFF are for the lower part.
24385 For the other display methods, LEN through LOWER_YOFF are zero. */
24387 static void
24388 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24389 short upper_xoff, short upper_yoff,
24390 short lower_xoff, short lower_yoff)
24392 struct glyph *glyph;
24393 enum glyph_row_area area = it->area;
24395 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24396 if (glyph < it->glyph_row->glyphs[area + 1])
24398 /* If the glyph row is reversed, we need to prepend the glyph
24399 rather than append it. */
24400 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24402 struct glyph *g;
24404 /* Make room for the additional glyph. */
24405 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24406 g[1] = *g;
24407 glyph = it->glyph_row->glyphs[area];
24409 glyph->charpos = CHARPOS (it->position);
24410 glyph->object = it->object;
24411 glyph->pixel_width = it->pixel_width;
24412 glyph->ascent = it->ascent;
24413 glyph->descent = it->descent;
24414 glyph->voffset = it->voffset;
24415 glyph->type = GLYPHLESS_GLYPH;
24416 glyph->u.glyphless.method = it->glyphless_method;
24417 glyph->u.glyphless.for_no_font = for_no_font;
24418 glyph->u.glyphless.len = len;
24419 glyph->u.glyphless.ch = it->c;
24420 glyph->slice.glyphless.upper_xoff = upper_xoff;
24421 glyph->slice.glyphless.upper_yoff = upper_yoff;
24422 glyph->slice.glyphless.lower_xoff = lower_xoff;
24423 glyph->slice.glyphless.lower_yoff = lower_yoff;
24424 glyph->avoid_cursor_p = it->avoid_cursor_p;
24425 glyph->multibyte_p = it->multibyte_p;
24426 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24428 /* In R2L rows, the left and the right box edges need to be
24429 drawn in reverse direction. */
24430 glyph->right_box_line_p = it->start_of_box_run_p;
24431 glyph->left_box_line_p = it->end_of_box_run_p;
24433 else
24435 glyph->left_box_line_p = it->start_of_box_run_p;
24436 glyph->right_box_line_p = it->end_of_box_run_p;
24438 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24439 || it->phys_descent > it->descent);
24440 glyph->padding_p = 0;
24441 glyph->glyph_not_available_p = 0;
24442 glyph->face_id = face_id;
24443 glyph->font_type = FONT_TYPE_UNKNOWN;
24444 if (it->bidi_p)
24446 glyph->resolved_level = it->bidi_it.resolved_level;
24447 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24448 emacs_abort ();
24449 glyph->bidi_type = it->bidi_it.type;
24451 ++it->glyph_row->used[area];
24453 else
24454 IT_EXPAND_MATRIX_WIDTH (it, area);
24458 /* Produce a glyph for a glyphless character for iterator IT.
24459 IT->glyphless_method specifies which method to use for displaying
24460 the character. See the description of enum
24461 glyphless_display_method in dispextern.h for the detail.
24463 FOR_NO_FONT is nonzero if and only if this is for a character for
24464 which no font was found. ACRONYM, if non-nil, is an acronym string
24465 for the character. */
24467 static void
24468 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24470 int face_id;
24471 struct face *face;
24472 struct font *font;
24473 int base_width, base_height, width, height;
24474 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24475 int len;
24477 /* Get the metrics of the base font. We always refer to the current
24478 ASCII face. */
24479 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24480 font = face->font ? face->font : FRAME_FONT (it->f);
24481 it->ascent = FONT_BASE (font) + font->baseline_offset;
24482 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24483 base_height = it->ascent + it->descent;
24484 base_width = font->average_width;
24486 /* Get a face ID for the glyph by utilizing a cache (the same way as
24487 done for `escape-glyph' in get_next_display_element). */
24488 if (it->f == last_glyphless_glyph_frame
24489 && it->face_id == last_glyphless_glyph_face_id)
24491 face_id = last_glyphless_glyph_merged_face_id;
24493 else
24495 /* Merge the `glyphless-char' face into the current face. */
24496 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24497 last_glyphless_glyph_frame = it->f;
24498 last_glyphless_glyph_face_id = it->face_id;
24499 last_glyphless_glyph_merged_face_id = face_id;
24502 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24504 it->pixel_width = THIN_SPACE_WIDTH;
24505 len = 0;
24506 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24508 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24510 width = CHAR_WIDTH (it->c);
24511 if (width == 0)
24512 width = 1;
24513 else if (width > 4)
24514 width = 4;
24515 it->pixel_width = base_width * width;
24516 len = 0;
24517 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24519 else
24521 char buf[7];
24522 const char *str;
24523 unsigned int code[6];
24524 int upper_len;
24525 int ascent, descent;
24526 struct font_metrics metrics_upper, metrics_lower;
24528 face = FACE_FROM_ID (it->f, face_id);
24529 font = face->font ? face->font : FRAME_FONT (it->f);
24530 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24532 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24534 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24535 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24536 if (CONSP (acronym))
24537 acronym = XCAR (acronym);
24538 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24540 else
24542 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24543 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24544 str = buf;
24546 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24547 code[len] = font->driver->encode_char (font, str[len]);
24548 upper_len = (len + 1) / 2;
24549 font->driver->text_extents (font, code, upper_len,
24550 &metrics_upper);
24551 font->driver->text_extents (font, code + upper_len, len - upper_len,
24552 &metrics_lower);
24556 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24557 width = max (metrics_upper.width, metrics_lower.width) + 4;
24558 upper_xoff = upper_yoff = 2; /* the typical case */
24559 if (base_width >= width)
24561 /* Align the upper to the left, the lower to the right. */
24562 it->pixel_width = base_width;
24563 lower_xoff = base_width - 2 - metrics_lower.width;
24565 else
24567 /* Center the shorter one. */
24568 it->pixel_width = width;
24569 if (metrics_upper.width >= metrics_lower.width)
24570 lower_xoff = (width - metrics_lower.width) / 2;
24571 else
24573 /* FIXME: This code doesn't look right. It formerly was
24574 missing the "lower_xoff = 0;", which couldn't have
24575 been right since it left lower_xoff uninitialized. */
24576 lower_xoff = 0;
24577 upper_xoff = (width - metrics_upper.width) / 2;
24581 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24582 top, bottom, and between upper and lower strings. */
24583 height = (metrics_upper.ascent + metrics_upper.descent
24584 + metrics_lower.ascent + metrics_lower.descent) + 5;
24585 /* Center vertically.
24586 H:base_height, D:base_descent
24587 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24589 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24590 descent = D - H/2 + h/2;
24591 lower_yoff = descent - 2 - ld;
24592 upper_yoff = lower_yoff - la - 1 - ud; */
24593 ascent = - (it->descent - (base_height + height + 1) / 2);
24594 descent = it->descent - (base_height - height) / 2;
24595 lower_yoff = descent - 2 - metrics_lower.descent;
24596 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
24597 - metrics_upper.descent);
24598 /* Don't make the height shorter than the base height. */
24599 if (height > base_height)
24601 it->ascent = ascent;
24602 it->descent = descent;
24606 it->phys_ascent = it->ascent;
24607 it->phys_descent = it->descent;
24608 if (it->glyph_row)
24609 append_glyphless_glyph (it, face_id, for_no_font, len,
24610 upper_xoff, upper_yoff,
24611 lower_xoff, lower_yoff);
24612 it->nglyphs = 1;
24613 take_vertical_position_into_account (it);
24617 /* RIF:
24618 Produce glyphs/get display metrics for the display element IT is
24619 loaded with. See the description of struct it in dispextern.h
24620 for an overview of struct it. */
24622 void
24623 x_produce_glyphs (struct it *it)
24625 int extra_line_spacing = it->extra_line_spacing;
24627 it->glyph_not_available_p = 0;
24629 if (it->what == IT_CHARACTER)
24631 XChar2b char2b;
24632 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24633 struct font *font = face->font;
24634 struct font_metrics *pcm = NULL;
24635 int boff; /* baseline offset */
24637 if (font == NULL)
24639 /* When no suitable font is found, display this character by
24640 the method specified in the first extra slot of
24641 Vglyphless_char_display. */
24642 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
24644 eassert (it->what == IT_GLYPHLESS);
24645 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
24646 goto done;
24649 boff = font->baseline_offset;
24650 if (font->vertical_centering)
24651 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24653 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24655 int stretched_p;
24657 it->nglyphs = 1;
24659 if (it->override_ascent >= 0)
24661 it->ascent = it->override_ascent;
24662 it->descent = it->override_descent;
24663 boff = it->override_boff;
24665 else
24667 it->ascent = FONT_BASE (font) + boff;
24668 it->descent = FONT_DESCENT (font) - boff;
24671 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24673 pcm = get_per_char_metric (font, &char2b);
24674 if (pcm->width == 0
24675 && pcm->rbearing == 0 && pcm->lbearing == 0)
24676 pcm = NULL;
24679 if (pcm)
24681 it->phys_ascent = pcm->ascent + boff;
24682 it->phys_descent = pcm->descent - boff;
24683 it->pixel_width = pcm->width;
24685 else
24687 it->glyph_not_available_p = 1;
24688 it->phys_ascent = it->ascent;
24689 it->phys_descent = it->descent;
24690 it->pixel_width = font->space_width;
24693 if (it->constrain_row_ascent_descent_p)
24695 if (it->descent > it->max_descent)
24697 it->ascent += it->descent - it->max_descent;
24698 it->descent = it->max_descent;
24700 if (it->ascent > it->max_ascent)
24702 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24703 it->ascent = it->max_ascent;
24705 it->phys_ascent = min (it->phys_ascent, it->ascent);
24706 it->phys_descent = min (it->phys_descent, it->descent);
24707 extra_line_spacing = 0;
24710 /* If this is a space inside a region of text with
24711 `space-width' property, change its width. */
24712 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24713 if (stretched_p)
24714 it->pixel_width *= XFLOATINT (it->space_width);
24716 /* If face has a box, add the box thickness to the character
24717 height. If character has a box line to the left and/or
24718 right, add the box line width to the character's width. */
24719 if (face->box != FACE_NO_BOX)
24721 int thick = face->box_line_width;
24723 if (thick > 0)
24725 it->ascent += thick;
24726 it->descent += thick;
24728 else
24729 thick = -thick;
24731 if (it->start_of_box_run_p)
24732 it->pixel_width += thick;
24733 if (it->end_of_box_run_p)
24734 it->pixel_width += thick;
24737 /* If face has an overline, add the height of the overline
24738 (1 pixel) and a 1 pixel margin to the character height. */
24739 if (face->overline_p)
24740 it->ascent += overline_margin;
24742 if (it->constrain_row_ascent_descent_p)
24744 if (it->ascent > it->max_ascent)
24745 it->ascent = it->max_ascent;
24746 if (it->descent > it->max_descent)
24747 it->descent = it->max_descent;
24750 take_vertical_position_into_account (it);
24752 /* If we have to actually produce glyphs, do it. */
24753 if (it->glyph_row)
24755 if (stretched_p)
24757 /* Translate a space with a `space-width' property
24758 into a stretch glyph. */
24759 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24760 / FONT_HEIGHT (font));
24761 append_stretch_glyph (it, it->object, it->pixel_width,
24762 it->ascent + it->descent, ascent);
24764 else
24765 append_glyph (it);
24767 /* If characters with lbearing or rbearing are displayed
24768 in this line, record that fact in a flag of the
24769 glyph row. This is used to optimize X output code. */
24770 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24771 it->glyph_row->contains_overlapping_glyphs_p = 1;
24773 if (! stretched_p && it->pixel_width == 0)
24774 /* We assure that all visible glyphs have at least 1-pixel
24775 width. */
24776 it->pixel_width = 1;
24778 else if (it->char_to_display == '\n')
24780 /* A newline has no width, but we need the height of the
24781 line. But if previous part of the line sets a height,
24782 don't increase that height */
24784 Lisp_Object height;
24785 Lisp_Object total_height = Qnil;
24787 it->override_ascent = -1;
24788 it->pixel_width = 0;
24789 it->nglyphs = 0;
24791 height = get_it_property (it, Qline_height);
24792 /* Split (line-height total-height) list */
24793 if (CONSP (height)
24794 && CONSP (XCDR (height))
24795 && NILP (XCDR (XCDR (height))))
24797 total_height = XCAR (XCDR (height));
24798 height = XCAR (height);
24800 height = calc_line_height_property (it, height, font, boff, 1);
24802 if (it->override_ascent >= 0)
24804 it->ascent = it->override_ascent;
24805 it->descent = it->override_descent;
24806 boff = it->override_boff;
24808 else
24810 it->ascent = FONT_BASE (font) + boff;
24811 it->descent = FONT_DESCENT (font) - boff;
24814 if (EQ (height, Qt))
24816 if (it->descent > it->max_descent)
24818 it->ascent += it->descent - it->max_descent;
24819 it->descent = it->max_descent;
24821 if (it->ascent > it->max_ascent)
24823 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24824 it->ascent = it->max_ascent;
24826 it->phys_ascent = min (it->phys_ascent, it->ascent);
24827 it->phys_descent = min (it->phys_descent, it->descent);
24828 it->constrain_row_ascent_descent_p = 1;
24829 extra_line_spacing = 0;
24831 else
24833 Lisp_Object spacing;
24835 it->phys_ascent = it->ascent;
24836 it->phys_descent = it->descent;
24838 if ((it->max_ascent > 0 || it->max_descent > 0)
24839 && face->box != FACE_NO_BOX
24840 && face->box_line_width > 0)
24842 it->ascent += face->box_line_width;
24843 it->descent += face->box_line_width;
24845 if (!NILP (height)
24846 && XINT (height) > it->ascent + it->descent)
24847 it->ascent = XINT (height) - it->descent;
24849 if (!NILP (total_height))
24850 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24851 else
24853 spacing = get_it_property (it, Qline_spacing);
24854 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24856 if (INTEGERP (spacing))
24858 extra_line_spacing = XINT (spacing);
24859 if (!NILP (total_height))
24860 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24864 else /* i.e. (it->char_to_display == '\t') */
24866 if (font->space_width > 0)
24868 int tab_width = it->tab_width * font->space_width;
24869 int x = it->current_x + it->continuation_lines_width;
24870 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24872 /* If the distance from the current position to the next tab
24873 stop is less than a space character width, use the
24874 tab stop after that. */
24875 if (next_tab_x - x < font->space_width)
24876 next_tab_x += tab_width;
24878 it->pixel_width = next_tab_x - x;
24879 it->nglyphs = 1;
24880 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24881 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24883 if (it->glyph_row)
24885 append_stretch_glyph (it, it->object, it->pixel_width,
24886 it->ascent + it->descent, it->ascent);
24889 else
24891 it->pixel_width = 0;
24892 it->nglyphs = 1;
24896 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24898 /* A static composition.
24900 Note: A composition is represented as one glyph in the
24901 glyph matrix. There are no padding glyphs.
24903 Important note: pixel_width, ascent, and descent are the
24904 values of what is drawn by draw_glyphs (i.e. the values of
24905 the overall glyphs composed). */
24906 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24907 int boff; /* baseline offset */
24908 struct composition *cmp = composition_table[it->cmp_it.id];
24909 int glyph_len = cmp->glyph_len;
24910 struct font *font = face->font;
24912 it->nglyphs = 1;
24914 /* If we have not yet calculated pixel size data of glyphs of
24915 the composition for the current face font, calculate them
24916 now. Theoretically, we have to check all fonts for the
24917 glyphs, but that requires much time and memory space. So,
24918 here we check only the font of the first glyph. This may
24919 lead to incorrect display, but it's very rare, and C-l
24920 (recenter-top-bottom) can correct the display anyway. */
24921 if (! cmp->font || cmp->font != font)
24923 /* Ascent and descent of the font of the first character
24924 of this composition (adjusted by baseline offset).
24925 Ascent and descent of overall glyphs should not be less
24926 than these, respectively. */
24927 int font_ascent, font_descent, font_height;
24928 /* Bounding box of the overall glyphs. */
24929 int leftmost, rightmost, lowest, highest;
24930 int lbearing, rbearing;
24931 int i, width, ascent, descent;
24932 int left_padded = 0, right_padded = 0;
24933 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24934 XChar2b char2b;
24935 struct font_metrics *pcm;
24936 int font_not_found_p;
24937 ptrdiff_t pos;
24939 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24940 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24941 break;
24942 if (glyph_len < cmp->glyph_len)
24943 right_padded = 1;
24944 for (i = 0; i < glyph_len; i++)
24946 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24947 break;
24948 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24950 if (i > 0)
24951 left_padded = 1;
24953 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24954 : IT_CHARPOS (*it));
24955 /* If no suitable font is found, use the default font. */
24956 font_not_found_p = font == NULL;
24957 if (font_not_found_p)
24959 face = face->ascii_face;
24960 font = face->font;
24962 boff = font->baseline_offset;
24963 if (font->vertical_centering)
24964 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24965 font_ascent = FONT_BASE (font) + boff;
24966 font_descent = FONT_DESCENT (font) - boff;
24967 font_height = FONT_HEIGHT (font);
24969 cmp->font = font;
24971 pcm = NULL;
24972 if (! font_not_found_p)
24974 get_char_face_and_encoding (it->f, c, it->face_id,
24975 &char2b, 0);
24976 pcm = get_per_char_metric (font, &char2b);
24979 /* Initialize the bounding box. */
24980 if (pcm)
24982 width = cmp->glyph_len > 0 ? pcm->width : 0;
24983 ascent = pcm->ascent;
24984 descent = pcm->descent;
24985 lbearing = pcm->lbearing;
24986 rbearing = pcm->rbearing;
24988 else
24990 width = cmp->glyph_len > 0 ? font->space_width : 0;
24991 ascent = FONT_BASE (font);
24992 descent = FONT_DESCENT (font);
24993 lbearing = 0;
24994 rbearing = width;
24997 rightmost = width;
24998 leftmost = 0;
24999 lowest = - descent + boff;
25000 highest = ascent + boff;
25002 if (! font_not_found_p
25003 && font->default_ascent
25004 && CHAR_TABLE_P (Vuse_default_ascent)
25005 && !NILP (Faref (Vuse_default_ascent,
25006 make_number (it->char_to_display))))
25007 highest = font->default_ascent + boff;
25009 /* Draw the first glyph at the normal position. It may be
25010 shifted to right later if some other glyphs are drawn
25011 at the left. */
25012 cmp->offsets[i * 2] = 0;
25013 cmp->offsets[i * 2 + 1] = boff;
25014 cmp->lbearing = lbearing;
25015 cmp->rbearing = rbearing;
25017 /* Set cmp->offsets for the remaining glyphs. */
25018 for (i++; i < glyph_len; i++)
25020 int left, right, btm, top;
25021 int ch = COMPOSITION_GLYPH (cmp, i);
25022 int face_id;
25023 struct face *this_face;
25025 if (ch == '\t')
25026 ch = ' ';
25027 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25028 this_face = FACE_FROM_ID (it->f, face_id);
25029 font = this_face->font;
25031 if (font == NULL)
25032 pcm = NULL;
25033 else
25035 get_char_face_and_encoding (it->f, ch, face_id,
25036 &char2b, 0);
25037 pcm = get_per_char_metric (font, &char2b);
25039 if (! pcm)
25040 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25041 else
25043 width = pcm->width;
25044 ascent = pcm->ascent;
25045 descent = pcm->descent;
25046 lbearing = pcm->lbearing;
25047 rbearing = pcm->rbearing;
25048 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25050 /* Relative composition with or without
25051 alternate chars. */
25052 left = (leftmost + rightmost - width) / 2;
25053 btm = - descent + boff;
25054 if (font->relative_compose
25055 && (! CHAR_TABLE_P (Vignore_relative_composition)
25056 || NILP (Faref (Vignore_relative_composition,
25057 make_number (ch)))))
25060 if (- descent >= font->relative_compose)
25061 /* One extra pixel between two glyphs. */
25062 btm = highest + 1;
25063 else if (ascent <= 0)
25064 /* One extra pixel between two glyphs. */
25065 btm = lowest - 1 - ascent - descent;
25068 else
25070 /* A composition rule is specified by an integer
25071 value that encodes global and new reference
25072 points (GREF and NREF). GREF and NREF are
25073 specified by numbers as below:
25075 0---1---2 -- ascent
25079 9--10--11 -- center
25081 ---3---4---5--- baseline
25083 6---7---8 -- descent
25085 int rule = COMPOSITION_RULE (cmp, i);
25086 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25088 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25089 grefx = gref % 3, nrefx = nref % 3;
25090 grefy = gref / 3, nrefy = nref / 3;
25091 if (xoff)
25092 xoff = font_height * (xoff - 128) / 256;
25093 if (yoff)
25094 yoff = font_height * (yoff - 128) / 256;
25096 left = (leftmost
25097 + grefx * (rightmost - leftmost) / 2
25098 - nrefx * width / 2
25099 + xoff);
25101 btm = ((grefy == 0 ? highest
25102 : grefy == 1 ? 0
25103 : grefy == 2 ? lowest
25104 : (highest + lowest) / 2)
25105 - (nrefy == 0 ? ascent + descent
25106 : nrefy == 1 ? descent - boff
25107 : nrefy == 2 ? 0
25108 : (ascent + descent) / 2)
25109 + yoff);
25112 cmp->offsets[i * 2] = left;
25113 cmp->offsets[i * 2 + 1] = btm + descent;
25115 /* Update the bounding box of the overall glyphs. */
25116 if (width > 0)
25118 right = left + width;
25119 if (left < leftmost)
25120 leftmost = left;
25121 if (right > rightmost)
25122 rightmost = right;
25124 top = btm + descent + ascent;
25125 if (top > highest)
25126 highest = top;
25127 if (btm < lowest)
25128 lowest = btm;
25130 if (cmp->lbearing > left + lbearing)
25131 cmp->lbearing = left + lbearing;
25132 if (cmp->rbearing < left + rbearing)
25133 cmp->rbearing = left + rbearing;
25137 /* If there are glyphs whose x-offsets are negative,
25138 shift all glyphs to the right and make all x-offsets
25139 non-negative. */
25140 if (leftmost < 0)
25142 for (i = 0; i < cmp->glyph_len; i++)
25143 cmp->offsets[i * 2] -= leftmost;
25144 rightmost -= leftmost;
25145 cmp->lbearing -= leftmost;
25146 cmp->rbearing -= leftmost;
25149 if (left_padded && cmp->lbearing < 0)
25151 for (i = 0; i < cmp->glyph_len; i++)
25152 cmp->offsets[i * 2] -= cmp->lbearing;
25153 rightmost -= cmp->lbearing;
25154 cmp->rbearing -= cmp->lbearing;
25155 cmp->lbearing = 0;
25157 if (right_padded && rightmost < cmp->rbearing)
25159 rightmost = cmp->rbearing;
25162 cmp->pixel_width = rightmost;
25163 cmp->ascent = highest;
25164 cmp->descent = - lowest;
25165 if (cmp->ascent < font_ascent)
25166 cmp->ascent = font_ascent;
25167 if (cmp->descent < font_descent)
25168 cmp->descent = font_descent;
25171 if (it->glyph_row
25172 && (cmp->lbearing < 0
25173 || cmp->rbearing > cmp->pixel_width))
25174 it->glyph_row->contains_overlapping_glyphs_p = 1;
25176 it->pixel_width = cmp->pixel_width;
25177 it->ascent = it->phys_ascent = cmp->ascent;
25178 it->descent = it->phys_descent = cmp->descent;
25179 if (face->box != FACE_NO_BOX)
25181 int thick = face->box_line_width;
25183 if (thick > 0)
25185 it->ascent += thick;
25186 it->descent += thick;
25188 else
25189 thick = - thick;
25191 if (it->start_of_box_run_p)
25192 it->pixel_width += thick;
25193 if (it->end_of_box_run_p)
25194 it->pixel_width += thick;
25197 /* If face has an overline, add the height of the overline
25198 (1 pixel) and a 1 pixel margin to the character height. */
25199 if (face->overline_p)
25200 it->ascent += overline_margin;
25202 take_vertical_position_into_account (it);
25203 if (it->ascent < 0)
25204 it->ascent = 0;
25205 if (it->descent < 0)
25206 it->descent = 0;
25208 if (it->glyph_row && cmp->glyph_len > 0)
25209 append_composite_glyph (it);
25211 else if (it->what == IT_COMPOSITION)
25213 /* A dynamic (automatic) composition. */
25214 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25215 Lisp_Object gstring;
25216 struct font_metrics metrics;
25218 it->nglyphs = 1;
25220 gstring = composition_gstring_from_id (it->cmp_it.id);
25221 it->pixel_width
25222 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25223 &metrics);
25224 if (it->glyph_row
25225 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25226 it->glyph_row->contains_overlapping_glyphs_p = 1;
25227 it->ascent = it->phys_ascent = metrics.ascent;
25228 it->descent = it->phys_descent = metrics.descent;
25229 if (face->box != FACE_NO_BOX)
25231 int thick = face->box_line_width;
25233 if (thick > 0)
25235 it->ascent += thick;
25236 it->descent += thick;
25238 else
25239 thick = - thick;
25241 if (it->start_of_box_run_p)
25242 it->pixel_width += thick;
25243 if (it->end_of_box_run_p)
25244 it->pixel_width += thick;
25246 /* If face has an overline, add the height of the overline
25247 (1 pixel) and a 1 pixel margin to the character height. */
25248 if (face->overline_p)
25249 it->ascent += overline_margin;
25250 take_vertical_position_into_account (it);
25251 if (it->ascent < 0)
25252 it->ascent = 0;
25253 if (it->descent < 0)
25254 it->descent = 0;
25256 if (it->glyph_row)
25257 append_composite_glyph (it);
25259 else if (it->what == IT_GLYPHLESS)
25260 produce_glyphless_glyph (it, 0, Qnil);
25261 else if (it->what == IT_IMAGE)
25262 produce_image_glyph (it);
25263 else if (it->what == IT_STRETCH)
25264 produce_stretch_glyph (it);
25266 done:
25267 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25268 because this isn't true for images with `:ascent 100'. */
25269 eassert (it->ascent >= 0 && it->descent >= 0);
25270 if (it->area == TEXT_AREA)
25271 it->current_x += it->pixel_width;
25273 if (extra_line_spacing > 0)
25275 it->descent += extra_line_spacing;
25276 if (extra_line_spacing > it->max_extra_line_spacing)
25277 it->max_extra_line_spacing = extra_line_spacing;
25280 it->max_ascent = max (it->max_ascent, it->ascent);
25281 it->max_descent = max (it->max_descent, it->descent);
25282 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25283 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25286 /* EXPORT for RIF:
25287 Output LEN glyphs starting at START at the nominal cursor position.
25288 Advance the nominal cursor over the text. The global variable
25289 updated_window contains the window being updated, updated_row is
25290 the glyph row being updated, and updated_area is the area of that
25291 row being updated. */
25293 void
25294 x_write_glyphs (struct glyph *start, int len)
25296 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25298 eassert (updated_window && updated_row);
25299 /* When the window is hscrolled, cursor hpos can legitimately be out
25300 of bounds, but we draw the cursor at the corresponding window
25301 margin in that case. */
25302 if (!updated_row->reversed_p && chpos < 0)
25303 chpos = 0;
25304 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25305 chpos = updated_row->used[TEXT_AREA] - 1;
25307 block_input ();
25309 /* Write glyphs. */
25311 hpos = start - updated_row->glyphs[updated_area];
25312 x = draw_glyphs (updated_window, output_cursor.x,
25313 updated_row, updated_area,
25314 hpos, hpos + len,
25315 DRAW_NORMAL_TEXT, 0);
25317 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25318 if (updated_area == TEXT_AREA
25319 && updated_window->phys_cursor_on_p
25320 && updated_window->phys_cursor.vpos == output_cursor.vpos
25321 && chpos >= hpos
25322 && chpos < hpos + len)
25323 updated_window->phys_cursor_on_p = 0;
25325 unblock_input ();
25327 /* Advance the output cursor. */
25328 output_cursor.hpos += len;
25329 output_cursor.x = x;
25333 /* EXPORT for RIF:
25334 Insert LEN glyphs from START at the nominal cursor position. */
25336 void
25337 x_insert_glyphs (struct glyph *start, int len)
25339 struct frame *f;
25340 struct window *w;
25341 int line_height, shift_by_width, shifted_region_width;
25342 struct glyph_row *row;
25343 struct glyph *glyph;
25344 int frame_x, frame_y;
25345 ptrdiff_t hpos;
25347 eassert (updated_window && updated_row);
25348 block_input ();
25349 w = updated_window;
25350 f = XFRAME (WINDOW_FRAME (w));
25352 /* Get the height of the line we are in. */
25353 row = updated_row;
25354 line_height = row->height;
25356 /* Get the width of the glyphs to insert. */
25357 shift_by_width = 0;
25358 for (glyph = start; glyph < start + len; ++glyph)
25359 shift_by_width += glyph->pixel_width;
25361 /* Get the width of the region to shift right. */
25362 shifted_region_width = (window_box_width (w, updated_area)
25363 - output_cursor.x
25364 - shift_by_width);
25366 /* Shift right. */
25367 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25368 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25370 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25371 line_height, shift_by_width);
25373 /* Write the glyphs. */
25374 hpos = start - row->glyphs[updated_area];
25375 draw_glyphs (w, output_cursor.x, row, updated_area,
25376 hpos, hpos + len,
25377 DRAW_NORMAL_TEXT, 0);
25379 /* Advance the output cursor. */
25380 output_cursor.hpos += len;
25381 output_cursor.x += shift_by_width;
25382 unblock_input ();
25386 /* EXPORT for RIF:
25387 Erase the current text line from the nominal cursor position
25388 (inclusive) to pixel column TO_X (exclusive). The idea is that
25389 everything from TO_X onward is already erased.
25391 TO_X is a pixel position relative to updated_area of
25392 updated_window. TO_X == -1 means clear to the end of this area. */
25394 void
25395 x_clear_end_of_line (int to_x)
25397 struct frame *f;
25398 struct window *w = updated_window;
25399 int max_x, min_y, max_y;
25400 int from_x, from_y, to_y;
25402 eassert (updated_window && updated_row);
25403 f = XFRAME (w->frame);
25405 if (updated_row->full_width_p)
25406 max_x = WINDOW_TOTAL_WIDTH (w);
25407 else
25408 max_x = window_box_width (w, updated_area);
25409 max_y = window_text_bottom_y (w);
25411 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25412 of window. For TO_X > 0, truncate to end of drawing area. */
25413 if (to_x == 0)
25414 return;
25415 else if (to_x < 0)
25416 to_x = max_x;
25417 else
25418 to_x = min (to_x, max_x);
25420 to_y = min (max_y, output_cursor.y + updated_row->height);
25422 /* Notice if the cursor will be cleared by this operation. */
25423 if (!updated_row->full_width_p)
25424 notice_overwritten_cursor (w, updated_area,
25425 output_cursor.x, -1,
25426 updated_row->y,
25427 MATRIX_ROW_BOTTOM_Y (updated_row));
25429 from_x = output_cursor.x;
25431 /* Translate to frame coordinates. */
25432 if (updated_row->full_width_p)
25434 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25435 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25437 else
25439 int area_left = window_box_left (w, updated_area);
25440 from_x += area_left;
25441 to_x += area_left;
25444 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25445 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25446 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25448 /* Prevent inadvertently clearing to end of the X window. */
25449 if (to_x > from_x && to_y > from_y)
25451 block_input ();
25452 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25453 to_x - from_x, to_y - from_y);
25454 unblock_input ();
25458 #endif /* HAVE_WINDOW_SYSTEM */
25462 /***********************************************************************
25463 Cursor types
25464 ***********************************************************************/
25466 /* Value is the internal representation of the specified cursor type
25467 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25468 of the bar cursor. */
25470 static enum text_cursor_kinds
25471 get_specified_cursor_type (Lisp_Object arg, int *width)
25473 enum text_cursor_kinds type;
25475 if (NILP (arg))
25476 return NO_CURSOR;
25478 if (EQ (arg, Qbox))
25479 return FILLED_BOX_CURSOR;
25481 if (EQ (arg, Qhollow))
25482 return HOLLOW_BOX_CURSOR;
25484 if (EQ (arg, Qbar))
25486 *width = 2;
25487 return BAR_CURSOR;
25490 if (CONSP (arg)
25491 && EQ (XCAR (arg), Qbar)
25492 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25494 *width = XINT (XCDR (arg));
25495 return BAR_CURSOR;
25498 if (EQ (arg, Qhbar))
25500 *width = 2;
25501 return HBAR_CURSOR;
25504 if (CONSP (arg)
25505 && EQ (XCAR (arg), Qhbar)
25506 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25508 *width = XINT (XCDR (arg));
25509 return HBAR_CURSOR;
25512 /* Treat anything unknown as "hollow box cursor".
25513 It was bad to signal an error; people have trouble fixing
25514 .Xdefaults with Emacs, when it has something bad in it. */
25515 type = HOLLOW_BOX_CURSOR;
25517 return type;
25520 /* Set the default cursor types for specified frame. */
25521 void
25522 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25524 int width = 1;
25525 Lisp_Object tem;
25527 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25528 FRAME_CURSOR_WIDTH (f) = width;
25530 /* By default, set up the blink-off state depending on the on-state. */
25532 tem = Fassoc (arg, Vblink_cursor_alist);
25533 if (!NILP (tem))
25535 FRAME_BLINK_OFF_CURSOR (f)
25536 = get_specified_cursor_type (XCDR (tem), &width);
25537 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25539 else
25540 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25544 #ifdef HAVE_WINDOW_SYSTEM
25546 /* Return the cursor we want to be displayed in window W. Return
25547 width of bar/hbar cursor through WIDTH arg. Return with
25548 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25549 (i.e. if the `system caret' should track this cursor).
25551 In a mini-buffer window, we want the cursor only to appear if we
25552 are reading input from this window. For the selected window, we
25553 want the cursor type given by the frame parameter or buffer local
25554 setting of cursor-type. If explicitly marked off, draw no cursor.
25555 In all other cases, we want a hollow box cursor. */
25557 static enum text_cursor_kinds
25558 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25559 int *active_cursor)
25561 struct frame *f = XFRAME (w->frame);
25562 struct buffer *b = XBUFFER (w->contents);
25563 int cursor_type = DEFAULT_CURSOR;
25564 Lisp_Object alt_cursor;
25565 int non_selected = 0;
25567 *active_cursor = 1;
25569 /* Echo area */
25570 if (cursor_in_echo_area
25571 && FRAME_HAS_MINIBUF_P (f)
25572 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25574 if (w == XWINDOW (echo_area_window))
25576 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25578 *width = FRAME_CURSOR_WIDTH (f);
25579 return FRAME_DESIRED_CURSOR (f);
25581 else
25582 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25585 *active_cursor = 0;
25586 non_selected = 1;
25589 /* Detect a nonselected window or nonselected frame. */
25590 else if (w != XWINDOW (f->selected_window)
25591 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
25593 *active_cursor = 0;
25595 if (MINI_WINDOW_P (w) && minibuf_level == 0)
25596 return NO_CURSOR;
25598 non_selected = 1;
25601 /* Never display a cursor in a window in which cursor-type is nil. */
25602 if (NILP (BVAR (b, cursor_type)))
25603 return NO_CURSOR;
25605 /* Get the normal cursor type for this window. */
25606 if (EQ (BVAR (b, cursor_type), Qt))
25608 cursor_type = FRAME_DESIRED_CURSOR (f);
25609 *width = FRAME_CURSOR_WIDTH (f);
25611 else
25612 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
25614 /* Use cursor-in-non-selected-windows instead
25615 for non-selected window or frame. */
25616 if (non_selected)
25618 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
25619 if (!EQ (Qt, alt_cursor))
25620 return get_specified_cursor_type (alt_cursor, width);
25621 /* t means modify the normal cursor type. */
25622 if (cursor_type == FILLED_BOX_CURSOR)
25623 cursor_type = HOLLOW_BOX_CURSOR;
25624 else if (cursor_type == BAR_CURSOR && *width > 1)
25625 --*width;
25626 return cursor_type;
25629 /* Use normal cursor if not blinked off. */
25630 if (!w->cursor_off_p)
25632 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25634 if (cursor_type == FILLED_BOX_CURSOR)
25636 /* Using a block cursor on large images can be very annoying.
25637 So use a hollow cursor for "large" images.
25638 If image is not transparent (no mask), also use hollow cursor. */
25639 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25640 if (img != NULL && IMAGEP (img->spec))
25642 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25643 where N = size of default frame font size.
25644 This should cover most of the "tiny" icons people may use. */
25645 if (!img->mask
25646 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
25647 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
25648 cursor_type = HOLLOW_BOX_CURSOR;
25651 else if (cursor_type != NO_CURSOR)
25653 /* Display current only supports BOX and HOLLOW cursors for images.
25654 So for now, unconditionally use a HOLLOW cursor when cursor is
25655 not a solid box cursor. */
25656 cursor_type = HOLLOW_BOX_CURSOR;
25659 return cursor_type;
25662 /* Cursor is blinked off, so determine how to "toggle" it. */
25664 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25665 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25666 return get_specified_cursor_type (XCDR (alt_cursor), width);
25668 /* Then see if frame has specified a specific blink off cursor type. */
25669 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25671 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25672 return FRAME_BLINK_OFF_CURSOR (f);
25675 #if 0
25676 /* Some people liked having a permanently visible blinking cursor,
25677 while others had very strong opinions against it. So it was
25678 decided to remove it. KFS 2003-09-03 */
25680 /* Finally perform built-in cursor blinking:
25681 filled box <-> hollow box
25682 wide [h]bar <-> narrow [h]bar
25683 narrow [h]bar <-> no cursor
25684 other type <-> no cursor */
25686 if (cursor_type == FILLED_BOX_CURSOR)
25687 return HOLLOW_BOX_CURSOR;
25689 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25691 *width = 1;
25692 return cursor_type;
25694 #endif
25696 return NO_CURSOR;
25700 /* Notice when the text cursor of window W has been completely
25701 overwritten by a drawing operation that outputs glyphs in AREA
25702 starting at X0 and ending at X1 in the line starting at Y0 and
25703 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25704 the rest of the line after X0 has been written. Y coordinates
25705 are window-relative. */
25707 static void
25708 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25709 int x0, int x1, int y0, int y1)
25711 int cx0, cx1, cy0, cy1;
25712 struct glyph_row *row;
25714 if (!w->phys_cursor_on_p)
25715 return;
25716 if (area != TEXT_AREA)
25717 return;
25719 if (w->phys_cursor.vpos < 0
25720 || w->phys_cursor.vpos >= w->current_matrix->nrows
25721 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25722 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
25723 return;
25725 if (row->cursor_in_fringe_p)
25727 row->cursor_in_fringe_p = 0;
25728 draw_fringe_bitmap (w, row, row->reversed_p);
25729 w->phys_cursor_on_p = 0;
25730 return;
25733 cx0 = w->phys_cursor.x;
25734 cx1 = cx0 + w->phys_cursor_width;
25735 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25736 return;
25738 /* The cursor image will be completely removed from the
25739 screen if the output area intersects the cursor area in
25740 y-direction. When we draw in [y0 y1[, and some part of
25741 the cursor is at y < y0, that part must have been drawn
25742 before. When scrolling, the cursor is erased before
25743 actually scrolling, so we don't come here. When not
25744 scrolling, the rows above the old cursor row must have
25745 changed, and in this case these rows must have written
25746 over the cursor image.
25748 Likewise if part of the cursor is below y1, with the
25749 exception of the cursor being in the first blank row at
25750 the buffer and window end because update_text_area
25751 doesn't draw that row. (Except when it does, but
25752 that's handled in update_text_area.) */
25754 cy0 = w->phys_cursor.y;
25755 cy1 = cy0 + w->phys_cursor_height;
25756 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25757 return;
25759 w->phys_cursor_on_p = 0;
25762 #endif /* HAVE_WINDOW_SYSTEM */
25765 /************************************************************************
25766 Mouse Face
25767 ************************************************************************/
25769 #ifdef HAVE_WINDOW_SYSTEM
25771 /* EXPORT for RIF:
25772 Fix the display of area AREA of overlapping row ROW in window W
25773 with respect to the overlapping part OVERLAPS. */
25775 void
25776 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25777 enum glyph_row_area area, int overlaps)
25779 int i, x;
25781 block_input ();
25783 x = 0;
25784 for (i = 0; i < row->used[area];)
25786 if (row->glyphs[area][i].overlaps_vertically_p)
25788 int start = i, start_x = x;
25792 x += row->glyphs[area][i].pixel_width;
25793 ++i;
25795 while (i < row->used[area]
25796 && row->glyphs[area][i].overlaps_vertically_p);
25798 draw_glyphs (w, start_x, row, area,
25799 start, i,
25800 DRAW_NORMAL_TEXT, overlaps);
25802 else
25804 x += row->glyphs[area][i].pixel_width;
25805 ++i;
25809 unblock_input ();
25813 /* EXPORT:
25814 Draw the cursor glyph of window W in glyph row ROW. See the
25815 comment of draw_glyphs for the meaning of HL. */
25817 void
25818 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25819 enum draw_glyphs_face hl)
25821 /* If cursor hpos is out of bounds, don't draw garbage. This can
25822 happen in mini-buffer windows when switching between echo area
25823 glyphs and mini-buffer. */
25824 if ((row->reversed_p
25825 ? (w->phys_cursor.hpos >= 0)
25826 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25828 int on_p = w->phys_cursor_on_p;
25829 int x1;
25830 int hpos = w->phys_cursor.hpos;
25832 /* When the window is hscrolled, cursor hpos can legitimately be
25833 out of bounds, but we draw the cursor at the corresponding
25834 window margin in that case. */
25835 if (!row->reversed_p && hpos < 0)
25836 hpos = 0;
25837 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
25838 hpos = row->used[TEXT_AREA] - 1;
25840 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
25841 hl, 0);
25842 w->phys_cursor_on_p = on_p;
25844 if (hl == DRAW_CURSOR)
25845 w->phys_cursor_width = x1 - w->phys_cursor.x;
25846 /* When we erase the cursor, and ROW is overlapped by other
25847 rows, make sure that these overlapping parts of other rows
25848 are redrawn. */
25849 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25851 w->phys_cursor_width = x1 - w->phys_cursor.x;
25853 if (row > w->current_matrix->rows
25854 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25855 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25856 OVERLAPS_ERASED_CURSOR);
25858 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25859 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25860 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25861 OVERLAPS_ERASED_CURSOR);
25867 /* EXPORT:
25868 Erase the image of a cursor of window W from the screen. */
25870 void
25871 erase_phys_cursor (struct window *w)
25873 struct frame *f = XFRAME (w->frame);
25874 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25875 int hpos = w->phys_cursor.hpos;
25876 int vpos = w->phys_cursor.vpos;
25877 int mouse_face_here_p = 0;
25878 struct glyph_matrix *active_glyphs = w->current_matrix;
25879 struct glyph_row *cursor_row;
25880 struct glyph *cursor_glyph;
25881 enum draw_glyphs_face hl;
25883 /* No cursor displayed or row invalidated => nothing to do on the
25884 screen. */
25885 if (w->phys_cursor_type == NO_CURSOR)
25886 goto mark_cursor_off;
25888 /* VPOS >= active_glyphs->nrows means that window has been resized.
25889 Don't bother to erase the cursor. */
25890 if (vpos >= active_glyphs->nrows)
25891 goto mark_cursor_off;
25893 /* If row containing cursor is marked invalid, there is nothing we
25894 can do. */
25895 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25896 if (!cursor_row->enabled_p)
25897 goto mark_cursor_off;
25899 /* If line spacing is > 0, old cursor may only be partially visible in
25900 window after split-window. So adjust visible height. */
25901 cursor_row->visible_height = min (cursor_row->visible_height,
25902 window_text_bottom_y (w) - cursor_row->y);
25904 /* If row is completely invisible, don't attempt to delete a cursor which
25905 isn't there. This can happen if cursor is at top of a window, and
25906 we switch to a buffer with a header line in that window. */
25907 if (cursor_row->visible_height <= 0)
25908 goto mark_cursor_off;
25910 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25911 if (cursor_row->cursor_in_fringe_p)
25913 cursor_row->cursor_in_fringe_p = 0;
25914 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25915 goto mark_cursor_off;
25918 /* This can happen when the new row is shorter than the old one.
25919 In this case, either draw_glyphs or clear_end_of_line
25920 should have cleared the cursor. Note that we wouldn't be
25921 able to erase the cursor in this case because we don't have a
25922 cursor glyph at hand. */
25923 if ((cursor_row->reversed_p
25924 ? (w->phys_cursor.hpos < 0)
25925 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25926 goto mark_cursor_off;
25928 /* When the window is hscrolled, cursor hpos can legitimately be out
25929 of bounds, but we draw the cursor at the corresponding window
25930 margin in that case. */
25931 if (!cursor_row->reversed_p && hpos < 0)
25932 hpos = 0;
25933 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
25934 hpos = cursor_row->used[TEXT_AREA] - 1;
25936 /* If the cursor is in the mouse face area, redisplay that when
25937 we clear the cursor. */
25938 if (! NILP (hlinfo->mouse_face_window)
25939 && coords_in_mouse_face_p (w, hpos, vpos)
25940 /* Don't redraw the cursor's spot in mouse face if it is at the
25941 end of a line (on a newline). The cursor appears there, but
25942 mouse highlighting does not. */
25943 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25944 mouse_face_here_p = 1;
25946 /* Maybe clear the display under the cursor. */
25947 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25949 int x, y, left_x;
25950 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25951 int width;
25953 cursor_glyph = get_phys_cursor_glyph (w);
25954 if (cursor_glyph == NULL)
25955 goto mark_cursor_off;
25957 width = cursor_glyph->pixel_width;
25958 left_x = window_box_left_offset (w, TEXT_AREA);
25959 x = w->phys_cursor.x;
25960 if (x < left_x)
25961 width -= left_x - x;
25962 width = min (width, window_box_width (w, TEXT_AREA) - x);
25963 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25964 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25966 if (width > 0)
25967 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25970 /* Erase the cursor by redrawing the character underneath it. */
25971 if (mouse_face_here_p)
25972 hl = DRAW_MOUSE_FACE;
25973 else
25974 hl = DRAW_NORMAL_TEXT;
25975 draw_phys_cursor_glyph (w, cursor_row, hl);
25977 mark_cursor_off:
25978 w->phys_cursor_on_p = 0;
25979 w->phys_cursor_type = NO_CURSOR;
25983 /* EXPORT:
25984 Display or clear cursor of window W. If ON is zero, clear the
25985 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25986 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25988 void
25989 display_and_set_cursor (struct window *w, int on,
25990 int hpos, int vpos, int x, int y)
25992 struct frame *f = XFRAME (w->frame);
25993 int new_cursor_type;
25994 int new_cursor_width;
25995 int active_cursor;
25996 struct glyph_row *glyph_row;
25997 struct glyph *glyph;
25999 /* This is pointless on invisible frames, and dangerous on garbaged
26000 windows and frames; in the latter case, the frame or window may
26001 be in the midst of changing its size, and x and y may be off the
26002 window. */
26003 if (! FRAME_VISIBLE_P (f)
26004 || FRAME_GARBAGED_P (f)
26005 || vpos >= w->current_matrix->nrows
26006 || hpos >= w->current_matrix->matrix_w)
26007 return;
26009 /* If cursor is off and we want it off, return quickly. */
26010 if (!on && !w->phys_cursor_on_p)
26011 return;
26013 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26014 /* If cursor row is not enabled, we don't really know where to
26015 display the cursor. */
26016 if (!glyph_row->enabled_p)
26018 w->phys_cursor_on_p = 0;
26019 return;
26022 glyph = NULL;
26023 if (!glyph_row->exact_window_width_line_p
26024 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26025 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26027 eassert (input_blocked_p ());
26029 /* Set new_cursor_type to the cursor we want to be displayed. */
26030 new_cursor_type = get_window_cursor_type (w, glyph,
26031 &new_cursor_width, &active_cursor);
26033 /* If cursor is currently being shown and we don't want it to be or
26034 it is in the wrong place, or the cursor type is not what we want,
26035 erase it. */
26036 if (w->phys_cursor_on_p
26037 && (!on
26038 || w->phys_cursor.x != x
26039 || w->phys_cursor.y != y
26040 || new_cursor_type != w->phys_cursor_type
26041 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26042 && new_cursor_width != w->phys_cursor_width)))
26043 erase_phys_cursor (w);
26045 /* Don't check phys_cursor_on_p here because that flag is only set
26046 to zero in some cases where we know that the cursor has been
26047 completely erased, to avoid the extra work of erasing the cursor
26048 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26049 still not be visible, or it has only been partly erased. */
26050 if (on)
26052 w->phys_cursor_ascent = glyph_row->ascent;
26053 w->phys_cursor_height = glyph_row->height;
26055 /* Set phys_cursor_.* before x_draw_.* is called because some
26056 of them may need the information. */
26057 w->phys_cursor.x = x;
26058 w->phys_cursor.y = glyph_row->y;
26059 w->phys_cursor.hpos = hpos;
26060 w->phys_cursor.vpos = vpos;
26063 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26064 new_cursor_type, new_cursor_width,
26065 on, active_cursor);
26069 /* Switch the display of W's cursor on or off, according to the value
26070 of ON. */
26072 static void
26073 update_window_cursor (struct window *w, int on)
26075 /* Don't update cursor in windows whose frame is in the process
26076 of being deleted. */
26077 if (w->current_matrix)
26079 int hpos = w->phys_cursor.hpos;
26080 int vpos = w->phys_cursor.vpos;
26081 struct glyph_row *row;
26083 if (vpos >= w->current_matrix->nrows
26084 || hpos >= w->current_matrix->matrix_w)
26085 return;
26087 row = MATRIX_ROW (w->current_matrix, vpos);
26089 /* When the window is hscrolled, cursor hpos can legitimately be
26090 out of bounds, but we draw the cursor at the corresponding
26091 window margin in that case. */
26092 if (!row->reversed_p && hpos < 0)
26093 hpos = 0;
26094 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26095 hpos = row->used[TEXT_AREA] - 1;
26097 block_input ();
26098 display_and_set_cursor (w, on, hpos, vpos,
26099 w->phys_cursor.x, w->phys_cursor.y);
26100 unblock_input ();
26105 /* Call update_window_cursor with parameter ON_P on all leaf windows
26106 in the window tree rooted at W. */
26108 static void
26109 update_cursor_in_window_tree (struct window *w, int on_p)
26111 while (w)
26113 if (WINDOWP (w->contents))
26114 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26115 else
26116 update_window_cursor (w, on_p);
26118 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26123 /* EXPORT:
26124 Display the cursor on window W, or clear it, according to ON_P.
26125 Don't change the cursor's position. */
26127 void
26128 x_update_cursor (struct frame *f, int on_p)
26130 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26134 /* EXPORT:
26135 Clear the cursor of window W to background color, and mark the
26136 cursor as not shown. This is used when the text where the cursor
26137 is about to be rewritten. */
26139 void
26140 x_clear_cursor (struct window *w)
26142 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26143 update_window_cursor (w, 0);
26146 #endif /* HAVE_WINDOW_SYSTEM */
26148 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26149 and MSDOS. */
26150 static void
26151 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26152 int start_hpos, int end_hpos,
26153 enum draw_glyphs_face draw)
26155 #ifdef HAVE_WINDOW_SYSTEM
26156 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26158 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26159 return;
26161 #endif
26162 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26163 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26164 #endif
26167 /* Display the active region described by mouse_face_* according to DRAW. */
26169 static void
26170 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26172 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26173 struct frame *f = XFRAME (WINDOW_FRAME (w));
26175 if (/* If window is in the process of being destroyed, don't bother
26176 to do anything. */
26177 w->current_matrix != NULL
26178 /* Don't update mouse highlight if hidden */
26179 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26180 /* Recognize when we are called to operate on rows that don't exist
26181 anymore. This can happen when a window is split. */
26182 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26184 int phys_cursor_on_p = w->phys_cursor_on_p;
26185 struct glyph_row *row, *first, *last;
26187 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26188 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26190 for (row = first; row <= last && row->enabled_p; ++row)
26192 int start_hpos, end_hpos, start_x;
26194 /* For all but the first row, the highlight starts at column 0. */
26195 if (row == first)
26197 /* R2L rows have BEG and END in reversed order, but the
26198 screen drawing geometry is always left to right. So
26199 we need to mirror the beginning and end of the
26200 highlighted area in R2L rows. */
26201 if (!row->reversed_p)
26203 start_hpos = hlinfo->mouse_face_beg_col;
26204 start_x = hlinfo->mouse_face_beg_x;
26206 else if (row == last)
26208 start_hpos = hlinfo->mouse_face_end_col;
26209 start_x = hlinfo->mouse_face_end_x;
26211 else
26213 start_hpos = 0;
26214 start_x = 0;
26217 else if (row->reversed_p && row == last)
26219 start_hpos = hlinfo->mouse_face_end_col;
26220 start_x = hlinfo->mouse_face_end_x;
26222 else
26224 start_hpos = 0;
26225 start_x = 0;
26228 if (row == last)
26230 if (!row->reversed_p)
26231 end_hpos = hlinfo->mouse_face_end_col;
26232 else if (row == first)
26233 end_hpos = hlinfo->mouse_face_beg_col;
26234 else
26236 end_hpos = row->used[TEXT_AREA];
26237 if (draw == DRAW_NORMAL_TEXT)
26238 row->fill_line_p = 1; /* Clear to end of line */
26241 else if (row->reversed_p && row == first)
26242 end_hpos = hlinfo->mouse_face_beg_col;
26243 else
26245 end_hpos = row->used[TEXT_AREA];
26246 if (draw == DRAW_NORMAL_TEXT)
26247 row->fill_line_p = 1; /* Clear to end of line */
26250 if (end_hpos > start_hpos)
26252 draw_row_with_mouse_face (w, start_x, row,
26253 start_hpos, end_hpos, draw);
26255 row->mouse_face_p
26256 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26260 #ifdef HAVE_WINDOW_SYSTEM
26261 /* When we've written over the cursor, arrange for it to
26262 be displayed again. */
26263 if (FRAME_WINDOW_P (f)
26264 && phys_cursor_on_p && !w->phys_cursor_on_p)
26266 int hpos = w->phys_cursor.hpos;
26268 /* When the window is hscrolled, cursor hpos can legitimately be
26269 out of bounds, but we draw the cursor at the corresponding
26270 window margin in that case. */
26271 if (!row->reversed_p && hpos < 0)
26272 hpos = 0;
26273 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26274 hpos = row->used[TEXT_AREA] - 1;
26276 block_input ();
26277 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26278 w->phys_cursor.x, w->phys_cursor.y);
26279 unblock_input ();
26281 #endif /* HAVE_WINDOW_SYSTEM */
26284 #ifdef HAVE_WINDOW_SYSTEM
26285 /* Change the mouse cursor. */
26286 if (FRAME_WINDOW_P (f))
26288 if (draw == DRAW_NORMAL_TEXT
26289 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26290 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26291 else if (draw == DRAW_MOUSE_FACE)
26292 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26293 else
26294 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26296 #endif /* HAVE_WINDOW_SYSTEM */
26299 /* EXPORT:
26300 Clear out the mouse-highlighted active region.
26301 Redraw it un-highlighted first. Value is non-zero if mouse
26302 face was actually drawn unhighlighted. */
26305 clear_mouse_face (Mouse_HLInfo *hlinfo)
26307 int cleared = 0;
26309 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26311 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26312 cleared = 1;
26315 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26316 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26317 hlinfo->mouse_face_window = Qnil;
26318 hlinfo->mouse_face_overlay = Qnil;
26319 return cleared;
26322 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26323 within the mouse face on that window. */
26324 static int
26325 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26327 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26329 /* Quickly resolve the easy cases. */
26330 if (!(WINDOWP (hlinfo->mouse_face_window)
26331 && XWINDOW (hlinfo->mouse_face_window) == w))
26332 return 0;
26333 if (vpos < hlinfo->mouse_face_beg_row
26334 || vpos > hlinfo->mouse_face_end_row)
26335 return 0;
26336 if (vpos > hlinfo->mouse_face_beg_row
26337 && vpos < hlinfo->mouse_face_end_row)
26338 return 1;
26340 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26342 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26344 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26345 return 1;
26347 else if ((vpos == hlinfo->mouse_face_beg_row
26348 && hpos >= hlinfo->mouse_face_beg_col)
26349 || (vpos == hlinfo->mouse_face_end_row
26350 && hpos < hlinfo->mouse_face_end_col))
26351 return 1;
26353 else
26355 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26357 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26358 return 1;
26360 else if ((vpos == hlinfo->mouse_face_beg_row
26361 && hpos <= hlinfo->mouse_face_beg_col)
26362 || (vpos == hlinfo->mouse_face_end_row
26363 && hpos > hlinfo->mouse_face_end_col))
26364 return 1;
26366 return 0;
26370 /* EXPORT:
26371 Non-zero if physical cursor of window W is within mouse face. */
26374 cursor_in_mouse_face_p (struct window *w)
26376 int hpos = w->phys_cursor.hpos;
26377 int vpos = w->phys_cursor.vpos;
26378 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26380 /* When the window is hscrolled, cursor hpos can legitimately be out
26381 of bounds, but we draw the cursor at the corresponding window
26382 margin in that case. */
26383 if (!row->reversed_p && hpos < 0)
26384 hpos = 0;
26385 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26386 hpos = row->used[TEXT_AREA] - 1;
26388 return coords_in_mouse_face_p (w, hpos, vpos);
26393 /* Find the glyph rows START_ROW and END_ROW of window W that display
26394 characters between buffer positions START_CHARPOS and END_CHARPOS
26395 (excluding END_CHARPOS). DISP_STRING is a display string that
26396 covers these buffer positions. This is similar to
26397 row_containing_pos, but is more accurate when bidi reordering makes
26398 buffer positions change non-linearly with glyph rows. */
26399 static void
26400 rows_from_pos_range (struct window *w,
26401 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26402 Lisp_Object disp_string,
26403 struct glyph_row **start, struct glyph_row **end)
26405 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26406 int last_y = window_text_bottom_y (w);
26407 struct glyph_row *row;
26409 *start = NULL;
26410 *end = NULL;
26412 while (!first->enabled_p
26413 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26414 first++;
26416 /* Find the START row. */
26417 for (row = first;
26418 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26419 row++)
26421 /* A row can potentially be the START row if the range of the
26422 characters it displays intersects the range
26423 [START_CHARPOS..END_CHARPOS). */
26424 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26425 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26426 /* See the commentary in row_containing_pos, for the
26427 explanation of the complicated way to check whether
26428 some position is beyond the end of the characters
26429 displayed by a row. */
26430 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26431 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26432 && !row->ends_at_zv_p
26433 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26434 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26435 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26436 && !row->ends_at_zv_p
26437 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26439 /* Found a candidate row. Now make sure at least one of the
26440 glyphs it displays has a charpos from the range
26441 [START_CHARPOS..END_CHARPOS).
26443 This is not obvious because bidi reordering could make
26444 buffer positions of a row be 1,2,3,102,101,100, and if we
26445 want to highlight characters in [50..60), we don't want
26446 this row, even though [50..60) does intersect [1..103),
26447 the range of character positions given by the row's start
26448 and end positions. */
26449 struct glyph *g = row->glyphs[TEXT_AREA];
26450 struct glyph *e = g + row->used[TEXT_AREA];
26452 while (g < e)
26454 if (((BUFFERP (g->object) || INTEGERP (g->object))
26455 && start_charpos <= g->charpos && g->charpos < end_charpos)
26456 /* A glyph that comes from DISP_STRING is by
26457 definition to be highlighted. */
26458 || EQ (g->object, disp_string))
26459 *start = row;
26460 g++;
26462 if (*start)
26463 break;
26467 /* Find the END row. */
26468 if (!*start
26469 /* If the last row is partially visible, start looking for END
26470 from that row, instead of starting from FIRST. */
26471 && !(row->enabled_p
26472 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26473 row = first;
26474 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26476 struct glyph_row *next = row + 1;
26477 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26479 if (!next->enabled_p
26480 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26481 /* The first row >= START whose range of displayed characters
26482 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26483 is the row END + 1. */
26484 || (start_charpos < next_start
26485 && end_charpos < next_start)
26486 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26487 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26488 && !next->ends_at_zv_p
26489 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26490 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26491 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26492 && !next->ends_at_zv_p
26493 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26495 *end = row;
26496 break;
26498 else
26500 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26501 but none of the characters it displays are in the range, it is
26502 also END + 1. */
26503 struct glyph *g = next->glyphs[TEXT_AREA];
26504 struct glyph *s = g;
26505 struct glyph *e = g + next->used[TEXT_AREA];
26507 while (g < e)
26509 if (((BUFFERP (g->object) || INTEGERP (g->object))
26510 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26511 /* If the buffer position of the first glyph in
26512 the row is equal to END_CHARPOS, it means
26513 the last character to be highlighted is the
26514 newline of ROW, and we must consider NEXT as
26515 END, not END+1. */
26516 || (((!next->reversed_p && g == s)
26517 || (next->reversed_p && g == e - 1))
26518 && (g->charpos == end_charpos
26519 /* Special case for when NEXT is an
26520 empty line at ZV. */
26521 || (g->charpos == -1
26522 && !row->ends_at_zv_p
26523 && next_start == end_charpos)))))
26524 /* A glyph that comes from DISP_STRING is by
26525 definition to be highlighted. */
26526 || EQ (g->object, disp_string))
26527 break;
26528 g++;
26530 if (g == e)
26532 *end = row;
26533 break;
26535 /* The first row that ends at ZV must be the last to be
26536 highlighted. */
26537 else if (next->ends_at_zv_p)
26539 *end = next;
26540 break;
26546 /* This function sets the mouse_face_* elements of HLINFO, assuming
26547 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26548 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26549 for the overlay or run of text properties specifying the mouse
26550 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26551 before-string and after-string that must also be highlighted.
26552 DISP_STRING, if non-nil, is a display string that may cover some
26553 or all of the highlighted text. */
26555 static void
26556 mouse_face_from_buffer_pos (Lisp_Object window,
26557 Mouse_HLInfo *hlinfo,
26558 ptrdiff_t mouse_charpos,
26559 ptrdiff_t start_charpos,
26560 ptrdiff_t end_charpos,
26561 Lisp_Object before_string,
26562 Lisp_Object after_string,
26563 Lisp_Object disp_string)
26565 struct window *w = XWINDOW (window);
26566 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26567 struct glyph_row *r1, *r2;
26568 struct glyph *glyph, *end;
26569 ptrdiff_t ignore, pos;
26570 int x;
26572 eassert (NILP (disp_string) || STRINGP (disp_string));
26573 eassert (NILP (before_string) || STRINGP (before_string));
26574 eassert (NILP (after_string) || STRINGP (after_string));
26576 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26577 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26578 if (r1 == NULL)
26579 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26580 /* If the before-string or display-string contains newlines,
26581 rows_from_pos_range skips to its last row. Move back. */
26582 if (!NILP (before_string) || !NILP (disp_string))
26584 struct glyph_row *prev;
26585 while ((prev = r1 - 1, prev >= first)
26586 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26587 && prev->used[TEXT_AREA] > 0)
26589 struct glyph *beg = prev->glyphs[TEXT_AREA];
26590 glyph = beg + prev->used[TEXT_AREA];
26591 while (--glyph >= beg && INTEGERP (glyph->object));
26592 if (glyph < beg
26593 || !(EQ (glyph->object, before_string)
26594 || EQ (glyph->object, disp_string)))
26595 break;
26596 r1 = prev;
26599 if (r2 == NULL)
26601 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26602 hlinfo->mouse_face_past_end = 1;
26604 else if (!NILP (after_string))
26606 /* If the after-string has newlines, advance to its last row. */
26607 struct glyph_row *next;
26608 struct glyph_row *last
26609 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26611 for (next = r2 + 1;
26612 next <= last
26613 && next->used[TEXT_AREA] > 0
26614 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
26615 ++next)
26616 r2 = next;
26618 /* The rest of the display engine assumes that mouse_face_beg_row is
26619 either above mouse_face_end_row or identical to it. But with
26620 bidi-reordered continued lines, the row for START_CHARPOS could
26621 be below the row for END_CHARPOS. If so, swap the rows and store
26622 them in correct order. */
26623 if (r1->y > r2->y)
26625 struct glyph_row *tem = r2;
26627 r2 = r1;
26628 r1 = tem;
26631 hlinfo->mouse_face_beg_y = r1->y;
26632 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
26633 hlinfo->mouse_face_end_y = r2->y;
26634 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
26636 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26637 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26638 could be anywhere in the row and in any order. The strategy
26639 below is to find the leftmost and the rightmost glyph that
26640 belongs to either of these 3 strings, or whose position is
26641 between START_CHARPOS and END_CHARPOS, and highlight all the
26642 glyphs between those two. This may cover more than just the text
26643 between START_CHARPOS and END_CHARPOS if the range of characters
26644 strides the bidi level boundary, e.g. if the beginning is in R2L
26645 text while the end is in L2R text or vice versa. */
26646 if (!r1->reversed_p)
26648 /* This row is in a left to right paragraph. Scan it left to
26649 right. */
26650 glyph = r1->glyphs[TEXT_AREA];
26651 end = glyph + r1->used[TEXT_AREA];
26652 x = r1->x;
26654 /* Skip truncation glyphs at the start of the glyph row. */
26655 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
26656 for (; glyph < end
26657 && INTEGERP (glyph->object)
26658 && glyph->charpos < 0;
26659 ++glyph)
26660 x += glyph->pixel_width;
26662 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26663 or DISP_STRING, and the first glyph from buffer whose
26664 position is between START_CHARPOS and END_CHARPOS. */
26665 for (; glyph < end
26666 && !INTEGERP (glyph->object)
26667 && !EQ (glyph->object, disp_string)
26668 && !(BUFFERP (glyph->object)
26669 && (glyph->charpos >= start_charpos
26670 && glyph->charpos < end_charpos));
26671 ++glyph)
26673 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26674 are present at buffer positions between START_CHARPOS and
26675 END_CHARPOS, or if they come from an overlay. */
26676 if (EQ (glyph->object, before_string))
26678 pos = string_buffer_position (before_string,
26679 start_charpos);
26680 /* If pos == 0, it means before_string came from an
26681 overlay, not from a buffer position. */
26682 if (!pos || (pos >= start_charpos && pos < end_charpos))
26683 break;
26685 else if (EQ (glyph->object, after_string))
26687 pos = string_buffer_position (after_string, end_charpos);
26688 if (!pos || (pos >= start_charpos && pos < end_charpos))
26689 break;
26691 x += glyph->pixel_width;
26693 hlinfo->mouse_face_beg_x = x;
26694 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26696 else
26698 /* This row is in a right to left paragraph. Scan it right to
26699 left. */
26700 struct glyph *g;
26702 end = r1->glyphs[TEXT_AREA] - 1;
26703 glyph = end + r1->used[TEXT_AREA];
26705 /* Skip truncation glyphs at the start of the glyph row. */
26706 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
26707 for (; glyph > end
26708 && INTEGERP (glyph->object)
26709 && glyph->charpos < 0;
26710 --glyph)
26713 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26714 or DISP_STRING, and the first glyph from buffer whose
26715 position is between START_CHARPOS and END_CHARPOS. */
26716 for (; glyph > end
26717 && !INTEGERP (glyph->object)
26718 && !EQ (glyph->object, disp_string)
26719 && !(BUFFERP (glyph->object)
26720 && (glyph->charpos >= start_charpos
26721 && glyph->charpos < end_charpos));
26722 --glyph)
26724 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26725 are present at buffer positions between START_CHARPOS and
26726 END_CHARPOS, or if they come from an overlay. */
26727 if (EQ (glyph->object, before_string))
26729 pos = string_buffer_position (before_string, start_charpos);
26730 /* If pos == 0, it means before_string came from an
26731 overlay, not from a buffer position. */
26732 if (!pos || (pos >= start_charpos && pos < end_charpos))
26733 break;
26735 else if (EQ (glyph->object, after_string))
26737 pos = string_buffer_position (after_string, end_charpos);
26738 if (!pos || (pos >= start_charpos && pos < end_charpos))
26739 break;
26743 glyph++; /* first glyph to the right of the highlighted area */
26744 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26745 x += g->pixel_width;
26746 hlinfo->mouse_face_beg_x = x;
26747 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26750 /* If the highlight ends in a different row, compute GLYPH and END
26751 for the end row. Otherwise, reuse the values computed above for
26752 the row where the highlight begins. */
26753 if (r2 != r1)
26755 if (!r2->reversed_p)
26757 glyph = r2->glyphs[TEXT_AREA];
26758 end = glyph + r2->used[TEXT_AREA];
26759 x = r2->x;
26761 else
26763 end = r2->glyphs[TEXT_AREA] - 1;
26764 glyph = end + r2->used[TEXT_AREA];
26768 if (!r2->reversed_p)
26770 /* Skip truncation and continuation glyphs near the end of the
26771 row, and also blanks and stretch glyphs inserted by
26772 extend_face_to_end_of_line. */
26773 while (end > glyph
26774 && INTEGERP ((end - 1)->object))
26775 --end;
26776 /* Scan the rest of the glyph row from the end, looking for the
26777 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26778 DISP_STRING, or whose position is between START_CHARPOS
26779 and END_CHARPOS */
26780 for (--end;
26781 end > glyph
26782 && !INTEGERP (end->object)
26783 && !EQ (end->object, disp_string)
26784 && !(BUFFERP (end->object)
26785 && (end->charpos >= start_charpos
26786 && end->charpos < end_charpos));
26787 --end)
26789 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26790 are present at buffer positions between START_CHARPOS and
26791 END_CHARPOS, or if they come from an overlay. */
26792 if (EQ (end->object, before_string))
26794 pos = string_buffer_position (before_string, start_charpos);
26795 if (!pos || (pos >= start_charpos && pos < end_charpos))
26796 break;
26798 else if (EQ (end->object, after_string))
26800 pos = string_buffer_position (after_string, end_charpos);
26801 if (!pos || (pos >= start_charpos && pos < end_charpos))
26802 break;
26805 /* Find the X coordinate of the last glyph to be highlighted. */
26806 for (; glyph <= end; ++glyph)
26807 x += glyph->pixel_width;
26809 hlinfo->mouse_face_end_x = x;
26810 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26812 else
26814 /* Skip truncation and continuation glyphs near the end of the
26815 row, and also blanks and stretch glyphs inserted by
26816 extend_face_to_end_of_line. */
26817 x = r2->x;
26818 end++;
26819 while (end < glyph
26820 && INTEGERP (end->object))
26822 x += end->pixel_width;
26823 ++end;
26825 /* Scan the rest of the glyph row from the end, looking for the
26826 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26827 DISP_STRING, or whose position is between START_CHARPOS
26828 and END_CHARPOS */
26829 for ( ;
26830 end < glyph
26831 && !INTEGERP (end->object)
26832 && !EQ (end->object, disp_string)
26833 && !(BUFFERP (end->object)
26834 && (end->charpos >= start_charpos
26835 && end->charpos < end_charpos));
26836 ++end)
26838 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26839 are present at buffer positions between START_CHARPOS and
26840 END_CHARPOS, or if they come from an overlay. */
26841 if (EQ (end->object, before_string))
26843 pos = string_buffer_position (before_string, start_charpos);
26844 if (!pos || (pos >= start_charpos && pos < end_charpos))
26845 break;
26847 else if (EQ (end->object, after_string))
26849 pos = string_buffer_position (after_string, end_charpos);
26850 if (!pos || (pos >= start_charpos && pos < end_charpos))
26851 break;
26853 x += end->pixel_width;
26855 /* If we exited the above loop because we arrived at the last
26856 glyph of the row, and its buffer position is still not in
26857 range, it means the last character in range is the preceding
26858 newline. Bump the end column and x values to get past the
26859 last glyph. */
26860 if (end == glyph
26861 && BUFFERP (end->object)
26862 && (end->charpos < start_charpos
26863 || end->charpos >= end_charpos))
26865 x += end->pixel_width;
26866 ++end;
26868 hlinfo->mouse_face_end_x = x;
26869 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26872 hlinfo->mouse_face_window = window;
26873 hlinfo->mouse_face_face_id
26874 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26875 mouse_charpos + 1,
26876 !hlinfo->mouse_face_hidden, -1);
26877 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26880 /* The following function is not used anymore (replaced with
26881 mouse_face_from_string_pos), but I leave it here for the time
26882 being, in case someone would. */
26884 #if 0 /* not used */
26886 /* Find the position of the glyph for position POS in OBJECT in
26887 window W's current matrix, and return in *X, *Y the pixel
26888 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26890 RIGHT_P non-zero means return the position of the right edge of the
26891 glyph, RIGHT_P zero means return the left edge position.
26893 If no glyph for POS exists in the matrix, return the position of
26894 the glyph with the next smaller position that is in the matrix, if
26895 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26896 exists in the matrix, return the position of the glyph with the
26897 next larger position in OBJECT.
26899 Value is non-zero if a glyph was found. */
26901 static int
26902 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
26903 int *hpos, int *vpos, int *x, int *y, int right_p)
26905 int yb = window_text_bottom_y (w);
26906 struct glyph_row *r;
26907 struct glyph *best_glyph = NULL;
26908 struct glyph_row *best_row = NULL;
26909 int best_x = 0;
26911 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26912 r->enabled_p && r->y < yb;
26913 ++r)
26915 struct glyph *g = r->glyphs[TEXT_AREA];
26916 struct glyph *e = g + r->used[TEXT_AREA];
26917 int gx;
26919 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26920 if (EQ (g->object, object))
26922 if (g->charpos == pos)
26924 best_glyph = g;
26925 best_x = gx;
26926 best_row = r;
26927 goto found;
26929 else if (best_glyph == NULL
26930 || ((eabs (g->charpos - pos)
26931 < eabs (best_glyph->charpos - pos))
26932 && (right_p
26933 ? g->charpos < pos
26934 : g->charpos > pos)))
26936 best_glyph = g;
26937 best_x = gx;
26938 best_row = r;
26943 found:
26945 if (best_glyph)
26947 *x = best_x;
26948 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26950 if (right_p)
26952 *x += best_glyph->pixel_width;
26953 ++*hpos;
26956 *y = best_row->y;
26957 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
26960 return best_glyph != NULL;
26962 #endif /* not used */
26964 /* Find the positions of the first and the last glyphs in window W's
26965 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26966 (assumed to be a string), and return in HLINFO's mouse_face_*
26967 members the pixel and column/row coordinates of those glyphs. */
26969 static void
26970 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26971 Lisp_Object object,
26972 ptrdiff_t startpos, ptrdiff_t endpos)
26974 int yb = window_text_bottom_y (w);
26975 struct glyph_row *r;
26976 struct glyph *g, *e;
26977 int gx;
26978 int found = 0;
26980 /* Find the glyph row with at least one position in the range
26981 [STARTPOS..ENDPOS], and the first glyph in that row whose
26982 position belongs to that range. */
26983 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26984 r->enabled_p && r->y < yb;
26985 ++r)
26987 if (!r->reversed_p)
26989 g = r->glyphs[TEXT_AREA];
26990 e = g + r->used[TEXT_AREA];
26991 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26992 if (EQ (g->object, object)
26993 && startpos <= g->charpos && g->charpos <= endpos)
26995 hlinfo->mouse_face_beg_row
26996 = MATRIX_ROW_VPOS (r, w->current_matrix);
26997 hlinfo->mouse_face_beg_y = r->y;
26998 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26999 hlinfo->mouse_face_beg_x = gx;
27000 found = 1;
27001 break;
27004 else
27006 struct glyph *g1;
27008 e = r->glyphs[TEXT_AREA];
27009 g = e + r->used[TEXT_AREA];
27010 for ( ; g > e; --g)
27011 if (EQ ((g-1)->object, object)
27012 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27014 hlinfo->mouse_face_beg_row
27015 = MATRIX_ROW_VPOS (r, w->current_matrix);
27016 hlinfo->mouse_face_beg_y = r->y;
27017 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27018 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27019 gx += g1->pixel_width;
27020 hlinfo->mouse_face_beg_x = gx;
27021 found = 1;
27022 break;
27025 if (found)
27026 break;
27029 if (!found)
27030 return;
27032 /* Starting with the next row, look for the first row which does NOT
27033 include any glyphs whose positions are in the range. */
27034 for (++r; r->enabled_p && r->y < yb; ++r)
27036 g = r->glyphs[TEXT_AREA];
27037 e = g + r->used[TEXT_AREA];
27038 found = 0;
27039 for ( ; g < e; ++g)
27040 if (EQ (g->object, object)
27041 && startpos <= g->charpos && g->charpos <= endpos)
27043 found = 1;
27044 break;
27046 if (!found)
27047 break;
27050 /* The highlighted region ends on the previous row. */
27051 r--;
27053 /* Set the end row and its vertical pixel coordinate. */
27054 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27055 hlinfo->mouse_face_end_y = r->y;
27057 /* Compute and set the end column and the end column's horizontal
27058 pixel coordinate. */
27059 if (!r->reversed_p)
27061 g = r->glyphs[TEXT_AREA];
27062 e = g + r->used[TEXT_AREA];
27063 for ( ; e > g; --e)
27064 if (EQ ((e-1)->object, object)
27065 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27066 break;
27067 hlinfo->mouse_face_end_col = e - g;
27069 for (gx = r->x; g < e; ++g)
27070 gx += g->pixel_width;
27071 hlinfo->mouse_face_end_x = gx;
27073 else
27075 e = r->glyphs[TEXT_AREA];
27076 g = e + r->used[TEXT_AREA];
27077 for (gx = r->x ; e < g; ++e)
27079 if (EQ (e->object, object)
27080 && startpos <= e->charpos && e->charpos <= endpos)
27081 break;
27082 gx += e->pixel_width;
27084 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27085 hlinfo->mouse_face_end_x = gx;
27089 #ifdef HAVE_WINDOW_SYSTEM
27091 /* See if position X, Y is within a hot-spot of an image. */
27093 static int
27094 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27096 if (!CONSP (hot_spot))
27097 return 0;
27099 if (EQ (XCAR (hot_spot), Qrect))
27101 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27102 Lisp_Object rect = XCDR (hot_spot);
27103 Lisp_Object tem;
27104 if (!CONSP (rect))
27105 return 0;
27106 if (!CONSP (XCAR (rect)))
27107 return 0;
27108 if (!CONSP (XCDR (rect)))
27109 return 0;
27110 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27111 return 0;
27112 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27113 return 0;
27114 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27115 return 0;
27116 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27117 return 0;
27118 return 1;
27120 else if (EQ (XCAR (hot_spot), Qcircle))
27122 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27123 Lisp_Object circ = XCDR (hot_spot);
27124 Lisp_Object lr, lx0, ly0;
27125 if (CONSP (circ)
27126 && CONSP (XCAR (circ))
27127 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27128 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27129 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27131 double r = XFLOATINT (lr);
27132 double dx = XINT (lx0) - x;
27133 double dy = XINT (ly0) - y;
27134 return (dx * dx + dy * dy <= r * r);
27137 else if (EQ (XCAR (hot_spot), Qpoly))
27139 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27140 if (VECTORP (XCDR (hot_spot)))
27142 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27143 Lisp_Object *poly = v->contents;
27144 ptrdiff_t n = v->header.size;
27145 ptrdiff_t i;
27146 int inside = 0;
27147 Lisp_Object lx, ly;
27148 int x0, y0;
27150 /* Need an even number of coordinates, and at least 3 edges. */
27151 if (n < 6 || n & 1)
27152 return 0;
27154 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27155 If count is odd, we are inside polygon. Pixels on edges
27156 may or may not be included depending on actual geometry of the
27157 polygon. */
27158 if ((lx = poly[n-2], !INTEGERP (lx))
27159 || (ly = poly[n-1], !INTEGERP (lx)))
27160 return 0;
27161 x0 = XINT (lx), y0 = XINT (ly);
27162 for (i = 0; i < n; i += 2)
27164 int x1 = x0, y1 = y0;
27165 if ((lx = poly[i], !INTEGERP (lx))
27166 || (ly = poly[i+1], !INTEGERP (ly)))
27167 return 0;
27168 x0 = XINT (lx), y0 = XINT (ly);
27170 /* Does this segment cross the X line? */
27171 if (x0 >= x)
27173 if (x1 >= x)
27174 continue;
27176 else if (x1 < x)
27177 continue;
27178 if (y > y0 && y > y1)
27179 continue;
27180 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27181 inside = !inside;
27183 return inside;
27186 return 0;
27189 Lisp_Object
27190 find_hot_spot (Lisp_Object map, int x, int y)
27192 while (CONSP (map))
27194 if (CONSP (XCAR (map))
27195 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27196 return XCAR (map);
27197 map = XCDR (map);
27200 return Qnil;
27203 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27204 3, 3, 0,
27205 doc: /* Lookup in image map MAP coordinates X and Y.
27206 An image map is an alist where each element has the format (AREA ID PLIST).
27207 An AREA is specified as either a rectangle, a circle, or a polygon:
27208 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27209 pixel coordinates of the upper left and bottom right corners.
27210 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27211 and the radius of the circle; r may be a float or integer.
27212 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27213 vector describes one corner in the polygon.
27214 Returns the alist element for the first matching AREA in MAP. */)
27215 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27217 if (NILP (map))
27218 return Qnil;
27220 CHECK_NUMBER (x);
27221 CHECK_NUMBER (y);
27223 return find_hot_spot (map,
27224 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27225 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27229 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27230 static void
27231 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27233 /* Do not change cursor shape while dragging mouse. */
27234 if (!NILP (do_mouse_tracking))
27235 return;
27237 if (!NILP (pointer))
27239 if (EQ (pointer, Qarrow))
27240 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27241 else if (EQ (pointer, Qhand))
27242 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27243 else if (EQ (pointer, Qtext))
27244 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27245 else if (EQ (pointer, intern ("hdrag")))
27246 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27247 #ifdef HAVE_X_WINDOWS
27248 else if (EQ (pointer, intern ("vdrag")))
27249 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27250 #endif
27251 else if (EQ (pointer, intern ("hourglass")))
27252 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27253 else if (EQ (pointer, Qmodeline))
27254 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27255 else
27256 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27259 if (cursor != No_Cursor)
27260 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27263 #endif /* HAVE_WINDOW_SYSTEM */
27265 /* Take proper action when mouse has moved to the mode or header line
27266 or marginal area AREA of window W, x-position X and y-position Y.
27267 X is relative to the start of the text display area of W, so the
27268 width of bitmap areas and scroll bars must be subtracted to get a
27269 position relative to the start of the mode line. */
27271 static void
27272 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27273 enum window_part area)
27275 struct window *w = XWINDOW (window);
27276 struct frame *f = XFRAME (w->frame);
27277 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27278 #ifdef HAVE_WINDOW_SYSTEM
27279 Display_Info *dpyinfo;
27280 #endif
27281 Cursor cursor = No_Cursor;
27282 Lisp_Object pointer = Qnil;
27283 int dx, dy, width, height;
27284 ptrdiff_t charpos;
27285 Lisp_Object string, object = Qnil;
27286 Lisp_Object pos IF_LINT (= Qnil), help;
27288 Lisp_Object mouse_face;
27289 int original_x_pixel = x;
27290 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27291 struct glyph_row *row IF_LINT (= 0);
27293 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27295 int x0;
27296 struct glyph *end;
27298 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27299 returns them in row/column units! */
27300 string = mode_line_string (w, area, &x, &y, &charpos,
27301 &object, &dx, &dy, &width, &height);
27303 row = (area == ON_MODE_LINE
27304 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27305 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27307 /* Find the glyph under the mouse pointer. */
27308 if (row->mode_line_p && row->enabled_p)
27310 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27311 end = glyph + row->used[TEXT_AREA];
27313 for (x0 = original_x_pixel;
27314 glyph < end && x0 >= glyph->pixel_width;
27315 ++glyph)
27316 x0 -= glyph->pixel_width;
27318 if (glyph >= end)
27319 glyph = NULL;
27322 else
27324 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27325 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27326 returns them in row/column units! */
27327 string = marginal_area_string (w, area, &x, &y, &charpos,
27328 &object, &dx, &dy, &width, &height);
27331 help = Qnil;
27333 #ifdef HAVE_WINDOW_SYSTEM
27334 if (IMAGEP (object))
27336 Lisp_Object image_map, hotspot;
27337 if ((image_map = Fplist_get (XCDR (object), QCmap),
27338 !NILP (image_map))
27339 && (hotspot = find_hot_spot (image_map, dx, dy),
27340 CONSP (hotspot))
27341 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27343 Lisp_Object plist;
27345 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27346 If so, we could look for mouse-enter, mouse-leave
27347 properties in PLIST (and do something...). */
27348 hotspot = XCDR (hotspot);
27349 if (CONSP (hotspot)
27350 && (plist = XCAR (hotspot), CONSP (plist)))
27352 pointer = Fplist_get (plist, Qpointer);
27353 if (NILP (pointer))
27354 pointer = Qhand;
27355 help = Fplist_get (plist, Qhelp_echo);
27356 if (!NILP (help))
27358 help_echo_string = help;
27359 XSETWINDOW (help_echo_window, w);
27360 help_echo_object = w->contents;
27361 help_echo_pos = charpos;
27365 if (NILP (pointer))
27366 pointer = Fplist_get (XCDR (object), QCpointer);
27368 #endif /* HAVE_WINDOW_SYSTEM */
27370 if (STRINGP (string))
27371 pos = make_number (charpos);
27373 /* Set the help text and mouse pointer. If the mouse is on a part
27374 of the mode line without any text (e.g. past the right edge of
27375 the mode line text), use the default help text and pointer. */
27376 if (STRINGP (string) || area == ON_MODE_LINE)
27378 /* Arrange to display the help by setting the global variables
27379 help_echo_string, help_echo_object, and help_echo_pos. */
27380 if (NILP (help))
27382 if (STRINGP (string))
27383 help = Fget_text_property (pos, Qhelp_echo, string);
27385 if (!NILP (help))
27387 help_echo_string = help;
27388 XSETWINDOW (help_echo_window, w);
27389 help_echo_object = string;
27390 help_echo_pos = charpos;
27392 else if (area == ON_MODE_LINE)
27394 Lisp_Object default_help
27395 = buffer_local_value_1 (Qmode_line_default_help_echo,
27396 w->contents);
27398 if (STRINGP (default_help))
27400 help_echo_string = default_help;
27401 XSETWINDOW (help_echo_window, w);
27402 help_echo_object = Qnil;
27403 help_echo_pos = -1;
27408 #ifdef HAVE_WINDOW_SYSTEM
27409 /* Change the mouse pointer according to what is under it. */
27410 if (FRAME_WINDOW_P (f))
27412 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27413 if (STRINGP (string))
27415 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27417 if (NILP (pointer))
27418 pointer = Fget_text_property (pos, Qpointer, string);
27420 /* Change the mouse pointer according to what is under X/Y. */
27421 if (NILP (pointer)
27422 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27424 Lisp_Object map;
27425 map = Fget_text_property (pos, Qlocal_map, string);
27426 if (!KEYMAPP (map))
27427 map = Fget_text_property (pos, Qkeymap, string);
27428 if (!KEYMAPP (map))
27429 cursor = dpyinfo->vertical_scroll_bar_cursor;
27432 else
27433 /* Default mode-line pointer. */
27434 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27436 #endif
27439 /* Change the mouse face according to what is under X/Y. */
27440 if (STRINGP (string))
27442 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27443 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27444 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27445 && glyph)
27447 Lisp_Object b, e;
27449 struct glyph * tmp_glyph;
27451 int gpos;
27452 int gseq_length;
27453 int total_pixel_width;
27454 ptrdiff_t begpos, endpos, ignore;
27456 int vpos, hpos;
27458 b = Fprevious_single_property_change (make_number (charpos + 1),
27459 Qmouse_face, string, Qnil);
27460 if (NILP (b))
27461 begpos = 0;
27462 else
27463 begpos = XINT (b);
27465 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27466 if (NILP (e))
27467 endpos = SCHARS (string);
27468 else
27469 endpos = XINT (e);
27471 /* Calculate the glyph position GPOS of GLYPH in the
27472 displayed string, relative to the beginning of the
27473 highlighted part of the string.
27475 Note: GPOS is different from CHARPOS. CHARPOS is the
27476 position of GLYPH in the internal string object. A mode
27477 line string format has structures which are converted to
27478 a flattened string by the Emacs Lisp interpreter. The
27479 internal string is an element of those structures. The
27480 displayed string is the flattened string. */
27481 tmp_glyph = row_start_glyph;
27482 while (tmp_glyph < glyph
27483 && (!(EQ (tmp_glyph->object, glyph->object)
27484 && begpos <= tmp_glyph->charpos
27485 && tmp_glyph->charpos < endpos)))
27486 tmp_glyph++;
27487 gpos = glyph - tmp_glyph;
27489 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27490 the highlighted part of the displayed string to which
27491 GLYPH belongs. Note: GSEQ_LENGTH is different from
27492 SCHARS (STRING), because the latter returns the length of
27493 the internal string. */
27494 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27495 tmp_glyph > glyph
27496 && (!(EQ (tmp_glyph->object, glyph->object)
27497 && begpos <= tmp_glyph->charpos
27498 && tmp_glyph->charpos < endpos));
27499 tmp_glyph--)
27501 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27503 /* Calculate the total pixel width of all the glyphs between
27504 the beginning of the highlighted area and GLYPH. */
27505 total_pixel_width = 0;
27506 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27507 total_pixel_width += tmp_glyph->pixel_width;
27509 /* Pre calculation of re-rendering position. Note: X is in
27510 column units here, after the call to mode_line_string or
27511 marginal_area_string. */
27512 hpos = x - gpos;
27513 vpos = (area == ON_MODE_LINE
27514 ? (w->current_matrix)->nrows - 1
27515 : 0);
27517 /* If GLYPH's position is included in the region that is
27518 already drawn in mouse face, we have nothing to do. */
27519 if ( EQ (window, hlinfo->mouse_face_window)
27520 && (!row->reversed_p
27521 ? (hlinfo->mouse_face_beg_col <= hpos
27522 && hpos < hlinfo->mouse_face_end_col)
27523 /* In R2L rows we swap BEG and END, see below. */
27524 : (hlinfo->mouse_face_end_col <= hpos
27525 && hpos < hlinfo->mouse_face_beg_col))
27526 && hlinfo->mouse_face_beg_row == vpos )
27527 return;
27529 if (clear_mouse_face (hlinfo))
27530 cursor = No_Cursor;
27532 if (!row->reversed_p)
27534 hlinfo->mouse_face_beg_col = hpos;
27535 hlinfo->mouse_face_beg_x = original_x_pixel
27536 - (total_pixel_width + dx);
27537 hlinfo->mouse_face_end_col = hpos + gseq_length;
27538 hlinfo->mouse_face_end_x = 0;
27540 else
27542 /* In R2L rows, show_mouse_face expects BEG and END
27543 coordinates to be swapped. */
27544 hlinfo->mouse_face_end_col = hpos;
27545 hlinfo->mouse_face_end_x = original_x_pixel
27546 - (total_pixel_width + dx);
27547 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27548 hlinfo->mouse_face_beg_x = 0;
27551 hlinfo->mouse_face_beg_row = vpos;
27552 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27553 hlinfo->mouse_face_beg_y = 0;
27554 hlinfo->mouse_face_end_y = 0;
27555 hlinfo->mouse_face_past_end = 0;
27556 hlinfo->mouse_face_window = window;
27558 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27559 charpos,
27560 0, 0, 0,
27561 &ignore,
27562 glyph->face_id,
27564 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27566 if (NILP (pointer))
27567 pointer = Qhand;
27569 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27570 clear_mouse_face (hlinfo);
27572 #ifdef HAVE_WINDOW_SYSTEM
27573 if (FRAME_WINDOW_P (f))
27574 define_frame_cursor1 (f, cursor, pointer);
27575 #endif
27579 /* EXPORT:
27580 Take proper action when the mouse has moved to position X, Y on
27581 frame F with regards to highlighting portions of display that have
27582 mouse-face properties. Also de-highlight portions of display where
27583 the mouse was before, set the mouse pointer shape as appropriate
27584 for the mouse coordinates, and activate help echo (tooltips).
27585 X and Y can be negative or out of range. */
27587 void
27588 note_mouse_highlight (struct frame *f, int x, int y)
27590 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27591 enum window_part part = ON_NOTHING;
27592 Lisp_Object window;
27593 struct window *w;
27594 Cursor cursor = No_Cursor;
27595 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27596 struct buffer *b;
27598 /* When a menu is active, don't highlight because this looks odd. */
27599 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27600 if (popup_activated ())
27601 return;
27602 #endif
27604 if (!f->glyphs_initialized_p
27605 || f->pointer_invisible)
27606 return;
27608 hlinfo->mouse_face_mouse_x = x;
27609 hlinfo->mouse_face_mouse_y = y;
27610 hlinfo->mouse_face_mouse_frame = f;
27612 if (hlinfo->mouse_face_defer)
27613 return;
27615 /* Which window is that in? */
27616 window = window_from_coordinates (f, x, y, &part, 1);
27618 /* If displaying active text in another window, clear that. */
27619 if (! EQ (window, hlinfo->mouse_face_window)
27620 /* Also clear if we move out of text area in same window. */
27621 || (!NILP (hlinfo->mouse_face_window)
27622 && !NILP (window)
27623 && part != ON_TEXT
27624 && part != ON_MODE_LINE
27625 && part != ON_HEADER_LINE))
27626 clear_mouse_face (hlinfo);
27628 /* Not on a window -> return. */
27629 if (!WINDOWP (window))
27630 return;
27632 /* Reset help_echo_string. It will get recomputed below. */
27633 help_echo_string = Qnil;
27635 /* Convert to window-relative pixel coordinates. */
27636 w = XWINDOW (window);
27637 frame_to_window_pixel_xy (w, &x, &y);
27639 #ifdef HAVE_WINDOW_SYSTEM
27640 /* Handle tool-bar window differently since it doesn't display a
27641 buffer. */
27642 if (EQ (window, f->tool_bar_window))
27644 note_tool_bar_highlight (f, x, y);
27645 return;
27647 #endif
27649 /* Mouse is on the mode, header line or margin? */
27650 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
27651 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
27653 note_mode_line_or_margin_highlight (window, x, y, part);
27654 return;
27657 #ifdef HAVE_WINDOW_SYSTEM
27658 if (part == ON_VERTICAL_BORDER)
27660 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27661 help_echo_string = build_string ("drag-mouse-1: resize");
27663 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
27664 || part == ON_SCROLL_BAR)
27665 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27666 else
27667 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27668 #endif
27670 /* Are we in a window whose display is up to date?
27671 And verify the buffer's text has not changed. */
27672 b = XBUFFER (w->contents);
27673 if (part == ON_TEXT
27674 && w->window_end_valid
27675 && w->last_modified == BUF_MODIFF (b)
27676 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
27678 int hpos, vpos, dx, dy, area = LAST_AREA;
27679 ptrdiff_t pos;
27680 struct glyph *glyph;
27681 Lisp_Object object;
27682 Lisp_Object mouse_face = Qnil, position;
27683 Lisp_Object *overlay_vec = NULL;
27684 ptrdiff_t i, noverlays;
27685 struct buffer *obuf;
27686 ptrdiff_t obegv, ozv;
27687 int same_region;
27689 /* Find the glyph under X/Y. */
27690 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
27692 #ifdef HAVE_WINDOW_SYSTEM
27693 /* Look for :pointer property on image. */
27694 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27696 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27697 if (img != NULL && IMAGEP (img->spec))
27699 Lisp_Object image_map, hotspot;
27700 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
27701 !NILP (image_map))
27702 && (hotspot = find_hot_spot (image_map,
27703 glyph->slice.img.x + dx,
27704 glyph->slice.img.y + dy),
27705 CONSP (hotspot))
27706 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27708 Lisp_Object plist;
27710 /* Could check XCAR (hotspot) to see if we enter/leave
27711 this hot-spot.
27712 If so, we could look for mouse-enter, mouse-leave
27713 properties in PLIST (and do something...). */
27714 hotspot = XCDR (hotspot);
27715 if (CONSP (hotspot)
27716 && (plist = XCAR (hotspot), CONSP (plist)))
27718 pointer = Fplist_get (plist, Qpointer);
27719 if (NILP (pointer))
27720 pointer = Qhand;
27721 help_echo_string = Fplist_get (plist, Qhelp_echo);
27722 if (!NILP (help_echo_string))
27724 help_echo_window = window;
27725 help_echo_object = glyph->object;
27726 help_echo_pos = glyph->charpos;
27730 if (NILP (pointer))
27731 pointer = Fplist_get (XCDR (img->spec), QCpointer);
27734 #endif /* HAVE_WINDOW_SYSTEM */
27736 /* Clear mouse face if X/Y not over text. */
27737 if (glyph == NULL
27738 || area != TEXT_AREA
27739 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
27740 /* Glyph's OBJECT is an integer for glyphs inserted by the
27741 display engine for its internal purposes, like truncation
27742 and continuation glyphs and blanks beyond the end of
27743 line's text on text terminals. If we are over such a
27744 glyph, we are not over any text. */
27745 || INTEGERP (glyph->object)
27746 /* R2L rows have a stretch glyph at their front, which
27747 stands for no text, whereas L2R rows have no glyphs at
27748 all beyond the end of text. Treat such stretch glyphs
27749 like we do with NULL glyphs in L2R rows. */
27750 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
27751 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
27752 && glyph->type == STRETCH_GLYPH
27753 && glyph->avoid_cursor_p))
27755 if (clear_mouse_face (hlinfo))
27756 cursor = No_Cursor;
27757 #ifdef HAVE_WINDOW_SYSTEM
27758 if (FRAME_WINDOW_P (f) && NILP (pointer))
27760 if (area != TEXT_AREA)
27761 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27762 else
27763 pointer = Vvoid_text_area_pointer;
27765 #endif
27766 goto set_cursor;
27769 pos = glyph->charpos;
27770 object = glyph->object;
27771 if (!STRINGP (object) && !BUFFERP (object))
27772 goto set_cursor;
27774 /* If we get an out-of-range value, return now; avoid an error. */
27775 if (BUFFERP (object) && pos > BUF_Z (b))
27776 goto set_cursor;
27778 /* Make the window's buffer temporarily current for
27779 overlays_at and compute_char_face. */
27780 obuf = current_buffer;
27781 current_buffer = b;
27782 obegv = BEGV;
27783 ozv = ZV;
27784 BEGV = BEG;
27785 ZV = Z;
27787 /* Is this char mouse-active or does it have help-echo? */
27788 position = make_number (pos);
27790 if (BUFFERP (object))
27792 /* Put all the overlays we want in a vector in overlay_vec. */
27793 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27794 /* Sort overlays into increasing priority order. */
27795 noverlays = sort_overlays (overlay_vec, noverlays, w);
27797 else
27798 noverlays = 0;
27800 if (NILP (Vmouse_highlight))
27802 clear_mouse_face (hlinfo);
27803 goto check_help_echo;
27806 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27808 if (same_region)
27809 cursor = No_Cursor;
27811 /* Check mouse-face highlighting. */
27812 if (! same_region
27813 /* If there exists an overlay with mouse-face overlapping
27814 the one we are currently highlighting, we have to
27815 check if we enter the overlapping overlay, and then
27816 highlight only that. */
27817 || (OVERLAYP (hlinfo->mouse_face_overlay)
27818 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27820 /* Find the highest priority overlay with a mouse-face. */
27821 Lisp_Object overlay = Qnil;
27822 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27824 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27825 if (!NILP (mouse_face))
27826 overlay = overlay_vec[i];
27829 /* If we're highlighting the same overlay as before, there's
27830 no need to do that again. */
27831 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27832 goto check_help_echo;
27833 hlinfo->mouse_face_overlay = overlay;
27835 /* Clear the display of the old active region, if any. */
27836 if (clear_mouse_face (hlinfo))
27837 cursor = No_Cursor;
27839 /* If no overlay applies, get a text property. */
27840 if (NILP (overlay))
27841 mouse_face = Fget_text_property (position, Qmouse_face, object);
27843 /* Next, compute the bounds of the mouse highlighting and
27844 display it. */
27845 if (!NILP (mouse_face) && STRINGP (object))
27847 /* The mouse-highlighting comes from a display string
27848 with a mouse-face. */
27849 Lisp_Object s, e;
27850 ptrdiff_t ignore;
27852 s = Fprevious_single_property_change
27853 (make_number (pos + 1), Qmouse_face, object, Qnil);
27854 e = Fnext_single_property_change
27855 (position, Qmouse_face, object, Qnil);
27856 if (NILP (s))
27857 s = make_number (0);
27858 if (NILP (e))
27859 e = make_number (SCHARS (object) - 1);
27860 mouse_face_from_string_pos (w, hlinfo, object,
27861 XINT (s), XINT (e));
27862 hlinfo->mouse_face_past_end = 0;
27863 hlinfo->mouse_face_window = window;
27864 hlinfo->mouse_face_face_id
27865 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27866 glyph->face_id, 1);
27867 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27868 cursor = No_Cursor;
27870 else
27872 /* The mouse-highlighting, if any, comes from an overlay
27873 or text property in the buffer. */
27874 Lisp_Object buffer IF_LINT (= Qnil);
27875 Lisp_Object disp_string IF_LINT (= Qnil);
27877 if (STRINGP (object))
27879 /* If we are on a display string with no mouse-face,
27880 check if the text under it has one. */
27881 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27882 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27883 pos = string_buffer_position (object, start);
27884 if (pos > 0)
27886 mouse_face = get_char_property_and_overlay
27887 (make_number (pos), Qmouse_face, w->contents, &overlay);
27888 buffer = w->contents;
27889 disp_string = object;
27892 else
27894 buffer = object;
27895 disp_string = Qnil;
27898 if (!NILP (mouse_face))
27900 Lisp_Object before, after;
27901 Lisp_Object before_string, after_string;
27902 /* To correctly find the limits of mouse highlight
27903 in a bidi-reordered buffer, we must not use the
27904 optimization of limiting the search in
27905 previous-single-property-change and
27906 next-single-property-change, because
27907 rows_from_pos_range needs the real start and end
27908 positions to DTRT in this case. That's because
27909 the first row visible in a window does not
27910 necessarily display the character whose position
27911 is the smallest. */
27912 Lisp_Object lim1 =
27913 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27914 ? Fmarker_position (w->start)
27915 : Qnil;
27916 Lisp_Object lim2 =
27917 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27918 ? make_number (BUF_Z (XBUFFER (buffer))
27919 - XFASTINT (w->window_end_pos))
27920 : Qnil;
27922 if (NILP (overlay))
27924 /* Handle the text property case. */
27925 before = Fprevious_single_property_change
27926 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27927 after = Fnext_single_property_change
27928 (make_number (pos), Qmouse_face, buffer, lim2);
27929 before_string = after_string = Qnil;
27931 else
27933 /* Handle the overlay case. */
27934 before = Foverlay_start (overlay);
27935 after = Foverlay_end (overlay);
27936 before_string = Foverlay_get (overlay, Qbefore_string);
27937 after_string = Foverlay_get (overlay, Qafter_string);
27939 if (!STRINGP (before_string)) before_string = Qnil;
27940 if (!STRINGP (after_string)) after_string = Qnil;
27943 mouse_face_from_buffer_pos (window, hlinfo, pos,
27944 NILP (before)
27946 : XFASTINT (before),
27947 NILP (after)
27948 ? BUF_Z (XBUFFER (buffer))
27949 : XFASTINT (after),
27950 before_string, after_string,
27951 disp_string);
27952 cursor = No_Cursor;
27957 check_help_echo:
27959 /* Look for a `help-echo' property. */
27960 if (NILP (help_echo_string)) {
27961 Lisp_Object help, overlay;
27963 /* Check overlays first. */
27964 help = overlay = Qnil;
27965 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27967 overlay = overlay_vec[i];
27968 help = Foverlay_get (overlay, Qhelp_echo);
27971 if (!NILP (help))
27973 help_echo_string = help;
27974 help_echo_window = window;
27975 help_echo_object = overlay;
27976 help_echo_pos = pos;
27978 else
27980 Lisp_Object obj = glyph->object;
27981 ptrdiff_t charpos = glyph->charpos;
27983 /* Try text properties. */
27984 if (STRINGP (obj)
27985 && charpos >= 0
27986 && charpos < SCHARS (obj))
27988 help = Fget_text_property (make_number (charpos),
27989 Qhelp_echo, obj);
27990 if (NILP (help))
27992 /* If the string itself doesn't specify a help-echo,
27993 see if the buffer text ``under'' it does. */
27994 struct glyph_row *r
27995 = MATRIX_ROW (w->current_matrix, vpos);
27996 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27997 ptrdiff_t p = string_buffer_position (obj, start);
27998 if (p > 0)
28000 help = Fget_char_property (make_number (p),
28001 Qhelp_echo, w->contents);
28002 if (!NILP (help))
28004 charpos = p;
28005 obj = w->contents;
28010 else if (BUFFERP (obj)
28011 && charpos >= BEGV
28012 && charpos < ZV)
28013 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28014 obj);
28016 if (!NILP (help))
28018 help_echo_string = help;
28019 help_echo_window = window;
28020 help_echo_object = obj;
28021 help_echo_pos = charpos;
28026 #ifdef HAVE_WINDOW_SYSTEM
28027 /* Look for a `pointer' property. */
28028 if (FRAME_WINDOW_P (f) && NILP (pointer))
28030 /* Check overlays first. */
28031 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28032 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28034 if (NILP (pointer))
28036 Lisp_Object obj = glyph->object;
28037 ptrdiff_t charpos = glyph->charpos;
28039 /* Try text properties. */
28040 if (STRINGP (obj)
28041 && charpos >= 0
28042 && charpos < SCHARS (obj))
28044 pointer = Fget_text_property (make_number (charpos),
28045 Qpointer, obj);
28046 if (NILP (pointer))
28048 /* If the string itself doesn't specify a pointer,
28049 see if the buffer text ``under'' it does. */
28050 struct glyph_row *r
28051 = MATRIX_ROW (w->current_matrix, vpos);
28052 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28053 ptrdiff_t p = string_buffer_position (obj, start);
28054 if (p > 0)
28055 pointer = Fget_char_property (make_number (p),
28056 Qpointer, w->contents);
28059 else if (BUFFERP (obj)
28060 && charpos >= BEGV
28061 && charpos < ZV)
28062 pointer = Fget_text_property (make_number (charpos),
28063 Qpointer, obj);
28066 #endif /* HAVE_WINDOW_SYSTEM */
28068 BEGV = obegv;
28069 ZV = ozv;
28070 current_buffer = obuf;
28073 set_cursor:
28075 #ifdef HAVE_WINDOW_SYSTEM
28076 if (FRAME_WINDOW_P (f))
28077 define_frame_cursor1 (f, cursor, pointer);
28078 #else
28079 /* This is here to prevent a compiler error, about "label at end of
28080 compound statement". */
28081 return;
28082 #endif
28086 /* EXPORT for RIF:
28087 Clear any mouse-face on window W. This function is part of the
28088 redisplay interface, and is called from try_window_id and similar
28089 functions to ensure the mouse-highlight is off. */
28091 void
28092 x_clear_window_mouse_face (struct window *w)
28094 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28095 Lisp_Object window;
28097 block_input ();
28098 XSETWINDOW (window, w);
28099 if (EQ (window, hlinfo->mouse_face_window))
28100 clear_mouse_face (hlinfo);
28101 unblock_input ();
28105 /* EXPORT:
28106 Just discard the mouse face information for frame F, if any.
28107 This is used when the size of F is changed. */
28109 void
28110 cancel_mouse_face (struct frame *f)
28112 Lisp_Object window;
28113 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28115 window = hlinfo->mouse_face_window;
28116 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28118 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28119 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28120 hlinfo->mouse_face_window = Qnil;
28126 /***********************************************************************
28127 Exposure Events
28128 ***********************************************************************/
28130 #ifdef HAVE_WINDOW_SYSTEM
28132 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28133 which intersects rectangle R. R is in window-relative coordinates. */
28135 static void
28136 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28137 enum glyph_row_area area)
28139 struct glyph *first = row->glyphs[area];
28140 struct glyph *end = row->glyphs[area] + row->used[area];
28141 struct glyph *last;
28142 int first_x, start_x, x;
28144 if (area == TEXT_AREA && row->fill_line_p)
28145 /* If row extends face to end of line write the whole line. */
28146 draw_glyphs (w, 0, row, area,
28147 0, row->used[area],
28148 DRAW_NORMAL_TEXT, 0);
28149 else
28151 /* Set START_X to the window-relative start position for drawing glyphs of
28152 AREA. The first glyph of the text area can be partially visible.
28153 The first glyphs of other areas cannot. */
28154 start_x = window_box_left_offset (w, area);
28155 x = start_x;
28156 if (area == TEXT_AREA)
28157 x += row->x;
28159 /* Find the first glyph that must be redrawn. */
28160 while (first < end
28161 && x + first->pixel_width < r->x)
28163 x += first->pixel_width;
28164 ++first;
28167 /* Find the last one. */
28168 last = first;
28169 first_x = x;
28170 while (last < end
28171 && x < r->x + r->width)
28173 x += last->pixel_width;
28174 ++last;
28177 /* Repaint. */
28178 if (last > first)
28179 draw_glyphs (w, first_x - start_x, row, area,
28180 first - row->glyphs[area], last - row->glyphs[area],
28181 DRAW_NORMAL_TEXT, 0);
28186 /* Redraw the parts of the glyph row ROW on window W intersecting
28187 rectangle R. R is in window-relative coordinates. Value is
28188 non-zero if mouse-face was overwritten. */
28190 static int
28191 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28193 eassert (row->enabled_p);
28195 if (row->mode_line_p || w->pseudo_window_p)
28196 draw_glyphs (w, 0, row, TEXT_AREA,
28197 0, row->used[TEXT_AREA],
28198 DRAW_NORMAL_TEXT, 0);
28199 else
28201 if (row->used[LEFT_MARGIN_AREA])
28202 expose_area (w, row, r, LEFT_MARGIN_AREA);
28203 if (row->used[TEXT_AREA])
28204 expose_area (w, row, r, TEXT_AREA);
28205 if (row->used[RIGHT_MARGIN_AREA])
28206 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28207 draw_row_fringe_bitmaps (w, row);
28210 return row->mouse_face_p;
28214 /* Redraw those parts of glyphs rows during expose event handling that
28215 overlap other rows. Redrawing of an exposed line writes over parts
28216 of lines overlapping that exposed line; this function fixes that.
28218 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28219 row in W's current matrix that is exposed and overlaps other rows.
28220 LAST_OVERLAPPING_ROW is the last such row. */
28222 static void
28223 expose_overlaps (struct window *w,
28224 struct glyph_row *first_overlapping_row,
28225 struct glyph_row *last_overlapping_row,
28226 XRectangle *r)
28228 struct glyph_row *row;
28230 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28231 if (row->overlapping_p)
28233 eassert (row->enabled_p && !row->mode_line_p);
28235 row->clip = r;
28236 if (row->used[LEFT_MARGIN_AREA])
28237 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28239 if (row->used[TEXT_AREA])
28240 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28242 if (row->used[RIGHT_MARGIN_AREA])
28243 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28244 row->clip = NULL;
28249 /* Return non-zero if W's cursor intersects rectangle R. */
28251 static int
28252 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28254 XRectangle cr, result;
28255 struct glyph *cursor_glyph;
28256 struct glyph_row *row;
28258 if (w->phys_cursor.vpos >= 0
28259 && w->phys_cursor.vpos < w->current_matrix->nrows
28260 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28261 row->enabled_p)
28262 && row->cursor_in_fringe_p)
28264 /* Cursor is in the fringe. */
28265 cr.x = window_box_right_offset (w,
28266 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28267 ? RIGHT_MARGIN_AREA
28268 : TEXT_AREA));
28269 cr.y = row->y;
28270 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28271 cr.height = row->height;
28272 return x_intersect_rectangles (&cr, r, &result);
28275 cursor_glyph = get_phys_cursor_glyph (w);
28276 if (cursor_glyph)
28278 /* r is relative to W's box, but w->phys_cursor.x is relative
28279 to left edge of W's TEXT area. Adjust it. */
28280 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28281 cr.y = w->phys_cursor.y;
28282 cr.width = cursor_glyph->pixel_width;
28283 cr.height = w->phys_cursor_height;
28284 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28285 I assume the effect is the same -- and this is portable. */
28286 return x_intersect_rectangles (&cr, r, &result);
28288 /* If we don't understand the format, pretend we're not in the hot-spot. */
28289 return 0;
28293 /* EXPORT:
28294 Draw a vertical window border to the right of window W if W doesn't
28295 have vertical scroll bars. */
28297 void
28298 x_draw_vertical_border (struct window *w)
28300 struct frame *f = XFRAME (WINDOW_FRAME (w));
28302 /* We could do better, if we knew what type of scroll-bar the adjacent
28303 windows (on either side) have... But we don't :-(
28304 However, I think this works ok. ++KFS 2003-04-25 */
28306 /* Redraw borders between horizontally adjacent windows. Don't
28307 do it for frames with vertical scroll bars because either the
28308 right scroll bar of a window, or the left scroll bar of its
28309 neighbor will suffice as a border. */
28310 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28311 return;
28313 /* Note: It is necessary to redraw both the left and the right
28314 borders, for when only this single window W is being
28315 redisplayed. */
28316 if (!WINDOW_RIGHTMOST_P (w)
28317 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28319 int x0, x1, y0, y1;
28321 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28322 y1 -= 1;
28324 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28325 x1 -= 1;
28327 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28329 if (!WINDOW_LEFTMOST_P (w)
28330 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28332 int x0, x1, y0, y1;
28334 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28335 y1 -= 1;
28337 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28338 x0 -= 1;
28340 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28345 /* Redraw the part of window W intersection rectangle FR. Pixel
28346 coordinates in FR are frame-relative. Call this function with
28347 input blocked. Value is non-zero if the exposure overwrites
28348 mouse-face. */
28350 static int
28351 expose_window (struct window *w, XRectangle *fr)
28353 struct frame *f = XFRAME (w->frame);
28354 XRectangle wr, r;
28355 int mouse_face_overwritten_p = 0;
28357 /* If window is not yet fully initialized, do nothing. This can
28358 happen when toolkit scroll bars are used and a window is split.
28359 Reconfiguring the scroll bar will generate an expose for a newly
28360 created window. */
28361 if (w->current_matrix == NULL)
28362 return 0;
28364 /* When we're currently updating the window, display and current
28365 matrix usually don't agree. Arrange for a thorough display
28366 later. */
28367 if (w == updated_window)
28369 SET_FRAME_GARBAGED (f);
28370 return 0;
28373 /* Frame-relative pixel rectangle of W. */
28374 wr.x = WINDOW_LEFT_EDGE_X (w);
28375 wr.y = WINDOW_TOP_EDGE_Y (w);
28376 wr.width = WINDOW_TOTAL_WIDTH (w);
28377 wr.height = WINDOW_TOTAL_HEIGHT (w);
28379 if (x_intersect_rectangles (fr, &wr, &r))
28381 int yb = window_text_bottom_y (w);
28382 struct glyph_row *row;
28383 int cursor_cleared_p, phys_cursor_on_p;
28384 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28386 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28387 r.x, r.y, r.width, r.height));
28389 /* Convert to window coordinates. */
28390 r.x -= WINDOW_LEFT_EDGE_X (w);
28391 r.y -= WINDOW_TOP_EDGE_Y (w);
28393 /* Turn off the cursor. */
28394 if (!w->pseudo_window_p
28395 && phys_cursor_in_rect_p (w, &r))
28397 x_clear_cursor (w);
28398 cursor_cleared_p = 1;
28400 else
28401 cursor_cleared_p = 0;
28403 /* If the row containing the cursor extends face to end of line,
28404 then expose_area might overwrite the cursor outside the
28405 rectangle and thus notice_overwritten_cursor might clear
28406 w->phys_cursor_on_p. We remember the original value and
28407 check later if it is changed. */
28408 phys_cursor_on_p = w->phys_cursor_on_p;
28410 /* Update lines intersecting rectangle R. */
28411 first_overlapping_row = last_overlapping_row = NULL;
28412 for (row = w->current_matrix->rows;
28413 row->enabled_p;
28414 ++row)
28416 int y0 = row->y;
28417 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28419 if ((y0 >= r.y && y0 < r.y + r.height)
28420 || (y1 > r.y && y1 < r.y + r.height)
28421 || (r.y >= y0 && r.y < y1)
28422 || (r.y + r.height > y0 && r.y + r.height < y1))
28424 /* A header line may be overlapping, but there is no need
28425 to fix overlapping areas for them. KFS 2005-02-12 */
28426 if (row->overlapping_p && !row->mode_line_p)
28428 if (first_overlapping_row == NULL)
28429 first_overlapping_row = row;
28430 last_overlapping_row = row;
28433 row->clip = fr;
28434 if (expose_line (w, row, &r))
28435 mouse_face_overwritten_p = 1;
28436 row->clip = NULL;
28438 else if (row->overlapping_p)
28440 /* We must redraw a row overlapping the exposed area. */
28441 if (y0 < r.y
28442 ? y0 + row->phys_height > r.y
28443 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28445 if (first_overlapping_row == NULL)
28446 first_overlapping_row = row;
28447 last_overlapping_row = row;
28451 if (y1 >= yb)
28452 break;
28455 /* Display the mode line if there is one. */
28456 if (WINDOW_WANTS_MODELINE_P (w)
28457 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28458 row->enabled_p)
28459 && row->y < r.y + r.height)
28461 if (expose_line (w, row, &r))
28462 mouse_face_overwritten_p = 1;
28465 if (!w->pseudo_window_p)
28467 /* Fix the display of overlapping rows. */
28468 if (first_overlapping_row)
28469 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28470 fr);
28472 /* Draw border between windows. */
28473 x_draw_vertical_border (w);
28475 /* Turn the cursor on again. */
28476 if (cursor_cleared_p
28477 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28478 update_window_cursor (w, 1);
28482 return mouse_face_overwritten_p;
28487 /* Redraw (parts) of all windows in the window tree rooted at W that
28488 intersect R. R contains frame pixel coordinates. Value is
28489 non-zero if the exposure overwrites mouse-face. */
28491 static int
28492 expose_window_tree (struct window *w, XRectangle *r)
28494 struct frame *f = XFRAME (w->frame);
28495 int mouse_face_overwritten_p = 0;
28497 while (w && !FRAME_GARBAGED_P (f))
28499 if (WINDOWP (w->contents))
28500 mouse_face_overwritten_p
28501 |= expose_window_tree (XWINDOW (w->contents), r);
28502 else
28503 mouse_face_overwritten_p |= expose_window (w, r);
28505 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28508 return mouse_face_overwritten_p;
28512 /* EXPORT:
28513 Redisplay an exposed area of frame F. X and Y are the upper-left
28514 corner of the exposed rectangle. W and H are width and height of
28515 the exposed area. All are pixel values. W or H zero means redraw
28516 the entire frame. */
28518 void
28519 expose_frame (struct frame *f, int x, int y, int w, int h)
28521 XRectangle r;
28522 int mouse_face_overwritten_p = 0;
28524 TRACE ((stderr, "expose_frame "));
28526 /* No need to redraw if frame will be redrawn soon. */
28527 if (FRAME_GARBAGED_P (f))
28529 TRACE ((stderr, " garbaged\n"));
28530 return;
28533 /* If basic faces haven't been realized yet, there is no point in
28534 trying to redraw anything. This can happen when we get an expose
28535 event while Emacs is starting, e.g. by moving another window. */
28536 if (FRAME_FACE_CACHE (f) == NULL
28537 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28539 TRACE ((stderr, " no faces\n"));
28540 return;
28543 if (w == 0 || h == 0)
28545 r.x = r.y = 0;
28546 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28547 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28549 else
28551 r.x = x;
28552 r.y = y;
28553 r.width = w;
28554 r.height = h;
28557 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28558 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28560 if (WINDOWP (f->tool_bar_window))
28561 mouse_face_overwritten_p
28562 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28564 #ifdef HAVE_X_WINDOWS
28565 #ifndef MSDOS
28566 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28567 if (WINDOWP (f->menu_bar_window))
28568 mouse_face_overwritten_p
28569 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28570 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28571 #endif
28572 #endif
28574 /* Some window managers support a focus-follows-mouse style with
28575 delayed raising of frames. Imagine a partially obscured frame,
28576 and moving the mouse into partially obscured mouse-face on that
28577 frame. The visible part of the mouse-face will be highlighted,
28578 then the WM raises the obscured frame. With at least one WM, KDE
28579 2.1, Emacs is not getting any event for the raising of the frame
28580 (even tried with SubstructureRedirectMask), only Expose events.
28581 These expose events will draw text normally, i.e. not
28582 highlighted. Which means we must redo the highlight here.
28583 Subsume it under ``we love X''. --gerd 2001-08-15 */
28584 /* Included in Windows version because Windows most likely does not
28585 do the right thing if any third party tool offers
28586 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28587 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28589 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28590 if (f == hlinfo->mouse_face_mouse_frame)
28592 int mouse_x = hlinfo->mouse_face_mouse_x;
28593 int mouse_y = hlinfo->mouse_face_mouse_y;
28594 clear_mouse_face (hlinfo);
28595 note_mouse_highlight (f, mouse_x, mouse_y);
28601 /* EXPORT:
28602 Determine the intersection of two rectangles R1 and R2. Return
28603 the intersection in *RESULT. Value is non-zero if RESULT is not
28604 empty. */
28607 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
28609 XRectangle *left, *right;
28610 XRectangle *upper, *lower;
28611 int intersection_p = 0;
28613 /* Rearrange so that R1 is the left-most rectangle. */
28614 if (r1->x < r2->x)
28615 left = r1, right = r2;
28616 else
28617 left = r2, right = r1;
28619 /* X0 of the intersection is right.x0, if this is inside R1,
28620 otherwise there is no intersection. */
28621 if (right->x <= left->x + left->width)
28623 result->x = right->x;
28625 /* The right end of the intersection is the minimum of
28626 the right ends of left and right. */
28627 result->width = (min (left->x + left->width, right->x + right->width)
28628 - result->x);
28630 /* Same game for Y. */
28631 if (r1->y < r2->y)
28632 upper = r1, lower = r2;
28633 else
28634 upper = r2, lower = r1;
28636 /* The upper end of the intersection is lower.y0, if this is inside
28637 of upper. Otherwise, there is no intersection. */
28638 if (lower->y <= upper->y + upper->height)
28640 result->y = lower->y;
28642 /* The lower end of the intersection is the minimum of the lower
28643 ends of upper and lower. */
28644 result->height = (min (lower->y + lower->height,
28645 upper->y + upper->height)
28646 - result->y);
28647 intersection_p = 1;
28651 return intersection_p;
28654 #endif /* HAVE_WINDOW_SYSTEM */
28657 /***********************************************************************
28658 Initialization
28659 ***********************************************************************/
28661 void
28662 syms_of_xdisp (void)
28664 Vwith_echo_area_save_vector = Qnil;
28665 staticpro (&Vwith_echo_area_save_vector);
28667 Vmessage_stack = Qnil;
28668 staticpro (&Vmessage_stack);
28670 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
28671 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
28673 message_dolog_marker1 = Fmake_marker ();
28674 staticpro (&message_dolog_marker1);
28675 message_dolog_marker2 = Fmake_marker ();
28676 staticpro (&message_dolog_marker2);
28677 message_dolog_marker3 = Fmake_marker ();
28678 staticpro (&message_dolog_marker3);
28680 #ifdef GLYPH_DEBUG
28681 defsubr (&Sdump_frame_glyph_matrix);
28682 defsubr (&Sdump_glyph_matrix);
28683 defsubr (&Sdump_glyph_row);
28684 defsubr (&Sdump_tool_bar_row);
28685 defsubr (&Strace_redisplay);
28686 defsubr (&Strace_to_stderr);
28687 #endif
28688 #ifdef HAVE_WINDOW_SYSTEM
28689 defsubr (&Stool_bar_lines_needed);
28690 defsubr (&Slookup_image_map);
28691 #endif
28692 defsubr (&Sformat_mode_line);
28693 defsubr (&Sinvisible_p);
28694 defsubr (&Scurrent_bidi_paragraph_direction);
28696 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
28697 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
28698 DEFSYM (Qoverriding_local_map, "overriding-local-map");
28699 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
28700 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
28701 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
28702 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
28703 DEFSYM (Qeval, "eval");
28704 DEFSYM (QCdata, ":data");
28705 DEFSYM (Qdisplay, "display");
28706 DEFSYM (Qspace_width, "space-width");
28707 DEFSYM (Qraise, "raise");
28708 DEFSYM (Qslice, "slice");
28709 DEFSYM (Qspace, "space");
28710 DEFSYM (Qmargin, "margin");
28711 DEFSYM (Qpointer, "pointer");
28712 DEFSYM (Qleft_margin, "left-margin");
28713 DEFSYM (Qright_margin, "right-margin");
28714 DEFSYM (Qcenter, "center");
28715 DEFSYM (Qline_height, "line-height");
28716 DEFSYM (QCalign_to, ":align-to");
28717 DEFSYM (QCrelative_width, ":relative-width");
28718 DEFSYM (QCrelative_height, ":relative-height");
28719 DEFSYM (QCeval, ":eval");
28720 DEFSYM (QCpropertize, ":propertize");
28721 DEFSYM (QCfile, ":file");
28722 DEFSYM (Qfontified, "fontified");
28723 DEFSYM (Qfontification_functions, "fontification-functions");
28724 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
28725 DEFSYM (Qescape_glyph, "escape-glyph");
28726 DEFSYM (Qnobreak_space, "nobreak-space");
28727 DEFSYM (Qimage, "image");
28728 DEFSYM (Qtext, "text");
28729 DEFSYM (Qboth, "both");
28730 DEFSYM (Qboth_horiz, "both-horiz");
28731 DEFSYM (Qtext_image_horiz, "text-image-horiz");
28732 DEFSYM (QCmap, ":map");
28733 DEFSYM (QCpointer, ":pointer");
28734 DEFSYM (Qrect, "rect");
28735 DEFSYM (Qcircle, "circle");
28736 DEFSYM (Qpoly, "poly");
28737 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
28738 DEFSYM (Qgrow_only, "grow-only");
28739 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
28740 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
28741 DEFSYM (Qposition, "position");
28742 DEFSYM (Qbuffer_position, "buffer-position");
28743 DEFSYM (Qobject, "object");
28744 DEFSYM (Qbar, "bar");
28745 DEFSYM (Qhbar, "hbar");
28746 DEFSYM (Qbox, "box");
28747 DEFSYM (Qhollow, "hollow");
28748 DEFSYM (Qhand, "hand");
28749 DEFSYM (Qarrow, "arrow");
28750 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
28752 list_of_error = Fcons (Fcons (intern_c_string ("error"),
28753 Fcons (intern_c_string ("void-variable"), Qnil)),
28754 Qnil);
28755 staticpro (&list_of_error);
28757 DEFSYM (Qlast_arrow_position, "last-arrow-position");
28758 DEFSYM (Qlast_arrow_string, "last-arrow-string");
28759 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
28760 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
28762 echo_buffer[0] = echo_buffer[1] = Qnil;
28763 staticpro (&echo_buffer[0]);
28764 staticpro (&echo_buffer[1]);
28766 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
28767 staticpro (&echo_area_buffer[0]);
28768 staticpro (&echo_area_buffer[1]);
28770 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
28771 staticpro (&Vmessages_buffer_name);
28773 mode_line_proptrans_alist = Qnil;
28774 staticpro (&mode_line_proptrans_alist);
28775 mode_line_string_list = Qnil;
28776 staticpro (&mode_line_string_list);
28777 mode_line_string_face = Qnil;
28778 staticpro (&mode_line_string_face);
28779 mode_line_string_face_prop = Qnil;
28780 staticpro (&mode_line_string_face_prop);
28781 Vmode_line_unwind_vector = Qnil;
28782 staticpro (&Vmode_line_unwind_vector);
28784 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
28786 help_echo_string = Qnil;
28787 staticpro (&help_echo_string);
28788 help_echo_object = Qnil;
28789 staticpro (&help_echo_object);
28790 help_echo_window = Qnil;
28791 staticpro (&help_echo_window);
28792 previous_help_echo_string = Qnil;
28793 staticpro (&previous_help_echo_string);
28794 help_echo_pos = -1;
28796 DEFSYM (Qright_to_left, "right-to-left");
28797 DEFSYM (Qleft_to_right, "left-to-right");
28799 #ifdef HAVE_WINDOW_SYSTEM
28800 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28801 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
28802 For example, if a block cursor is over a tab, it will be drawn as
28803 wide as that tab on the display. */);
28804 x_stretch_cursor_p = 0;
28805 #endif
28807 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28808 doc: /* Non-nil means highlight trailing whitespace.
28809 The face used for trailing whitespace is `trailing-whitespace'. */);
28810 Vshow_trailing_whitespace = Qnil;
28812 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28813 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28814 If the value is t, Emacs highlights non-ASCII chars which have the
28815 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28816 or `escape-glyph' face respectively.
28818 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28819 U+2011 (non-breaking hyphen) are affected.
28821 Any other non-nil value means to display these characters as a escape
28822 glyph followed by an ordinary space or hyphen.
28824 A value of nil means no special handling of these characters. */);
28825 Vnobreak_char_display = Qt;
28827 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28828 doc: /* The pointer shape to show in void text areas.
28829 A value of nil means to show the text pointer. Other options are `arrow',
28830 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28831 Vvoid_text_area_pointer = Qarrow;
28833 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28834 doc: /* Non-nil means don't actually do any redisplay.
28835 This is used for internal purposes. */);
28836 Vinhibit_redisplay = Qnil;
28838 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28839 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28840 Vglobal_mode_string = Qnil;
28842 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28843 doc: /* Marker for where to display an arrow on top of the buffer text.
28844 This must be the beginning of a line in order to work.
28845 See also `overlay-arrow-string'. */);
28846 Voverlay_arrow_position = Qnil;
28848 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28849 doc: /* String to display as an arrow in non-window frames.
28850 See also `overlay-arrow-position'. */);
28851 Voverlay_arrow_string = build_pure_c_string ("=>");
28853 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28854 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28855 The symbols on this list are examined during redisplay to determine
28856 where to display overlay arrows. */);
28857 Voverlay_arrow_variable_list
28858 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28860 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28861 doc: /* The number of lines to try scrolling a window by when point moves out.
28862 If that fails to bring point back on frame, point is centered instead.
28863 If this is zero, point is always centered after it moves off frame.
28864 If you want scrolling to always be a line at a time, you should set
28865 `scroll-conservatively' to a large value rather than set this to 1. */);
28867 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28868 doc: /* Scroll up to this many lines, to bring point back on screen.
28869 If point moves off-screen, redisplay will scroll by up to
28870 `scroll-conservatively' lines in order to bring point just barely
28871 onto the screen again. If that cannot be done, then redisplay
28872 recenters point as usual.
28874 If the value is greater than 100, redisplay will never recenter point,
28875 but will always scroll just enough text to bring point into view, even
28876 if you move far away.
28878 A value of zero means always recenter point if it moves off screen. */);
28879 scroll_conservatively = 0;
28881 DEFVAR_INT ("scroll-margin", scroll_margin,
28882 doc: /* Number of lines of margin at the top and bottom of a window.
28883 Recenter the window whenever point gets within this many lines
28884 of the top or bottom of the window. */);
28885 scroll_margin = 0;
28887 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28888 doc: /* Pixels per inch value for non-window system displays.
28889 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28890 Vdisplay_pixels_per_inch = make_float (72.0);
28892 #ifdef GLYPH_DEBUG
28893 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28894 #endif
28896 DEFVAR_LISP ("truncate-partial-width-windows",
28897 Vtruncate_partial_width_windows,
28898 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28899 For an integer value, truncate lines in each window narrower than the
28900 full frame width, provided the window width is less than that integer;
28901 otherwise, respect the value of `truncate-lines'.
28903 For any other non-nil value, truncate lines in all windows that do
28904 not span the full frame width.
28906 A value of nil means to respect the value of `truncate-lines'.
28908 If `word-wrap' is enabled, you might want to reduce this. */);
28909 Vtruncate_partial_width_windows = make_number (50);
28911 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28912 doc: /* Maximum buffer size for which line number should be displayed.
28913 If the buffer is bigger than this, the line number does not appear
28914 in the mode line. A value of nil means no limit. */);
28915 Vline_number_display_limit = Qnil;
28917 DEFVAR_INT ("line-number-display-limit-width",
28918 line_number_display_limit_width,
28919 doc: /* Maximum line width (in characters) for line number display.
28920 If the average length of the lines near point is bigger than this, then the
28921 line number may be omitted from the mode line. */);
28922 line_number_display_limit_width = 200;
28924 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28925 doc: /* Non-nil means highlight region even in nonselected windows. */);
28926 highlight_nonselected_windows = 0;
28928 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28929 doc: /* Non-nil if more than one frame is visible on this display.
28930 Minibuffer-only frames don't count, but iconified frames do.
28931 This variable is not guaranteed to be accurate except while processing
28932 `frame-title-format' and `icon-title-format'. */);
28934 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28935 doc: /* Template for displaying the title bar of visible frames.
28936 \(Assuming the window manager supports this feature.)
28938 This variable has the same structure as `mode-line-format', except that
28939 the %c and %l constructs are ignored. It is used only on frames for
28940 which no explicit name has been set \(see `modify-frame-parameters'). */);
28942 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28943 doc: /* Template for displaying the title bar of an iconified frame.
28944 \(Assuming the window manager supports this feature.)
28945 This variable has the same structure as `mode-line-format' (which see),
28946 and is used only on frames for which no explicit name has been set
28947 \(see `modify-frame-parameters'). */);
28948 Vicon_title_format
28949 = Vframe_title_format
28950 = listn (CONSTYPE_PURE, 3,
28951 intern_c_string ("multiple-frames"),
28952 build_pure_c_string ("%b"),
28953 listn (CONSTYPE_PURE, 4,
28954 empty_unibyte_string,
28955 intern_c_string ("invocation-name"),
28956 build_pure_c_string ("@"),
28957 intern_c_string ("system-name")));
28959 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28960 doc: /* Maximum number of lines to keep in the message log buffer.
28961 If nil, disable message logging. If t, log messages but don't truncate
28962 the buffer when it becomes large. */);
28963 Vmessage_log_max = make_number (1000);
28965 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28966 doc: /* Functions called before redisplay, if window sizes have changed.
28967 The value should be a list of functions that take one argument.
28968 Just before redisplay, for each frame, if any of its windows have changed
28969 size since the last redisplay, or have been split or deleted,
28970 all the functions in the list are called, with the frame as argument. */);
28971 Vwindow_size_change_functions = Qnil;
28973 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28974 doc: /* List of functions to call before redisplaying a window with scrolling.
28975 Each function is called with two arguments, the window and its new
28976 display-start position. Note that these functions are also called by
28977 `set-window-buffer'. Also note that the value of `window-end' is not
28978 valid when these functions are called.
28980 Warning: Do not use this feature to alter the way the window
28981 is scrolled. It is not designed for that, and such use probably won't
28982 work. */);
28983 Vwindow_scroll_functions = Qnil;
28985 DEFVAR_LISP ("window-text-change-functions",
28986 Vwindow_text_change_functions,
28987 doc: /* Functions to call in redisplay when text in the window might change. */);
28988 Vwindow_text_change_functions = Qnil;
28990 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
28991 doc: /* Functions called when redisplay of a window reaches the end trigger.
28992 Each function is called with two arguments, the window and the end trigger value.
28993 See `set-window-redisplay-end-trigger'. */);
28994 Vredisplay_end_trigger_functions = Qnil;
28996 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
28997 doc: /* Non-nil means autoselect window with mouse pointer.
28998 If nil, do not autoselect windows.
28999 A positive number means delay autoselection by that many seconds: a
29000 window is autoselected only after the mouse has remained in that
29001 window for the duration of the delay.
29002 A negative number has a similar effect, but causes windows to be
29003 autoselected only after the mouse has stopped moving. \(Because of
29004 the way Emacs compares mouse events, you will occasionally wait twice
29005 that time before the window gets selected.\)
29006 Any other value means to autoselect window instantaneously when the
29007 mouse pointer enters it.
29009 Autoselection selects the minibuffer only if it is active, and never
29010 unselects the minibuffer if it is active.
29012 When customizing this variable make sure that the actual value of
29013 `focus-follows-mouse' matches the behavior of your window manager. */);
29014 Vmouse_autoselect_window = Qnil;
29016 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29017 doc: /* Non-nil means automatically resize tool-bars.
29018 This dynamically changes the tool-bar's height to the minimum height
29019 that is needed to make all tool-bar items visible.
29020 If value is `grow-only', the tool-bar's height is only increased
29021 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29022 Vauto_resize_tool_bars = Qt;
29024 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29025 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29026 auto_raise_tool_bar_buttons_p = 1;
29028 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29029 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29030 make_cursor_line_fully_visible_p = 1;
29032 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29033 doc: /* Border below tool-bar in pixels.
29034 If an integer, use it as the height of the border.
29035 If it is one of `internal-border-width' or `border-width', use the
29036 value of the corresponding frame parameter.
29037 Otherwise, no border is added below the tool-bar. */);
29038 Vtool_bar_border = Qinternal_border_width;
29040 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29041 doc: /* Margin around tool-bar buttons in pixels.
29042 If an integer, use that for both horizontal and vertical margins.
29043 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29044 HORZ specifying the horizontal margin, and VERT specifying the
29045 vertical margin. */);
29046 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29048 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29049 doc: /* Relief thickness of tool-bar buttons. */);
29050 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29052 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29053 doc: /* Tool bar style to use.
29054 It can be one of
29055 image - show images only
29056 text - show text only
29057 both - show both, text below image
29058 both-horiz - show text to the right of the image
29059 text-image-horiz - show text to the left of the image
29060 any other - use system default or image if no system default.
29062 This variable only affects the GTK+ toolkit version of Emacs. */);
29063 Vtool_bar_style = Qnil;
29065 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29066 doc: /* Maximum number of characters a label can have to be shown.
29067 The tool bar style must also show labels for this to have any effect, see
29068 `tool-bar-style'. */);
29069 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29071 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29072 doc: /* List of functions to call to fontify regions of text.
29073 Each function is called with one argument POS. Functions must
29074 fontify a region starting at POS in the current buffer, and give
29075 fontified regions the property `fontified'. */);
29076 Vfontification_functions = Qnil;
29077 Fmake_variable_buffer_local (Qfontification_functions);
29079 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29080 unibyte_display_via_language_environment,
29081 doc: /* Non-nil means display unibyte text according to language environment.
29082 Specifically, this means that raw bytes in the range 160-255 decimal
29083 are displayed by converting them to the equivalent multibyte characters
29084 according to the current language environment. As a result, they are
29085 displayed according to the current fontset.
29087 Note that this variable affects only how these bytes are displayed,
29088 but does not change the fact they are interpreted as raw bytes. */);
29089 unibyte_display_via_language_environment = 0;
29091 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29092 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29093 If a float, it specifies a fraction of the mini-window frame's height.
29094 If an integer, it specifies a number of lines. */);
29095 Vmax_mini_window_height = make_float (0.25);
29097 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29098 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29099 A value of nil means don't automatically resize mini-windows.
29100 A value of t means resize them to fit the text displayed in them.
29101 A value of `grow-only', the default, means let mini-windows grow only;
29102 they return to their normal size when the minibuffer is closed, or the
29103 echo area becomes empty. */);
29104 Vresize_mini_windows = Qgrow_only;
29106 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29107 doc: /* Alist specifying how to blink the cursor off.
29108 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29109 `cursor-type' frame-parameter or variable equals ON-STATE,
29110 comparing using `equal', Emacs uses OFF-STATE to specify
29111 how to blink it off. ON-STATE and OFF-STATE are values for
29112 the `cursor-type' frame parameter.
29114 If a frame's ON-STATE has no entry in this list,
29115 the frame's other specifications determine how to blink the cursor off. */);
29116 Vblink_cursor_alist = Qnil;
29118 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29119 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29120 If non-nil, windows are automatically scrolled horizontally to make
29121 point visible. */);
29122 automatic_hscrolling_p = 1;
29123 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29125 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29126 doc: /* How many columns away from the window edge point is allowed to get
29127 before automatic hscrolling will horizontally scroll the window. */);
29128 hscroll_margin = 5;
29130 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29131 doc: /* How many columns to scroll the window when point gets too close to the edge.
29132 When point is less than `hscroll-margin' columns from the window
29133 edge, automatic hscrolling will scroll the window by the amount of columns
29134 determined by this variable. If its value is a positive integer, scroll that
29135 many columns. If it's a positive floating-point number, it specifies the
29136 fraction of the window's width to scroll. If it's nil or zero, point will be
29137 centered horizontally after the scroll. Any other value, including negative
29138 numbers, are treated as if the value were zero.
29140 Automatic hscrolling always moves point outside the scroll margin, so if
29141 point was more than scroll step columns inside the margin, the window will
29142 scroll more than the value given by the scroll step.
29144 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29145 and `scroll-right' overrides this variable's effect. */);
29146 Vhscroll_step = make_number (0);
29148 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29149 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29150 Bind this around calls to `message' to let it take effect. */);
29151 message_truncate_lines = 0;
29153 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29154 doc: /* Normal hook run to update the menu bar definitions.
29155 Redisplay runs this hook before it redisplays the menu bar.
29156 This is used to update submenus such as Buffers,
29157 whose contents depend on various data. */);
29158 Vmenu_bar_update_hook = Qnil;
29160 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29161 doc: /* Frame for which we are updating a menu.
29162 The enable predicate for a menu binding should check this variable. */);
29163 Vmenu_updating_frame = Qnil;
29165 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29166 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29167 inhibit_menubar_update = 0;
29169 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29170 doc: /* Prefix prepended to all continuation lines at display time.
29171 The value may be a string, an image, or a stretch-glyph; it is
29172 interpreted in the same way as the value of a `display' text property.
29174 This variable is overridden by any `wrap-prefix' text or overlay
29175 property.
29177 To add a prefix to non-continuation lines, use `line-prefix'. */);
29178 Vwrap_prefix = Qnil;
29179 DEFSYM (Qwrap_prefix, "wrap-prefix");
29180 Fmake_variable_buffer_local (Qwrap_prefix);
29182 DEFVAR_LISP ("line-prefix", Vline_prefix,
29183 doc: /* Prefix prepended to all non-continuation lines at display time.
29184 The value may be a string, an image, or a stretch-glyph; it is
29185 interpreted in the same way as the value of a `display' text property.
29187 This variable is overridden by any `line-prefix' text or overlay
29188 property.
29190 To add a prefix to continuation lines, use `wrap-prefix'. */);
29191 Vline_prefix = Qnil;
29192 DEFSYM (Qline_prefix, "line-prefix");
29193 Fmake_variable_buffer_local (Qline_prefix);
29195 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29196 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29197 inhibit_eval_during_redisplay = 0;
29199 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29200 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29201 inhibit_free_realized_faces = 0;
29203 #ifdef GLYPH_DEBUG
29204 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29205 doc: /* Inhibit try_window_id display optimization. */);
29206 inhibit_try_window_id = 0;
29208 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29209 doc: /* Inhibit try_window_reusing display optimization. */);
29210 inhibit_try_window_reusing = 0;
29212 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29213 doc: /* Inhibit try_cursor_movement display optimization. */);
29214 inhibit_try_cursor_movement = 0;
29215 #endif /* GLYPH_DEBUG */
29217 DEFVAR_INT ("overline-margin", overline_margin,
29218 doc: /* Space between overline and text, in pixels.
29219 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29220 margin to the character height. */);
29221 overline_margin = 2;
29223 DEFVAR_INT ("underline-minimum-offset",
29224 underline_minimum_offset,
29225 doc: /* Minimum distance between baseline and underline.
29226 This can improve legibility of underlined text at small font sizes,
29227 particularly when using variable `x-use-underline-position-properties'
29228 with fonts that specify an UNDERLINE_POSITION relatively close to the
29229 baseline. The default value is 1. */);
29230 underline_minimum_offset = 1;
29232 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29233 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29234 This feature only works when on a window system that can change
29235 cursor shapes. */);
29236 display_hourglass_p = 1;
29238 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29239 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29240 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29242 hourglass_atimer = NULL;
29243 hourglass_shown_p = 0;
29245 DEFSYM (Qglyphless_char, "glyphless-char");
29246 DEFSYM (Qhex_code, "hex-code");
29247 DEFSYM (Qempty_box, "empty-box");
29248 DEFSYM (Qthin_space, "thin-space");
29249 DEFSYM (Qzero_width, "zero-width");
29251 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29252 /* Intern this now in case it isn't already done.
29253 Setting this variable twice is harmless.
29254 But don't staticpro it here--that is done in alloc.c. */
29255 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29256 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29258 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29259 doc: /* Char-table defining glyphless characters.
29260 Each element, if non-nil, should be one of the following:
29261 an ASCII acronym string: display this string in a box
29262 `hex-code': display the hexadecimal code of a character in a box
29263 `empty-box': display as an empty box
29264 `thin-space': display as 1-pixel width space
29265 `zero-width': don't display
29266 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29267 display method for graphical terminals and text terminals respectively.
29268 GRAPHICAL and TEXT should each have one of the values listed above.
29270 The char-table has one extra slot to control the display of a character for
29271 which no font is found. This slot only takes effect on graphical terminals.
29272 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29273 `thin-space'. The default is `empty-box'. */);
29274 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29275 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29276 Qempty_box);
29278 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29279 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29280 Vdebug_on_message = Qnil;
29284 /* Initialize this module when Emacs starts. */
29286 void
29287 init_xdisp (void)
29289 current_header_line_height = current_mode_line_height = -1;
29291 CHARPOS (this_line_start_pos) = 0;
29293 if (!noninteractive)
29295 struct window *m = XWINDOW (minibuf_window);
29296 Lisp_Object frame = m->frame;
29297 struct frame *f = XFRAME (frame);
29298 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29299 struct window *r = XWINDOW (root);
29300 int i;
29302 echo_area_window = minibuf_window;
29304 r->top_line = FRAME_TOP_MARGIN (f);
29305 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29306 r->total_cols = FRAME_COLS (f);
29308 m->top_line = FRAME_LINES (f) - 1;
29309 m->total_lines = 1;
29310 m->total_cols = FRAME_COLS (f);
29312 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29313 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29314 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29316 /* The default ellipsis glyphs `...'. */
29317 for (i = 0; i < 3; ++i)
29318 default_invis_vector[i] = make_number ('.');
29322 /* Allocate the buffer for frame titles.
29323 Also used for `format-mode-line'. */
29324 int size = 100;
29325 mode_line_noprop_buf = xmalloc (size);
29326 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29327 mode_line_noprop_ptr = mode_line_noprop_buf;
29328 mode_line_target = MODE_LINE_DISPLAY;
29331 help_echo_showing_p = 0;
29334 /* Platform-independent portion of hourglass implementation. */
29336 /* Cancel a currently active hourglass timer, and start a new one. */
29337 void
29338 start_hourglass (void)
29340 #if defined (HAVE_WINDOW_SYSTEM)
29341 EMACS_TIME delay;
29343 cancel_hourglass ();
29345 if (INTEGERP (Vhourglass_delay)
29346 && XINT (Vhourglass_delay) > 0)
29347 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29348 TYPE_MAXIMUM (time_t)),
29350 else if (FLOATP (Vhourglass_delay)
29351 && XFLOAT_DATA (Vhourglass_delay) > 0)
29352 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29353 else
29354 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29356 #ifdef HAVE_NTGUI
29358 extern void w32_note_current_window (void);
29359 w32_note_current_window ();
29361 #endif /* HAVE_NTGUI */
29363 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29364 show_hourglass, NULL);
29365 #endif
29369 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29370 shown. */
29371 void
29372 cancel_hourglass (void)
29374 #if defined (HAVE_WINDOW_SYSTEM)
29375 if (hourglass_atimer)
29377 cancel_atimer (hourglass_atimer);
29378 hourglass_atimer = NULL;
29381 if (hourglass_shown_p)
29382 hide_hourglass ();
29383 #endif