Fix Eshell bug
[emacs.git] / src / xdisp.c
blob5ec72407191c7e37b6f7562e724a387c61d3e0e1
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;
18976 if (STRINGP (it->object))
18977 position = make_number (IT_STRING_CHARPOS (*it));
18978 else if (BUFFERP (it->object))
18979 position = make_number (IT_CHARPOS (*it));
18980 else
18981 return Qnil;
18983 return Fget_char_property (position, prop, it->object);
18986 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18988 static void
18989 handle_line_prefix (struct it *it)
18991 Lisp_Object prefix;
18993 if (it->continuation_lines_width > 0)
18995 prefix = get_it_property (it, Qwrap_prefix);
18996 if (NILP (prefix))
18997 prefix = Vwrap_prefix;
18999 else
19001 prefix = get_it_property (it, Qline_prefix);
19002 if (NILP (prefix))
19003 prefix = Vline_prefix;
19005 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19007 /* If the prefix is wider than the window, and we try to wrap
19008 it, it would acquire its own wrap prefix, and so on till the
19009 iterator stack overflows. So, don't wrap the prefix. */
19010 it->line_wrap = TRUNCATE;
19011 it->avoid_cursor_p = 1;
19017 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19018 only for R2L lines from display_line and display_string, when they
19019 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19020 the line/string needs to be continued on the next glyph row. */
19021 static void
19022 unproduce_glyphs (struct it *it, int n)
19024 struct glyph *glyph, *end;
19026 eassert (it->glyph_row);
19027 eassert (it->glyph_row->reversed_p);
19028 eassert (it->area == TEXT_AREA);
19029 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19031 if (n > it->glyph_row->used[TEXT_AREA])
19032 n = it->glyph_row->used[TEXT_AREA];
19033 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19034 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19035 for ( ; glyph < end; glyph++)
19036 glyph[-n] = *glyph;
19039 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19040 and ROW->maxpos. */
19041 static void
19042 find_row_edges (struct it *it, struct glyph_row *row,
19043 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19044 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19046 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19047 lines' rows is implemented for bidi-reordered rows. */
19049 /* ROW->minpos is the value of min_pos, the minimal buffer position
19050 we have in ROW, or ROW->start.pos if that is smaller. */
19051 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19052 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19053 else
19054 /* We didn't find buffer positions smaller than ROW->start, or
19055 didn't find _any_ valid buffer positions in any of the glyphs,
19056 so we must trust the iterator's computed positions. */
19057 row->minpos = row->start.pos;
19058 if (max_pos <= 0)
19060 max_pos = CHARPOS (it->current.pos);
19061 max_bpos = BYTEPOS (it->current.pos);
19064 /* Here are the various use-cases for ending the row, and the
19065 corresponding values for ROW->maxpos:
19067 Line ends in a newline from buffer eol_pos + 1
19068 Line is continued from buffer max_pos + 1
19069 Line is truncated on right it->current.pos
19070 Line ends in a newline from string max_pos + 1(*)
19071 (*) + 1 only when line ends in a forward scan
19072 Line is continued from string max_pos
19073 Line is continued from display vector max_pos
19074 Line is entirely from a string min_pos == max_pos
19075 Line is entirely from a display vector min_pos == max_pos
19076 Line that ends at ZV ZV
19078 If you discover other use-cases, please add them here as
19079 appropriate. */
19080 if (row->ends_at_zv_p)
19081 row->maxpos = it->current.pos;
19082 else if (row->used[TEXT_AREA])
19084 int seen_this_string = 0;
19085 struct glyph_row *r1 = row - 1;
19087 /* Did we see the same display string on the previous row? */
19088 if (STRINGP (it->object)
19089 /* this is not the first row */
19090 && row > it->w->desired_matrix->rows
19091 /* previous row is not the header line */
19092 && !r1->mode_line_p
19093 /* previous row also ends in a newline from a string */
19094 && r1->ends_in_newline_from_string_p)
19096 struct glyph *start, *end;
19098 /* Search for the last glyph of the previous row that came
19099 from buffer or string. Depending on whether the row is
19100 L2R or R2L, we need to process it front to back or the
19101 other way round. */
19102 if (!r1->reversed_p)
19104 start = r1->glyphs[TEXT_AREA];
19105 end = start + r1->used[TEXT_AREA];
19106 /* Glyphs inserted by redisplay have an integer (zero)
19107 as their object. */
19108 while (end > start
19109 && INTEGERP ((end - 1)->object)
19110 && (end - 1)->charpos <= 0)
19111 --end;
19112 if (end > start)
19114 if (EQ ((end - 1)->object, it->object))
19115 seen_this_string = 1;
19117 else
19118 /* If all the glyphs of the previous row were inserted
19119 by redisplay, it means the previous row was
19120 produced from a single newline, which is only
19121 possible if that newline came from the same string
19122 as the one which produced this ROW. */
19123 seen_this_string = 1;
19125 else
19127 end = r1->glyphs[TEXT_AREA] - 1;
19128 start = end + r1->used[TEXT_AREA];
19129 while (end < start
19130 && INTEGERP ((end + 1)->object)
19131 && (end + 1)->charpos <= 0)
19132 ++end;
19133 if (end < start)
19135 if (EQ ((end + 1)->object, it->object))
19136 seen_this_string = 1;
19138 else
19139 seen_this_string = 1;
19142 /* Take note of each display string that covers a newline only
19143 once, the first time we see it. This is for when a display
19144 string includes more than one newline in it. */
19145 if (row->ends_in_newline_from_string_p && !seen_this_string)
19147 /* If we were scanning the buffer forward when we displayed
19148 the string, we want to account for at least one buffer
19149 position that belongs to this row (position covered by
19150 the display string), so that cursor positioning will
19151 consider this row as a candidate when point is at the end
19152 of the visual line represented by this row. This is not
19153 required when scanning back, because max_pos will already
19154 have a much larger value. */
19155 if (CHARPOS (row->end.pos) > max_pos)
19156 INC_BOTH (max_pos, max_bpos);
19157 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19159 else if (CHARPOS (it->eol_pos) > 0)
19160 SET_TEXT_POS (row->maxpos,
19161 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19162 else if (row->continued_p)
19164 /* If max_pos is different from IT's current position, it
19165 means IT->method does not belong to the display element
19166 at max_pos. However, it also means that the display
19167 element at max_pos was displayed in its entirety on this
19168 line, which is equivalent to saying that the next line
19169 starts at the next buffer position. */
19170 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19171 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19172 else
19174 INC_BOTH (max_pos, max_bpos);
19175 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19178 else if (row->truncated_on_right_p)
19179 /* display_line already called reseat_at_next_visible_line_start,
19180 which puts the iterator at the beginning of the next line, in
19181 the logical order. */
19182 row->maxpos = it->current.pos;
19183 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19184 /* A line that is entirely from a string/image/stretch... */
19185 row->maxpos = row->minpos;
19186 else
19187 emacs_abort ();
19189 else
19190 row->maxpos = it->current.pos;
19193 /* Construct the glyph row IT->glyph_row in the desired matrix of
19194 IT->w from text at the current position of IT. See dispextern.h
19195 for an overview of struct it. Value is non-zero if
19196 IT->glyph_row displays text, as opposed to a line displaying ZV
19197 only. */
19199 static int
19200 display_line (struct it *it)
19202 struct glyph_row *row = it->glyph_row;
19203 Lisp_Object overlay_arrow_string;
19204 struct it wrap_it;
19205 void *wrap_data = NULL;
19206 int may_wrap = 0, wrap_x IF_LINT (= 0);
19207 int wrap_row_used = -1;
19208 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19209 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19210 int wrap_row_extra_line_spacing IF_LINT (= 0);
19211 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19212 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19213 int cvpos;
19214 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19215 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19217 /* We always start displaying at hpos zero even if hscrolled. */
19218 eassert (it->hpos == 0 && it->current_x == 0);
19220 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19221 >= it->w->desired_matrix->nrows)
19223 it->w->nrows_scale_factor++;
19224 fonts_changed_p = 1;
19225 return 0;
19228 /* Is IT->w showing the region? */
19229 it->w->region_showing = it->region_beg_charpos > 0 ? it->region_beg_charpos : 0;
19231 /* Clear the result glyph row and enable it. */
19232 prepare_desired_row (row);
19234 row->y = it->current_y;
19235 row->start = it->start;
19236 row->continuation_lines_width = it->continuation_lines_width;
19237 row->displays_text_p = 1;
19238 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19239 it->starts_in_middle_of_char_p = 0;
19241 /* Arrange the overlays nicely for our purposes. Usually, we call
19242 display_line on only one line at a time, in which case this
19243 can't really hurt too much, or we call it on lines which appear
19244 one after another in the buffer, in which case all calls to
19245 recenter_overlay_lists but the first will be pretty cheap. */
19246 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19248 /* Move over display elements that are not visible because we are
19249 hscrolled. This may stop at an x-position < IT->first_visible_x
19250 if the first glyph is partially visible or if we hit a line end. */
19251 if (it->current_x < it->first_visible_x)
19253 enum move_it_result move_result;
19255 this_line_min_pos = row->start.pos;
19256 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19257 MOVE_TO_POS | MOVE_TO_X);
19258 /* If we are under a large hscroll, move_it_in_display_line_to
19259 could hit the end of the line without reaching
19260 it->first_visible_x. Pretend that we did reach it. This is
19261 especially important on a TTY, where we will call
19262 extend_face_to_end_of_line, which needs to know how many
19263 blank glyphs to produce. */
19264 if (it->current_x < it->first_visible_x
19265 && (move_result == MOVE_NEWLINE_OR_CR
19266 || move_result == MOVE_POS_MATCH_OR_ZV))
19267 it->current_x = it->first_visible_x;
19269 /* Record the smallest positions seen while we moved over
19270 display elements that are not visible. This is needed by
19271 redisplay_internal for optimizing the case where the cursor
19272 stays inside the same line. The rest of this function only
19273 considers positions that are actually displayed, so
19274 RECORD_MAX_MIN_POS will not otherwise record positions that
19275 are hscrolled to the left of the left edge of the window. */
19276 min_pos = CHARPOS (this_line_min_pos);
19277 min_bpos = BYTEPOS (this_line_min_pos);
19279 else
19281 /* We only do this when not calling `move_it_in_display_line_to'
19282 above, because move_it_in_display_line_to calls
19283 handle_line_prefix itself. */
19284 handle_line_prefix (it);
19287 /* Get the initial row height. This is either the height of the
19288 text hscrolled, if there is any, or zero. */
19289 row->ascent = it->max_ascent;
19290 row->height = it->max_ascent + it->max_descent;
19291 row->phys_ascent = it->max_phys_ascent;
19292 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19293 row->extra_line_spacing = it->max_extra_line_spacing;
19295 /* Utility macro to record max and min buffer positions seen until now. */
19296 #define RECORD_MAX_MIN_POS(IT) \
19297 do \
19299 int composition_p = !STRINGP ((IT)->string) \
19300 && ((IT)->what == IT_COMPOSITION); \
19301 ptrdiff_t current_pos = \
19302 composition_p ? (IT)->cmp_it.charpos \
19303 : IT_CHARPOS (*(IT)); \
19304 ptrdiff_t current_bpos = \
19305 composition_p ? CHAR_TO_BYTE (current_pos) \
19306 : IT_BYTEPOS (*(IT)); \
19307 if (current_pos < min_pos) \
19309 min_pos = current_pos; \
19310 min_bpos = current_bpos; \
19312 if (IT_CHARPOS (*it) > max_pos) \
19314 max_pos = IT_CHARPOS (*it); \
19315 max_bpos = IT_BYTEPOS (*it); \
19318 while (0)
19320 /* Loop generating characters. The loop is left with IT on the next
19321 character to display. */
19322 while (1)
19324 int n_glyphs_before, hpos_before, x_before;
19325 int x, nglyphs;
19326 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19328 /* Retrieve the next thing to display. Value is zero if end of
19329 buffer reached. */
19330 if (!get_next_display_element (it))
19332 /* Maybe add a space at the end of this line that is used to
19333 display the cursor there under X. Set the charpos of the
19334 first glyph of blank lines not corresponding to any text
19335 to -1. */
19336 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19337 row->exact_window_width_line_p = 1;
19338 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19339 || row->used[TEXT_AREA] == 0)
19341 row->glyphs[TEXT_AREA]->charpos = -1;
19342 row->displays_text_p = 0;
19344 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19345 && (!MINI_WINDOW_P (it->w)
19346 || (minibuf_level && EQ (it->window, minibuf_window))))
19347 row->indicate_empty_line_p = 1;
19350 it->continuation_lines_width = 0;
19351 row->ends_at_zv_p = 1;
19352 /* A row that displays right-to-left text must always have
19353 its last face extended all the way to the end of line,
19354 even if this row ends in ZV, because we still write to
19355 the screen left to right. We also need to extend the
19356 last face if the default face is remapped to some
19357 different face, otherwise the functions that clear
19358 portions of the screen will clear with the default face's
19359 background color. */
19360 if (row->reversed_p
19361 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19362 extend_face_to_end_of_line (it);
19363 break;
19366 /* Now, get the metrics of what we want to display. This also
19367 generates glyphs in `row' (which is IT->glyph_row). */
19368 n_glyphs_before = row->used[TEXT_AREA];
19369 x = it->current_x;
19371 /* Remember the line height so far in case the next element doesn't
19372 fit on the line. */
19373 if (it->line_wrap != TRUNCATE)
19375 ascent = it->max_ascent;
19376 descent = it->max_descent;
19377 phys_ascent = it->max_phys_ascent;
19378 phys_descent = it->max_phys_descent;
19380 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19382 if (IT_DISPLAYING_WHITESPACE (it))
19383 may_wrap = 1;
19384 else if (may_wrap)
19386 SAVE_IT (wrap_it, *it, wrap_data);
19387 wrap_x = x;
19388 wrap_row_used = row->used[TEXT_AREA];
19389 wrap_row_ascent = row->ascent;
19390 wrap_row_height = row->height;
19391 wrap_row_phys_ascent = row->phys_ascent;
19392 wrap_row_phys_height = row->phys_height;
19393 wrap_row_extra_line_spacing = row->extra_line_spacing;
19394 wrap_row_min_pos = min_pos;
19395 wrap_row_min_bpos = min_bpos;
19396 wrap_row_max_pos = max_pos;
19397 wrap_row_max_bpos = max_bpos;
19398 may_wrap = 0;
19403 PRODUCE_GLYPHS (it);
19405 /* If this display element was in marginal areas, continue with
19406 the next one. */
19407 if (it->area != TEXT_AREA)
19409 row->ascent = max (row->ascent, it->max_ascent);
19410 row->height = max (row->height, it->max_ascent + it->max_descent);
19411 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19412 row->phys_height = max (row->phys_height,
19413 it->max_phys_ascent + it->max_phys_descent);
19414 row->extra_line_spacing = max (row->extra_line_spacing,
19415 it->max_extra_line_spacing);
19416 set_iterator_to_next (it, 1);
19417 continue;
19420 /* Does the display element fit on the line? If we truncate
19421 lines, we should draw past the right edge of the window. If
19422 we don't truncate, we want to stop so that we can display the
19423 continuation glyph before the right margin. If lines are
19424 continued, there are two possible strategies for characters
19425 resulting in more than 1 glyph (e.g. tabs): Display as many
19426 glyphs as possible in this line and leave the rest for the
19427 continuation line, or display the whole element in the next
19428 line. Original redisplay did the former, so we do it also. */
19429 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19430 hpos_before = it->hpos;
19431 x_before = x;
19433 if (/* Not a newline. */
19434 nglyphs > 0
19435 /* Glyphs produced fit entirely in the line. */
19436 && it->current_x < it->last_visible_x)
19438 it->hpos += nglyphs;
19439 row->ascent = max (row->ascent, it->max_ascent);
19440 row->height = max (row->height, it->max_ascent + it->max_descent);
19441 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19442 row->phys_height = max (row->phys_height,
19443 it->max_phys_ascent + it->max_phys_descent);
19444 row->extra_line_spacing = max (row->extra_line_spacing,
19445 it->max_extra_line_spacing);
19446 if (it->current_x - it->pixel_width < it->first_visible_x)
19447 row->x = x - it->first_visible_x;
19448 /* Record the maximum and minimum buffer positions seen so
19449 far in glyphs that will be displayed by this row. */
19450 if (it->bidi_p)
19451 RECORD_MAX_MIN_POS (it);
19453 else
19455 int i, new_x;
19456 struct glyph *glyph;
19458 for (i = 0; i < nglyphs; ++i, x = new_x)
19460 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19461 new_x = x + glyph->pixel_width;
19463 if (/* Lines are continued. */
19464 it->line_wrap != TRUNCATE
19465 && (/* Glyph doesn't fit on the line. */
19466 new_x > it->last_visible_x
19467 /* Or it fits exactly on a window system frame. */
19468 || (new_x == it->last_visible_x
19469 && FRAME_WINDOW_P (it->f)
19470 && (row->reversed_p
19471 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19472 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19474 /* End of a continued line. */
19476 if (it->hpos == 0
19477 || (new_x == it->last_visible_x
19478 && FRAME_WINDOW_P (it->f)
19479 && (row->reversed_p
19480 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19481 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19483 /* Current glyph is the only one on the line or
19484 fits exactly on the line. We must continue
19485 the line because we can't draw the cursor
19486 after the glyph. */
19487 row->continued_p = 1;
19488 it->current_x = new_x;
19489 it->continuation_lines_width += new_x;
19490 ++it->hpos;
19491 if (i == nglyphs - 1)
19493 /* If line-wrap is on, check if a previous
19494 wrap point was found. */
19495 if (wrap_row_used > 0
19496 /* Even if there is a previous wrap
19497 point, continue the line here as
19498 usual, if (i) the previous character
19499 was a space or tab AND (ii) the
19500 current character is not. */
19501 && (!may_wrap
19502 || IT_DISPLAYING_WHITESPACE (it)))
19503 goto back_to_wrap;
19505 /* Record the maximum and minimum buffer
19506 positions seen so far in glyphs that will be
19507 displayed by this row. */
19508 if (it->bidi_p)
19509 RECORD_MAX_MIN_POS (it);
19510 set_iterator_to_next (it, 1);
19511 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19513 if (!get_next_display_element (it))
19515 row->exact_window_width_line_p = 1;
19516 it->continuation_lines_width = 0;
19517 row->continued_p = 0;
19518 row->ends_at_zv_p = 1;
19520 else if (ITERATOR_AT_END_OF_LINE_P (it))
19522 row->continued_p = 0;
19523 row->exact_window_width_line_p = 1;
19527 else if (it->bidi_p)
19528 RECORD_MAX_MIN_POS (it);
19530 else if (CHAR_GLYPH_PADDING_P (*glyph)
19531 && !FRAME_WINDOW_P (it->f))
19533 /* A padding glyph that doesn't fit on this line.
19534 This means the whole character doesn't fit
19535 on the line. */
19536 if (row->reversed_p)
19537 unproduce_glyphs (it, row->used[TEXT_AREA]
19538 - n_glyphs_before);
19539 row->used[TEXT_AREA] = n_glyphs_before;
19541 /* Fill the rest of the row with continuation
19542 glyphs like in 20.x. */
19543 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19544 < row->glyphs[1 + TEXT_AREA])
19545 produce_special_glyphs (it, IT_CONTINUATION);
19547 row->continued_p = 1;
19548 it->current_x = x_before;
19549 it->continuation_lines_width += x_before;
19551 /* Restore the height to what it was before the
19552 element not fitting on the line. */
19553 it->max_ascent = ascent;
19554 it->max_descent = descent;
19555 it->max_phys_ascent = phys_ascent;
19556 it->max_phys_descent = phys_descent;
19558 else if (wrap_row_used > 0)
19560 back_to_wrap:
19561 if (row->reversed_p)
19562 unproduce_glyphs (it,
19563 row->used[TEXT_AREA] - wrap_row_used);
19564 RESTORE_IT (it, &wrap_it, wrap_data);
19565 it->continuation_lines_width += wrap_x;
19566 row->used[TEXT_AREA] = wrap_row_used;
19567 row->ascent = wrap_row_ascent;
19568 row->height = wrap_row_height;
19569 row->phys_ascent = wrap_row_phys_ascent;
19570 row->phys_height = wrap_row_phys_height;
19571 row->extra_line_spacing = wrap_row_extra_line_spacing;
19572 min_pos = wrap_row_min_pos;
19573 min_bpos = wrap_row_min_bpos;
19574 max_pos = wrap_row_max_pos;
19575 max_bpos = wrap_row_max_bpos;
19576 row->continued_p = 1;
19577 row->ends_at_zv_p = 0;
19578 row->exact_window_width_line_p = 0;
19579 it->continuation_lines_width += x;
19581 /* Make sure that a non-default face is extended
19582 up to the right margin of the window. */
19583 extend_face_to_end_of_line (it);
19585 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19587 /* A TAB that extends past the right edge of the
19588 window. This produces a single glyph on
19589 window system frames. We leave the glyph in
19590 this row and let it fill the row, but don't
19591 consume the TAB. */
19592 if ((row->reversed_p
19593 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19594 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19595 produce_special_glyphs (it, IT_CONTINUATION);
19596 it->continuation_lines_width += it->last_visible_x;
19597 row->ends_in_middle_of_char_p = 1;
19598 row->continued_p = 1;
19599 glyph->pixel_width = it->last_visible_x - x;
19600 it->starts_in_middle_of_char_p = 1;
19602 else
19604 /* Something other than a TAB that draws past
19605 the right edge of the window. Restore
19606 positions to values before the element. */
19607 if (row->reversed_p)
19608 unproduce_glyphs (it, row->used[TEXT_AREA]
19609 - (n_glyphs_before + i));
19610 row->used[TEXT_AREA] = n_glyphs_before + i;
19612 /* Display continuation glyphs. */
19613 it->current_x = x_before;
19614 it->continuation_lines_width += x;
19615 if (!FRAME_WINDOW_P (it->f)
19616 || (row->reversed_p
19617 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19618 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19619 produce_special_glyphs (it, IT_CONTINUATION);
19620 row->continued_p = 1;
19622 extend_face_to_end_of_line (it);
19624 if (nglyphs > 1 && i > 0)
19626 row->ends_in_middle_of_char_p = 1;
19627 it->starts_in_middle_of_char_p = 1;
19630 /* Restore the height to what it was before the
19631 element not fitting on the line. */
19632 it->max_ascent = ascent;
19633 it->max_descent = descent;
19634 it->max_phys_ascent = phys_ascent;
19635 it->max_phys_descent = phys_descent;
19638 break;
19640 else if (new_x > it->first_visible_x)
19642 /* Increment number of glyphs actually displayed. */
19643 ++it->hpos;
19645 /* Record the maximum and minimum buffer positions
19646 seen so far in glyphs that will be displayed by
19647 this row. */
19648 if (it->bidi_p)
19649 RECORD_MAX_MIN_POS (it);
19651 if (x < it->first_visible_x)
19652 /* Glyph is partially visible, i.e. row starts at
19653 negative X position. */
19654 row->x = x - it->first_visible_x;
19656 else
19658 /* Glyph is completely off the left margin of the
19659 window. This should not happen because of the
19660 move_it_in_display_line at the start of this
19661 function, unless the text display area of the
19662 window is empty. */
19663 eassert (it->first_visible_x <= it->last_visible_x);
19666 /* Even if this display element produced no glyphs at all,
19667 we want to record its position. */
19668 if (it->bidi_p && nglyphs == 0)
19669 RECORD_MAX_MIN_POS (it);
19671 row->ascent = max (row->ascent, it->max_ascent);
19672 row->height = max (row->height, it->max_ascent + it->max_descent);
19673 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19674 row->phys_height = max (row->phys_height,
19675 it->max_phys_ascent + it->max_phys_descent);
19676 row->extra_line_spacing = max (row->extra_line_spacing,
19677 it->max_extra_line_spacing);
19679 /* End of this display line if row is continued. */
19680 if (row->continued_p || row->ends_at_zv_p)
19681 break;
19684 at_end_of_line:
19685 /* Is this a line end? If yes, we're also done, after making
19686 sure that a non-default face is extended up to the right
19687 margin of the window. */
19688 if (ITERATOR_AT_END_OF_LINE_P (it))
19690 int used_before = row->used[TEXT_AREA];
19692 row->ends_in_newline_from_string_p = STRINGP (it->object);
19694 /* Add a space at the end of the line that is used to
19695 display the cursor there. */
19696 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19697 append_space_for_newline (it, 0);
19699 /* Extend the face to the end of the line. */
19700 extend_face_to_end_of_line (it);
19702 /* Make sure we have the position. */
19703 if (used_before == 0)
19704 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19706 /* Record the position of the newline, for use in
19707 find_row_edges. */
19708 it->eol_pos = it->current.pos;
19710 /* Consume the line end. This skips over invisible lines. */
19711 set_iterator_to_next (it, 1);
19712 it->continuation_lines_width = 0;
19713 break;
19716 /* Proceed with next display element. Note that this skips
19717 over lines invisible because of selective display. */
19718 set_iterator_to_next (it, 1);
19720 /* If we truncate lines, we are done when the last displayed
19721 glyphs reach past the right margin of the window. */
19722 if (it->line_wrap == TRUNCATE
19723 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19724 ? (it->current_x >= it->last_visible_x)
19725 : (it->current_x > it->last_visible_x)))
19727 /* Maybe add truncation glyphs. */
19728 if (!FRAME_WINDOW_P (it->f)
19729 || (row->reversed_p
19730 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19731 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19733 int i, n;
19735 if (!row->reversed_p)
19737 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19738 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19739 break;
19741 else
19743 for (i = 0; i < row->used[TEXT_AREA]; i++)
19744 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19745 break;
19746 /* Remove any padding glyphs at the front of ROW, to
19747 make room for the truncation glyphs we will be
19748 adding below. The loop below always inserts at
19749 least one truncation glyph, so also remove the
19750 last glyph added to ROW. */
19751 unproduce_glyphs (it, i + 1);
19752 /* Adjust i for the loop below. */
19753 i = row->used[TEXT_AREA] - (i + 1);
19756 it->current_x = x_before;
19757 if (!FRAME_WINDOW_P (it->f))
19759 for (n = row->used[TEXT_AREA]; i < n; ++i)
19761 row->used[TEXT_AREA] = i;
19762 produce_special_glyphs (it, IT_TRUNCATION);
19765 else
19767 row->used[TEXT_AREA] = i;
19768 produce_special_glyphs (it, IT_TRUNCATION);
19771 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19773 /* Don't truncate if we can overflow newline into fringe. */
19774 if (!get_next_display_element (it))
19776 it->continuation_lines_width = 0;
19777 row->ends_at_zv_p = 1;
19778 row->exact_window_width_line_p = 1;
19779 break;
19781 if (ITERATOR_AT_END_OF_LINE_P (it))
19783 row->exact_window_width_line_p = 1;
19784 goto at_end_of_line;
19786 it->current_x = x_before;
19789 row->truncated_on_right_p = 1;
19790 it->continuation_lines_width = 0;
19791 reseat_at_next_visible_line_start (it, 0);
19792 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19793 it->hpos = hpos_before;
19794 break;
19798 if (wrap_data)
19799 bidi_unshelve_cache (wrap_data, 1);
19801 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19802 at the left window margin. */
19803 if (it->first_visible_x
19804 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19806 if (!FRAME_WINDOW_P (it->f)
19807 || (row->reversed_p
19808 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19809 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19810 insert_left_trunc_glyphs (it);
19811 row->truncated_on_left_p = 1;
19814 /* Remember the position at which this line ends.
19816 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19817 cannot be before the call to find_row_edges below, since that is
19818 where these positions are determined. */
19819 row->end = it->current;
19820 if (!it->bidi_p)
19822 row->minpos = row->start.pos;
19823 row->maxpos = row->end.pos;
19825 else
19827 /* ROW->minpos and ROW->maxpos must be the smallest and
19828 `1 + the largest' buffer positions in ROW. But if ROW was
19829 bidi-reordered, these two positions can be anywhere in the
19830 row, so we must determine them now. */
19831 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19834 /* If the start of this line is the overlay arrow-position, then
19835 mark this glyph row as the one containing the overlay arrow.
19836 This is clearly a mess with variable size fonts. It would be
19837 better to let it be displayed like cursors under X. */
19838 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
19839 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19840 !NILP (overlay_arrow_string)))
19842 /* Overlay arrow in window redisplay is a fringe bitmap. */
19843 if (STRINGP (overlay_arrow_string))
19845 struct glyph_row *arrow_row
19846 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19847 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19848 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19849 struct glyph *p = row->glyphs[TEXT_AREA];
19850 struct glyph *p2, *end;
19852 /* Copy the arrow glyphs. */
19853 while (glyph < arrow_end)
19854 *p++ = *glyph++;
19856 /* Throw away padding glyphs. */
19857 p2 = p;
19858 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19859 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19860 ++p2;
19861 if (p2 > p)
19863 while (p2 < end)
19864 *p++ = *p2++;
19865 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19868 else
19870 eassert (INTEGERP (overlay_arrow_string));
19871 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19873 overlay_arrow_seen = 1;
19876 /* Highlight trailing whitespace. */
19877 if (!NILP (Vshow_trailing_whitespace))
19878 highlight_trailing_whitespace (it->f, it->glyph_row);
19880 /* Compute pixel dimensions of this line. */
19881 compute_line_metrics (it);
19883 /* Implementation note: No changes in the glyphs of ROW or in their
19884 faces can be done past this point, because compute_line_metrics
19885 computes ROW's hash value and stores it within the glyph_row
19886 structure. */
19888 /* Record whether this row ends inside an ellipsis. */
19889 row->ends_in_ellipsis_p
19890 = (it->method == GET_FROM_DISPLAY_VECTOR
19891 && it->ellipsis_p);
19893 /* Save fringe bitmaps in this row. */
19894 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19895 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19896 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19897 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19899 it->left_user_fringe_bitmap = 0;
19900 it->left_user_fringe_face_id = 0;
19901 it->right_user_fringe_bitmap = 0;
19902 it->right_user_fringe_face_id = 0;
19904 /* Maybe set the cursor. */
19905 cvpos = it->w->cursor.vpos;
19906 if ((cvpos < 0
19907 /* In bidi-reordered rows, keep checking for proper cursor
19908 position even if one has been found already, because buffer
19909 positions in such rows change non-linearly with ROW->VPOS,
19910 when a line is continued. One exception: when we are at ZV,
19911 display cursor on the first suitable glyph row, since all
19912 the empty rows after that also have their position set to ZV. */
19913 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19914 lines' rows is implemented for bidi-reordered rows. */
19915 || (it->bidi_p
19916 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19917 && PT >= MATRIX_ROW_START_CHARPOS (row)
19918 && PT <= MATRIX_ROW_END_CHARPOS (row)
19919 && cursor_row_p (row))
19920 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19922 /* Prepare for the next line. This line starts horizontally at (X
19923 HPOS) = (0 0). Vertical positions are incremented. As a
19924 convenience for the caller, IT->glyph_row is set to the next
19925 row to be used. */
19926 it->current_x = it->hpos = 0;
19927 it->current_y += row->height;
19928 SET_TEXT_POS (it->eol_pos, 0, 0);
19929 ++it->vpos;
19930 ++it->glyph_row;
19931 /* The next row should by default use the same value of the
19932 reversed_p flag as this one. set_iterator_to_next decides when
19933 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19934 the flag accordingly. */
19935 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19936 it->glyph_row->reversed_p = row->reversed_p;
19937 it->start = row->end;
19938 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
19940 #undef RECORD_MAX_MIN_POS
19943 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19944 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19945 doc: /* Return paragraph direction at point in BUFFER.
19946 Value is either `left-to-right' or `right-to-left'.
19947 If BUFFER is omitted or nil, it defaults to the current buffer.
19949 Paragraph direction determines how the text in the paragraph is displayed.
19950 In left-to-right paragraphs, text begins at the left margin of the window
19951 and the reading direction is generally left to right. In right-to-left
19952 paragraphs, text begins at the right margin and is read from right to left.
19954 See also `bidi-paragraph-direction'. */)
19955 (Lisp_Object buffer)
19957 struct buffer *buf = current_buffer;
19958 struct buffer *old = buf;
19960 if (! NILP (buffer))
19962 CHECK_BUFFER (buffer);
19963 buf = XBUFFER (buffer);
19966 if (NILP (BVAR (buf, bidi_display_reordering))
19967 || NILP (BVAR (buf, enable_multibyte_characters))
19968 /* When we are loading loadup.el, the character property tables
19969 needed for bidi iteration are not yet available. */
19970 || !NILP (Vpurify_flag))
19971 return Qleft_to_right;
19972 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19973 return BVAR (buf, bidi_paragraph_direction);
19974 else
19976 /* Determine the direction from buffer text. We could try to
19977 use current_matrix if it is up to date, but this seems fast
19978 enough as it is. */
19979 struct bidi_it itb;
19980 ptrdiff_t pos = BUF_PT (buf);
19981 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
19982 int c;
19983 void *itb_data = bidi_shelve_cache ();
19985 set_buffer_temp (buf);
19986 /* bidi_paragraph_init finds the base direction of the paragraph
19987 by searching forward from paragraph start. We need the base
19988 direction of the current or _previous_ paragraph, so we need
19989 to make sure we are within that paragraph. To that end, find
19990 the previous non-empty line. */
19991 if (pos >= ZV && pos > BEGV)
19992 DEC_BOTH (pos, bytepos);
19993 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19994 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
19996 while ((c = FETCH_BYTE (bytepos)) == '\n'
19997 || c == ' ' || c == '\t' || c == '\f')
19999 if (bytepos <= BEGV_BYTE)
20000 break;
20001 bytepos--;
20002 pos--;
20004 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20005 bytepos--;
20007 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20008 itb.paragraph_dir = NEUTRAL_DIR;
20009 itb.string.s = NULL;
20010 itb.string.lstring = Qnil;
20011 itb.string.bufpos = 0;
20012 itb.string.unibyte = 0;
20013 itb.w = XWINDOW (selected_window);
20014 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20015 bidi_unshelve_cache (itb_data, 0);
20016 set_buffer_temp (old);
20017 switch (itb.paragraph_dir)
20019 case L2R:
20020 return Qleft_to_right;
20021 break;
20022 case R2L:
20023 return Qright_to_left;
20024 break;
20025 default:
20026 emacs_abort ();
20033 /***********************************************************************
20034 Menu Bar
20035 ***********************************************************************/
20037 /* Redisplay the menu bar in the frame for window W.
20039 The menu bar of X frames that don't have X toolkit support is
20040 displayed in a special window W->frame->menu_bar_window.
20042 The menu bar of terminal frames is treated specially as far as
20043 glyph matrices are concerned. Menu bar lines are not part of
20044 windows, so the update is done directly on the frame matrix rows
20045 for the menu bar. */
20047 static void
20048 display_menu_bar (struct window *w)
20050 struct frame *f = XFRAME (WINDOW_FRAME (w));
20051 struct it it;
20052 Lisp_Object items;
20053 int i;
20055 /* Don't do all this for graphical frames. */
20056 #ifdef HAVE_NTGUI
20057 if (FRAME_W32_P (f))
20058 return;
20059 #endif
20060 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20061 if (FRAME_X_P (f))
20062 return;
20063 #endif
20065 #ifdef HAVE_NS
20066 if (FRAME_NS_P (f))
20067 return;
20068 #endif /* HAVE_NS */
20070 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20071 eassert (!FRAME_WINDOW_P (f));
20072 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20073 it.first_visible_x = 0;
20074 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20075 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20076 if (FRAME_WINDOW_P (f))
20078 /* Menu bar lines are displayed in the desired matrix of the
20079 dummy window menu_bar_window. */
20080 struct window *menu_w;
20081 menu_w = XWINDOW (f->menu_bar_window);
20082 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20083 MENU_FACE_ID);
20084 it.first_visible_x = 0;
20085 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20087 else
20088 #endif /* not USE_X_TOOLKIT and not USE_GTK */
20090 /* This is a TTY frame, i.e. character hpos/vpos are used as
20091 pixel x/y. */
20092 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20093 MENU_FACE_ID);
20094 it.first_visible_x = 0;
20095 it.last_visible_x = FRAME_COLS (f);
20098 /* FIXME: This should be controlled by a user option. See the
20099 comments in redisplay_tool_bar and display_mode_line about
20100 this. */
20101 it.paragraph_embedding = L2R;
20103 /* Clear all rows of the menu bar. */
20104 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20106 struct glyph_row *row = it.glyph_row + i;
20107 clear_glyph_row (row);
20108 row->enabled_p = 1;
20109 row->full_width_p = 1;
20112 /* Display all items of the menu bar. */
20113 items = FRAME_MENU_BAR_ITEMS (it.f);
20114 for (i = 0; i < ASIZE (items); i += 4)
20116 Lisp_Object string;
20118 /* Stop at nil string. */
20119 string = AREF (items, i + 1);
20120 if (NILP (string))
20121 break;
20123 /* Remember where item was displayed. */
20124 ASET (items, i + 3, make_number (it.hpos));
20126 /* Display the item, pad with one space. */
20127 if (it.current_x < it.last_visible_x)
20128 display_string (NULL, string, Qnil, 0, 0, &it,
20129 SCHARS (string) + 1, 0, 0, -1);
20132 /* Fill out the line with spaces. */
20133 if (it.current_x < it.last_visible_x)
20134 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20136 /* Compute the total height of the lines. */
20137 compute_line_metrics (&it);
20142 /***********************************************************************
20143 Mode Line
20144 ***********************************************************************/
20146 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20147 FORCE is non-zero, redisplay mode lines unconditionally.
20148 Otherwise, redisplay only mode lines that are garbaged. Value is
20149 the number of windows whose mode lines were redisplayed. */
20151 static int
20152 redisplay_mode_lines (Lisp_Object window, int force)
20154 int nwindows = 0;
20156 while (!NILP (window))
20158 struct window *w = XWINDOW (window);
20160 if (WINDOWP (w->contents))
20161 nwindows += redisplay_mode_lines (w->contents, force);
20162 else if (force
20163 || FRAME_GARBAGED_P (XFRAME (w->frame))
20164 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20166 struct text_pos lpoint;
20167 struct buffer *old = current_buffer;
20169 /* Set the window's buffer for the mode line display. */
20170 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20171 set_buffer_internal_1 (XBUFFER (w->contents));
20173 /* Point refers normally to the selected window. For any
20174 other window, set up appropriate value. */
20175 if (!EQ (window, selected_window))
20177 struct text_pos pt;
20179 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20180 if (CHARPOS (pt) < BEGV)
20181 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20182 else if (CHARPOS (pt) > (ZV - 1))
20183 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20184 else
20185 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20188 /* Display mode lines. */
20189 clear_glyph_matrix (w->desired_matrix);
20190 if (display_mode_lines (w))
20192 ++nwindows;
20193 w->must_be_updated_p = 1;
20196 /* Restore old settings. */
20197 set_buffer_internal_1 (old);
20198 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20201 window = w->next;
20204 return nwindows;
20208 /* Display the mode and/or header line of window W. Value is the
20209 sum number of mode lines and header lines displayed. */
20211 static int
20212 display_mode_lines (struct window *w)
20214 Lisp_Object old_selected_window = selected_window;
20215 Lisp_Object old_selected_frame = selected_frame;
20216 Lisp_Object new_frame = w->frame;
20217 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
20218 int n = 0;
20220 selected_frame = new_frame;
20221 /* FIXME: If we were to allow the mode-line's computation changing the buffer
20222 or window's point, then we'd need select_window_1 here as well. */
20223 XSETWINDOW (selected_window, w);
20224 XFRAME (new_frame)->selected_window = selected_window;
20226 /* These will be set while the mode line specs are processed. */
20227 line_number_displayed = 0;
20228 w->column_number_displayed = -1;
20230 if (WINDOW_WANTS_MODELINE_P (w))
20232 struct window *sel_w = XWINDOW (old_selected_window);
20234 /* Select mode line face based on the real selected window. */
20235 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20236 BVAR (current_buffer, mode_line_format));
20237 ++n;
20240 if (WINDOW_WANTS_HEADER_LINE_P (w))
20242 display_mode_line (w, HEADER_LINE_FACE_ID,
20243 BVAR (current_buffer, header_line_format));
20244 ++n;
20247 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20248 selected_frame = old_selected_frame;
20249 selected_window = old_selected_window;
20250 return n;
20254 /* Display mode or header line of window W. FACE_ID specifies which
20255 line to display; it is either MODE_LINE_FACE_ID or
20256 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20257 display. Value is the pixel height of the mode/header line
20258 displayed. */
20260 static int
20261 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20263 struct it it;
20264 struct face *face;
20265 ptrdiff_t count = SPECPDL_INDEX ();
20267 init_iterator (&it, w, -1, -1, NULL, face_id);
20268 /* Don't extend on a previously drawn mode-line.
20269 This may happen if called from pos_visible_p. */
20270 it.glyph_row->enabled_p = 0;
20271 prepare_desired_row (it.glyph_row);
20273 it.glyph_row->mode_line_p = 1;
20275 /* FIXME: This should be controlled by a user option. But
20276 supporting such an option is not trivial, since the mode line is
20277 made up of many separate strings. */
20278 it.paragraph_embedding = L2R;
20280 record_unwind_protect (unwind_format_mode_line,
20281 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20283 mode_line_target = MODE_LINE_DISPLAY;
20285 /* Temporarily make frame's keyboard the current kboard so that
20286 kboard-local variables in the mode_line_format will get the right
20287 values. */
20288 push_kboard (FRAME_KBOARD (it.f));
20289 record_unwind_save_match_data ();
20290 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20291 pop_kboard ();
20293 unbind_to (count, Qnil);
20295 /* Fill up with spaces. */
20296 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20298 compute_line_metrics (&it);
20299 it.glyph_row->full_width_p = 1;
20300 it.glyph_row->continued_p = 0;
20301 it.glyph_row->truncated_on_left_p = 0;
20302 it.glyph_row->truncated_on_right_p = 0;
20304 /* Make a 3D mode-line have a shadow at its right end. */
20305 face = FACE_FROM_ID (it.f, face_id);
20306 extend_face_to_end_of_line (&it);
20307 if (face->box != FACE_NO_BOX)
20309 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20310 + it.glyph_row->used[TEXT_AREA] - 1);
20311 last->right_box_line_p = 1;
20314 return it.glyph_row->height;
20317 /* Move element ELT in LIST to the front of LIST.
20318 Return the updated list. */
20320 static Lisp_Object
20321 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20323 register Lisp_Object tail, prev;
20324 register Lisp_Object tem;
20326 tail = list;
20327 prev = Qnil;
20328 while (CONSP (tail))
20330 tem = XCAR (tail);
20332 if (EQ (elt, tem))
20334 /* Splice out the link TAIL. */
20335 if (NILP (prev))
20336 list = XCDR (tail);
20337 else
20338 Fsetcdr (prev, XCDR (tail));
20340 /* Now make it the first. */
20341 Fsetcdr (tail, list);
20342 return tail;
20344 else
20345 prev = tail;
20346 tail = XCDR (tail);
20347 QUIT;
20350 /* Not found--return unchanged LIST. */
20351 return list;
20354 /* Contribute ELT to the mode line for window IT->w. How it
20355 translates into text depends on its data type.
20357 IT describes the display environment in which we display, as usual.
20359 DEPTH is the depth in recursion. It is used to prevent
20360 infinite recursion here.
20362 FIELD_WIDTH is the number of characters the display of ELT should
20363 occupy in the mode line, and PRECISION is the maximum number of
20364 characters to display from ELT's representation. See
20365 display_string for details.
20367 Returns the hpos of the end of the text generated by ELT.
20369 PROPS is a property list to add to any string we encounter.
20371 If RISKY is nonzero, remove (disregard) any properties in any string
20372 we encounter, and ignore :eval and :propertize.
20374 The global variable `mode_line_target' determines whether the
20375 output is passed to `store_mode_line_noprop',
20376 `store_mode_line_string', or `display_string'. */
20378 static int
20379 display_mode_element (struct it *it, int depth, int field_width, int precision,
20380 Lisp_Object elt, Lisp_Object props, int risky)
20382 int n = 0, field, prec;
20383 int literal = 0;
20385 tail_recurse:
20386 if (depth > 100)
20387 elt = build_string ("*too-deep*");
20389 depth++;
20391 switch (XTYPE (elt))
20393 case Lisp_String:
20395 /* A string: output it and check for %-constructs within it. */
20396 unsigned char c;
20397 ptrdiff_t offset = 0;
20399 if (SCHARS (elt) > 0
20400 && (!NILP (props) || risky))
20402 Lisp_Object oprops, aelt;
20403 oprops = Ftext_properties_at (make_number (0), elt);
20405 /* If the starting string's properties are not what
20406 we want, translate the string. Also, if the string
20407 is risky, do that anyway. */
20409 if (NILP (Fequal (props, oprops)) || risky)
20411 /* If the starting string has properties,
20412 merge the specified ones onto the existing ones. */
20413 if (! NILP (oprops) && !risky)
20415 Lisp_Object tem;
20417 oprops = Fcopy_sequence (oprops);
20418 tem = props;
20419 while (CONSP (tem))
20421 oprops = Fplist_put (oprops, XCAR (tem),
20422 XCAR (XCDR (tem)));
20423 tem = XCDR (XCDR (tem));
20425 props = oprops;
20428 aelt = Fassoc (elt, mode_line_proptrans_alist);
20429 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20431 /* AELT is what we want. Move it to the front
20432 without consing. */
20433 elt = XCAR (aelt);
20434 mode_line_proptrans_alist
20435 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20437 else
20439 Lisp_Object tem;
20441 /* If AELT has the wrong props, it is useless.
20442 so get rid of it. */
20443 if (! NILP (aelt))
20444 mode_line_proptrans_alist
20445 = Fdelq (aelt, mode_line_proptrans_alist);
20447 elt = Fcopy_sequence (elt);
20448 Fset_text_properties (make_number (0), Flength (elt),
20449 props, elt);
20450 /* Add this item to mode_line_proptrans_alist. */
20451 mode_line_proptrans_alist
20452 = Fcons (Fcons (elt, props),
20453 mode_line_proptrans_alist);
20454 /* Truncate mode_line_proptrans_alist
20455 to at most 50 elements. */
20456 tem = Fnthcdr (make_number (50),
20457 mode_line_proptrans_alist);
20458 if (! NILP (tem))
20459 XSETCDR (tem, Qnil);
20464 offset = 0;
20466 if (literal)
20468 prec = precision - n;
20469 switch (mode_line_target)
20471 case MODE_LINE_NOPROP:
20472 case MODE_LINE_TITLE:
20473 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20474 break;
20475 case MODE_LINE_STRING:
20476 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20477 break;
20478 case MODE_LINE_DISPLAY:
20479 n += display_string (NULL, elt, Qnil, 0, 0, it,
20480 0, prec, 0, STRING_MULTIBYTE (elt));
20481 break;
20484 break;
20487 /* Handle the non-literal case. */
20489 while ((precision <= 0 || n < precision)
20490 && SREF (elt, offset) != 0
20491 && (mode_line_target != MODE_LINE_DISPLAY
20492 || it->current_x < it->last_visible_x))
20494 ptrdiff_t last_offset = offset;
20496 /* Advance to end of string or next format specifier. */
20497 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20500 if (offset - 1 != last_offset)
20502 ptrdiff_t nchars, nbytes;
20504 /* Output to end of string or up to '%'. Field width
20505 is length of string. Don't output more than
20506 PRECISION allows us. */
20507 offset--;
20509 prec = c_string_width (SDATA (elt) + last_offset,
20510 offset - last_offset, precision - n,
20511 &nchars, &nbytes);
20513 switch (mode_line_target)
20515 case MODE_LINE_NOPROP:
20516 case MODE_LINE_TITLE:
20517 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20518 break;
20519 case MODE_LINE_STRING:
20521 ptrdiff_t bytepos = last_offset;
20522 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20523 ptrdiff_t endpos = (precision <= 0
20524 ? string_byte_to_char (elt, offset)
20525 : charpos + nchars);
20527 n += store_mode_line_string (NULL,
20528 Fsubstring (elt, make_number (charpos),
20529 make_number (endpos)),
20530 0, 0, 0, Qnil);
20532 break;
20533 case MODE_LINE_DISPLAY:
20535 ptrdiff_t bytepos = last_offset;
20536 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20538 if (precision <= 0)
20539 nchars = string_byte_to_char (elt, offset) - charpos;
20540 n += display_string (NULL, elt, Qnil, 0, charpos,
20541 it, 0, nchars, 0,
20542 STRING_MULTIBYTE (elt));
20544 break;
20547 else /* c == '%' */
20549 ptrdiff_t percent_position = offset;
20551 /* Get the specified minimum width. Zero means
20552 don't pad. */
20553 field = 0;
20554 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20555 field = field * 10 + c - '0';
20557 /* Don't pad beyond the total padding allowed. */
20558 if (field_width - n > 0 && field > field_width - n)
20559 field = field_width - n;
20561 /* Note that either PRECISION <= 0 or N < PRECISION. */
20562 prec = precision - n;
20564 if (c == 'M')
20565 n += display_mode_element (it, depth, field, prec,
20566 Vglobal_mode_string, props,
20567 risky);
20568 else if (c != 0)
20570 bool multibyte;
20571 ptrdiff_t bytepos, charpos;
20572 const char *spec;
20573 Lisp_Object string;
20575 bytepos = percent_position;
20576 charpos = (STRING_MULTIBYTE (elt)
20577 ? string_byte_to_char (elt, bytepos)
20578 : bytepos);
20579 spec = decode_mode_spec (it->w, c, field, &string);
20580 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20582 switch (mode_line_target)
20584 case MODE_LINE_NOPROP:
20585 case MODE_LINE_TITLE:
20586 n += store_mode_line_noprop (spec, field, prec);
20587 break;
20588 case MODE_LINE_STRING:
20590 Lisp_Object tem = build_string (spec);
20591 props = Ftext_properties_at (make_number (charpos), elt);
20592 /* Should only keep face property in props */
20593 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20595 break;
20596 case MODE_LINE_DISPLAY:
20598 int nglyphs_before, nwritten;
20600 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20601 nwritten = display_string (spec, string, elt,
20602 charpos, 0, it,
20603 field, prec, 0,
20604 multibyte);
20606 /* Assign to the glyphs written above the
20607 string where the `%x' came from, position
20608 of the `%'. */
20609 if (nwritten > 0)
20611 struct glyph *glyph
20612 = (it->glyph_row->glyphs[TEXT_AREA]
20613 + nglyphs_before);
20614 int i;
20616 for (i = 0; i < nwritten; ++i)
20618 glyph[i].object = elt;
20619 glyph[i].charpos = charpos;
20622 n += nwritten;
20625 break;
20628 else /* c == 0 */
20629 break;
20633 break;
20635 case Lisp_Symbol:
20636 /* A symbol: process the value of the symbol recursively
20637 as if it appeared here directly. Avoid error if symbol void.
20638 Special case: if value of symbol is a string, output the string
20639 literally. */
20641 register Lisp_Object tem;
20643 /* If the variable is not marked as risky to set
20644 then its contents are risky to use. */
20645 if (NILP (Fget (elt, Qrisky_local_variable)))
20646 risky = 1;
20648 tem = Fboundp (elt);
20649 if (!NILP (tem))
20651 tem = Fsymbol_value (elt);
20652 /* If value is a string, output that string literally:
20653 don't check for % within it. */
20654 if (STRINGP (tem))
20655 literal = 1;
20657 if (!EQ (tem, elt))
20659 /* Give up right away for nil or t. */
20660 elt = tem;
20661 goto tail_recurse;
20665 break;
20667 case Lisp_Cons:
20669 register Lisp_Object car, tem;
20671 /* A cons cell: five distinct cases.
20672 If first element is :eval or :propertize, do something special.
20673 If first element is a string or a cons, process all the elements
20674 and effectively concatenate them.
20675 If first element is a negative number, truncate displaying cdr to
20676 at most that many characters. If positive, pad (with spaces)
20677 to at least that many characters.
20678 If first element is a symbol, process the cadr or caddr recursively
20679 according to whether the symbol's value is non-nil or nil. */
20680 car = XCAR (elt);
20681 if (EQ (car, QCeval))
20683 /* An element of the form (:eval FORM) means evaluate FORM
20684 and use the result as mode line elements. */
20686 if (risky)
20687 break;
20689 if (CONSP (XCDR (elt)))
20691 Lisp_Object spec;
20692 spec = safe_eval (XCAR (XCDR (elt)));
20693 n += display_mode_element (it, depth, field_width - n,
20694 precision - n, spec, props,
20695 risky);
20698 else if (EQ (car, QCpropertize))
20700 /* An element of the form (:propertize ELT PROPS...)
20701 means display ELT but applying properties PROPS. */
20703 if (risky)
20704 break;
20706 if (CONSP (XCDR (elt)))
20707 n += display_mode_element (it, depth, field_width - n,
20708 precision - n, XCAR (XCDR (elt)),
20709 XCDR (XCDR (elt)), risky);
20711 else if (SYMBOLP (car))
20713 tem = Fboundp (car);
20714 elt = XCDR (elt);
20715 if (!CONSP (elt))
20716 goto invalid;
20717 /* elt is now the cdr, and we know it is a cons cell.
20718 Use its car if CAR has a non-nil value. */
20719 if (!NILP (tem))
20721 tem = Fsymbol_value (car);
20722 if (!NILP (tem))
20724 elt = XCAR (elt);
20725 goto tail_recurse;
20728 /* Symbol's value is nil (or symbol is unbound)
20729 Get the cddr of the original list
20730 and if possible find the caddr and use that. */
20731 elt = XCDR (elt);
20732 if (NILP (elt))
20733 break;
20734 else if (!CONSP (elt))
20735 goto invalid;
20736 elt = XCAR (elt);
20737 goto tail_recurse;
20739 else if (INTEGERP (car))
20741 register int lim = XINT (car);
20742 elt = XCDR (elt);
20743 if (lim < 0)
20745 /* Negative int means reduce maximum width. */
20746 if (precision <= 0)
20747 precision = -lim;
20748 else
20749 precision = min (precision, -lim);
20751 else if (lim > 0)
20753 /* Padding specified. Don't let it be more than
20754 current maximum. */
20755 if (precision > 0)
20756 lim = min (precision, lim);
20758 /* If that's more padding than already wanted, queue it.
20759 But don't reduce padding already specified even if
20760 that is beyond the current truncation point. */
20761 field_width = max (lim, field_width);
20763 goto tail_recurse;
20765 else if (STRINGP (car) || CONSP (car))
20767 Lisp_Object halftail = elt;
20768 int len = 0;
20770 while (CONSP (elt)
20771 && (precision <= 0 || n < precision))
20773 n += display_mode_element (it, depth,
20774 /* Do padding only after the last
20775 element in the list. */
20776 (! CONSP (XCDR (elt))
20777 ? field_width - n
20778 : 0),
20779 precision - n, XCAR (elt),
20780 props, risky);
20781 elt = XCDR (elt);
20782 len++;
20783 if ((len & 1) == 0)
20784 halftail = XCDR (halftail);
20785 /* Check for cycle. */
20786 if (EQ (halftail, elt))
20787 break;
20791 break;
20793 default:
20794 invalid:
20795 elt = build_string ("*invalid*");
20796 goto tail_recurse;
20799 /* Pad to FIELD_WIDTH. */
20800 if (field_width > 0 && n < field_width)
20802 switch (mode_line_target)
20804 case MODE_LINE_NOPROP:
20805 case MODE_LINE_TITLE:
20806 n += store_mode_line_noprop ("", field_width - n, 0);
20807 break;
20808 case MODE_LINE_STRING:
20809 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20810 break;
20811 case MODE_LINE_DISPLAY:
20812 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20813 0, 0, 0);
20814 break;
20818 return n;
20821 /* Store a mode-line string element in mode_line_string_list.
20823 If STRING is non-null, display that C string. Otherwise, the Lisp
20824 string LISP_STRING is displayed.
20826 FIELD_WIDTH is the minimum number of output glyphs to produce.
20827 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20828 with spaces. FIELD_WIDTH <= 0 means don't pad.
20830 PRECISION is the maximum number of characters to output from
20831 STRING. PRECISION <= 0 means don't truncate the string.
20833 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20834 properties to the string.
20836 PROPS are the properties to add to the string.
20837 The mode_line_string_face face property is always added to the string.
20840 static int
20841 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20842 int field_width, int precision, Lisp_Object props)
20844 ptrdiff_t len;
20845 int n = 0;
20847 if (string != NULL)
20849 len = strlen (string);
20850 if (precision > 0 && len > precision)
20851 len = precision;
20852 lisp_string = make_string (string, len);
20853 if (NILP (props))
20854 props = mode_line_string_face_prop;
20855 else if (!NILP (mode_line_string_face))
20857 Lisp_Object face = Fplist_get (props, Qface);
20858 props = Fcopy_sequence (props);
20859 if (NILP (face))
20860 face = mode_line_string_face;
20861 else
20862 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20863 props = Fplist_put (props, Qface, face);
20865 Fadd_text_properties (make_number (0), make_number (len),
20866 props, lisp_string);
20868 else
20870 len = XFASTINT (Flength (lisp_string));
20871 if (precision > 0 && len > precision)
20873 len = precision;
20874 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20875 precision = -1;
20877 if (!NILP (mode_line_string_face))
20879 Lisp_Object face;
20880 if (NILP (props))
20881 props = Ftext_properties_at (make_number (0), lisp_string);
20882 face = Fplist_get (props, Qface);
20883 if (NILP (face))
20884 face = mode_line_string_face;
20885 else
20886 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20887 props = Fcons (Qface, Fcons (face, Qnil));
20888 if (copy_string)
20889 lisp_string = Fcopy_sequence (lisp_string);
20891 if (!NILP (props))
20892 Fadd_text_properties (make_number (0), make_number (len),
20893 props, lisp_string);
20896 if (len > 0)
20898 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20899 n += len;
20902 if (field_width > len)
20904 field_width -= len;
20905 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20906 if (!NILP (props))
20907 Fadd_text_properties (make_number (0), make_number (field_width),
20908 props, lisp_string);
20909 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20910 n += field_width;
20913 return n;
20917 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20918 1, 4, 0,
20919 doc: /* Format a string out of a mode line format specification.
20920 First arg FORMAT specifies the mode line format (see `mode-line-format'
20921 for details) to use.
20923 By default, the format is evaluated for the currently selected window.
20925 Optional second arg FACE specifies the face property to put on all
20926 characters for which no face is specified. The value nil means the
20927 default face. The value t means whatever face the window's mode line
20928 currently uses (either `mode-line' or `mode-line-inactive',
20929 depending on whether the window is the selected window or not).
20930 An integer value means the value string has no text
20931 properties.
20933 Optional third and fourth args WINDOW and BUFFER specify the window
20934 and buffer to use as the context for the formatting (defaults
20935 are the selected window and the WINDOW's buffer). */)
20936 (Lisp_Object format, Lisp_Object face,
20937 Lisp_Object window, Lisp_Object buffer)
20939 struct it it;
20940 int len;
20941 struct window *w;
20942 struct buffer *old_buffer = NULL;
20943 int face_id;
20944 int no_props = INTEGERP (face);
20945 ptrdiff_t count = SPECPDL_INDEX ();
20946 Lisp_Object str;
20947 int string_start = 0;
20949 w = decode_any_window (window);
20950 XSETWINDOW (window, w);
20952 if (NILP (buffer))
20953 buffer = w->contents;
20954 CHECK_BUFFER (buffer);
20956 /* Make formatting the modeline a non-op when noninteractive, otherwise
20957 there will be problems later caused by a partially initialized frame. */
20958 if (NILP (format) || noninteractive)
20959 return empty_unibyte_string;
20961 if (no_props)
20962 face = Qnil;
20964 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20965 : EQ (face, Qt) ? (EQ (window, selected_window)
20966 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20967 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20968 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20969 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20970 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20971 : DEFAULT_FACE_ID;
20973 old_buffer = current_buffer;
20975 /* Save things including mode_line_proptrans_alist,
20976 and set that to nil so that we don't alter the outer value. */
20977 record_unwind_protect (unwind_format_mode_line,
20978 format_mode_line_unwind_data
20979 (XFRAME (WINDOW_FRAME (w)),
20980 old_buffer, selected_window, 1));
20981 mode_line_proptrans_alist = Qnil;
20983 Fselect_window (window, Qt);
20984 set_buffer_internal_1 (XBUFFER (buffer));
20986 init_iterator (&it, w, -1, -1, NULL, face_id);
20988 if (no_props)
20990 mode_line_target = MODE_LINE_NOPROP;
20991 mode_line_string_face_prop = Qnil;
20992 mode_line_string_list = Qnil;
20993 string_start = MODE_LINE_NOPROP_LEN (0);
20995 else
20997 mode_line_target = MODE_LINE_STRING;
20998 mode_line_string_list = Qnil;
20999 mode_line_string_face = face;
21000 mode_line_string_face_prop
21001 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
21004 push_kboard (FRAME_KBOARD (it.f));
21005 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21006 pop_kboard ();
21008 if (no_props)
21010 len = MODE_LINE_NOPROP_LEN (string_start);
21011 str = make_string (mode_line_noprop_buf + string_start, len);
21013 else
21015 mode_line_string_list = Fnreverse (mode_line_string_list);
21016 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21017 empty_unibyte_string);
21020 unbind_to (count, Qnil);
21021 return str;
21024 /* Write a null-terminated, right justified decimal representation of
21025 the positive integer D to BUF using a minimal field width WIDTH. */
21027 static void
21028 pint2str (register char *buf, register int width, register ptrdiff_t d)
21030 register char *p = buf;
21032 if (d <= 0)
21033 *p++ = '0';
21034 else
21036 while (d > 0)
21038 *p++ = d % 10 + '0';
21039 d /= 10;
21043 for (width -= (int) (p - buf); width > 0; --width)
21044 *p++ = ' ';
21045 *p-- = '\0';
21046 while (p > buf)
21048 d = *buf;
21049 *buf++ = *p;
21050 *p-- = d;
21054 /* Write a null-terminated, right justified decimal and "human
21055 readable" representation of the nonnegative integer D to BUF using
21056 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21058 static const char power_letter[] =
21060 0, /* no letter */
21061 'k', /* kilo */
21062 'M', /* mega */
21063 'G', /* giga */
21064 'T', /* tera */
21065 'P', /* peta */
21066 'E', /* exa */
21067 'Z', /* zetta */
21068 'Y' /* yotta */
21071 static void
21072 pint2hrstr (char *buf, int width, ptrdiff_t d)
21074 /* We aim to represent the nonnegative integer D as
21075 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21076 ptrdiff_t quotient = d;
21077 int remainder = 0;
21078 /* -1 means: do not use TENTHS. */
21079 int tenths = -1;
21080 int exponent = 0;
21082 /* Length of QUOTIENT.TENTHS as a string. */
21083 int length;
21085 char * psuffix;
21086 char * p;
21088 if (quotient >= 1000)
21090 /* Scale to the appropriate EXPONENT. */
21093 remainder = quotient % 1000;
21094 quotient /= 1000;
21095 exponent++;
21097 while (quotient >= 1000);
21099 /* Round to nearest and decide whether to use TENTHS or not. */
21100 if (quotient <= 9)
21102 tenths = remainder / 100;
21103 if (remainder % 100 >= 50)
21105 if (tenths < 9)
21106 tenths++;
21107 else
21109 quotient++;
21110 if (quotient == 10)
21111 tenths = -1;
21112 else
21113 tenths = 0;
21117 else
21118 if (remainder >= 500)
21120 if (quotient < 999)
21121 quotient++;
21122 else
21124 quotient = 1;
21125 exponent++;
21126 tenths = 0;
21131 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21132 if (tenths == -1 && quotient <= 99)
21133 if (quotient <= 9)
21134 length = 1;
21135 else
21136 length = 2;
21137 else
21138 length = 3;
21139 p = psuffix = buf + max (width, length);
21141 /* Print EXPONENT. */
21142 *psuffix++ = power_letter[exponent];
21143 *psuffix = '\0';
21145 /* Print TENTHS. */
21146 if (tenths >= 0)
21148 *--p = '0' + tenths;
21149 *--p = '.';
21152 /* Print QUOTIENT. */
21155 int digit = quotient % 10;
21156 *--p = '0' + digit;
21158 while ((quotient /= 10) != 0);
21160 /* Print leading spaces. */
21161 while (buf < p)
21162 *--p = ' ';
21165 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21166 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21167 type of CODING_SYSTEM. Return updated pointer into BUF. */
21169 static unsigned char invalid_eol_type[] = "(*invalid*)";
21171 static char *
21172 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21174 Lisp_Object val;
21175 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21176 const unsigned char *eol_str;
21177 int eol_str_len;
21178 /* The EOL conversion we are using. */
21179 Lisp_Object eoltype;
21181 val = CODING_SYSTEM_SPEC (coding_system);
21182 eoltype = Qnil;
21184 if (!VECTORP (val)) /* Not yet decided. */
21186 *buf++ = multibyte ? '-' : ' ';
21187 if (eol_flag)
21188 eoltype = eol_mnemonic_undecided;
21189 /* Don't mention EOL conversion if it isn't decided. */
21191 else
21193 Lisp_Object attrs;
21194 Lisp_Object eolvalue;
21196 attrs = AREF (val, 0);
21197 eolvalue = AREF (val, 2);
21199 *buf++ = multibyte
21200 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21201 : ' ';
21203 if (eol_flag)
21205 /* The EOL conversion that is normal on this system. */
21207 if (NILP (eolvalue)) /* Not yet decided. */
21208 eoltype = eol_mnemonic_undecided;
21209 else if (VECTORP (eolvalue)) /* Not yet decided. */
21210 eoltype = eol_mnemonic_undecided;
21211 else /* eolvalue is Qunix, Qdos, or Qmac. */
21212 eoltype = (EQ (eolvalue, Qunix)
21213 ? eol_mnemonic_unix
21214 : (EQ (eolvalue, Qdos) == 1
21215 ? eol_mnemonic_dos : eol_mnemonic_mac));
21219 if (eol_flag)
21221 /* Mention the EOL conversion if it is not the usual one. */
21222 if (STRINGP (eoltype))
21224 eol_str = SDATA (eoltype);
21225 eol_str_len = SBYTES (eoltype);
21227 else if (CHARACTERP (eoltype))
21229 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21230 int c = XFASTINT (eoltype);
21231 eol_str_len = CHAR_STRING (c, tmp);
21232 eol_str = tmp;
21234 else
21236 eol_str = invalid_eol_type;
21237 eol_str_len = sizeof (invalid_eol_type) - 1;
21239 memcpy (buf, eol_str, eol_str_len);
21240 buf += eol_str_len;
21243 return buf;
21246 /* Return a string for the output of a mode line %-spec for window W,
21247 generated by character C. FIELD_WIDTH > 0 means pad the string
21248 returned with spaces to that value. Return a Lisp string in
21249 *STRING if the resulting string is taken from that Lisp string.
21251 Note we operate on the current buffer for most purposes. */
21253 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21255 static const char *
21256 decode_mode_spec (struct window *w, register int c, int field_width,
21257 Lisp_Object *string)
21259 Lisp_Object obj;
21260 struct frame *f = XFRAME (WINDOW_FRAME (w));
21261 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21262 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21263 produce strings from numerical values, so limit preposterously
21264 large values of FIELD_WIDTH to avoid overrunning the buffer's
21265 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21266 bytes plus the terminating null. */
21267 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21268 struct buffer *b = current_buffer;
21270 obj = Qnil;
21271 *string = Qnil;
21273 switch (c)
21275 case '*':
21276 if (!NILP (BVAR (b, read_only)))
21277 return "%";
21278 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21279 return "*";
21280 return "-";
21282 case '+':
21283 /* This differs from %* only for a modified read-only buffer. */
21284 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21285 return "*";
21286 if (!NILP (BVAR (b, read_only)))
21287 return "%";
21288 return "-";
21290 case '&':
21291 /* This differs from %* in ignoring read-only-ness. */
21292 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21293 return "*";
21294 return "-";
21296 case '%':
21297 return "%";
21299 case '[':
21301 int i;
21302 char *p;
21304 if (command_loop_level > 5)
21305 return "[[[... ";
21306 p = decode_mode_spec_buf;
21307 for (i = 0; i < command_loop_level; i++)
21308 *p++ = '[';
21309 *p = 0;
21310 return decode_mode_spec_buf;
21313 case ']':
21315 int i;
21316 char *p;
21318 if (command_loop_level > 5)
21319 return " ...]]]";
21320 p = decode_mode_spec_buf;
21321 for (i = 0; i < command_loop_level; i++)
21322 *p++ = ']';
21323 *p = 0;
21324 return decode_mode_spec_buf;
21327 case '-':
21329 register int i;
21331 /* Let lots_of_dashes be a string of infinite length. */
21332 if (mode_line_target == MODE_LINE_NOPROP
21333 || mode_line_target == MODE_LINE_STRING)
21334 return "--";
21335 if (field_width <= 0
21336 || field_width > sizeof (lots_of_dashes))
21338 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21339 decode_mode_spec_buf[i] = '-';
21340 decode_mode_spec_buf[i] = '\0';
21341 return decode_mode_spec_buf;
21343 else
21344 return lots_of_dashes;
21347 case 'b':
21348 obj = BVAR (b, name);
21349 break;
21351 case 'c':
21352 /* %c and %l are ignored in `frame-title-format'.
21353 (In redisplay_internal, the frame title is drawn _before_ the
21354 windows are updated, so the stuff which depends on actual
21355 window contents (such as %l) may fail to render properly, or
21356 even crash emacs.) */
21357 if (mode_line_target == MODE_LINE_TITLE)
21358 return "";
21359 else
21361 ptrdiff_t col = current_column ();
21362 w->column_number_displayed = col;
21363 pint2str (decode_mode_spec_buf, width, col);
21364 return decode_mode_spec_buf;
21367 case 'e':
21368 #ifndef SYSTEM_MALLOC
21370 if (NILP (Vmemory_full))
21371 return "";
21372 else
21373 return "!MEM FULL! ";
21375 #else
21376 return "";
21377 #endif
21379 case 'F':
21380 /* %F displays the frame name. */
21381 if (!NILP (f->title))
21382 return SSDATA (f->title);
21383 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21384 return SSDATA (f->name);
21385 return "Emacs";
21387 case 'f':
21388 obj = BVAR (b, filename);
21389 break;
21391 case 'i':
21393 ptrdiff_t size = ZV - BEGV;
21394 pint2str (decode_mode_spec_buf, width, size);
21395 return decode_mode_spec_buf;
21398 case 'I':
21400 ptrdiff_t size = ZV - BEGV;
21401 pint2hrstr (decode_mode_spec_buf, width, size);
21402 return decode_mode_spec_buf;
21405 case 'l':
21407 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21408 ptrdiff_t topline, nlines, height;
21409 ptrdiff_t junk;
21411 /* %c and %l are ignored in `frame-title-format'. */
21412 if (mode_line_target == MODE_LINE_TITLE)
21413 return "";
21415 startpos = marker_position (w->start);
21416 startpos_byte = marker_byte_position (w->start);
21417 height = WINDOW_TOTAL_LINES (w);
21419 /* If we decided that this buffer isn't suitable for line numbers,
21420 don't forget that too fast. */
21421 if (w->base_line_pos == -1)
21422 goto no_value;
21424 /* If the buffer is very big, don't waste time. */
21425 if (INTEGERP (Vline_number_display_limit)
21426 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21428 w->base_line_pos = 0;
21429 w->base_line_number = 0;
21430 goto no_value;
21433 if (w->base_line_number > 0
21434 && w->base_line_pos > 0
21435 && w->base_line_pos <= startpos)
21437 line = w->base_line_number;
21438 linepos = w->base_line_pos;
21439 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21441 else
21443 line = 1;
21444 linepos = BUF_BEGV (b);
21445 linepos_byte = BUF_BEGV_BYTE (b);
21448 /* Count lines from base line to window start position. */
21449 nlines = display_count_lines (linepos_byte,
21450 startpos_byte,
21451 startpos, &junk);
21453 topline = nlines + line;
21455 /* Determine a new base line, if the old one is too close
21456 or too far away, or if we did not have one.
21457 "Too close" means it's plausible a scroll-down would
21458 go back past it. */
21459 if (startpos == BUF_BEGV (b))
21461 w->base_line_number = topline;
21462 w->base_line_pos = BUF_BEGV (b);
21464 else if (nlines < height + 25 || nlines > height * 3 + 50
21465 || linepos == BUF_BEGV (b))
21467 ptrdiff_t limit = BUF_BEGV (b);
21468 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21469 ptrdiff_t position;
21470 ptrdiff_t distance =
21471 (height * 2 + 30) * line_number_display_limit_width;
21473 if (startpos - distance > limit)
21475 limit = startpos - distance;
21476 limit_byte = CHAR_TO_BYTE (limit);
21479 nlines = display_count_lines (startpos_byte,
21480 limit_byte,
21481 - (height * 2 + 30),
21482 &position);
21483 /* If we couldn't find the lines we wanted within
21484 line_number_display_limit_width chars per line,
21485 give up on line numbers for this window. */
21486 if (position == limit_byte && limit == startpos - distance)
21488 w->base_line_pos = -1;
21489 w->base_line_number = 0;
21490 goto no_value;
21493 w->base_line_number = topline - nlines;
21494 w->base_line_pos = BYTE_TO_CHAR (position);
21497 /* Now count lines from the start pos to point. */
21498 nlines = display_count_lines (startpos_byte,
21499 PT_BYTE, PT, &junk);
21501 /* Record that we did display the line number. */
21502 line_number_displayed = 1;
21504 /* Make the string to show. */
21505 pint2str (decode_mode_spec_buf, width, topline + nlines);
21506 return decode_mode_spec_buf;
21507 no_value:
21509 char* p = decode_mode_spec_buf;
21510 int pad = width - 2;
21511 while (pad-- > 0)
21512 *p++ = ' ';
21513 *p++ = '?';
21514 *p++ = '?';
21515 *p = '\0';
21516 return decode_mode_spec_buf;
21519 break;
21521 case 'm':
21522 obj = BVAR (b, mode_name);
21523 break;
21525 case 'n':
21526 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21527 return " Narrow";
21528 break;
21530 case 'p':
21532 ptrdiff_t pos = marker_position (w->start);
21533 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21535 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21537 if (pos <= BUF_BEGV (b))
21538 return "All";
21539 else
21540 return "Bottom";
21542 else if (pos <= BUF_BEGV (b))
21543 return "Top";
21544 else
21546 if (total > 1000000)
21547 /* Do it differently for a large value, to avoid overflow. */
21548 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21549 else
21550 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21551 /* We can't normally display a 3-digit number,
21552 so get us a 2-digit number that is close. */
21553 if (total == 100)
21554 total = 99;
21555 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21556 return decode_mode_spec_buf;
21560 /* Display percentage of size above the bottom of the screen. */
21561 case 'P':
21563 ptrdiff_t toppos = marker_position (w->start);
21564 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21565 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21567 if (botpos >= BUF_ZV (b))
21569 if (toppos <= BUF_BEGV (b))
21570 return "All";
21571 else
21572 return "Bottom";
21574 else
21576 if (total > 1000000)
21577 /* Do it differently for a large value, to avoid overflow. */
21578 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21579 else
21580 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21581 /* We can't normally display a 3-digit number,
21582 so get us a 2-digit number that is close. */
21583 if (total == 100)
21584 total = 99;
21585 if (toppos <= BUF_BEGV (b))
21586 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
21587 else
21588 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21589 return decode_mode_spec_buf;
21593 case 's':
21594 /* status of process */
21595 obj = Fget_buffer_process (Fcurrent_buffer ());
21596 if (NILP (obj))
21597 return "no process";
21598 #ifndef MSDOS
21599 obj = Fsymbol_name (Fprocess_status (obj));
21600 #endif
21601 break;
21603 case '@':
21605 ptrdiff_t count = inhibit_garbage_collection ();
21606 Lisp_Object val = call1 (intern ("file-remote-p"),
21607 BVAR (current_buffer, directory));
21608 unbind_to (count, Qnil);
21610 if (NILP (val))
21611 return "-";
21612 else
21613 return "@";
21616 case 'z':
21617 /* coding-system (not including end-of-line format) */
21618 case 'Z':
21619 /* coding-system (including end-of-line type) */
21621 int eol_flag = (c == 'Z');
21622 char *p = decode_mode_spec_buf;
21624 if (! FRAME_WINDOW_P (f))
21626 /* No need to mention EOL here--the terminal never needs
21627 to do EOL conversion. */
21628 p = decode_mode_spec_coding (CODING_ID_NAME
21629 (FRAME_KEYBOARD_CODING (f)->id),
21630 p, 0);
21631 p = decode_mode_spec_coding (CODING_ID_NAME
21632 (FRAME_TERMINAL_CODING (f)->id),
21633 p, 0);
21635 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21636 p, eol_flag);
21638 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21639 #ifdef subprocesses
21640 obj = Fget_buffer_process (Fcurrent_buffer ());
21641 if (PROCESSP (obj))
21643 p = decode_mode_spec_coding
21644 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
21645 p = decode_mode_spec_coding
21646 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
21648 #endif /* subprocesses */
21649 #endif /* 0 */
21650 *p = 0;
21651 return decode_mode_spec_buf;
21655 if (STRINGP (obj))
21657 *string = obj;
21658 return SSDATA (obj);
21660 else
21661 return "";
21665 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
21666 means count lines back from START_BYTE. But don't go beyond
21667 LIMIT_BYTE. Return the number of lines thus found (always
21668 nonnegative).
21670 Set *BYTE_POS_PTR to the byte position where we stopped. This is
21671 either the position COUNT lines after/before START_BYTE, if we
21672 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
21673 COUNT lines. */
21675 static ptrdiff_t
21676 display_count_lines (ptrdiff_t start_byte,
21677 ptrdiff_t limit_byte, ptrdiff_t count,
21678 ptrdiff_t *byte_pos_ptr)
21680 register unsigned char *cursor;
21681 unsigned char *base;
21683 register ptrdiff_t ceiling;
21684 register unsigned char *ceiling_addr;
21685 ptrdiff_t orig_count = count;
21687 /* If we are not in selective display mode,
21688 check only for newlines. */
21689 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21690 && !INTEGERP (BVAR (current_buffer, selective_display)));
21692 if (count > 0)
21694 while (start_byte < limit_byte)
21696 ceiling = BUFFER_CEILING_OF (start_byte);
21697 ceiling = min (limit_byte - 1, ceiling);
21698 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21699 base = (cursor = BYTE_POS_ADDR (start_byte));
21703 if (selective_display)
21705 while (*cursor != '\n' && *cursor != 015
21706 && ++cursor != ceiling_addr)
21707 continue;
21708 if (cursor == ceiling_addr)
21709 break;
21711 else
21713 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
21714 if (! cursor)
21715 break;
21718 cursor++;
21720 if (--count == 0)
21722 start_byte += cursor - base;
21723 *byte_pos_ptr = start_byte;
21724 return orig_count;
21727 while (cursor < ceiling_addr);
21729 start_byte += ceiling_addr - base;
21732 else
21734 while (start_byte > limit_byte)
21736 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21737 ceiling = max (limit_byte, ceiling);
21738 ceiling_addr = BYTE_POS_ADDR (ceiling);
21739 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21740 while (1)
21742 if (selective_display)
21744 while (--cursor >= ceiling_addr
21745 && *cursor != '\n' && *cursor != 015)
21746 continue;
21747 if (cursor < ceiling_addr)
21748 break;
21750 else
21752 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
21753 if (! cursor)
21754 break;
21757 if (++count == 0)
21759 start_byte += cursor - base + 1;
21760 *byte_pos_ptr = start_byte;
21761 /* When scanning backwards, we should
21762 not count the newline posterior to which we stop. */
21763 return - orig_count - 1;
21766 start_byte += ceiling_addr - base;
21770 *byte_pos_ptr = limit_byte;
21772 if (count < 0)
21773 return - orig_count + count;
21774 return orig_count - count;
21780 /***********************************************************************
21781 Displaying strings
21782 ***********************************************************************/
21784 /* Display a NUL-terminated string, starting with index START.
21786 If STRING is non-null, display that C string. Otherwise, the Lisp
21787 string LISP_STRING is displayed. There's a case that STRING is
21788 non-null and LISP_STRING is not nil. It means STRING is a string
21789 data of LISP_STRING. In that case, we display LISP_STRING while
21790 ignoring its text properties.
21792 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21793 FACE_STRING. Display STRING or LISP_STRING with the face at
21794 FACE_STRING_POS in FACE_STRING:
21796 Display the string in the environment given by IT, but use the
21797 standard display table, temporarily.
21799 FIELD_WIDTH is the minimum number of output glyphs to produce.
21800 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21801 with spaces. If STRING has more characters, more than FIELD_WIDTH
21802 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21804 PRECISION is the maximum number of characters to output from
21805 STRING. PRECISION < 0 means don't truncate the string.
21807 This is roughly equivalent to printf format specifiers:
21809 FIELD_WIDTH PRECISION PRINTF
21810 ----------------------------------------
21811 -1 -1 %s
21812 -1 10 %.10s
21813 10 -1 %10s
21814 20 10 %20.10s
21816 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21817 display them, and < 0 means obey the current buffer's value of
21818 enable_multibyte_characters.
21820 Value is the number of columns displayed. */
21822 static int
21823 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21824 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
21825 int field_width, int precision, int max_x, int multibyte)
21827 int hpos_at_start = it->hpos;
21828 int saved_face_id = it->face_id;
21829 struct glyph_row *row = it->glyph_row;
21830 ptrdiff_t it_charpos;
21832 /* Initialize the iterator IT for iteration over STRING beginning
21833 with index START. */
21834 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21835 precision, field_width, multibyte);
21836 if (string && STRINGP (lisp_string))
21837 /* LISP_STRING is the one returned by decode_mode_spec. We should
21838 ignore its text properties. */
21839 it->stop_charpos = it->end_charpos;
21841 /* If displaying STRING, set up the face of the iterator from
21842 FACE_STRING, if that's given. */
21843 if (STRINGP (face_string))
21845 ptrdiff_t endptr;
21846 struct face *face;
21848 it->face_id
21849 = face_at_string_position (it->w, face_string, face_string_pos,
21850 0, it->region_beg_charpos,
21851 it->region_end_charpos,
21852 &endptr, it->base_face_id, 0);
21853 face = FACE_FROM_ID (it->f, it->face_id);
21854 it->face_box_p = face->box != FACE_NO_BOX;
21857 /* Set max_x to the maximum allowed X position. Don't let it go
21858 beyond the right edge of the window. */
21859 if (max_x <= 0)
21860 max_x = it->last_visible_x;
21861 else
21862 max_x = min (max_x, it->last_visible_x);
21864 /* Skip over display elements that are not visible. because IT->w is
21865 hscrolled. */
21866 if (it->current_x < it->first_visible_x)
21867 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21868 MOVE_TO_POS | MOVE_TO_X);
21870 row->ascent = it->max_ascent;
21871 row->height = it->max_ascent + it->max_descent;
21872 row->phys_ascent = it->max_phys_ascent;
21873 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21874 row->extra_line_spacing = it->max_extra_line_spacing;
21876 if (STRINGP (it->string))
21877 it_charpos = IT_STRING_CHARPOS (*it);
21878 else
21879 it_charpos = IT_CHARPOS (*it);
21881 /* This condition is for the case that we are called with current_x
21882 past last_visible_x. */
21883 while (it->current_x < max_x)
21885 int x_before, x, n_glyphs_before, i, nglyphs;
21887 /* Get the next display element. */
21888 if (!get_next_display_element (it))
21889 break;
21891 /* Produce glyphs. */
21892 x_before = it->current_x;
21893 n_glyphs_before = row->used[TEXT_AREA];
21894 PRODUCE_GLYPHS (it);
21896 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21897 i = 0;
21898 x = x_before;
21899 while (i < nglyphs)
21901 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21903 if (it->line_wrap != TRUNCATE
21904 && x + glyph->pixel_width > max_x)
21906 /* End of continued line or max_x reached. */
21907 if (CHAR_GLYPH_PADDING_P (*glyph))
21909 /* A wide character is unbreakable. */
21910 if (row->reversed_p)
21911 unproduce_glyphs (it, row->used[TEXT_AREA]
21912 - n_glyphs_before);
21913 row->used[TEXT_AREA] = n_glyphs_before;
21914 it->current_x = x_before;
21916 else
21918 if (row->reversed_p)
21919 unproduce_glyphs (it, row->used[TEXT_AREA]
21920 - (n_glyphs_before + i));
21921 row->used[TEXT_AREA] = n_glyphs_before + i;
21922 it->current_x = x;
21924 break;
21926 else if (x + glyph->pixel_width >= it->first_visible_x)
21928 /* Glyph is at least partially visible. */
21929 ++it->hpos;
21930 if (x < it->first_visible_x)
21931 row->x = x - it->first_visible_x;
21933 else
21935 /* Glyph is off the left margin of the display area.
21936 Should not happen. */
21937 emacs_abort ();
21940 row->ascent = max (row->ascent, it->max_ascent);
21941 row->height = max (row->height, it->max_ascent + it->max_descent);
21942 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21943 row->phys_height = max (row->phys_height,
21944 it->max_phys_ascent + it->max_phys_descent);
21945 row->extra_line_spacing = max (row->extra_line_spacing,
21946 it->max_extra_line_spacing);
21947 x += glyph->pixel_width;
21948 ++i;
21951 /* Stop if max_x reached. */
21952 if (i < nglyphs)
21953 break;
21955 /* Stop at line ends. */
21956 if (ITERATOR_AT_END_OF_LINE_P (it))
21958 it->continuation_lines_width = 0;
21959 break;
21962 set_iterator_to_next (it, 1);
21963 if (STRINGP (it->string))
21964 it_charpos = IT_STRING_CHARPOS (*it);
21965 else
21966 it_charpos = IT_CHARPOS (*it);
21968 /* Stop if truncating at the right edge. */
21969 if (it->line_wrap == TRUNCATE
21970 && it->current_x >= it->last_visible_x)
21972 /* Add truncation mark, but don't do it if the line is
21973 truncated at a padding space. */
21974 if (it_charpos < it->string_nchars)
21976 if (!FRAME_WINDOW_P (it->f))
21978 int ii, n;
21980 if (it->current_x > it->last_visible_x)
21982 if (!row->reversed_p)
21984 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21985 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21986 break;
21988 else
21990 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21991 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21992 break;
21993 unproduce_glyphs (it, ii + 1);
21994 ii = row->used[TEXT_AREA] - (ii + 1);
21996 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
21998 row->used[TEXT_AREA] = ii;
21999 produce_special_glyphs (it, IT_TRUNCATION);
22002 produce_special_glyphs (it, IT_TRUNCATION);
22004 row->truncated_on_right_p = 1;
22006 break;
22010 /* Maybe insert a truncation at the left. */
22011 if (it->first_visible_x
22012 && it_charpos > 0)
22014 if (!FRAME_WINDOW_P (it->f)
22015 || (row->reversed_p
22016 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22017 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22018 insert_left_trunc_glyphs (it);
22019 row->truncated_on_left_p = 1;
22022 it->face_id = saved_face_id;
22024 /* Value is number of columns displayed. */
22025 return it->hpos - hpos_at_start;
22030 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22031 appears as an element of LIST or as the car of an element of LIST.
22032 If PROPVAL is a list, compare each element against LIST in that
22033 way, and return 1/2 if any element of PROPVAL is found in LIST.
22034 Otherwise return 0. This function cannot quit.
22035 The return value is 2 if the text is invisible but with an ellipsis
22036 and 1 if it's invisible and without an ellipsis. */
22039 invisible_p (register Lisp_Object propval, Lisp_Object list)
22041 register Lisp_Object tail, proptail;
22043 for (tail = list; CONSP (tail); tail = XCDR (tail))
22045 register Lisp_Object tem;
22046 tem = XCAR (tail);
22047 if (EQ (propval, tem))
22048 return 1;
22049 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22050 return NILP (XCDR (tem)) ? 1 : 2;
22053 if (CONSP (propval))
22055 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22057 Lisp_Object propelt;
22058 propelt = XCAR (proptail);
22059 for (tail = list; CONSP (tail); tail = XCDR (tail))
22061 register Lisp_Object tem;
22062 tem = XCAR (tail);
22063 if (EQ (propelt, tem))
22064 return 1;
22065 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22066 return NILP (XCDR (tem)) ? 1 : 2;
22071 return 0;
22074 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22075 doc: /* Non-nil if the property makes the text invisible.
22076 POS-OR-PROP can be a marker or number, in which case it is taken to be
22077 a position in the current buffer and the value of the `invisible' property
22078 is checked; or it can be some other value, which is then presumed to be the
22079 value of the `invisible' property of the text of interest.
22080 The non-nil value returned can be t for truly invisible text or something
22081 else if the text is replaced by an ellipsis. */)
22082 (Lisp_Object pos_or_prop)
22084 Lisp_Object prop
22085 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22086 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22087 : pos_or_prop);
22088 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22089 return (invis == 0 ? Qnil
22090 : invis == 1 ? Qt
22091 : make_number (invis));
22094 /* Calculate a width or height in pixels from a specification using
22095 the following elements:
22097 SPEC ::=
22098 NUM - a (fractional) multiple of the default font width/height
22099 (NUM) - specifies exactly NUM pixels
22100 UNIT - a fixed number of pixels, see below.
22101 ELEMENT - size of a display element in pixels, see below.
22102 (NUM . SPEC) - equals NUM * SPEC
22103 (+ SPEC SPEC ...) - add pixel values
22104 (- SPEC SPEC ...) - subtract pixel values
22105 (- SPEC) - negate pixel value
22107 NUM ::=
22108 INT or FLOAT - a number constant
22109 SYMBOL - use symbol's (buffer local) variable binding.
22111 UNIT ::=
22112 in - pixels per inch *)
22113 mm - pixels per 1/1000 meter *)
22114 cm - pixels per 1/100 meter *)
22115 width - width of current font in pixels.
22116 height - height of current font in pixels.
22118 *) using the ratio(s) defined in display-pixels-per-inch.
22120 ELEMENT ::=
22122 left-fringe - left fringe width in pixels
22123 right-fringe - right fringe width in pixels
22125 left-margin - left margin width in pixels
22126 right-margin - right margin width in pixels
22128 scroll-bar - scroll-bar area width in pixels
22130 Examples:
22132 Pixels corresponding to 5 inches:
22133 (5 . in)
22135 Total width of non-text areas on left side of window (if scroll-bar is on left):
22136 '(space :width (+ left-fringe left-margin scroll-bar))
22138 Align to first text column (in header line):
22139 '(space :align-to 0)
22141 Align to middle of text area minus half the width of variable `my-image'
22142 containing a loaded image:
22143 '(space :align-to (0.5 . (- text my-image)))
22145 Width of left margin minus width of 1 character in the default font:
22146 '(space :width (- left-margin 1))
22148 Width of left margin minus width of 2 characters in the current font:
22149 '(space :width (- left-margin (2 . width)))
22151 Center 1 character over left-margin (in header line):
22152 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22154 Different ways to express width of left fringe plus left margin minus one pixel:
22155 '(space :width (- (+ left-fringe left-margin) (1)))
22156 '(space :width (+ left-fringe left-margin (- (1))))
22157 '(space :width (+ left-fringe left-margin (-1)))
22161 static int
22162 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22163 struct font *font, int width_p, int *align_to)
22165 double pixels;
22167 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22168 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22170 if (NILP (prop))
22171 return OK_PIXELS (0);
22173 eassert (FRAME_LIVE_P (it->f));
22175 if (SYMBOLP (prop))
22177 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22179 char *unit = SSDATA (SYMBOL_NAME (prop));
22181 if (unit[0] == 'i' && unit[1] == 'n')
22182 pixels = 1.0;
22183 else if (unit[0] == 'm' && unit[1] == 'm')
22184 pixels = 25.4;
22185 else if (unit[0] == 'c' && unit[1] == 'm')
22186 pixels = 2.54;
22187 else
22188 pixels = 0;
22189 if (pixels > 0)
22191 double ppi = (width_p ? FRAME_RES_X (it->f)
22192 : FRAME_RES_Y (it->f));
22194 if (ppi > 0)
22195 return OK_PIXELS (ppi / pixels);
22196 return 0;
22200 #ifdef HAVE_WINDOW_SYSTEM
22201 if (EQ (prop, Qheight))
22202 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22203 if (EQ (prop, Qwidth))
22204 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22205 #else
22206 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22207 return OK_PIXELS (1);
22208 #endif
22210 if (EQ (prop, Qtext))
22211 return OK_PIXELS (width_p
22212 ? window_box_width (it->w, TEXT_AREA)
22213 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22215 if (align_to && *align_to < 0)
22217 *res = 0;
22218 if (EQ (prop, Qleft))
22219 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22220 if (EQ (prop, Qright))
22221 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22222 if (EQ (prop, Qcenter))
22223 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22224 + window_box_width (it->w, TEXT_AREA) / 2);
22225 if (EQ (prop, Qleft_fringe))
22226 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22227 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22228 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22229 if (EQ (prop, Qright_fringe))
22230 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22231 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22232 : window_box_right_offset (it->w, TEXT_AREA));
22233 if (EQ (prop, Qleft_margin))
22234 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22235 if (EQ (prop, Qright_margin))
22236 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22237 if (EQ (prop, Qscroll_bar))
22238 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22240 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22241 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22242 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22243 : 0)));
22245 else
22247 if (EQ (prop, Qleft_fringe))
22248 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22249 if (EQ (prop, Qright_fringe))
22250 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22251 if (EQ (prop, Qleft_margin))
22252 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22253 if (EQ (prop, Qright_margin))
22254 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22255 if (EQ (prop, Qscroll_bar))
22256 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22259 prop = buffer_local_value_1 (prop, it->w->contents);
22260 if (EQ (prop, Qunbound))
22261 prop = Qnil;
22264 if (INTEGERP (prop) || FLOATP (prop))
22266 int base_unit = (width_p
22267 ? FRAME_COLUMN_WIDTH (it->f)
22268 : FRAME_LINE_HEIGHT (it->f));
22269 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22272 if (CONSP (prop))
22274 Lisp_Object car = XCAR (prop);
22275 Lisp_Object cdr = XCDR (prop);
22277 if (SYMBOLP (car))
22279 #ifdef HAVE_WINDOW_SYSTEM
22280 if (FRAME_WINDOW_P (it->f)
22281 && valid_image_p (prop))
22283 ptrdiff_t id = lookup_image (it->f, prop);
22284 struct image *img = IMAGE_FROM_ID (it->f, id);
22286 return OK_PIXELS (width_p ? img->width : img->height);
22288 #endif
22289 if (EQ (car, Qplus) || EQ (car, Qminus))
22291 int first = 1;
22292 double px;
22294 pixels = 0;
22295 while (CONSP (cdr))
22297 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22298 font, width_p, align_to))
22299 return 0;
22300 if (first)
22301 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22302 else
22303 pixels += px;
22304 cdr = XCDR (cdr);
22306 if (EQ (car, Qminus))
22307 pixels = -pixels;
22308 return OK_PIXELS (pixels);
22311 car = buffer_local_value_1 (car, it->w->contents);
22312 if (EQ (car, Qunbound))
22313 car = Qnil;
22316 if (INTEGERP (car) || FLOATP (car))
22318 double fact;
22319 pixels = XFLOATINT (car);
22320 if (NILP (cdr))
22321 return OK_PIXELS (pixels);
22322 if (calc_pixel_width_or_height (&fact, it, cdr,
22323 font, width_p, align_to))
22324 return OK_PIXELS (pixels * fact);
22325 return 0;
22328 return 0;
22331 return 0;
22335 /***********************************************************************
22336 Glyph Display
22337 ***********************************************************************/
22339 #ifdef HAVE_WINDOW_SYSTEM
22341 #ifdef GLYPH_DEBUG
22343 void
22344 dump_glyph_string (struct glyph_string *s)
22346 fprintf (stderr, "glyph string\n");
22347 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22348 s->x, s->y, s->width, s->height);
22349 fprintf (stderr, " ybase = %d\n", s->ybase);
22350 fprintf (stderr, " hl = %d\n", s->hl);
22351 fprintf (stderr, " left overhang = %d, right = %d\n",
22352 s->left_overhang, s->right_overhang);
22353 fprintf (stderr, " nchars = %d\n", s->nchars);
22354 fprintf (stderr, " extends to end of line = %d\n",
22355 s->extends_to_end_of_line_p);
22356 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22357 fprintf (stderr, " bg width = %d\n", s->background_width);
22360 #endif /* GLYPH_DEBUG */
22362 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22363 of XChar2b structures for S; it can't be allocated in
22364 init_glyph_string because it must be allocated via `alloca'. W
22365 is the window on which S is drawn. ROW and AREA are the glyph row
22366 and area within the row from which S is constructed. START is the
22367 index of the first glyph structure covered by S. HL is a
22368 face-override for drawing S. */
22370 #ifdef HAVE_NTGUI
22371 #define OPTIONAL_HDC(hdc) HDC hdc,
22372 #define DECLARE_HDC(hdc) HDC hdc;
22373 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22374 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22375 #endif
22377 #ifndef OPTIONAL_HDC
22378 #define OPTIONAL_HDC(hdc)
22379 #define DECLARE_HDC(hdc)
22380 #define ALLOCATE_HDC(hdc, f)
22381 #define RELEASE_HDC(hdc, f)
22382 #endif
22384 static void
22385 init_glyph_string (struct glyph_string *s,
22386 OPTIONAL_HDC (hdc)
22387 XChar2b *char2b, struct window *w, struct glyph_row *row,
22388 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22390 memset (s, 0, sizeof *s);
22391 s->w = w;
22392 s->f = XFRAME (w->frame);
22393 #ifdef HAVE_NTGUI
22394 s->hdc = hdc;
22395 #endif
22396 s->display = FRAME_X_DISPLAY (s->f);
22397 s->window = FRAME_X_WINDOW (s->f);
22398 s->char2b = char2b;
22399 s->hl = hl;
22400 s->row = row;
22401 s->area = area;
22402 s->first_glyph = row->glyphs[area] + start;
22403 s->height = row->height;
22404 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22405 s->ybase = s->y + row->ascent;
22409 /* Append the list of glyph strings with head H and tail T to the list
22410 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22412 static void
22413 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22414 struct glyph_string *h, struct glyph_string *t)
22416 if (h)
22418 if (*head)
22419 (*tail)->next = h;
22420 else
22421 *head = h;
22422 h->prev = *tail;
22423 *tail = t;
22428 /* Prepend the list of glyph strings with head H and tail T to the
22429 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22430 result. */
22432 static void
22433 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22434 struct glyph_string *h, struct glyph_string *t)
22436 if (h)
22438 if (*head)
22439 (*head)->prev = t;
22440 else
22441 *tail = t;
22442 t->next = *head;
22443 *head = h;
22448 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22449 Set *HEAD and *TAIL to the resulting list. */
22451 static void
22452 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22453 struct glyph_string *s)
22455 s->next = s->prev = NULL;
22456 append_glyph_string_lists (head, tail, s, s);
22460 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22461 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22462 make sure that X resources for the face returned are allocated.
22463 Value is a pointer to a realized face that is ready for display if
22464 DISPLAY_P is non-zero. */
22466 static struct face *
22467 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22468 XChar2b *char2b, int display_p)
22470 struct face *face = FACE_FROM_ID (f, face_id);
22471 unsigned code = 0;
22473 if (face->font)
22475 code = face->font->driver->encode_char (face->font, c);
22477 if (code == FONT_INVALID_CODE)
22478 code = 0;
22480 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22482 /* Make sure X resources of the face are allocated. */
22483 #ifdef HAVE_X_WINDOWS
22484 if (display_p)
22485 #endif
22487 eassert (face != NULL);
22488 PREPARE_FACE_FOR_DISPLAY (f, face);
22491 return face;
22495 /* Get face and two-byte form of character glyph GLYPH on frame F.
22496 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22497 a pointer to a realized face that is ready for display. */
22499 static struct face *
22500 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22501 XChar2b *char2b, int *two_byte_p)
22503 struct face *face;
22504 unsigned code = 0;
22506 eassert (glyph->type == CHAR_GLYPH);
22507 face = FACE_FROM_ID (f, glyph->face_id);
22509 /* Make sure X resources of the face are allocated. */
22510 eassert (face != NULL);
22511 PREPARE_FACE_FOR_DISPLAY (f, face);
22513 if (two_byte_p)
22514 *two_byte_p = 0;
22516 if (face->font)
22518 if (CHAR_BYTE8_P (glyph->u.ch))
22519 code = CHAR_TO_BYTE8 (glyph->u.ch);
22520 else
22521 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22523 if (code == FONT_INVALID_CODE)
22524 code = 0;
22527 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22528 return face;
22532 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22533 Return 1 if FONT has a glyph for C, otherwise return 0. */
22535 static int
22536 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22538 unsigned code;
22540 if (CHAR_BYTE8_P (c))
22541 code = CHAR_TO_BYTE8 (c);
22542 else
22543 code = font->driver->encode_char (font, c);
22545 if (code == FONT_INVALID_CODE)
22546 return 0;
22547 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22548 return 1;
22552 /* Fill glyph string S with composition components specified by S->cmp.
22554 BASE_FACE is the base face of the composition.
22555 S->cmp_from is the index of the first component for S.
22557 OVERLAPS non-zero means S should draw the foreground only, and use
22558 its physical height for clipping. See also draw_glyphs.
22560 Value is the index of a component not in S. */
22562 static int
22563 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22564 int overlaps)
22566 int i;
22567 /* For all glyphs of this composition, starting at the offset
22568 S->cmp_from, until we reach the end of the definition or encounter a
22569 glyph that requires the different face, add it to S. */
22570 struct face *face;
22572 eassert (s);
22574 s->for_overlaps = overlaps;
22575 s->face = NULL;
22576 s->font = NULL;
22577 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22579 int c = COMPOSITION_GLYPH (s->cmp, i);
22581 /* TAB in a composition means display glyphs with padding space
22582 on the left or right. */
22583 if (c != '\t')
22585 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22586 -1, Qnil);
22588 face = get_char_face_and_encoding (s->f, c, face_id,
22589 s->char2b + i, 1);
22590 if (face)
22592 if (! s->face)
22594 s->face = face;
22595 s->font = s->face->font;
22597 else if (s->face != face)
22598 break;
22601 ++s->nchars;
22603 s->cmp_to = i;
22605 if (s->face == NULL)
22607 s->face = base_face->ascii_face;
22608 s->font = s->face->font;
22611 /* All glyph strings for the same composition has the same width,
22612 i.e. the width set for the first component of the composition. */
22613 s->width = s->first_glyph->pixel_width;
22615 /* If the specified font could not be loaded, use the frame's
22616 default font, but record the fact that we couldn't load it in
22617 the glyph string so that we can draw rectangles for the
22618 characters of the glyph string. */
22619 if (s->font == NULL)
22621 s->font_not_found_p = 1;
22622 s->font = FRAME_FONT (s->f);
22625 /* Adjust base line for subscript/superscript text. */
22626 s->ybase += s->first_glyph->voffset;
22628 /* This glyph string must always be drawn with 16-bit functions. */
22629 s->two_byte_p = 1;
22631 return s->cmp_to;
22634 static int
22635 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22636 int start, int end, int overlaps)
22638 struct glyph *glyph, *last;
22639 Lisp_Object lgstring;
22640 int i;
22642 s->for_overlaps = overlaps;
22643 glyph = s->row->glyphs[s->area] + start;
22644 last = s->row->glyphs[s->area] + end;
22645 s->cmp_id = glyph->u.cmp.id;
22646 s->cmp_from = glyph->slice.cmp.from;
22647 s->cmp_to = glyph->slice.cmp.to + 1;
22648 s->face = FACE_FROM_ID (s->f, face_id);
22649 lgstring = composition_gstring_from_id (s->cmp_id);
22650 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22651 glyph++;
22652 while (glyph < last
22653 && glyph->u.cmp.automatic
22654 && glyph->u.cmp.id == s->cmp_id
22655 && s->cmp_to == glyph->slice.cmp.from)
22656 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22658 for (i = s->cmp_from; i < s->cmp_to; i++)
22660 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22661 unsigned code = LGLYPH_CODE (lglyph);
22663 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22665 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22666 return glyph - s->row->glyphs[s->area];
22670 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22671 See the comment of fill_glyph_string for arguments.
22672 Value is the index of the first glyph not in S. */
22675 static int
22676 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22677 int start, int end, int overlaps)
22679 struct glyph *glyph, *last;
22680 int voffset;
22682 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22683 s->for_overlaps = overlaps;
22684 glyph = s->row->glyphs[s->area] + start;
22685 last = s->row->glyphs[s->area] + end;
22686 voffset = glyph->voffset;
22687 s->face = FACE_FROM_ID (s->f, face_id);
22688 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
22689 s->nchars = 1;
22690 s->width = glyph->pixel_width;
22691 glyph++;
22692 while (glyph < last
22693 && glyph->type == GLYPHLESS_GLYPH
22694 && glyph->voffset == voffset
22695 && glyph->face_id == face_id)
22697 s->nchars++;
22698 s->width += glyph->pixel_width;
22699 glyph++;
22701 s->ybase += voffset;
22702 return glyph - s->row->glyphs[s->area];
22706 /* Fill glyph string S from a sequence of character glyphs.
22708 FACE_ID is the face id of the string. START is the index of the
22709 first glyph to consider, END is the index of the last + 1.
22710 OVERLAPS non-zero means S should draw the foreground only, and use
22711 its physical height for clipping. See also draw_glyphs.
22713 Value is the index of the first glyph not in S. */
22715 static int
22716 fill_glyph_string (struct glyph_string *s, int face_id,
22717 int start, int end, int overlaps)
22719 struct glyph *glyph, *last;
22720 int voffset;
22721 int glyph_not_available_p;
22723 eassert (s->f == XFRAME (s->w->frame));
22724 eassert (s->nchars == 0);
22725 eassert (start >= 0 && end > start);
22727 s->for_overlaps = overlaps;
22728 glyph = s->row->glyphs[s->area] + start;
22729 last = s->row->glyphs[s->area] + end;
22730 voffset = glyph->voffset;
22731 s->padding_p = glyph->padding_p;
22732 glyph_not_available_p = glyph->glyph_not_available_p;
22734 while (glyph < last
22735 && glyph->type == CHAR_GLYPH
22736 && glyph->voffset == voffset
22737 /* Same face id implies same font, nowadays. */
22738 && glyph->face_id == face_id
22739 && glyph->glyph_not_available_p == glyph_not_available_p)
22741 int two_byte_p;
22743 s->face = get_glyph_face_and_encoding (s->f, glyph,
22744 s->char2b + s->nchars,
22745 &two_byte_p);
22746 s->two_byte_p = two_byte_p;
22747 ++s->nchars;
22748 eassert (s->nchars <= end - start);
22749 s->width += glyph->pixel_width;
22750 if (glyph++->padding_p != s->padding_p)
22751 break;
22754 s->font = s->face->font;
22756 /* If the specified font could not be loaded, use the frame's font,
22757 but record the fact that we couldn't load it in
22758 S->font_not_found_p so that we can draw rectangles for the
22759 characters of the glyph string. */
22760 if (s->font == NULL || glyph_not_available_p)
22762 s->font_not_found_p = 1;
22763 s->font = FRAME_FONT (s->f);
22766 /* Adjust base line for subscript/superscript text. */
22767 s->ybase += voffset;
22769 eassert (s->face && s->face->gc);
22770 return glyph - s->row->glyphs[s->area];
22774 /* Fill glyph string S from image glyph S->first_glyph. */
22776 static void
22777 fill_image_glyph_string (struct glyph_string *s)
22779 eassert (s->first_glyph->type == IMAGE_GLYPH);
22780 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22781 eassert (s->img);
22782 s->slice = s->first_glyph->slice.img;
22783 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22784 s->font = s->face->font;
22785 s->width = s->first_glyph->pixel_width;
22787 /* Adjust base line for subscript/superscript text. */
22788 s->ybase += s->first_glyph->voffset;
22792 /* Fill glyph string S from a sequence of stretch glyphs.
22794 START is the index of the first glyph to consider,
22795 END is the index of the last + 1.
22797 Value is the index of the first glyph not in S. */
22799 static int
22800 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22802 struct glyph *glyph, *last;
22803 int voffset, face_id;
22805 eassert (s->first_glyph->type == STRETCH_GLYPH);
22807 glyph = s->row->glyphs[s->area] + start;
22808 last = s->row->glyphs[s->area] + end;
22809 face_id = glyph->face_id;
22810 s->face = FACE_FROM_ID (s->f, face_id);
22811 s->font = s->face->font;
22812 s->width = glyph->pixel_width;
22813 s->nchars = 1;
22814 voffset = glyph->voffset;
22816 for (++glyph;
22817 (glyph < last
22818 && glyph->type == STRETCH_GLYPH
22819 && glyph->voffset == voffset
22820 && glyph->face_id == face_id);
22821 ++glyph)
22822 s->width += glyph->pixel_width;
22824 /* Adjust base line for subscript/superscript text. */
22825 s->ybase += voffset;
22827 /* The case that face->gc == 0 is handled when drawing the glyph
22828 string by calling PREPARE_FACE_FOR_DISPLAY. */
22829 eassert (s->face);
22830 return glyph - s->row->glyphs[s->area];
22833 static struct font_metrics *
22834 get_per_char_metric (struct font *font, XChar2b *char2b)
22836 static struct font_metrics metrics;
22837 unsigned code;
22839 if (! font)
22840 return NULL;
22841 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22842 if (code == FONT_INVALID_CODE)
22843 return NULL;
22844 font->driver->text_extents (font, &code, 1, &metrics);
22845 return &metrics;
22848 /* EXPORT for RIF:
22849 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22850 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22851 assumed to be zero. */
22853 void
22854 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22856 *left = *right = 0;
22858 if (glyph->type == CHAR_GLYPH)
22860 struct face *face;
22861 XChar2b char2b;
22862 struct font_metrics *pcm;
22864 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22865 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22867 if (pcm->rbearing > pcm->width)
22868 *right = pcm->rbearing - pcm->width;
22869 if (pcm->lbearing < 0)
22870 *left = -pcm->lbearing;
22873 else if (glyph->type == COMPOSITE_GLYPH)
22875 if (! glyph->u.cmp.automatic)
22877 struct composition *cmp = composition_table[glyph->u.cmp.id];
22879 if (cmp->rbearing > cmp->pixel_width)
22880 *right = cmp->rbearing - cmp->pixel_width;
22881 if (cmp->lbearing < 0)
22882 *left = - cmp->lbearing;
22884 else
22886 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22887 struct font_metrics metrics;
22889 composition_gstring_width (gstring, glyph->slice.cmp.from,
22890 glyph->slice.cmp.to + 1, &metrics);
22891 if (metrics.rbearing > metrics.width)
22892 *right = metrics.rbearing - metrics.width;
22893 if (metrics.lbearing < 0)
22894 *left = - metrics.lbearing;
22900 /* Return the index of the first glyph preceding glyph string S that
22901 is overwritten by S because of S's left overhang. Value is -1
22902 if no glyphs are overwritten. */
22904 static int
22905 left_overwritten (struct glyph_string *s)
22907 int k;
22909 if (s->left_overhang)
22911 int x = 0, i;
22912 struct glyph *glyphs = s->row->glyphs[s->area];
22913 int first = s->first_glyph - glyphs;
22915 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22916 x -= glyphs[i].pixel_width;
22918 k = i + 1;
22920 else
22921 k = -1;
22923 return k;
22927 /* Return the index of the first glyph preceding glyph string S that
22928 is overwriting S because of its right overhang. Value is -1 if no
22929 glyph in front of S overwrites S. */
22931 static int
22932 left_overwriting (struct glyph_string *s)
22934 int i, k, x;
22935 struct glyph *glyphs = s->row->glyphs[s->area];
22936 int first = s->first_glyph - glyphs;
22938 k = -1;
22939 x = 0;
22940 for (i = first - 1; i >= 0; --i)
22942 int left, right;
22943 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22944 if (x + right > 0)
22945 k = i;
22946 x -= glyphs[i].pixel_width;
22949 return k;
22953 /* Return the index of the last glyph following glyph string S that is
22954 overwritten by S because of S's right overhang. Value is -1 if
22955 no such glyph is found. */
22957 static int
22958 right_overwritten (struct glyph_string *s)
22960 int k = -1;
22962 if (s->right_overhang)
22964 int x = 0, i;
22965 struct glyph *glyphs = s->row->glyphs[s->area];
22966 int first = (s->first_glyph - glyphs
22967 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22968 int end = s->row->used[s->area];
22970 for (i = first; i < end && s->right_overhang > x; ++i)
22971 x += glyphs[i].pixel_width;
22973 k = i;
22976 return k;
22980 /* Return the index of the last glyph following glyph string S that
22981 overwrites S because of its left overhang. Value is negative
22982 if no such glyph is found. */
22984 static int
22985 right_overwriting (struct glyph_string *s)
22987 int i, k, x;
22988 int end = s->row->used[s->area];
22989 struct glyph *glyphs = s->row->glyphs[s->area];
22990 int first = (s->first_glyph - glyphs
22991 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
22993 k = -1;
22994 x = 0;
22995 for (i = first; i < end; ++i)
22997 int left, right;
22998 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22999 if (x - left < 0)
23000 k = i;
23001 x += glyphs[i].pixel_width;
23004 return k;
23008 /* Set background width of glyph string S. START is the index of the
23009 first glyph following S. LAST_X is the right-most x-position + 1
23010 in the drawing area. */
23012 static void
23013 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23015 /* If the face of this glyph string has to be drawn to the end of
23016 the drawing area, set S->extends_to_end_of_line_p. */
23018 if (start == s->row->used[s->area]
23019 && s->area == TEXT_AREA
23020 && ((s->row->fill_line_p
23021 && (s->hl == DRAW_NORMAL_TEXT
23022 || s->hl == DRAW_IMAGE_RAISED
23023 || s->hl == DRAW_IMAGE_SUNKEN))
23024 || s->hl == DRAW_MOUSE_FACE))
23025 s->extends_to_end_of_line_p = 1;
23027 /* If S extends its face to the end of the line, set its
23028 background_width to the distance to the right edge of the drawing
23029 area. */
23030 if (s->extends_to_end_of_line_p)
23031 s->background_width = last_x - s->x + 1;
23032 else
23033 s->background_width = s->width;
23037 /* Compute overhangs and x-positions for glyph string S and its
23038 predecessors, or successors. X is the starting x-position for S.
23039 BACKWARD_P non-zero means process predecessors. */
23041 static void
23042 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23044 if (backward_p)
23046 while (s)
23048 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23049 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23050 x -= s->width;
23051 s->x = x;
23052 s = s->prev;
23055 else
23057 while (s)
23059 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23060 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23061 s->x = x;
23062 x += s->width;
23063 s = s->next;
23070 /* The following macros are only called from draw_glyphs below.
23071 They reference the following parameters of that function directly:
23072 `w', `row', `area', and `overlap_p'
23073 as well as the following local variables:
23074 `s', `f', and `hdc' (in W32) */
23076 #ifdef HAVE_NTGUI
23077 /* On W32, silently add local `hdc' variable to argument list of
23078 init_glyph_string. */
23079 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23080 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23081 #else
23082 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23083 init_glyph_string (s, char2b, w, row, area, start, hl)
23084 #endif
23086 /* Add a glyph string for a stretch glyph to the list of strings
23087 between HEAD and TAIL. START is the index of the stretch glyph in
23088 row area AREA of glyph row ROW. END is the index of the last glyph
23089 in that glyph row area. X is the current output position assigned
23090 to the new glyph string constructed. HL overrides that face of the
23091 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23092 is the right-most x-position of the drawing area. */
23094 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23095 and below -- keep them on one line. */
23096 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23097 do \
23099 s = alloca (sizeof *s); \
23100 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23101 START = fill_stretch_glyph_string (s, START, END); \
23102 append_glyph_string (&HEAD, &TAIL, s); \
23103 s->x = (X); \
23105 while (0)
23108 /* Add a glyph string for an image glyph to the list of strings
23109 between HEAD and TAIL. START is the index of the image glyph in
23110 row area AREA of glyph row ROW. END is the index of the last glyph
23111 in that glyph row area. X is the current output position assigned
23112 to the new glyph string constructed. HL overrides that face of the
23113 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23114 is the right-most x-position of the drawing area. */
23116 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23117 do \
23119 s = alloca (sizeof *s); \
23120 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23121 fill_image_glyph_string (s); \
23122 append_glyph_string (&HEAD, &TAIL, s); \
23123 ++START; \
23124 s->x = (X); \
23126 while (0)
23129 /* Add a glyph string for a sequence of character glyphs to the list
23130 of strings between HEAD and TAIL. START is the index of the first
23131 glyph in row area AREA of glyph row ROW that is part of the new
23132 glyph string. END is the index of the last glyph in that glyph row
23133 area. X is the current output position assigned to the new glyph
23134 string constructed. HL overrides that face of the glyph; e.g. it
23135 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23136 right-most x-position of the drawing area. */
23138 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23139 do \
23141 int face_id; \
23142 XChar2b *char2b; \
23144 face_id = (row)->glyphs[area][START].face_id; \
23146 s = alloca (sizeof *s); \
23147 char2b = alloca ((END - START) * sizeof *char2b); \
23148 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23149 append_glyph_string (&HEAD, &TAIL, s); \
23150 s->x = (X); \
23151 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23153 while (0)
23156 /* Add a glyph string for a composite sequence to the list of strings
23157 between HEAD and TAIL. START is the index of the first glyph in
23158 row area AREA of glyph row ROW that is part of the new glyph
23159 string. END is the index of the last glyph in that glyph row area.
23160 X is the current output position assigned to the new glyph string
23161 constructed. HL overrides that face of the glyph; e.g. it is
23162 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23163 x-position of the drawing area. */
23165 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23166 do { \
23167 int face_id = (row)->glyphs[area][START].face_id; \
23168 struct face *base_face = FACE_FROM_ID (f, face_id); \
23169 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23170 struct composition *cmp = composition_table[cmp_id]; \
23171 XChar2b *char2b; \
23172 struct glyph_string *first_s = NULL; \
23173 int n; \
23175 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23177 /* Make glyph_strings for each glyph sequence that is drawable by \
23178 the same face, and append them to HEAD/TAIL. */ \
23179 for (n = 0; n < cmp->glyph_len;) \
23181 s = alloca (sizeof *s); \
23182 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23183 append_glyph_string (&(HEAD), &(TAIL), s); \
23184 s->cmp = cmp; \
23185 s->cmp_from = n; \
23186 s->x = (X); \
23187 if (n == 0) \
23188 first_s = s; \
23189 n = fill_composite_glyph_string (s, base_face, overlaps); \
23192 ++START; \
23193 s = first_s; \
23194 } while (0)
23197 /* Add a glyph string for a glyph-string sequence to the list of strings
23198 between HEAD and TAIL. */
23200 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23201 do { \
23202 int face_id; \
23203 XChar2b *char2b; \
23204 Lisp_Object gstring; \
23206 face_id = (row)->glyphs[area][START].face_id; \
23207 gstring = (composition_gstring_from_id \
23208 ((row)->glyphs[area][START].u.cmp.id)); \
23209 s = alloca (sizeof *s); \
23210 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23211 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23212 append_glyph_string (&(HEAD), &(TAIL), s); \
23213 s->x = (X); \
23214 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23215 } while (0)
23218 /* Add a glyph string for a sequence of glyphless character's glyphs
23219 to the list of strings between HEAD and TAIL. The meanings of
23220 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23222 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23223 do \
23225 int face_id; \
23227 face_id = (row)->glyphs[area][START].face_id; \
23229 s = alloca (sizeof *s); \
23230 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23231 append_glyph_string (&HEAD, &TAIL, s); \
23232 s->x = (X); \
23233 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23234 overlaps); \
23236 while (0)
23239 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23240 of AREA of glyph row ROW on window W between indices START and END.
23241 HL overrides the face for drawing glyph strings, e.g. it is
23242 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23243 x-positions of the drawing area.
23245 This is an ugly monster macro construct because we must use alloca
23246 to allocate glyph strings (because draw_glyphs can be called
23247 asynchronously). */
23249 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23250 do \
23252 HEAD = TAIL = NULL; \
23253 while (START < END) \
23255 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23256 switch (first_glyph->type) \
23258 case CHAR_GLYPH: \
23259 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23260 HL, X, LAST_X); \
23261 break; \
23263 case COMPOSITE_GLYPH: \
23264 if (first_glyph->u.cmp.automatic) \
23265 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23266 HL, X, LAST_X); \
23267 else \
23268 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23269 HL, X, LAST_X); \
23270 break; \
23272 case STRETCH_GLYPH: \
23273 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23274 HL, X, LAST_X); \
23275 break; \
23277 case IMAGE_GLYPH: \
23278 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23279 HL, X, LAST_X); \
23280 break; \
23282 case GLYPHLESS_GLYPH: \
23283 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23284 HL, X, LAST_X); \
23285 break; \
23287 default: \
23288 emacs_abort (); \
23291 if (s) \
23293 set_glyph_string_background_width (s, START, LAST_X); \
23294 (X) += s->width; \
23297 } while (0)
23300 /* Draw glyphs between START and END in AREA of ROW on window W,
23301 starting at x-position X. X is relative to AREA in W. HL is a
23302 face-override with the following meaning:
23304 DRAW_NORMAL_TEXT draw normally
23305 DRAW_CURSOR draw in cursor face
23306 DRAW_MOUSE_FACE draw in mouse face.
23307 DRAW_INVERSE_VIDEO draw in mode line face
23308 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23309 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23311 If OVERLAPS is non-zero, draw only the foreground of characters and
23312 clip to the physical height of ROW. Non-zero value also defines
23313 the overlapping part to be drawn:
23315 OVERLAPS_PRED overlap with preceding rows
23316 OVERLAPS_SUCC overlap with succeeding rows
23317 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23318 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23320 Value is the x-position reached, relative to AREA of W. */
23322 static int
23323 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23324 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23325 enum draw_glyphs_face hl, int overlaps)
23327 struct glyph_string *head, *tail;
23328 struct glyph_string *s;
23329 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23330 int i, j, x_reached, last_x, area_left = 0;
23331 struct frame *f = XFRAME (WINDOW_FRAME (w));
23332 DECLARE_HDC (hdc);
23334 ALLOCATE_HDC (hdc, f);
23336 /* Let's rather be paranoid than getting a SEGV. */
23337 end = min (end, row->used[area]);
23338 start = clip_to_bounds (0, start, end);
23340 /* Translate X to frame coordinates. Set last_x to the right
23341 end of the drawing area. */
23342 if (row->full_width_p)
23344 /* X is relative to the left edge of W, without scroll bars
23345 or fringes. */
23346 area_left = WINDOW_LEFT_EDGE_X (w);
23347 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23349 else
23351 area_left = window_box_left (w, area);
23352 last_x = area_left + window_box_width (w, area);
23354 x += area_left;
23356 /* Build a doubly-linked list of glyph_string structures between
23357 head and tail from what we have to draw. Note that the macro
23358 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23359 the reason we use a separate variable `i'. */
23360 i = start;
23361 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23362 if (tail)
23363 x_reached = tail->x + tail->background_width;
23364 else
23365 x_reached = x;
23367 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23368 the row, redraw some glyphs in front or following the glyph
23369 strings built above. */
23370 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23372 struct glyph_string *h, *t;
23373 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23374 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23375 int check_mouse_face = 0;
23376 int dummy_x = 0;
23378 /* If mouse highlighting is on, we may need to draw adjacent
23379 glyphs using mouse-face highlighting. */
23380 if (area == TEXT_AREA && row->mouse_face_p
23381 && hlinfo->mouse_face_beg_row >= 0
23382 && hlinfo->mouse_face_end_row >= 0)
23384 struct glyph_row *mouse_beg_row, *mouse_end_row;
23386 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23387 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23389 if (row >= mouse_beg_row && row <= mouse_end_row)
23391 check_mouse_face = 1;
23392 mouse_beg_col = (row == mouse_beg_row)
23393 ? hlinfo->mouse_face_beg_col : 0;
23394 mouse_end_col = (row == mouse_end_row)
23395 ? hlinfo->mouse_face_end_col
23396 : row->used[TEXT_AREA];
23400 /* Compute overhangs for all glyph strings. */
23401 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23402 for (s = head; s; s = s->next)
23403 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23405 /* Prepend glyph strings for glyphs in front of the first glyph
23406 string that are overwritten because of the first glyph
23407 string's left overhang. The background of all strings
23408 prepended must be drawn because the first glyph string
23409 draws over it. */
23410 i = left_overwritten (head);
23411 if (i >= 0)
23413 enum draw_glyphs_face overlap_hl;
23415 /* If this row contains mouse highlighting, attempt to draw
23416 the overlapped glyphs with the correct highlight. This
23417 code fails if the overlap encompasses more than one glyph
23418 and mouse-highlight spans only some of these glyphs.
23419 However, making it work perfectly involves a lot more
23420 code, and I don't know if the pathological case occurs in
23421 practice, so we'll stick to this for now. --- cyd */
23422 if (check_mouse_face
23423 && mouse_beg_col < start && mouse_end_col > i)
23424 overlap_hl = DRAW_MOUSE_FACE;
23425 else
23426 overlap_hl = DRAW_NORMAL_TEXT;
23428 j = i;
23429 BUILD_GLYPH_STRINGS (j, start, h, t,
23430 overlap_hl, dummy_x, last_x);
23431 start = i;
23432 compute_overhangs_and_x (t, head->x, 1);
23433 prepend_glyph_string_lists (&head, &tail, h, t);
23434 clip_head = head;
23437 /* Prepend glyph strings for glyphs in front of the first glyph
23438 string that overwrite that glyph string because of their
23439 right overhang. For these strings, only the foreground must
23440 be drawn, because it draws over the glyph string at `head'.
23441 The background must not be drawn because this would overwrite
23442 right overhangs of preceding glyphs for which no glyph
23443 strings exist. */
23444 i = left_overwriting (head);
23445 if (i >= 0)
23447 enum draw_glyphs_face overlap_hl;
23449 if (check_mouse_face
23450 && mouse_beg_col < start && mouse_end_col > i)
23451 overlap_hl = DRAW_MOUSE_FACE;
23452 else
23453 overlap_hl = DRAW_NORMAL_TEXT;
23455 clip_head = head;
23456 BUILD_GLYPH_STRINGS (i, start, h, t,
23457 overlap_hl, dummy_x, last_x);
23458 for (s = h; s; s = s->next)
23459 s->background_filled_p = 1;
23460 compute_overhangs_and_x (t, head->x, 1);
23461 prepend_glyph_string_lists (&head, &tail, h, t);
23464 /* Append glyphs strings for glyphs following the last glyph
23465 string tail that are overwritten by tail. The background of
23466 these strings has to be drawn because tail's foreground draws
23467 over it. */
23468 i = right_overwritten (tail);
23469 if (i >= 0)
23471 enum draw_glyphs_face overlap_hl;
23473 if (check_mouse_face
23474 && mouse_beg_col < i && mouse_end_col > end)
23475 overlap_hl = DRAW_MOUSE_FACE;
23476 else
23477 overlap_hl = DRAW_NORMAL_TEXT;
23479 BUILD_GLYPH_STRINGS (end, i, h, t,
23480 overlap_hl, x, last_x);
23481 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23482 we don't have `end = i;' here. */
23483 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23484 append_glyph_string_lists (&head, &tail, h, t);
23485 clip_tail = tail;
23488 /* Append glyph strings for glyphs following the last glyph
23489 string tail that overwrite tail. The foreground of such
23490 glyphs has to be drawn because it writes into the background
23491 of tail. The background must not be drawn because it could
23492 paint over the foreground of following glyphs. */
23493 i = right_overwriting (tail);
23494 if (i >= 0)
23496 enum draw_glyphs_face overlap_hl;
23497 if (check_mouse_face
23498 && mouse_beg_col < i && mouse_end_col > end)
23499 overlap_hl = DRAW_MOUSE_FACE;
23500 else
23501 overlap_hl = DRAW_NORMAL_TEXT;
23503 clip_tail = tail;
23504 i++; /* We must include the Ith glyph. */
23505 BUILD_GLYPH_STRINGS (end, i, h, t,
23506 overlap_hl, x, last_x);
23507 for (s = h; s; s = s->next)
23508 s->background_filled_p = 1;
23509 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23510 append_glyph_string_lists (&head, &tail, h, t);
23512 if (clip_head || clip_tail)
23513 for (s = head; s; s = s->next)
23515 s->clip_head = clip_head;
23516 s->clip_tail = clip_tail;
23520 /* Draw all strings. */
23521 for (s = head; s; s = s->next)
23522 FRAME_RIF (f)->draw_glyph_string (s);
23524 #ifndef HAVE_NS
23525 /* When focus a sole frame and move horizontally, this sets on_p to 0
23526 causing a failure to erase prev cursor position. */
23527 if (area == TEXT_AREA
23528 && !row->full_width_p
23529 /* When drawing overlapping rows, only the glyph strings'
23530 foreground is drawn, which doesn't erase a cursor
23531 completely. */
23532 && !overlaps)
23534 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23535 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23536 : (tail ? tail->x + tail->background_width : x));
23537 x0 -= area_left;
23538 x1 -= area_left;
23540 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23541 row->y, MATRIX_ROW_BOTTOM_Y (row));
23543 #endif
23545 /* Value is the x-position up to which drawn, relative to AREA of W.
23546 This doesn't include parts drawn because of overhangs. */
23547 if (row->full_width_p)
23548 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23549 else
23550 x_reached -= area_left;
23552 RELEASE_HDC (hdc, f);
23554 return x_reached;
23557 /* Expand row matrix if too narrow. Don't expand if area
23558 is not present. */
23560 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23562 if (!fonts_changed_p \
23563 && (it->glyph_row->glyphs[area] \
23564 < it->glyph_row->glyphs[area + 1])) \
23566 it->w->ncols_scale_factor++; \
23567 fonts_changed_p = 1; \
23571 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23572 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23574 static void
23575 append_glyph (struct it *it)
23577 struct glyph *glyph;
23578 enum glyph_row_area area = it->area;
23580 eassert (it->glyph_row);
23581 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23583 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23584 if (glyph < it->glyph_row->glyphs[area + 1])
23586 /* If the glyph row is reversed, we need to prepend the glyph
23587 rather than append it. */
23588 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23590 struct glyph *g;
23592 /* Make room for the additional glyph. */
23593 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23594 g[1] = *g;
23595 glyph = it->glyph_row->glyphs[area];
23597 glyph->charpos = CHARPOS (it->position);
23598 glyph->object = it->object;
23599 if (it->pixel_width > 0)
23601 glyph->pixel_width = it->pixel_width;
23602 glyph->padding_p = 0;
23604 else
23606 /* Assure at least 1-pixel width. Otherwise, cursor can't
23607 be displayed correctly. */
23608 glyph->pixel_width = 1;
23609 glyph->padding_p = 1;
23611 glyph->ascent = it->ascent;
23612 glyph->descent = it->descent;
23613 glyph->voffset = it->voffset;
23614 glyph->type = CHAR_GLYPH;
23615 glyph->avoid_cursor_p = it->avoid_cursor_p;
23616 glyph->multibyte_p = it->multibyte_p;
23617 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23619 /* In R2L rows, the left and the right box edges need to be
23620 drawn in reverse direction. */
23621 glyph->right_box_line_p = it->start_of_box_run_p;
23622 glyph->left_box_line_p = it->end_of_box_run_p;
23624 else
23626 glyph->left_box_line_p = it->start_of_box_run_p;
23627 glyph->right_box_line_p = it->end_of_box_run_p;
23629 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23630 || it->phys_descent > it->descent);
23631 glyph->glyph_not_available_p = it->glyph_not_available_p;
23632 glyph->face_id = it->face_id;
23633 glyph->u.ch = it->char_to_display;
23634 glyph->slice.img = null_glyph_slice;
23635 glyph->font_type = FONT_TYPE_UNKNOWN;
23636 if (it->bidi_p)
23638 glyph->resolved_level = it->bidi_it.resolved_level;
23639 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23640 emacs_abort ();
23641 glyph->bidi_type = it->bidi_it.type;
23643 else
23645 glyph->resolved_level = 0;
23646 glyph->bidi_type = UNKNOWN_BT;
23648 ++it->glyph_row->used[area];
23650 else
23651 IT_EXPAND_MATRIX_WIDTH (it, area);
23654 /* Store one glyph for the composition IT->cmp_it.id in
23655 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23656 non-null. */
23658 static void
23659 append_composite_glyph (struct it *it)
23661 struct glyph *glyph;
23662 enum glyph_row_area area = it->area;
23664 eassert (it->glyph_row);
23666 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23667 if (glyph < it->glyph_row->glyphs[area + 1])
23669 /* If the glyph row is reversed, we need to prepend the glyph
23670 rather than append it. */
23671 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23673 struct glyph *g;
23675 /* Make room for the new glyph. */
23676 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23677 g[1] = *g;
23678 glyph = it->glyph_row->glyphs[it->area];
23680 glyph->charpos = it->cmp_it.charpos;
23681 glyph->object = it->object;
23682 glyph->pixel_width = it->pixel_width;
23683 glyph->ascent = it->ascent;
23684 glyph->descent = it->descent;
23685 glyph->voffset = it->voffset;
23686 glyph->type = COMPOSITE_GLYPH;
23687 if (it->cmp_it.ch < 0)
23689 glyph->u.cmp.automatic = 0;
23690 glyph->u.cmp.id = it->cmp_it.id;
23691 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23693 else
23695 glyph->u.cmp.automatic = 1;
23696 glyph->u.cmp.id = it->cmp_it.id;
23697 glyph->slice.cmp.from = it->cmp_it.from;
23698 glyph->slice.cmp.to = it->cmp_it.to - 1;
23700 glyph->avoid_cursor_p = it->avoid_cursor_p;
23701 glyph->multibyte_p = it->multibyte_p;
23702 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23704 /* In R2L rows, the left and the right box edges need to be
23705 drawn in reverse direction. */
23706 glyph->right_box_line_p = it->start_of_box_run_p;
23707 glyph->left_box_line_p = it->end_of_box_run_p;
23709 else
23711 glyph->left_box_line_p = it->start_of_box_run_p;
23712 glyph->right_box_line_p = it->end_of_box_run_p;
23714 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23715 || it->phys_descent > it->descent);
23716 glyph->padding_p = 0;
23717 glyph->glyph_not_available_p = 0;
23718 glyph->face_id = it->face_id;
23719 glyph->font_type = FONT_TYPE_UNKNOWN;
23720 if (it->bidi_p)
23722 glyph->resolved_level = it->bidi_it.resolved_level;
23723 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23724 emacs_abort ();
23725 glyph->bidi_type = it->bidi_it.type;
23727 ++it->glyph_row->used[area];
23729 else
23730 IT_EXPAND_MATRIX_WIDTH (it, area);
23734 /* Change IT->ascent and IT->height according to the setting of
23735 IT->voffset. */
23737 static void
23738 take_vertical_position_into_account (struct it *it)
23740 if (it->voffset)
23742 if (it->voffset < 0)
23743 /* Increase the ascent so that we can display the text higher
23744 in the line. */
23745 it->ascent -= it->voffset;
23746 else
23747 /* Increase the descent so that we can display the text lower
23748 in the line. */
23749 it->descent += it->voffset;
23754 /* Produce glyphs/get display metrics for the image IT is loaded with.
23755 See the description of struct display_iterator in dispextern.h for
23756 an overview of struct display_iterator. */
23758 static void
23759 produce_image_glyph (struct it *it)
23761 struct image *img;
23762 struct face *face;
23763 int glyph_ascent, crop;
23764 struct glyph_slice slice;
23766 eassert (it->what == IT_IMAGE);
23768 face = FACE_FROM_ID (it->f, it->face_id);
23769 eassert (face);
23770 /* Make sure X resources of the face is loaded. */
23771 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23773 if (it->image_id < 0)
23775 /* Fringe bitmap. */
23776 it->ascent = it->phys_ascent = 0;
23777 it->descent = it->phys_descent = 0;
23778 it->pixel_width = 0;
23779 it->nglyphs = 0;
23780 return;
23783 img = IMAGE_FROM_ID (it->f, it->image_id);
23784 eassert (img);
23785 /* Make sure X resources of the image is loaded. */
23786 prepare_image_for_display (it->f, img);
23788 slice.x = slice.y = 0;
23789 slice.width = img->width;
23790 slice.height = img->height;
23792 if (INTEGERP (it->slice.x))
23793 slice.x = XINT (it->slice.x);
23794 else if (FLOATP (it->slice.x))
23795 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23797 if (INTEGERP (it->slice.y))
23798 slice.y = XINT (it->slice.y);
23799 else if (FLOATP (it->slice.y))
23800 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23802 if (INTEGERP (it->slice.width))
23803 slice.width = XINT (it->slice.width);
23804 else if (FLOATP (it->slice.width))
23805 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23807 if (INTEGERP (it->slice.height))
23808 slice.height = XINT (it->slice.height);
23809 else if (FLOATP (it->slice.height))
23810 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23812 if (slice.x >= img->width)
23813 slice.x = img->width;
23814 if (slice.y >= img->height)
23815 slice.y = img->height;
23816 if (slice.x + slice.width >= img->width)
23817 slice.width = img->width - slice.x;
23818 if (slice.y + slice.height > img->height)
23819 slice.height = img->height - slice.y;
23821 if (slice.width == 0 || slice.height == 0)
23822 return;
23824 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23826 it->descent = slice.height - glyph_ascent;
23827 if (slice.y == 0)
23828 it->descent += img->vmargin;
23829 if (slice.y + slice.height == img->height)
23830 it->descent += img->vmargin;
23831 it->phys_descent = it->descent;
23833 it->pixel_width = slice.width;
23834 if (slice.x == 0)
23835 it->pixel_width += img->hmargin;
23836 if (slice.x + slice.width == img->width)
23837 it->pixel_width += img->hmargin;
23839 /* It's quite possible for images to have an ascent greater than
23840 their height, so don't get confused in that case. */
23841 if (it->descent < 0)
23842 it->descent = 0;
23844 it->nglyphs = 1;
23846 if (face->box != FACE_NO_BOX)
23848 if (face->box_line_width > 0)
23850 if (slice.y == 0)
23851 it->ascent += face->box_line_width;
23852 if (slice.y + slice.height == img->height)
23853 it->descent += face->box_line_width;
23856 if (it->start_of_box_run_p && slice.x == 0)
23857 it->pixel_width += eabs (face->box_line_width);
23858 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23859 it->pixel_width += eabs (face->box_line_width);
23862 take_vertical_position_into_account (it);
23864 /* Automatically crop wide image glyphs at right edge so we can
23865 draw the cursor on same display row. */
23866 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23867 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23869 it->pixel_width -= crop;
23870 slice.width -= crop;
23873 if (it->glyph_row)
23875 struct glyph *glyph;
23876 enum glyph_row_area area = it->area;
23878 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23879 if (glyph < it->glyph_row->glyphs[area + 1])
23881 glyph->charpos = CHARPOS (it->position);
23882 glyph->object = it->object;
23883 glyph->pixel_width = it->pixel_width;
23884 glyph->ascent = glyph_ascent;
23885 glyph->descent = it->descent;
23886 glyph->voffset = it->voffset;
23887 glyph->type = IMAGE_GLYPH;
23888 glyph->avoid_cursor_p = it->avoid_cursor_p;
23889 glyph->multibyte_p = it->multibyte_p;
23890 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23892 /* In R2L rows, the left and the right box edges need to be
23893 drawn in reverse direction. */
23894 glyph->right_box_line_p = it->start_of_box_run_p;
23895 glyph->left_box_line_p = it->end_of_box_run_p;
23897 else
23899 glyph->left_box_line_p = it->start_of_box_run_p;
23900 glyph->right_box_line_p = it->end_of_box_run_p;
23902 glyph->overlaps_vertically_p = 0;
23903 glyph->padding_p = 0;
23904 glyph->glyph_not_available_p = 0;
23905 glyph->face_id = it->face_id;
23906 glyph->u.img_id = img->id;
23907 glyph->slice.img = slice;
23908 glyph->font_type = FONT_TYPE_UNKNOWN;
23909 if (it->bidi_p)
23911 glyph->resolved_level = it->bidi_it.resolved_level;
23912 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23913 emacs_abort ();
23914 glyph->bidi_type = it->bidi_it.type;
23916 ++it->glyph_row->used[area];
23918 else
23919 IT_EXPAND_MATRIX_WIDTH (it, area);
23924 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23925 of the glyph, WIDTH and HEIGHT are the width and height of the
23926 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23928 static void
23929 append_stretch_glyph (struct it *it, Lisp_Object object,
23930 int width, int height, int ascent)
23932 struct glyph *glyph;
23933 enum glyph_row_area area = it->area;
23935 eassert (ascent >= 0 && ascent <= height);
23937 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23938 if (glyph < it->glyph_row->glyphs[area + 1])
23940 /* If the glyph row is reversed, we need to prepend the glyph
23941 rather than append it. */
23942 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23944 struct glyph *g;
23946 /* Make room for the additional glyph. */
23947 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23948 g[1] = *g;
23949 glyph = it->glyph_row->glyphs[area];
23951 glyph->charpos = CHARPOS (it->position);
23952 glyph->object = object;
23953 glyph->pixel_width = width;
23954 glyph->ascent = ascent;
23955 glyph->descent = height - ascent;
23956 glyph->voffset = it->voffset;
23957 glyph->type = STRETCH_GLYPH;
23958 glyph->avoid_cursor_p = it->avoid_cursor_p;
23959 glyph->multibyte_p = it->multibyte_p;
23960 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23962 /* In R2L rows, the left and the right box edges need to be
23963 drawn in reverse direction. */
23964 glyph->right_box_line_p = it->start_of_box_run_p;
23965 glyph->left_box_line_p = it->end_of_box_run_p;
23967 else
23969 glyph->left_box_line_p = it->start_of_box_run_p;
23970 glyph->right_box_line_p = it->end_of_box_run_p;
23972 glyph->overlaps_vertically_p = 0;
23973 glyph->padding_p = 0;
23974 glyph->glyph_not_available_p = 0;
23975 glyph->face_id = it->face_id;
23976 glyph->u.stretch.ascent = ascent;
23977 glyph->u.stretch.height = height;
23978 glyph->slice.img = null_glyph_slice;
23979 glyph->font_type = FONT_TYPE_UNKNOWN;
23980 if (it->bidi_p)
23982 glyph->resolved_level = it->bidi_it.resolved_level;
23983 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23984 emacs_abort ();
23985 glyph->bidi_type = it->bidi_it.type;
23987 else
23989 glyph->resolved_level = 0;
23990 glyph->bidi_type = UNKNOWN_BT;
23992 ++it->glyph_row->used[area];
23994 else
23995 IT_EXPAND_MATRIX_WIDTH (it, area);
23998 #endif /* HAVE_WINDOW_SYSTEM */
24000 /* Produce a stretch glyph for iterator IT. IT->object is the value
24001 of the glyph property displayed. The value must be a list
24002 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24003 being recognized:
24005 1. `:width WIDTH' specifies that the space should be WIDTH *
24006 canonical char width wide. WIDTH may be an integer or floating
24007 point number.
24009 2. `:relative-width FACTOR' specifies that the width of the stretch
24010 should be computed from the width of the first character having the
24011 `glyph' property, and should be FACTOR times that width.
24013 3. `:align-to HPOS' specifies that the space should be wide enough
24014 to reach HPOS, a value in canonical character units.
24016 Exactly one of the above pairs must be present.
24018 4. `:height HEIGHT' specifies that the height of the stretch produced
24019 should be HEIGHT, measured in canonical character units.
24021 5. `:relative-height FACTOR' specifies that the height of the
24022 stretch should be FACTOR times the height of the characters having
24023 the glyph property.
24025 Either none or exactly one of 4 or 5 must be present.
24027 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24028 of the stretch should be used for the ascent of the stretch.
24029 ASCENT must be in the range 0 <= ASCENT <= 100. */
24031 void
24032 produce_stretch_glyph (struct it *it)
24034 /* (space :width WIDTH :height HEIGHT ...) */
24035 Lisp_Object prop, plist;
24036 int width = 0, height = 0, align_to = -1;
24037 int zero_width_ok_p = 0;
24038 double tem;
24039 struct font *font = NULL;
24041 #ifdef HAVE_WINDOW_SYSTEM
24042 int ascent = 0;
24043 int zero_height_ok_p = 0;
24045 if (FRAME_WINDOW_P (it->f))
24047 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24048 font = face->font ? face->font : FRAME_FONT (it->f);
24049 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24051 #endif
24053 /* List should start with `space'. */
24054 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24055 plist = XCDR (it->object);
24057 /* Compute the width of the stretch. */
24058 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24059 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24061 /* Absolute width `:width WIDTH' specified and valid. */
24062 zero_width_ok_p = 1;
24063 width = (int)tem;
24065 #ifdef HAVE_WINDOW_SYSTEM
24066 else if (FRAME_WINDOW_P (it->f)
24067 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24069 /* Relative width `:relative-width FACTOR' specified and valid.
24070 Compute the width of the characters having the `glyph'
24071 property. */
24072 struct it it2;
24073 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24075 it2 = *it;
24076 if (it->multibyte_p)
24077 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24078 else
24080 it2.c = it2.char_to_display = *p, it2.len = 1;
24081 if (! ASCII_CHAR_P (it2.c))
24082 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24085 it2.glyph_row = NULL;
24086 it2.what = IT_CHARACTER;
24087 x_produce_glyphs (&it2);
24088 width = NUMVAL (prop) * it2.pixel_width;
24090 #endif /* HAVE_WINDOW_SYSTEM */
24091 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24092 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24094 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24095 align_to = (align_to < 0
24097 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24098 else if (align_to < 0)
24099 align_to = window_box_left_offset (it->w, TEXT_AREA);
24100 width = max (0, (int)tem + align_to - it->current_x);
24101 zero_width_ok_p = 1;
24103 else
24104 /* Nothing specified -> width defaults to canonical char width. */
24105 width = FRAME_COLUMN_WIDTH (it->f);
24107 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24108 width = 1;
24110 #ifdef HAVE_WINDOW_SYSTEM
24111 /* Compute height. */
24112 if (FRAME_WINDOW_P (it->f))
24114 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24115 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24117 height = (int)tem;
24118 zero_height_ok_p = 1;
24120 else if (prop = Fplist_get (plist, QCrelative_height),
24121 NUMVAL (prop) > 0)
24122 height = FONT_HEIGHT (font) * NUMVAL (prop);
24123 else
24124 height = FONT_HEIGHT (font);
24126 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24127 height = 1;
24129 /* Compute percentage of height used for ascent. If
24130 `:ascent ASCENT' is present and valid, use that. Otherwise,
24131 derive the ascent from the font in use. */
24132 if (prop = Fplist_get (plist, QCascent),
24133 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24134 ascent = height * NUMVAL (prop) / 100.0;
24135 else if (!NILP (prop)
24136 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24137 ascent = min (max (0, (int)tem), height);
24138 else
24139 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24141 else
24142 #endif /* HAVE_WINDOW_SYSTEM */
24143 height = 1;
24145 if (width > 0 && it->line_wrap != TRUNCATE
24146 && it->current_x + width > it->last_visible_x)
24148 width = it->last_visible_x - it->current_x;
24149 #ifdef HAVE_WINDOW_SYSTEM
24150 /* Subtract one more pixel from the stretch width, but only on
24151 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24152 width -= FRAME_WINDOW_P (it->f);
24153 #endif
24156 if (width > 0 && height > 0 && it->glyph_row)
24158 Lisp_Object o_object = it->object;
24159 Lisp_Object object = it->stack[it->sp - 1].string;
24160 int n = width;
24162 if (!STRINGP (object))
24163 object = it->w->contents;
24164 #ifdef HAVE_WINDOW_SYSTEM
24165 if (FRAME_WINDOW_P (it->f))
24166 append_stretch_glyph (it, object, width, height, ascent);
24167 else
24168 #endif
24170 it->object = object;
24171 it->char_to_display = ' ';
24172 it->pixel_width = it->len = 1;
24173 while (n--)
24174 tty_append_glyph (it);
24175 it->object = o_object;
24179 it->pixel_width = width;
24180 #ifdef HAVE_WINDOW_SYSTEM
24181 if (FRAME_WINDOW_P (it->f))
24183 it->ascent = it->phys_ascent = ascent;
24184 it->descent = it->phys_descent = height - it->ascent;
24185 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24186 take_vertical_position_into_account (it);
24188 else
24189 #endif
24190 it->nglyphs = width;
24193 /* Get information about special display element WHAT in an
24194 environment described by IT. WHAT is one of IT_TRUNCATION or
24195 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24196 non-null glyph_row member. This function ensures that fields like
24197 face_id, c, len of IT are left untouched. */
24199 static void
24200 produce_special_glyphs (struct it *it, enum display_element_type what)
24202 struct it temp_it;
24203 Lisp_Object gc;
24204 GLYPH glyph;
24206 temp_it = *it;
24207 temp_it.object = make_number (0);
24208 memset (&temp_it.current, 0, sizeof temp_it.current);
24210 if (what == IT_CONTINUATION)
24212 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24213 if (it->bidi_it.paragraph_dir == R2L)
24214 SET_GLYPH_FROM_CHAR (glyph, '/');
24215 else
24216 SET_GLYPH_FROM_CHAR (glyph, '\\');
24217 if (it->dp
24218 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24220 /* FIXME: Should we mirror GC for R2L lines? */
24221 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24222 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24225 else if (what == IT_TRUNCATION)
24227 /* Truncation glyph. */
24228 SET_GLYPH_FROM_CHAR (glyph, '$');
24229 if (it->dp
24230 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24232 /* FIXME: Should we mirror GC for R2L lines? */
24233 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24234 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24237 else
24238 emacs_abort ();
24240 #ifdef HAVE_WINDOW_SYSTEM
24241 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24242 is turned off, we precede the truncation/continuation glyphs by a
24243 stretch glyph whose width is computed such that these special
24244 glyphs are aligned at the window margin, even when very different
24245 fonts are used in different glyph rows. */
24246 if (FRAME_WINDOW_P (temp_it.f)
24247 /* init_iterator calls this with it->glyph_row == NULL, and it
24248 wants only the pixel width of the truncation/continuation
24249 glyphs. */
24250 && temp_it.glyph_row
24251 /* insert_left_trunc_glyphs calls us at the beginning of the
24252 row, and it has its own calculation of the stretch glyph
24253 width. */
24254 && temp_it.glyph_row->used[TEXT_AREA] > 0
24255 && (temp_it.glyph_row->reversed_p
24256 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24257 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24259 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24261 if (stretch_width > 0)
24263 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24264 struct font *font =
24265 face->font ? face->font : FRAME_FONT (temp_it.f);
24266 int stretch_ascent =
24267 (((temp_it.ascent + temp_it.descent)
24268 * FONT_BASE (font)) / FONT_HEIGHT (font));
24270 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24271 temp_it.ascent + temp_it.descent,
24272 stretch_ascent);
24275 #endif
24277 temp_it.dp = NULL;
24278 temp_it.what = IT_CHARACTER;
24279 temp_it.len = 1;
24280 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24281 temp_it.face_id = GLYPH_FACE (glyph);
24282 temp_it.len = CHAR_BYTES (temp_it.c);
24284 PRODUCE_GLYPHS (&temp_it);
24285 it->pixel_width = temp_it.pixel_width;
24286 it->nglyphs = temp_it.pixel_width;
24289 #ifdef HAVE_WINDOW_SYSTEM
24291 /* Calculate line-height and line-spacing properties.
24292 An integer value specifies explicit pixel value.
24293 A float value specifies relative value to current face height.
24294 A cons (float . face-name) specifies relative value to
24295 height of specified face font.
24297 Returns height in pixels, or nil. */
24300 static Lisp_Object
24301 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24302 int boff, int override)
24304 Lisp_Object face_name = Qnil;
24305 int ascent, descent, height;
24307 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24308 return val;
24310 if (CONSP (val))
24312 face_name = XCAR (val);
24313 val = XCDR (val);
24314 if (!NUMBERP (val))
24315 val = make_number (1);
24316 if (NILP (face_name))
24318 height = it->ascent + it->descent;
24319 goto scale;
24323 if (NILP (face_name))
24325 font = FRAME_FONT (it->f);
24326 boff = FRAME_BASELINE_OFFSET (it->f);
24328 else if (EQ (face_name, Qt))
24330 override = 0;
24332 else
24334 int face_id;
24335 struct face *face;
24337 face_id = lookup_named_face (it->f, face_name, 0);
24338 if (face_id < 0)
24339 return make_number (-1);
24341 face = FACE_FROM_ID (it->f, face_id);
24342 font = face->font;
24343 if (font == NULL)
24344 return make_number (-1);
24345 boff = font->baseline_offset;
24346 if (font->vertical_centering)
24347 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24350 ascent = FONT_BASE (font) + boff;
24351 descent = FONT_DESCENT (font) - boff;
24353 if (override)
24355 it->override_ascent = ascent;
24356 it->override_descent = descent;
24357 it->override_boff = boff;
24360 height = ascent + descent;
24362 scale:
24363 if (FLOATP (val))
24364 height = (int)(XFLOAT_DATA (val) * height);
24365 else if (INTEGERP (val))
24366 height *= XINT (val);
24368 return make_number (height);
24372 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24373 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24374 and only if this is for a character for which no font was found.
24376 If the display method (it->glyphless_method) is
24377 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24378 length of the acronym or the hexadecimal string, UPPER_XOFF and
24379 UPPER_YOFF are pixel offsets for the upper part of the string,
24380 LOWER_XOFF and LOWER_YOFF are for the lower part.
24382 For the other display methods, LEN through LOWER_YOFF are zero. */
24384 static void
24385 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24386 short upper_xoff, short upper_yoff,
24387 short lower_xoff, short lower_yoff)
24389 struct glyph *glyph;
24390 enum glyph_row_area area = it->area;
24392 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24393 if (glyph < it->glyph_row->glyphs[area + 1])
24395 /* If the glyph row is reversed, we need to prepend the glyph
24396 rather than append it. */
24397 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24399 struct glyph *g;
24401 /* Make room for the additional glyph. */
24402 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24403 g[1] = *g;
24404 glyph = it->glyph_row->glyphs[area];
24406 glyph->charpos = CHARPOS (it->position);
24407 glyph->object = it->object;
24408 glyph->pixel_width = it->pixel_width;
24409 glyph->ascent = it->ascent;
24410 glyph->descent = it->descent;
24411 glyph->voffset = it->voffset;
24412 glyph->type = GLYPHLESS_GLYPH;
24413 glyph->u.glyphless.method = it->glyphless_method;
24414 glyph->u.glyphless.for_no_font = for_no_font;
24415 glyph->u.glyphless.len = len;
24416 glyph->u.glyphless.ch = it->c;
24417 glyph->slice.glyphless.upper_xoff = upper_xoff;
24418 glyph->slice.glyphless.upper_yoff = upper_yoff;
24419 glyph->slice.glyphless.lower_xoff = lower_xoff;
24420 glyph->slice.glyphless.lower_yoff = lower_yoff;
24421 glyph->avoid_cursor_p = it->avoid_cursor_p;
24422 glyph->multibyte_p = it->multibyte_p;
24423 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24425 /* In R2L rows, the left and the right box edges need to be
24426 drawn in reverse direction. */
24427 glyph->right_box_line_p = it->start_of_box_run_p;
24428 glyph->left_box_line_p = it->end_of_box_run_p;
24430 else
24432 glyph->left_box_line_p = it->start_of_box_run_p;
24433 glyph->right_box_line_p = it->end_of_box_run_p;
24435 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24436 || it->phys_descent > it->descent);
24437 glyph->padding_p = 0;
24438 glyph->glyph_not_available_p = 0;
24439 glyph->face_id = face_id;
24440 glyph->font_type = FONT_TYPE_UNKNOWN;
24441 if (it->bidi_p)
24443 glyph->resolved_level = it->bidi_it.resolved_level;
24444 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24445 emacs_abort ();
24446 glyph->bidi_type = it->bidi_it.type;
24448 ++it->glyph_row->used[area];
24450 else
24451 IT_EXPAND_MATRIX_WIDTH (it, area);
24455 /* Produce a glyph for a glyphless character for iterator IT.
24456 IT->glyphless_method specifies which method to use for displaying
24457 the character. See the description of enum
24458 glyphless_display_method in dispextern.h for the detail.
24460 FOR_NO_FONT is nonzero if and only if this is for a character for
24461 which no font was found. ACRONYM, if non-nil, is an acronym string
24462 for the character. */
24464 static void
24465 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24467 int face_id;
24468 struct face *face;
24469 struct font *font;
24470 int base_width, base_height, width, height;
24471 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24472 int len;
24474 /* Get the metrics of the base font. We always refer to the current
24475 ASCII face. */
24476 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24477 font = face->font ? face->font : FRAME_FONT (it->f);
24478 it->ascent = FONT_BASE (font) + font->baseline_offset;
24479 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24480 base_height = it->ascent + it->descent;
24481 base_width = font->average_width;
24483 /* Get a face ID for the glyph by utilizing a cache (the same way as
24484 done for `escape-glyph' in get_next_display_element). */
24485 if (it->f == last_glyphless_glyph_frame
24486 && it->face_id == last_glyphless_glyph_face_id)
24488 face_id = last_glyphless_glyph_merged_face_id;
24490 else
24492 /* Merge the `glyphless-char' face into the current face. */
24493 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24494 last_glyphless_glyph_frame = it->f;
24495 last_glyphless_glyph_face_id = it->face_id;
24496 last_glyphless_glyph_merged_face_id = face_id;
24499 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24501 it->pixel_width = THIN_SPACE_WIDTH;
24502 len = 0;
24503 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24505 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24507 width = CHAR_WIDTH (it->c);
24508 if (width == 0)
24509 width = 1;
24510 else if (width > 4)
24511 width = 4;
24512 it->pixel_width = base_width * width;
24513 len = 0;
24514 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24516 else
24518 char buf[7];
24519 const char *str;
24520 unsigned int code[6];
24521 int upper_len;
24522 int ascent, descent;
24523 struct font_metrics metrics_upper, metrics_lower;
24525 face = FACE_FROM_ID (it->f, face_id);
24526 font = face->font ? face->font : FRAME_FONT (it->f);
24527 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24529 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24531 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24532 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24533 if (CONSP (acronym))
24534 acronym = XCAR (acronym);
24535 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24537 else
24539 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24540 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24541 str = buf;
24543 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24544 code[len] = font->driver->encode_char (font, str[len]);
24545 upper_len = (len + 1) / 2;
24546 font->driver->text_extents (font, code, upper_len,
24547 &metrics_upper);
24548 font->driver->text_extents (font, code + upper_len, len - upper_len,
24549 &metrics_lower);
24553 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24554 width = max (metrics_upper.width, metrics_lower.width) + 4;
24555 upper_xoff = upper_yoff = 2; /* the typical case */
24556 if (base_width >= width)
24558 /* Align the upper to the left, the lower to the right. */
24559 it->pixel_width = base_width;
24560 lower_xoff = base_width - 2 - metrics_lower.width;
24562 else
24564 /* Center the shorter one. */
24565 it->pixel_width = width;
24566 if (metrics_upper.width >= metrics_lower.width)
24567 lower_xoff = (width - metrics_lower.width) / 2;
24568 else
24570 /* FIXME: This code doesn't look right. It formerly was
24571 missing the "lower_xoff = 0;", which couldn't have
24572 been right since it left lower_xoff uninitialized. */
24573 lower_xoff = 0;
24574 upper_xoff = (width - metrics_upper.width) / 2;
24578 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24579 top, bottom, and between upper and lower strings. */
24580 height = (metrics_upper.ascent + metrics_upper.descent
24581 + metrics_lower.ascent + metrics_lower.descent) + 5;
24582 /* Center vertically.
24583 H:base_height, D:base_descent
24584 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24586 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24587 descent = D - H/2 + h/2;
24588 lower_yoff = descent - 2 - ld;
24589 upper_yoff = lower_yoff - la - 1 - ud; */
24590 ascent = - (it->descent - (base_height + height + 1) / 2);
24591 descent = it->descent - (base_height - height) / 2;
24592 lower_yoff = descent - 2 - metrics_lower.descent;
24593 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
24594 - metrics_upper.descent);
24595 /* Don't make the height shorter than the base height. */
24596 if (height > base_height)
24598 it->ascent = ascent;
24599 it->descent = descent;
24603 it->phys_ascent = it->ascent;
24604 it->phys_descent = it->descent;
24605 if (it->glyph_row)
24606 append_glyphless_glyph (it, face_id, for_no_font, len,
24607 upper_xoff, upper_yoff,
24608 lower_xoff, lower_yoff);
24609 it->nglyphs = 1;
24610 take_vertical_position_into_account (it);
24614 /* RIF:
24615 Produce glyphs/get display metrics for the display element IT is
24616 loaded with. See the description of struct it in dispextern.h
24617 for an overview of struct it. */
24619 void
24620 x_produce_glyphs (struct it *it)
24622 int extra_line_spacing = it->extra_line_spacing;
24624 it->glyph_not_available_p = 0;
24626 if (it->what == IT_CHARACTER)
24628 XChar2b char2b;
24629 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24630 struct font *font = face->font;
24631 struct font_metrics *pcm = NULL;
24632 int boff; /* baseline offset */
24634 if (font == NULL)
24636 /* When no suitable font is found, display this character by
24637 the method specified in the first extra slot of
24638 Vglyphless_char_display. */
24639 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
24641 eassert (it->what == IT_GLYPHLESS);
24642 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
24643 goto done;
24646 boff = font->baseline_offset;
24647 if (font->vertical_centering)
24648 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24650 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24652 int stretched_p;
24654 it->nglyphs = 1;
24656 if (it->override_ascent >= 0)
24658 it->ascent = it->override_ascent;
24659 it->descent = it->override_descent;
24660 boff = it->override_boff;
24662 else
24664 it->ascent = FONT_BASE (font) + boff;
24665 it->descent = FONT_DESCENT (font) - boff;
24668 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24670 pcm = get_per_char_metric (font, &char2b);
24671 if (pcm->width == 0
24672 && pcm->rbearing == 0 && pcm->lbearing == 0)
24673 pcm = NULL;
24676 if (pcm)
24678 it->phys_ascent = pcm->ascent + boff;
24679 it->phys_descent = pcm->descent - boff;
24680 it->pixel_width = pcm->width;
24682 else
24684 it->glyph_not_available_p = 1;
24685 it->phys_ascent = it->ascent;
24686 it->phys_descent = it->descent;
24687 it->pixel_width = font->space_width;
24690 if (it->constrain_row_ascent_descent_p)
24692 if (it->descent > it->max_descent)
24694 it->ascent += it->descent - it->max_descent;
24695 it->descent = it->max_descent;
24697 if (it->ascent > it->max_ascent)
24699 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24700 it->ascent = it->max_ascent;
24702 it->phys_ascent = min (it->phys_ascent, it->ascent);
24703 it->phys_descent = min (it->phys_descent, it->descent);
24704 extra_line_spacing = 0;
24707 /* If this is a space inside a region of text with
24708 `space-width' property, change its width. */
24709 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24710 if (stretched_p)
24711 it->pixel_width *= XFLOATINT (it->space_width);
24713 /* If face has a box, add the box thickness to the character
24714 height. If character has a box line to the left and/or
24715 right, add the box line width to the character's width. */
24716 if (face->box != FACE_NO_BOX)
24718 int thick = face->box_line_width;
24720 if (thick > 0)
24722 it->ascent += thick;
24723 it->descent += thick;
24725 else
24726 thick = -thick;
24728 if (it->start_of_box_run_p)
24729 it->pixel_width += thick;
24730 if (it->end_of_box_run_p)
24731 it->pixel_width += thick;
24734 /* If face has an overline, add the height of the overline
24735 (1 pixel) and a 1 pixel margin to the character height. */
24736 if (face->overline_p)
24737 it->ascent += overline_margin;
24739 if (it->constrain_row_ascent_descent_p)
24741 if (it->ascent > it->max_ascent)
24742 it->ascent = it->max_ascent;
24743 if (it->descent > it->max_descent)
24744 it->descent = it->max_descent;
24747 take_vertical_position_into_account (it);
24749 /* If we have to actually produce glyphs, do it. */
24750 if (it->glyph_row)
24752 if (stretched_p)
24754 /* Translate a space with a `space-width' property
24755 into a stretch glyph. */
24756 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24757 / FONT_HEIGHT (font));
24758 append_stretch_glyph (it, it->object, it->pixel_width,
24759 it->ascent + it->descent, ascent);
24761 else
24762 append_glyph (it);
24764 /* If characters with lbearing or rbearing are displayed
24765 in this line, record that fact in a flag of the
24766 glyph row. This is used to optimize X output code. */
24767 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24768 it->glyph_row->contains_overlapping_glyphs_p = 1;
24770 if (! stretched_p && it->pixel_width == 0)
24771 /* We assure that all visible glyphs have at least 1-pixel
24772 width. */
24773 it->pixel_width = 1;
24775 else if (it->char_to_display == '\n')
24777 /* A newline has no width, but we need the height of the
24778 line. But if previous part of the line sets a height,
24779 don't increase that height */
24781 Lisp_Object height;
24782 Lisp_Object total_height = Qnil;
24784 it->override_ascent = -1;
24785 it->pixel_width = 0;
24786 it->nglyphs = 0;
24788 height = get_it_property (it, Qline_height);
24789 /* Split (line-height total-height) list */
24790 if (CONSP (height)
24791 && CONSP (XCDR (height))
24792 && NILP (XCDR (XCDR (height))))
24794 total_height = XCAR (XCDR (height));
24795 height = XCAR (height);
24797 height = calc_line_height_property (it, height, font, boff, 1);
24799 if (it->override_ascent >= 0)
24801 it->ascent = it->override_ascent;
24802 it->descent = it->override_descent;
24803 boff = it->override_boff;
24805 else
24807 it->ascent = FONT_BASE (font) + boff;
24808 it->descent = FONT_DESCENT (font) - boff;
24811 if (EQ (height, Qt))
24813 if (it->descent > it->max_descent)
24815 it->ascent += it->descent - it->max_descent;
24816 it->descent = it->max_descent;
24818 if (it->ascent > it->max_ascent)
24820 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24821 it->ascent = it->max_ascent;
24823 it->phys_ascent = min (it->phys_ascent, it->ascent);
24824 it->phys_descent = min (it->phys_descent, it->descent);
24825 it->constrain_row_ascent_descent_p = 1;
24826 extra_line_spacing = 0;
24828 else
24830 Lisp_Object spacing;
24832 it->phys_ascent = it->ascent;
24833 it->phys_descent = it->descent;
24835 if ((it->max_ascent > 0 || it->max_descent > 0)
24836 && face->box != FACE_NO_BOX
24837 && face->box_line_width > 0)
24839 it->ascent += face->box_line_width;
24840 it->descent += face->box_line_width;
24842 if (!NILP (height)
24843 && XINT (height) > it->ascent + it->descent)
24844 it->ascent = XINT (height) - it->descent;
24846 if (!NILP (total_height))
24847 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24848 else
24850 spacing = get_it_property (it, Qline_spacing);
24851 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24853 if (INTEGERP (spacing))
24855 extra_line_spacing = XINT (spacing);
24856 if (!NILP (total_height))
24857 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24861 else /* i.e. (it->char_to_display == '\t') */
24863 if (font->space_width > 0)
24865 int tab_width = it->tab_width * font->space_width;
24866 int x = it->current_x + it->continuation_lines_width;
24867 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24869 /* If the distance from the current position to the next tab
24870 stop is less than a space character width, use the
24871 tab stop after that. */
24872 if (next_tab_x - x < font->space_width)
24873 next_tab_x += tab_width;
24875 it->pixel_width = next_tab_x - x;
24876 it->nglyphs = 1;
24877 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24878 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24880 if (it->glyph_row)
24882 append_stretch_glyph (it, it->object, it->pixel_width,
24883 it->ascent + it->descent, it->ascent);
24886 else
24888 it->pixel_width = 0;
24889 it->nglyphs = 1;
24893 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24895 /* A static composition.
24897 Note: A composition is represented as one glyph in the
24898 glyph matrix. There are no padding glyphs.
24900 Important note: pixel_width, ascent, and descent are the
24901 values of what is drawn by draw_glyphs (i.e. the values of
24902 the overall glyphs composed). */
24903 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24904 int boff; /* baseline offset */
24905 struct composition *cmp = composition_table[it->cmp_it.id];
24906 int glyph_len = cmp->glyph_len;
24907 struct font *font = face->font;
24909 it->nglyphs = 1;
24911 /* If we have not yet calculated pixel size data of glyphs of
24912 the composition for the current face font, calculate them
24913 now. Theoretically, we have to check all fonts for the
24914 glyphs, but that requires much time and memory space. So,
24915 here we check only the font of the first glyph. This may
24916 lead to incorrect display, but it's very rare, and C-l
24917 (recenter-top-bottom) can correct the display anyway. */
24918 if (! cmp->font || cmp->font != font)
24920 /* Ascent and descent of the font of the first character
24921 of this composition (adjusted by baseline offset).
24922 Ascent and descent of overall glyphs should not be less
24923 than these, respectively. */
24924 int font_ascent, font_descent, font_height;
24925 /* Bounding box of the overall glyphs. */
24926 int leftmost, rightmost, lowest, highest;
24927 int lbearing, rbearing;
24928 int i, width, ascent, descent;
24929 int left_padded = 0, right_padded = 0;
24930 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24931 XChar2b char2b;
24932 struct font_metrics *pcm;
24933 int font_not_found_p;
24934 ptrdiff_t pos;
24936 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24937 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24938 break;
24939 if (glyph_len < cmp->glyph_len)
24940 right_padded = 1;
24941 for (i = 0; i < glyph_len; i++)
24943 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24944 break;
24945 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24947 if (i > 0)
24948 left_padded = 1;
24950 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24951 : IT_CHARPOS (*it));
24952 /* If no suitable font is found, use the default font. */
24953 font_not_found_p = font == NULL;
24954 if (font_not_found_p)
24956 face = face->ascii_face;
24957 font = face->font;
24959 boff = font->baseline_offset;
24960 if (font->vertical_centering)
24961 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24962 font_ascent = FONT_BASE (font) + boff;
24963 font_descent = FONT_DESCENT (font) - boff;
24964 font_height = FONT_HEIGHT (font);
24966 cmp->font = font;
24968 pcm = NULL;
24969 if (! font_not_found_p)
24971 get_char_face_and_encoding (it->f, c, it->face_id,
24972 &char2b, 0);
24973 pcm = get_per_char_metric (font, &char2b);
24976 /* Initialize the bounding box. */
24977 if (pcm)
24979 width = cmp->glyph_len > 0 ? pcm->width : 0;
24980 ascent = pcm->ascent;
24981 descent = pcm->descent;
24982 lbearing = pcm->lbearing;
24983 rbearing = pcm->rbearing;
24985 else
24987 width = cmp->glyph_len > 0 ? font->space_width : 0;
24988 ascent = FONT_BASE (font);
24989 descent = FONT_DESCENT (font);
24990 lbearing = 0;
24991 rbearing = width;
24994 rightmost = width;
24995 leftmost = 0;
24996 lowest = - descent + boff;
24997 highest = ascent + boff;
24999 if (! font_not_found_p
25000 && font->default_ascent
25001 && CHAR_TABLE_P (Vuse_default_ascent)
25002 && !NILP (Faref (Vuse_default_ascent,
25003 make_number (it->char_to_display))))
25004 highest = font->default_ascent + boff;
25006 /* Draw the first glyph at the normal position. It may be
25007 shifted to right later if some other glyphs are drawn
25008 at the left. */
25009 cmp->offsets[i * 2] = 0;
25010 cmp->offsets[i * 2 + 1] = boff;
25011 cmp->lbearing = lbearing;
25012 cmp->rbearing = rbearing;
25014 /* Set cmp->offsets for the remaining glyphs. */
25015 for (i++; i < glyph_len; i++)
25017 int left, right, btm, top;
25018 int ch = COMPOSITION_GLYPH (cmp, i);
25019 int face_id;
25020 struct face *this_face;
25022 if (ch == '\t')
25023 ch = ' ';
25024 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25025 this_face = FACE_FROM_ID (it->f, face_id);
25026 font = this_face->font;
25028 if (font == NULL)
25029 pcm = NULL;
25030 else
25032 get_char_face_and_encoding (it->f, ch, face_id,
25033 &char2b, 0);
25034 pcm = get_per_char_metric (font, &char2b);
25036 if (! pcm)
25037 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25038 else
25040 width = pcm->width;
25041 ascent = pcm->ascent;
25042 descent = pcm->descent;
25043 lbearing = pcm->lbearing;
25044 rbearing = pcm->rbearing;
25045 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25047 /* Relative composition with or without
25048 alternate chars. */
25049 left = (leftmost + rightmost - width) / 2;
25050 btm = - descent + boff;
25051 if (font->relative_compose
25052 && (! CHAR_TABLE_P (Vignore_relative_composition)
25053 || NILP (Faref (Vignore_relative_composition,
25054 make_number (ch)))))
25057 if (- descent >= font->relative_compose)
25058 /* One extra pixel between two glyphs. */
25059 btm = highest + 1;
25060 else if (ascent <= 0)
25061 /* One extra pixel between two glyphs. */
25062 btm = lowest - 1 - ascent - descent;
25065 else
25067 /* A composition rule is specified by an integer
25068 value that encodes global and new reference
25069 points (GREF and NREF). GREF and NREF are
25070 specified by numbers as below:
25072 0---1---2 -- ascent
25076 9--10--11 -- center
25078 ---3---4---5--- baseline
25080 6---7---8 -- descent
25082 int rule = COMPOSITION_RULE (cmp, i);
25083 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25085 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25086 grefx = gref % 3, nrefx = nref % 3;
25087 grefy = gref / 3, nrefy = nref / 3;
25088 if (xoff)
25089 xoff = font_height * (xoff - 128) / 256;
25090 if (yoff)
25091 yoff = font_height * (yoff - 128) / 256;
25093 left = (leftmost
25094 + grefx * (rightmost - leftmost) / 2
25095 - nrefx * width / 2
25096 + xoff);
25098 btm = ((grefy == 0 ? highest
25099 : grefy == 1 ? 0
25100 : grefy == 2 ? lowest
25101 : (highest + lowest) / 2)
25102 - (nrefy == 0 ? ascent + descent
25103 : nrefy == 1 ? descent - boff
25104 : nrefy == 2 ? 0
25105 : (ascent + descent) / 2)
25106 + yoff);
25109 cmp->offsets[i * 2] = left;
25110 cmp->offsets[i * 2 + 1] = btm + descent;
25112 /* Update the bounding box of the overall glyphs. */
25113 if (width > 0)
25115 right = left + width;
25116 if (left < leftmost)
25117 leftmost = left;
25118 if (right > rightmost)
25119 rightmost = right;
25121 top = btm + descent + ascent;
25122 if (top > highest)
25123 highest = top;
25124 if (btm < lowest)
25125 lowest = btm;
25127 if (cmp->lbearing > left + lbearing)
25128 cmp->lbearing = left + lbearing;
25129 if (cmp->rbearing < left + rbearing)
25130 cmp->rbearing = left + rbearing;
25134 /* If there are glyphs whose x-offsets are negative,
25135 shift all glyphs to the right and make all x-offsets
25136 non-negative. */
25137 if (leftmost < 0)
25139 for (i = 0; i < cmp->glyph_len; i++)
25140 cmp->offsets[i * 2] -= leftmost;
25141 rightmost -= leftmost;
25142 cmp->lbearing -= leftmost;
25143 cmp->rbearing -= leftmost;
25146 if (left_padded && cmp->lbearing < 0)
25148 for (i = 0; i < cmp->glyph_len; i++)
25149 cmp->offsets[i * 2] -= cmp->lbearing;
25150 rightmost -= cmp->lbearing;
25151 cmp->rbearing -= cmp->lbearing;
25152 cmp->lbearing = 0;
25154 if (right_padded && rightmost < cmp->rbearing)
25156 rightmost = cmp->rbearing;
25159 cmp->pixel_width = rightmost;
25160 cmp->ascent = highest;
25161 cmp->descent = - lowest;
25162 if (cmp->ascent < font_ascent)
25163 cmp->ascent = font_ascent;
25164 if (cmp->descent < font_descent)
25165 cmp->descent = font_descent;
25168 if (it->glyph_row
25169 && (cmp->lbearing < 0
25170 || cmp->rbearing > cmp->pixel_width))
25171 it->glyph_row->contains_overlapping_glyphs_p = 1;
25173 it->pixel_width = cmp->pixel_width;
25174 it->ascent = it->phys_ascent = cmp->ascent;
25175 it->descent = it->phys_descent = cmp->descent;
25176 if (face->box != FACE_NO_BOX)
25178 int thick = face->box_line_width;
25180 if (thick > 0)
25182 it->ascent += thick;
25183 it->descent += thick;
25185 else
25186 thick = - thick;
25188 if (it->start_of_box_run_p)
25189 it->pixel_width += thick;
25190 if (it->end_of_box_run_p)
25191 it->pixel_width += thick;
25194 /* If face has an overline, add the height of the overline
25195 (1 pixel) and a 1 pixel margin to the character height. */
25196 if (face->overline_p)
25197 it->ascent += overline_margin;
25199 take_vertical_position_into_account (it);
25200 if (it->ascent < 0)
25201 it->ascent = 0;
25202 if (it->descent < 0)
25203 it->descent = 0;
25205 if (it->glyph_row && cmp->glyph_len > 0)
25206 append_composite_glyph (it);
25208 else if (it->what == IT_COMPOSITION)
25210 /* A dynamic (automatic) composition. */
25211 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25212 Lisp_Object gstring;
25213 struct font_metrics metrics;
25215 it->nglyphs = 1;
25217 gstring = composition_gstring_from_id (it->cmp_it.id);
25218 it->pixel_width
25219 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25220 &metrics);
25221 if (it->glyph_row
25222 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25223 it->glyph_row->contains_overlapping_glyphs_p = 1;
25224 it->ascent = it->phys_ascent = metrics.ascent;
25225 it->descent = it->phys_descent = metrics.descent;
25226 if (face->box != FACE_NO_BOX)
25228 int thick = face->box_line_width;
25230 if (thick > 0)
25232 it->ascent += thick;
25233 it->descent += thick;
25235 else
25236 thick = - thick;
25238 if (it->start_of_box_run_p)
25239 it->pixel_width += thick;
25240 if (it->end_of_box_run_p)
25241 it->pixel_width += thick;
25243 /* If face has an overline, add the height of the overline
25244 (1 pixel) and a 1 pixel margin to the character height. */
25245 if (face->overline_p)
25246 it->ascent += overline_margin;
25247 take_vertical_position_into_account (it);
25248 if (it->ascent < 0)
25249 it->ascent = 0;
25250 if (it->descent < 0)
25251 it->descent = 0;
25253 if (it->glyph_row)
25254 append_composite_glyph (it);
25256 else if (it->what == IT_GLYPHLESS)
25257 produce_glyphless_glyph (it, 0, Qnil);
25258 else if (it->what == IT_IMAGE)
25259 produce_image_glyph (it);
25260 else if (it->what == IT_STRETCH)
25261 produce_stretch_glyph (it);
25263 done:
25264 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25265 because this isn't true for images with `:ascent 100'. */
25266 eassert (it->ascent >= 0 && it->descent >= 0);
25267 if (it->area == TEXT_AREA)
25268 it->current_x += it->pixel_width;
25270 if (extra_line_spacing > 0)
25272 it->descent += extra_line_spacing;
25273 if (extra_line_spacing > it->max_extra_line_spacing)
25274 it->max_extra_line_spacing = extra_line_spacing;
25277 it->max_ascent = max (it->max_ascent, it->ascent);
25278 it->max_descent = max (it->max_descent, it->descent);
25279 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25280 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25283 /* EXPORT for RIF:
25284 Output LEN glyphs starting at START at the nominal cursor position.
25285 Advance the nominal cursor over the text. The global variable
25286 updated_window contains the window being updated, updated_row is
25287 the glyph row being updated, and updated_area is the area of that
25288 row being updated. */
25290 void
25291 x_write_glyphs (struct glyph *start, int len)
25293 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25295 eassert (updated_window && updated_row);
25296 /* When the window is hscrolled, cursor hpos can legitimately be out
25297 of bounds, but we draw the cursor at the corresponding window
25298 margin in that case. */
25299 if (!updated_row->reversed_p && chpos < 0)
25300 chpos = 0;
25301 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25302 chpos = updated_row->used[TEXT_AREA] - 1;
25304 block_input ();
25306 /* Write glyphs. */
25308 hpos = start - updated_row->glyphs[updated_area];
25309 x = draw_glyphs (updated_window, output_cursor.x,
25310 updated_row, updated_area,
25311 hpos, hpos + len,
25312 DRAW_NORMAL_TEXT, 0);
25314 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25315 if (updated_area == TEXT_AREA
25316 && updated_window->phys_cursor_on_p
25317 && updated_window->phys_cursor.vpos == output_cursor.vpos
25318 && chpos >= hpos
25319 && chpos < hpos + len)
25320 updated_window->phys_cursor_on_p = 0;
25322 unblock_input ();
25324 /* Advance the output cursor. */
25325 output_cursor.hpos += len;
25326 output_cursor.x = x;
25330 /* EXPORT for RIF:
25331 Insert LEN glyphs from START at the nominal cursor position. */
25333 void
25334 x_insert_glyphs (struct glyph *start, int len)
25336 struct frame *f;
25337 struct window *w;
25338 int line_height, shift_by_width, shifted_region_width;
25339 struct glyph_row *row;
25340 struct glyph *glyph;
25341 int frame_x, frame_y;
25342 ptrdiff_t hpos;
25344 eassert (updated_window && updated_row);
25345 block_input ();
25346 w = updated_window;
25347 f = XFRAME (WINDOW_FRAME (w));
25349 /* Get the height of the line we are in. */
25350 row = updated_row;
25351 line_height = row->height;
25353 /* Get the width of the glyphs to insert. */
25354 shift_by_width = 0;
25355 for (glyph = start; glyph < start + len; ++glyph)
25356 shift_by_width += glyph->pixel_width;
25358 /* Get the width of the region to shift right. */
25359 shifted_region_width = (window_box_width (w, updated_area)
25360 - output_cursor.x
25361 - shift_by_width);
25363 /* Shift right. */
25364 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25365 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25367 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25368 line_height, shift_by_width);
25370 /* Write the glyphs. */
25371 hpos = start - row->glyphs[updated_area];
25372 draw_glyphs (w, output_cursor.x, row, updated_area,
25373 hpos, hpos + len,
25374 DRAW_NORMAL_TEXT, 0);
25376 /* Advance the output cursor. */
25377 output_cursor.hpos += len;
25378 output_cursor.x += shift_by_width;
25379 unblock_input ();
25383 /* EXPORT for RIF:
25384 Erase the current text line from the nominal cursor position
25385 (inclusive) to pixel column TO_X (exclusive). The idea is that
25386 everything from TO_X onward is already erased.
25388 TO_X is a pixel position relative to updated_area of
25389 updated_window. TO_X == -1 means clear to the end of this area. */
25391 void
25392 x_clear_end_of_line (int to_x)
25394 struct frame *f;
25395 struct window *w = updated_window;
25396 int max_x, min_y, max_y;
25397 int from_x, from_y, to_y;
25399 eassert (updated_window && updated_row);
25400 f = XFRAME (w->frame);
25402 if (updated_row->full_width_p)
25403 max_x = WINDOW_TOTAL_WIDTH (w);
25404 else
25405 max_x = window_box_width (w, updated_area);
25406 max_y = window_text_bottom_y (w);
25408 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25409 of window. For TO_X > 0, truncate to end of drawing area. */
25410 if (to_x == 0)
25411 return;
25412 else if (to_x < 0)
25413 to_x = max_x;
25414 else
25415 to_x = min (to_x, max_x);
25417 to_y = min (max_y, output_cursor.y + updated_row->height);
25419 /* Notice if the cursor will be cleared by this operation. */
25420 if (!updated_row->full_width_p)
25421 notice_overwritten_cursor (w, updated_area,
25422 output_cursor.x, -1,
25423 updated_row->y,
25424 MATRIX_ROW_BOTTOM_Y (updated_row));
25426 from_x = output_cursor.x;
25428 /* Translate to frame coordinates. */
25429 if (updated_row->full_width_p)
25431 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25432 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25434 else
25436 int area_left = window_box_left (w, updated_area);
25437 from_x += area_left;
25438 to_x += area_left;
25441 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25442 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25443 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25445 /* Prevent inadvertently clearing to end of the X window. */
25446 if (to_x > from_x && to_y > from_y)
25448 block_input ();
25449 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25450 to_x - from_x, to_y - from_y);
25451 unblock_input ();
25455 #endif /* HAVE_WINDOW_SYSTEM */
25459 /***********************************************************************
25460 Cursor types
25461 ***********************************************************************/
25463 /* Value is the internal representation of the specified cursor type
25464 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25465 of the bar cursor. */
25467 static enum text_cursor_kinds
25468 get_specified_cursor_type (Lisp_Object arg, int *width)
25470 enum text_cursor_kinds type;
25472 if (NILP (arg))
25473 return NO_CURSOR;
25475 if (EQ (arg, Qbox))
25476 return FILLED_BOX_CURSOR;
25478 if (EQ (arg, Qhollow))
25479 return HOLLOW_BOX_CURSOR;
25481 if (EQ (arg, Qbar))
25483 *width = 2;
25484 return BAR_CURSOR;
25487 if (CONSP (arg)
25488 && EQ (XCAR (arg), Qbar)
25489 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25491 *width = XINT (XCDR (arg));
25492 return BAR_CURSOR;
25495 if (EQ (arg, Qhbar))
25497 *width = 2;
25498 return HBAR_CURSOR;
25501 if (CONSP (arg)
25502 && EQ (XCAR (arg), Qhbar)
25503 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25505 *width = XINT (XCDR (arg));
25506 return HBAR_CURSOR;
25509 /* Treat anything unknown as "hollow box cursor".
25510 It was bad to signal an error; people have trouble fixing
25511 .Xdefaults with Emacs, when it has something bad in it. */
25512 type = HOLLOW_BOX_CURSOR;
25514 return type;
25517 /* Set the default cursor types for specified frame. */
25518 void
25519 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25521 int width = 1;
25522 Lisp_Object tem;
25524 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25525 FRAME_CURSOR_WIDTH (f) = width;
25527 /* By default, set up the blink-off state depending on the on-state. */
25529 tem = Fassoc (arg, Vblink_cursor_alist);
25530 if (!NILP (tem))
25532 FRAME_BLINK_OFF_CURSOR (f)
25533 = get_specified_cursor_type (XCDR (tem), &width);
25534 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25536 else
25537 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25541 #ifdef HAVE_WINDOW_SYSTEM
25543 /* Return the cursor we want to be displayed in window W. Return
25544 width of bar/hbar cursor through WIDTH arg. Return with
25545 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25546 (i.e. if the `system caret' should track this cursor).
25548 In a mini-buffer window, we want the cursor only to appear if we
25549 are reading input from this window. For the selected window, we
25550 want the cursor type given by the frame parameter or buffer local
25551 setting of cursor-type. If explicitly marked off, draw no cursor.
25552 In all other cases, we want a hollow box cursor. */
25554 static enum text_cursor_kinds
25555 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25556 int *active_cursor)
25558 struct frame *f = XFRAME (w->frame);
25559 struct buffer *b = XBUFFER (w->contents);
25560 int cursor_type = DEFAULT_CURSOR;
25561 Lisp_Object alt_cursor;
25562 int non_selected = 0;
25564 *active_cursor = 1;
25566 /* Echo area */
25567 if (cursor_in_echo_area
25568 && FRAME_HAS_MINIBUF_P (f)
25569 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25571 if (w == XWINDOW (echo_area_window))
25573 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25575 *width = FRAME_CURSOR_WIDTH (f);
25576 return FRAME_DESIRED_CURSOR (f);
25578 else
25579 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25582 *active_cursor = 0;
25583 non_selected = 1;
25586 /* Detect a nonselected window or nonselected frame. */
25587 else if (w != XWINDOW (f->selected_window)
25588 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
25590 *active_cursor = 0;
25592 if (MINI_WINDOW_P (w) && minibuf_level == 0)
25593 return NO_CURSOR;
25595 non_selected = 1;
25598 /* Never display a cursor in a window in which cursor-type is nil. */
25599 if (NILP (BVAR (b, cursor_type)))
25600 return NO_CURSOR;
25602 /* Get the normal cursor type for this window. */
25603 if (EQ (BVAR (b, cursor_type), Qt))
25605 cursor_type = FRAME_DESIRED_CURSOR (f);
25606 *width = FRAME_CURSOR_WIDTH (f);
25608 else
25609 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
25611 /* Use cursor-in-non-selected-windows instead
25612 for non-selected window or frame. */
25613 if (non_selected)
25615 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
25616 if (!EQ (Qt, alt_cursor))
25617 return get_specified_cursor_type (alt_cursor, width);
25618 /* t means modify the normal cursor type. */
25619 if (cursor_type == FILLED_BOX_CURSOR)
25620 cursor_type = HOLLOW_BOX_CURSOR;
25621 else if (cursor_type == BAR_CURSOR && *width > 1)
25622 --*width;
25623 return cursor_type;
25626 /* Use normal cursor if not blinked off. */
25627 if (!w->cursor_off_p)
25629 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25631 if (cursor_type == FILLED_BOX_CURSOR)
25633 /* Using a block cursor on large images can be very annoying.
25634 So use a hollow cursor for "large" images.
25635 If image is not transparent (no mask), also use hollow cursor. */
25636 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25637 if (img != NULL && IMAGEP (img->spec))
25639 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25640 where N = size of default frame font size.
25641 This should cover most of the "tiny" icons people may use. */
25642 if (!img->mask
25643 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
25644 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
25645 cursor_type = HOLLOW_BOX_CURSOR;
25648 else if (cursor_type != NO_CURSOR)
25650 /* Display current only supports BOX and HOLLOW cursors for images.
25651 So for now, unconditionally use a HOLLOW cursor when cursor is
25652 not a solid box cursor. */
25653 cursor_type = HOLLOW_BOX_CURSOR;
25656 return cursor_type;
25659 /* Cursor is blinked off, so determine how to "toggle" it. */
25661 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25662 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25663 return get_specified_cursor_type (XCDR (alt_cursor), width);
25665 /* Then see if frame has specified a specific blink off cursor type. */
25666 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25668 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25669 return FRAME_BLINK_OFF_CURSOR (f);
25672 #if 0
25673 /* Some people liked having a permanently visible blinking cursor,
25674 while others had very strong opinions against it. So it was
25675 decided to remove it. KFS 2003-09-03 */
25677 /* Finally perform built-in cursor blinking:
25678 filled box <-> hollow box
25679 wide [h]bar <-> narrow [h]bar
25680 narrow [h]bar <-> no cursor
25681 other type <-> no cursor */
25683 if (cursor_type == FILLED_BOX_CURSOR)
25684 return HOLLOW_BOX_CURSOR;
25686 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25688 *width = 1;
25689 return cursor_type;
25691 #endif
25693 return NO_CURSOR;
25697 /* Notice when the text cursor of window W has been completely
25698 overwritten by a drawing operation that outputs glyphs in AREA
25699 starting at X0 and ending at X1 in the line starting at Y0 and
25700 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25701 the rest of the line after X0 has been written. Y coordinates
25702 are window-relative. */
25704 static void
25705 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25706 int x0, int x1, int y0, int y1)
25708 int cx0, cx1, cy0, cy1;
25709 struct glyph_row *row;
25711 if (!w->phys_cursor_on_p)
25712 return;
25713 if (area != TEXT_AREA)
25714 return;
25716 if (w->phys_cursor.vpos < 0
25717 || w->phys_cursor.vpos >= w->current_matrix->nrows
25718 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25719 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
25720 return;
25722 if (row->cursor_in_fringe_p)
25724 row->cursor_in_fringe_p = 0;
25725 draw_fringe_bitmap (w, row, row->reversed_p);
25726 w->phys_cursor_on_p = 0;
25727 return;
25730 cx0 = w->phys_cursor.x;
25731 cx1 = cx0 + w->phys_cursor_width;
25732 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25733 return;
25735 /* The cursor image will be completely removed from the
25736 screen if the output area intersects the cursor area in
25737 y-direction. When we draw in [y0 y1[, and some part of
25738 the cursor is at y < y0, that part must have been drawn
25739 before. When scrolling, the cursor is erased before
25740 actually scrolling, so we don't come here. When not
25741 scrolling, the rows above the old cursor row must have
25742 changed, and in this case these rows must have written
25743 over the cursor image.
25745 Likewise if part of the cursor is below y1, with the
25746 exception of the cursor being in the first blank row at
25747 the buffer and window end because update_text_area
25748 doesn't draw that row. (Except when it does, but
25749 that's handled in update_text_area.) */
25751 cy0 = w->phys_cursor.y;
25752 cy1 = cy0 + w->phys_cursor_height;
25753 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25754 return;
25756 w->phys_cursor_on_p = 0;
25759 #endif /* HAVE_WINDOW_SYSTEM */
25762 /************************************************************************
25763 Mouse Face
25764 ************************************************************************/
25766 #ifdef HAVE_WINDOW_SYSTEM
25768 /* EXPORT for RIF:
25769 Fix the display of area AREA of overlapping row ROW in window W
25770 with respect to the overlapping part OVERLAPS. */
25772 void
25773 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25774 enum glyph_row_area area, int overlaps)
25776 int i, x;
25778 block_input ();
25780 x = 0;
25781 for (i = 0; i < row->used[area];)
25783 if (row->glyphs[area][i].overlaps_vertically_p)
25785 int start = i, start_x = x;
25789 x += row->glyphs[area][i].pixel_width;
25790 ++i;
25792 while (i < row->used[area]
25793 && row->glyphs[area][i].overlaps_vertically_p);
25795 draw_glyphs (w, start_x, row, area,
25796 start, i,
25797 DRAW_NORMAL_TEXT, overlaps);
25799 else
25801 x += row->glyphs[area][i].pixel_width;
25802 ++i;
25806 unblock_input ();
25810 /* EXPORT:
25811 Draw the cursor glyph of window W in glyph row ROW. See the
25812 comment of draw_glyphs for the meaning of HL. */
25814 void
25815 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25816 enum draw_glyphs_face hl)
25818 /* If cursor hpos is out of bounds, don't draw garbage. This can
25819 happen in mini-buffer windows when switching between echo area
25820 glyphs and mini-buffer. */
25821 if ((row->reversed_p
25822 ? (w->phys_cursor.hpos >= 0)
25823 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25825 int on_p = w->phys_cursor_on_p;
25826 int x1;
25827 int hpos = w->phys_cursor.hpos;
25829 /* When the window is hscrolled, cursor hpos can legitimately be
25830 out of bounds, but we draw the cursor at the corresponding
25831 window margin in that case. */
25832 if (!row->reversed_p && hpos < 0)
25833 hpos = 0;
25834 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
25835 hpos = row->used[TEXT_AREA] - 1;
25837 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
25838 hl, 0);
25839 w->phys_cursor_on_p = on_p;
25841 if (hl == DRAW_CURSOR)
25842 w->phys_cursor_width = x1 - w->phys_cursor.x;
25843 /* When we erase the cursor, and ROW is overlapped by other
25844 rows, make sure that these overlapping parts of other rows
25845 are redrawn. */
25846 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25848 w->phys_cursor_width = x1 - w->phys_cursor.x;
25850 if (row > w->current_matrix->rows
25851 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25852 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25853 OVERLAPS_ERASED_CURSOR);
25855 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25856 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25857 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25858 OVERLAPS_ERASED_CURSOR);
25864 /* EXPORT:
25865 Erase the image of a cursor of window W from the screen. */
25867 void
25868 erase_phys_cursor (struct window *w)
25870 struct frame *f = XFRAME (w->frame);
25871 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25872 int hpos = w->phys_cursor.hpos;
25873 int vpos = w->phys_cursor.vpos;
25874 int mouse_face_here_p = 0;
25875 struct glyph_matrix *active_glyphs = w->current_matrix;
25876 struct glyph_row *cursor_row;
25877 struct glyph *cursor_glyph;
25878 enum draw_glyphs_face hl;
25880 /* No cursor displayed or row invalidated => nothing to do on the
25881 screen. */
25882 if (w->phys_cursor_type == NO_CURSOR)
25883 goto mark_cursor_off;
25885 /* VPOS >= active_glyphs->nrows means that window has been resized.
25886 Don't bother to erase the cursor. */
25887 if (vpos >= active_glyphs->nrows)
25888 goto mark_cursor_off;
25890 /* If row containing cursor is marked invalid, there is nothing we
25891 can do. */
25892 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25893 if (!cursor_row->enabled_p)
25894 goto mark_cursor_off;
25896 /* If line spacing is > 0, old cursor may only be partially visible in
25897 window after split-window. So adjust visible height. */
25898 cursor_row->visible_height = min (cursor_row->visible_height,
25899 window_text_bottom_y (w) - cursor_row->y);
25901 /* If row is completely invisible, don't attempt to delete a cursor which
25902 isn't there. This can happen if cursor is at top of a window, and
25903 we switch to a buffer with a header line in that window. */
25904 if (cursor_row->visible_height <= 0)
25905 goto mark_cursor_off;
25907 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25908 if (cursor_row->cursor_in_fringe_p)
25910 cursor_row->cursor_in_fringe_p = 0;
25911 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25912 goto mark_cursor_off;
25915 /* This can happen when the new row is shorter than the old one.
25916 In this case, either draw_glyphs or clear_end_of_line
25917 should have cleared the cursor. Note that we wouldn't be
25918 able to erase the cursor in this case because we don't have a
25919 cursor glyph at hand. */
25920 if ((cursor_row->reversed_p
25921 ? (w->phys_cursor.hpos < 0)
25922 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25923 goto mark_cursor_off;
25925 /* When the window is hscrolled, cursor hpos can legitimately be out
25926 of bounds, but we draw the cursor at the corresponding window
25927 margin in that case. */
25928 if (!cursor_row->reversed_p && hpos < 0)
25929 hpos = 0;
25930 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
25931 hpos = cursor_row->used[TEXT_AREA] - 1;
25933 /* If the cursor is in the mouse face area, redisplay that when
25934 we clear the cursor. */
25935 if (! NILP (hlinfo->mouse_face_window)
25936 && coords_in_mouse_face_p (w, hpos, vpos)
25937 /* Don't redraw the cursor's spot in mouse face if it is at the
25938 end of a line (on a newline). The cursor appears there, but
25939 mouse highlighting does not. */
25940 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25941 mouse_face_here_p = 1;
25943 /* Maybe clear the display under the cursor. */
25944 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25946 int x, y, left_x;
25947 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25948 int width;
25950 cursor_glyph = get_phys_cursor_glyph (w);
25951 if (cursor_glyph == NULL)
25952 goto mark_cursor_off;
25954 width = cursor_glyph->pixel_width;
25955 left_x = window_box_left_offset (w, TEXT_AREA);
25956 x = w->phys_cursor.x;
25957 if (x < left_x)
25958 width -= left_x - x;
25959 width = min (width, window_box_width (w, TEXT_AREA) - x);
25960 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25961 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25963 if (width > 0)
25964 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25967 /* Erase the cursor by redrawing the character underneath it. */
25968 if (mouse_face_here_p)
25969 hl = DRAW_MOUSE_FACE;
25970 else
25971 hl = DRAW_NORMAL_TEXT;
25972 draw_phys_cursor_glyph (w, cursor_row, hl);
25974 mark_cursor_off:
25975 w->phys_cursor_on_p = 0;
25976 w->phys_cursor_type = NO_CURSOR;
25980 /* EXPORT:
25981 Display or clear cursor of window W. If ON is zero, clear the
25982 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25983 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25985 void
25986 display_and_set_cursor (struct window *w, int on,
25987 int hpos, int vpos, int x, int y)
25989 struct frame *f = XFRAME (w->frame);
25990 int new_cursor_type;
25991 int new_cursor_width;
25992 int active_cursor;
25993 struct glyph_row *glyph_row;
25994 struct glyph *glyph;
25996 /* This is pointless on invisible frames, and dangerous on garbaged
25997 windows and frames; in the latter case, the frame or window may
25998 be in the midst of changing its size, and x and y may be off the
25999 window. */
26000 if (! FRAME_VISIBLE_P (f)
26001 || FRAME_GARBAGED_P (f)
26002 || vpos >= w->current_matrix->nrows
26003 || hpos >= w->current_matrix->matrix_w)
26004 return;
26006 /* If cursor is off and we want it off, return quickly. */
26007 if (!on && !w->phys_cursor_on_p)
26008 return;
26010 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26011 /* If cursor row is not enabled, we don't really know where to
26012 display the cursor. */
26013 if (!glyph_row->enabled_p)
26015 w->phys_cursor_on_p = 0;
26016 return;
26019 glyph = NULL;
26020 if (!glyph_row->exact_window_width_line_p
26021 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26022 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26024 eassert (input_blocked_p ());
26026 /* Set new_cursor_type to the cursor we want to be displayed. */
26027 new_cursor_type = get_window_cursor_type (w, glyph,
26028 &new_cursor_width, &active_cursor);
26030 /* If cursor is currently being shown and we don't want it to be or
26031 it is in the wrong place, or the cursor type is not what we want,
26032 erase it. */
26033 if (w->phys_cursor_on_p
26034 && (!on
26035 || w->phys_cursor.x != x
26036 || w->phys_cursor.y != y
26037 || new_cursor_type != w->phys_cursor_type
26038 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26039 && new_cursor_width != w->phys_cursor_width)))
26040 erase_phys_cursor (w);
26042 /* Don't check phys_cursor_on_p here because that flag is only set
26043 to zero in some cases where we know that the cursor has been
26044 completely erased, to avoid the extra work of erasing the cursor
26045 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26046 still not be visible, or it has only been partly erased. */
26047 if (on)
26049 w->phys_cursor_ascent = glyph_row->ascent;
26050 w->phys_cursor_height = glyph_row->height;
26052 /* Set phys_cursor_.* before x_draw_.* is called because some
26053 of them may need the information. */
26054 w->phys_cursor.x = x;
26055 w->phys_cursor.y = glyph_row->y;
26056 w->phys_cursor.hpos = hpos;
26057 w->phys_cursor.vpos = vpos;
26060 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26061 new_cursor_type, new_cursor_width,
26062 on, active_cursor);
26066 /* Switch the display of W's cursor on or off, according to the value
26067 of ON. */
26069 static void
26070 update_window_cursor (struct window *w, int on)
26072 /* Don't update cursor in windows whose frame is in the process
26073 of being deleted. */
26074 if (w->current_matrix)
26076 int hpos = w->phys_cursor.hpos;
26077 int vpos = w->phys_cursor.vpos;
26078 struct glyph_row *row;
26080 if (vpos >= w->current_matrix->nrows
26081 || hpos >= w->current_matrix->matrix_w)
26082 return;
26084 row = MATRIX_ROW (w->current_matrix, vpos);
26086 /* When the window is hscrolled, cursor hpos can legitimately be
26087 out of bounds, but we draw the cursor at the corresponding
26088 window margin in that case. */
26089 if (!row->reversed_p && hpos < 0)
26090 hpos = 0;
26091 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26092 hpos = row->used[TEXT_AREA] - 1;
26094 block_input ();
26095 display_and_set_cursor (w, on, hpos, vpos,
26096 w->phys_cursor.x, w->phys_cursor.y);
26097 unblock_input ();
26102 /* Call update_window_cursor with parameter ON_P on all leaf windows
26103 in the window tree rooted at W. */
26105 static void
26106 update_cursor_in_window_tree (struct window *w, int on_p)
26108 while (w)
26110 if (WINDOWP (w->contents))
26111 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26112 else
26113 update_window_cursor (w, on_p);
26115 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26120 /* EXPORT:
26121 Display the cursor on window W, or clear it, according to ON_P.
26122 Don't change the cursor's position. */
26124 void
26125 x_update_cursor (struct frame *f, int on_p)
26127 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26131 /* EXPORT:
26132 Clear the cursor of window W to background color, and mark the
26133 cursor as not shown. This is used when the text where the cursor
26134 is about to be rewritten. */
26136 void
26137 x_clear_cursor (struct window *w)
26139 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26140 update_window_cursor (w, 0);
26143 #endif /* HAVE_WINDOW_SYSTEM */
26145 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26146 and MSDOS. */
26147 static void
26148 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26149 int start_hpos, int end_hpos,
26150 enum draw_glyphs_face draw)
26152 #ifdef HAVE_WINDOW_SYSTEM
26153 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26155 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26156 return;
26158 #endif
26159 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26160 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26161 #endif
26164 /* Display the active region described by mouse_face_* according to DRAW. */
26166 static void
26167 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26169 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26170 struct frame *f = XFRAME (WINDOW_FRAME (w));
26172 if (/* If window is in the process of being destroyed, don't bother
26173 to do anything. */
26174 w->current_matrix != NULL
26175 /* Don't update mouse highlight if hidden */
26176 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26177 /* Recognize when we are called to operate on rows that don't exist
26178 anymore. This can happen when a window is split. */
26179 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26181 int phys_cursor_on_p = w->phys_cursor_on_p;
26182 struct glyph_row *row, *first, *last;
26184 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26185 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26187 for (row = first; row <= last && row->enabled_p; ++row)
26189 int start_hpos, end_hpos, start_x;
26191 /* For all but the first row, the highlight starts at column 0. */
26192 if (row == first)
26194 /* R2L rows have BEG and END in reversed order, but the
26195 screen drawing geometry is always left to right. So
26196 we need to mirror the beginning and end of the
26197 highlighted area in R2L rows. */
26198 if (!row->reversed_p)
26200 start_hpos = hlinfo->mouse_face_beg_col;
26201 start_x = hlinfo->mouse_face_beg_x;
26203 else if (row == last)
26205 start_hpos = hlinfo->mouse_face_end_col;
26206 start_x = hlinfo->mouse_face_end_x;
26208 else
26210 start_hpos = 0;
26211 start_x = 0;
26214 else if (row->reversed_p && row == last)
26216 start_hpos = hlinfo->mouse_face_end_col;
26217 start_x = hlinfo->mouse_face_end_x;
26219 else
26221 start_hpos = 0;
26222 start_x = 0;
26225 if (row == last)
26227 if (!row->reversed_p)
26228 end_hpos = hlinfo->mouse_face_end_col;
26229 else if (row == first)
26230 end_hpos = hlinfo->mouse_face_beg_col;
26231 else
26233 end_hpos = row->used[TEXT_AREA];
26234 if (draw == DRAW_NORMAL_TEXT)
26235 row->fill_line_p = 1; /* Clear to end of line */
26238 else if (row->reversed_p && row == first)
26239 end_hpos = hlinfo->mouse_face_beg_col;
26240 else
26242 end_hpos = row->used[TEXT_AREA];
26243 if (draw == DRAW_NORMAL_TEXT)
26244 row->fill_line_p = 1; /* Clear to end of line */
26247 if (end_hpos > start_hpos)
26249 draw_row_with_mouse_face (w, start_x, row,
26250 start_hpos, end_hpos, draw);
26252 row->mouse_face_p
26253 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26257 #ifdef HAVE_WINDOW_SYSTEM
26258 /* When we've written over the cursor, arrange for it to
26259 be displayed again. */
26260 if (FRAME_WINDOW_P (f)
26261 && phys_cursor_on_p && !w->phys_cursor_on_p)
26263 int hpos = w->phys_cursor.hpos;
26265 /* When the window is hscrolled, cursor hpos can legitimately be
26266 out of bounds, but we draw the cursor at the corresponding
26267 window margin in that case. */
26268 if (!row->reversed_p && hpos < 0)
26269 hpos = 0;
26270 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26271 hpos = row->used[TEXT_AREA] - 1;
26273 block_input ();
26274 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26275 w->phys_cursor.x, w->phys_cursor.y);
26276 unblock_input ();
26278 #endif /* HAVE_WINDOW_SYSTEM */
26281 #ifdef HAVE_WINDOW_SYSTEM
26282 /* Change the mouse cursor. */
26283 if (FRAME_WINDOW_P (f))
26285 if (draw == DRAW_NORMAL_TEXT
26286 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26287 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26288 else if (draw == DRAW_MOUSE_FACE)
26289 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26290 else
26291 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26293 #endif /* HAVE_WINDOW_SYSTEM */
26296 /* EXPORT:
26297 Clear out the mouse-highlighted active region.
26298 Redraw it un-highlighted first. Value is non-zero if mouse
26299 face was actually drawn unhighlighted. */
26302 clear_mouse_face (Mouse_HLInfo *hlinfo)
26304 int cleared = 0;
26306 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26308 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26309 cleared = 1;
26312 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26313 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26314 hlinfo->mouse_face_window = Qnil;
26315 hlinfo->mouse_face_overlay = Qnil;
26316 return cleared;
26319 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26320 within the mouse face on that window. */
26321 static int
26322 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26324 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26326 /* Quickly resolve the easy cases. */
26327 if (!(WINDOWP (hlinfo->mouse_face_window)
26328 && XWINDOW (hlinfo->mouse_face_window) == w))
26329 return 0;
26330 if (vpos < hlinfo->mouse_face_beg_row
26331 || vpos > hlinfo->mouse_face_end_row)
26332 return 0;
26333 if (vpos > hlinfo->mouse_face_beg_row
26334 && vpos < hlinfo->mouse_face_end_row)
26335 return 1;
26337 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26339 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26341 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26342 return 1;
26344 else if ((vpos == hlinfo->mouse_face_beg_row
26345 && hpos >= hlinfo->mouse_face_beg_col)
26346 || (vpos == hlinfo->mouse_face_end_row
26347 && hpos < hlinfo->mouse_face_end_col))
26348 return 1;
26350 else
26352 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26354 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26355 return 1;
26357 else if ((vpos == hlinfo->mouse_face_beg_row
26358 && hpos <= hlinfo->mouse_face_beg_col)
26359 || (vpos == hlinfo->mouse_face_end_row
26360 && hpos > hlinfo->mouse_face_end_col))
26361 return 1;
26363 return 0;
26367 /* EXPORT:
26368 Non-zero if physical cursor of window W is within mouse face. */
26371 cursor_in_mouse_face_p (struct window *w)
26373 int hpos = w->phys_cursor.hpos;
26374 int vpos = w->phys_cursor.vpos;
26375 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26377 /* When the window is hscrolled, cursor hpos can legitimately be out
26378 of bounds, but we draw the cursor at the corresponding window
26379 margin in that case. */
26380 if (!row->reversed_p && hpos < 0)
26381 hpos = 0;
26382 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26383 hpos = row->used[TEXT_AREA] - 1;
26385 return coords_in_mouse_face_p (w, hpos, vpos);
26390 /* Find the glyph rows START_ROW and END_ROW of window W that display
26391 characters between buffer positions START_CHARPOS and END_CHARPOS
26392 (excluding END_CHARPOS). DISP_STRING is a display string that
26393 covers these buffer positions. This is similar to
26394 row_containing_pos, but is more accurate when bidi reordering makes
26395 buffer positions change non-linearly with glyph rows. */
26396 static void
26397 rows_from_pos_range (struct window *w,
26398 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26399 Lisp_Object disp_string,
26400 struct glyph_row **start, struct glyph_row **end)
26402 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26403 int last_y = window_text_bottom_y (w);
26404 struct glyph_row *row;
26406 *start = NULL;
26407 *end = NULL;
26409 while (!first->enabled_p
26410 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26411 first++;
26413 /* Find the START row. */
26414 for (row = first;
26415 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26416 row++)
26418 /* A row can potentially be the START row if the range of the
26419 characters it displays intersects the range
26420 [START_CHARPOS..END_CHARPOS). */
26421 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26422 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26423 /* See the commentary in row_containing_pos, for the
26424 explanation of the complicated way to check whether
26425 some position is beyond the end of the characters
26426 displayed by a row. */
26427 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26428 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26429 && !row->ends_at_zv_p
26430 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26431 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26432 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26433 && !row->ends_at_zv_p
26434 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26436 /* Found a candidate row. Now make sure at least one of the
26437 glyphs it displays has a charpos from the range
26438 [START_CHARPOS..END_CHARPOS).
26440 This is not obvious because bidi reordering could make
26441 buffer positions of a row be 1,2,3,102,101,100, and if we
26442 want to highlight characters in [50..60), we don't want
26443 this row, even though [50..60) does intersect [1..103),
26444 the range of character positions given by the row's start
26445 and end positions. */
26446 struct glyph *g = row->glyphs[TEXT_AREA];
26447 struct glyph *e = g + row->used[TEXT_AREA];
26449 while (g < e)
26451 if (((BUFFERP (g->object) || INTEGERP (g->object))
26452 && start_charpos <= g->charpos && g->charpos < end_charpos)
26453 /* A glyph that comes from DISP_STRING is by
26454 definition to be highlighted. */
26455 || EQ (g->object, disp_string))
26456 *start = row;
26457 g++;
26459 if (*start)
26460 break;
26464 /* Find the END row. */
26465 if (!*start
26466 /* If the last row is partially visible, start looking for END
26467 from that row, instead of starting from FIRST. */
26468 && !(row->enabled_p
26469 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26470 row = first;
26471 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26473 struct glyph_row *next = row + 1;
26474 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26476 if (!next->enabled_p
26477 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26478 /* The first row >= START whose range of displayed characters
26479 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26480 is the row END + 1. */
26481 || (start_charpos < next_start
26482 && end_charpos < next_start)
26483 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26484 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26485 && !next->ends_at_zv_p
26486 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26487 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26488 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26489 && !next->ends_at_zv_p
26490 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26492 *end = row;
26493 break;
26495 else
26497 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26498 but none of the characters it displays are in the range, it is
26499 also END + 1. */
26500 struct glyph *g = next->glyphs[TEXT_AREA];
26501 struct glyph *s = g;
26502 struct glyph *e = g + next->used[TEXT_AREA];
26504 while (g < e)
26506 if (((BUFFERP (g->object) || INTEGERP (g->object))
26507 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26508 /* If the buffer position of the first glyph in
26509 the row is equal to END_CHARPOS, it means
26510 the last character to be highlighted is the
26511 newline of ROW, and we must consider NEXT as
26512 END, not END+1. */
26513 || (((!next->reversed_p && g == s)
26514 || (next->reversed_p && g == e - 1))
26515 && (g->charpos == end_charpos
26516 /* Special case for when NEXT is an
26517 empty line at ZV. */
26518 || (g->charpos == -1
26519 && !row->ends_at_zv_p
26520 && next_start == end_charpos)))))
26521 /* A glyph that comes from DISP_STRING is by
26522 definition to be highlighted. */
26523 || EQ (g->object, disp_string))
26524 break;
26525 g++;
26527 if (g == e)
26529 *end = row;
26530 break;
26532 /* The first row that ends at ZV must be the last to be
26533 highlighted. */
26534 else if (next->ends_at_zv_p)
26536 *end = next;
26537 break;
26543 /* This function sets the mouse_face_* elements of HLINFO, assuming
26544 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26545 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26546 for the overlay or run of text properties specifying the mouse
26547 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26548 before-string and after-string that must also be highlighted.
26549 DISP_STRING, if non-nil, is a display string that may cover some
26550 or all of the highlighted text. */
26552 static void
26553 mouse_face_from_buffer_pos (Lisp_Object window,
26554 Mouse_HLInfo *hlinfo,
26555 ptrdiff_t mouse_charpos,
26556 ptrdiff_t start_charpos,
26557 ptrdiff_t end_charpos,
26558 Lisp_Object before_string,
26559 Lisp_Object after_string,
26560 Lisp_Object disp_string)
26562 struct window *w = XWINDOW (window);
26563 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26564 struct glyph_row *r1, *r2;
26565 struct glyph *glyph, *end;
26566 ptrdiff_t ignore, pos;
26567 int x;
26569 eassert (NILP (disp_string) || STRINGP (disp_string));
26570 eassert (NILP (before_string) || STRINGP (before_string));
26571 eassert (NILP (after_string) || STRINGP (after_string));
26573 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26574 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26575 if (r1 == NULL)
26576 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26577 /* If the before-string or display-string contains newlines,
26578 rows_from_pos_range skips to its last row. Move back. */
26579 if (!NILP (before_string) || !NILP (disp_string))
26581 struct glyph_row *prev;
26582 while ((prev = r1 - 1, prev >= first)
26583 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26584 && prev->used[TEXT_AREA] > 0)
26586 struct glyph *beg = prev->glyphs[TEXT_AREA];
26587 glyph = beg + prev->used[TEXT_AREA];
26588 while (--glyph >= beg && INTEGERP (glyph->object));
26589 if (glyph < beg
26590 || !(EQ (glyph->object, before_string)
26591 || EQ (glyph->object, disp_string)))
26592 break;
26593 r1 = prev;
26596 if (r2 == NULL)
26598 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26599 hlinfo->mouse_face_past_end = 1;
26601 else if (!NILP (after_string))
26603 /* If the after-string has newlines, advance to its last row. */
26604 struct glyph_row *next;
26605 struct glyph_row *last
26606 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26608 for (next = r2 + 1;
26609 next <= last
26610 && next->used[TEXT_AREA] > 0
26611 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
26612 ++next)
26613 r2 = next;
26615 /* The rest of the display engine assumes that mouse_face_beg_row is
26616 either above mouse_face_end_row or identical to it. But with
26617 bidi-reordered continued lines, the row for START_CHARPOS could
26618 be below the row for END_CHARPOS. If so, swap the rows and store
26619 them in correct order. */
26620 if (r1->y > r2->y)
26622 struct glyph_row *tem = r2;
26624 r2 = r1;
26625 r1 = tem;
26628 hlinfo->mouse_face_beg_y = r1->y;
26629 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
26630 hlinfo->mouse_face_end_y = r2->y;
26631 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
26633 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26634 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26635 could be anywhere in the row and in any order. The strategy
26636 below is to find the leftmost and the rightmost glyph that
26637 belongs to either of these 3 strings, or whose position is
26638 between START_CHARPOS and END_CHARPOS, and highlight all the
26639 glyphs between those two. This may cover more than just the text
26640 between START_CHARPOS and END_CHARPOS if the range of characters
26641 strides the bidi level boundary, e.g. if the beginning is in R2L
26642 text while the end is in L2R text or vice versa. */
26643 if (!r1->reversed_p)
26645 /* This row is in a left to right paragraph. Scan it left to
26646 right. */
26647 glyph = r1->glyphs[TEXT_AREA];
26648 end = glyph + r1->used[TEXT_AREA];
26649 x = r1->x;
26651 /* Skip truncation glyphs at the start of the glyph row. */
26652 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
26653 for (; glyph < end
26654 && INTEGERP (glyph->object)
26655 && glyph->charpos < 0;
26656 ++glyph)
26657 x += glyph->pixel_width;
26659 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26660 or DISP_STRING, and the first glyph from buffer whose
26661 position is between START_CHARPOS and END_CHARPOS. */
26662 for (; glyph < end
26663 && !INTEGERP (glyph->object)
26664 && !EQ (glyph->object, disp_string)
26665 && !(BUFFERP (glyph->object)
26666 && (glyph->charpos >= start_charpos
26667 && glyph->charpos < end_charpos));
26668 ++glyph)
26670 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26671 are present at buffer positions between START_CHARPOS and
26672 END_CHARPOS, or if they come from an overlay. */
26673 if (EQ (glyph->object, before_string))
26675 pos = string_buffer_position (before_string,
26676 start_charpos);
26677 /* If pos == 0, it means before_string came from an
26678 overlay, not from a buffer position. */
26679 if (!pos || (pos >= start_charpos && pos < end_charpos))
26680 break;
26682 else if (EQ (glyph->object, after_string))
26684 pos = string_buffer_position (after_string, end_charpos);
26685 if (!pos || (pos >= start_charpos && pos < end_charpos))
26686 break;
26688 x += glyph->pixel_width;
26690 hlinfo->mouse_face_beg_x = x;
26691 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26693 else
26695 /* This row is in a right to left paragraph. Scan it right to
26696 left. */
26697 struct glyph *g;
26699 end = r1->glyphs[TEXT_AREA] - 1;
26700 glyph = end + r1->used[TEXT_AREA];
26702 /* Skip truncation glyphs at the start of the glyph row. */
26703 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
26704 for (; glyph > end
26705 && INTEGERP (glyph->object)
26706 && glyph->charpos < 0;
26707 --glyph)
26710 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26711 or DISP_STRING, and the first glyph from buffer whose
26712 position is between START_CHARPOS and END_CHARPOS. */
26713 for (; glyph > end
26714 && !INTEGERP (glyph->object)
26715 && !EQ (glyph->object, disp_string)
26716 && !(BUFFERP (glyph->object)
26717 && (glyph->charpos >= start_charpos
26718 && glyph->charpos < end_charpos));
26719 --glyph)
26721 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26722 are present at buffer positions between START_CHARPOS and
26723 END_CHARPOS, or if they come from an overlay. */
26724 if (EQ (glyph->object, before_string))
26726 pos = string_buffer_position (before_string, start_charpos);
26727 /* If pos == 0, it means before_string came from an
26728 overlay, not from a buffer position. */
26729 if (!pos || (pos >= start_charpos && pos < end_charpos))
26730 break;
26732 else if (EQ (glyph->object, after_string))
26734 pos = string_buffer_position (after_string, end_charpos);
26735 if (!pos || (pos >= start_charpos && pos < end_charpos))
26736 break;
26740 glyph++; /* first glyph to the right of the highlighted area */
26741 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26742 x += g->pixel_width;
26743 hlinfo->mouse_face_beg_x = x;
26744 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26747 /* If the highlight ends in a different row, compute GLYPH and END
26748 for the end row. Otherwise, reuse the values computed above for
26749 the row where the highlight begins. */
26750 if (r2 != r1)
26752 if (!r2->reversed_p)
26754 glyph = r2->glyphs[TEXT_AREA];
26755 end = glyph + r2->used[TEXT_AREA];
26756 x = r2->x;
26758 else
26760 end = r2->glyphs[TEXT_AREA] - 1;
26761 glyph = end + r2->used[TEXT_AREA];
26765 if (!r2->reversed_p)
26767 /* Skip truncation and continuation glyphs near the end of the
26768 row, and also blanks and stretch glyphs inserted by
26769 extend_face_to_end_of_line. */
26770 while (end > glyph
26771 && INTEGERP ((end - 1)->object))
26772 --end;
26773 /* Scan the rest of the glyph row from the end, looking for the
26774 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26775 DISP_STRING, or whose position is between START_CHARPOS
26776 and END_CHARPOS */
26777 for (--end;
26778 end > glyph
26779 && !INTEGERP (end->object)
26780 && !EQ (end->object, disp_string)
26781 && !(BUFFERP (end->object)
26782 && (end->charpos >= start_charpos
26783 && end->charpos < end_charpos));
26784 --end)
26786 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26787 are present at buffer positions between START_CHARPOS and
26788 END_CHARPOS, or if they come from an overlay. */
26789 if (EQ (end->object, before_string))
26791 pos = string_buffer_position (before_string, start_charpos);
26792 if (!pos || (pos >= start_charpos && pos < end_charpos))
26793 break;
26795 else if (EQ (end->object, after_string))
26797 pos = string_buffer_position (after_string, end_charpos);
26798 if (!pos || (pos >= start_charpos && pos < end_charpos))
26799 break;
26802 /* Find the X coordinate of the last glyph to be highlighted. */
26803 for (; glyph <= end; ++glyph)
26804 x += glyph->pixel_width;
26806 hlinfo->mouse_face_end_x = x;
26807 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26809 else
26811 /* Skip truncation and continuation glyphs near the end of the
26812 row, and also blanks and stretch glyphs inserted by
26813 extend_face_to_end_of_line. */
26814 x = r2->x;
26815 end++;
26816 while (end < glyph
26817 && INTEGERP (end->object))
26819 x += end->pixel_width;
26820 ++end;
26822 /* Scan the rest of the glyph row from the end, looking for the
26823 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26824 DISP_STRING, or whose position is between START_CHARPOS
26825 and END_CHARPOS */
26826 for ( ;
26827 end < glyph
26828 && !INTEGERP (end->object)
26829 && !EQ (end->object, disp_string)
26830 && !(BUFFERP (end->object)
26831 && (end->charpos >= start_charpos
26832 && end->charpos < end_charpos));
26833 ++end)
26835 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26836 are present at buffer positions between START_CHARPOS and
26837 END_CHARPOS, or if they come from an overlay. */
26838 if (EQ (end->object, before_string))
26840 pos = string_buffer_position (before_string, start_charpos);
26841 if (!pos || (pos >= start_charpos && pos < end_charpos))
26842 break;
26844 else if (EQ (end->object, after_string))
26846 pos = string_buffer_position (after_string, end_charpos);
26847 if (!pos || (pos >= start_charpos && pos < end_charpos))
26848 break;
26850 x += end->pixel_width;
26852 /* If we exited the above loop because we arrived at the last
26853 glyph of the row, and its buffer position is still not in
26854 range, it means the last character in range is the preceding
26855 newline. Bump the end column and x values to get past the
26856 last glyph. */
26857 if (end == glyph
26858 && BUFFERP (end->object)
26859 && (end->charpos < start_charpos
26860 || end->charpos >= end_charpos))
26862 x += end->pixel_width;
26863 ++end;
26865 hlinfo->mouse_face_end_x = x;
26866 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26869 hlinfo->mouse_face_window = window;
26870 hlinfo->mouse_face_face_id
26871 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26872 mouse_charpos + 1,
26873 !hlinfo->mouse_face_hidden, -1);
26874 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26877 /* The following function is not used anymore (replaced with
26878 mouse_face_from_string_pos), but I leave it here for the time
26879 being, in case someone would. */
26881 #if 0 /* not used */
26883 /* Find the position of the glyph for position POS in OBJECT in
26884 window W's current matrix, and return in *X, *Y the pixel
26885 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26887 RIGHT_P non-zero means return the position of the right edge of the
26888 glyph, RIGHT_P zero means return the left edge position.
26890 If no glyph for POS exists in the matrix, return the position of
26891 the glyph with the next smaller position that is in the matrix, if
26892 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26893 exists in the matrix, return the position of the glyph with the
26894 next larger position in OBJECT.
26896 Value is non-zero if a glyph was found. */
26898 static int
26899 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
26900 int *hpos, int *vpos, int *x, int *y, int right_p)
26902 int yb = window_text_bottom_y (w);
26903 struct glyph_row *r;
26904 struct glyph *best_glyph = NULL;
26905 struct glyph_row *best_row = NULL;
26906 int best_x = 0;
26908 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26909 r->enabled_p && r->y < yb;
26910 ++r)
26912 struct glyph *g = r->glyphs[TEXT_AREA];
26913 struct glyph *e = g + r->used[TEXT_AREA];
26914 int gx;
26916 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26917 if (EQ (g->object, object))
26919 if (g->charpos == pos)
26921 best_glyph = g;
26922 best_x = gx;
26923 best_row = r;
26924 goto found;
26926 else if (best_glyph == NULL
26927 || ((eabs (g->charpos - pos)
26928 < eabs (best_glyph->charpos - pos))
26929 && (right_p
26930 ? g->charpos < pos
26931 : g->charpos > pos)))
26933 best_glyph = g;
26934 best_x = gx;
26935 best_row = r;
26940 found:
26942 if (best_glyph)
26944 *x = best_x;
26945 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26947 if (right_p)
26949 *x += best_glyph->pixel_width;
26950 ++*hpos;
26953 *y = best_row->y;
26954 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
26957 return best_glyph != NULL;
26959 #endif /* not used */
26961 /* Find the positions of the first and the last glyphs in window W's
26962 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26963 (assumed to be a string), and return in HLINFO's mouse_face_*
26964 members the pixel and column/row coordinates of those glyphs. */
26966 static void
26967 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26968 Lisp_Object object,
26969 ptrdiff_t startpos, ptrdiff_t endpos)
26971 int yb = window_text_bottom_y (w);
26972 struct glyph_row *r;
26973 struct glyph *g, *e;
26974 int gx;
26975 int found = 0;
26977 /* Find the glyph row with at least one position in the range
26978 [STARTPOS..ENDPOS], and the first glyph in that row whose
26979 position belongs to that range. */
26980 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26981 r->enabled_p && r->y < yb;
26982 ++r)
26984 if (!r->reversed_p)
26986 g = r->glyphs[TEXT_AREA];
26987 e = g + r->used[TEXT_AREA];
26988 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26989 if (EQ (g->object, object)
26990 && startpos <= g->charpos && g->charpos <= endpos)
26992 hlinfo->mouse_face_beg_row
26993 = MATRIX_ROW_VPOS (r, w->current_matrix);
26994 hlinfo->mouse_face_beg_y = r->y;
26995 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26996 hlinfo->mouse_face_beg_x = gx;
26997 found = 1;
26998 break;
27001 else
27003 struct glyph *g1;
27005 e = r->glyphs[TEXT_AREA];
27006 g = e + r->used[TEXT_AREA];
27007 for ( ; g > e; --g)
27008 if (EQ ((g-1)->object, object)
27009 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27011 hlinfo->mouse_face_beg_row
27012 = MATRIX_ROW_VPOS (r, w->current_matrix);
27013 hlinfo->mouse_face_beg_y = r->y;
27014 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27015 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27016 gx += g1->pixel_width;
27017 hlinfo->mouse_face_beg_x = gx;
27018 found = 1;
27019 break;
27022 if (found)
27023 break;
27026 if (!found)
27027 return;
27029 /* Starting with the next row, look for the first row which does NOT
27030 include any glyphs whose positions are in the range. */
27031 for (++r; r->enabled_p && r->y < yb; ++r)
27033 g = r->glyphs[TEXT_AREA];
27034 e = g + r->used[TEXT_AREA];
27035 found = 0;
27036 for ( ; g < e; ++g)
27037 if (EQ (g->object, object)
27038 && startpos <= g->charpos && g->charpos <= endpos)
27040 found = 1;
27041 break;
27043 if (!found)
27044 break;
27047 /* The highlighted region ends on the previous row. */
27048 r--;
27050 /* Set the end row and its vertical pixel coordinate. */
27051 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27052 hlinfo->mouse_face_end_y = r->y;
27054 /* Compute and set the end column and the end column's horizontal
27055 pixel coordinate. */
27056 if (!r->reversed_p)
27058 g = r->glyphs[TEXT_AREA];
27059 e = g + r->used[TEXT_AREA];
27060 for ( ; e > g; --e)
27061 if (EQ ((e-1)->object, object)
27062 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27063 break;
27064 hlinfo->mouse_face_end_col = e - g;
27066 for (gx = r->x; g < e; ++g)
27067 gx += g->pixel_width;
27068 hlinfo->mouse_face_end_x = gx;
27070 else
27072 e = r->glyphs[TEXT_AREA];
27073 g = e + r->used[TEXT_AREA];
27074 for (gx = r->x ; e < g; ++e)
27076 if (EQ (e->object, object)
27077 && startpos <= e->charpos && e->charpos <= endpos)
27078 break;
27079 gx += e->pixel_width;
27081 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27082 hlinfo->mouse_face_end_x = gx;
27086 #ifdef HAVE_WINDOW_SYSTEM
27088 /* See if position X, Y is within a hot-spot of an image. */
27090 static int
27091 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27093 if (!CONSP (hot_spot))
27094 return 0;
27096 if (EQ (XCAR (hot_spot), Qrect))
27098 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27099 Lisp_Object rect = XCDR (hot_spot);
27100 Lisp_Object tem;
27101 if (!CONSP (rect))
27102 return 0;
27103 if (!CONSP (XCAR (rect)))
27104 return 0;
27105 if (!CONSP (XCDR (rect)))
27106 return 0;
27107 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27108 return 0;
27109 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27110 return 0;
27111 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27112 return 0;
27113 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27114 return 0;
27115 return 1;
27117 else if (EQ (XCAR (hot_spot), Qcircle))
27119 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27120 Lisp_Object circ = XCDR (hot_spot);
27121 Lisp_Object lr, lx0, ly0;
27122 if (CONSP (circ)
27123 && CONSP (XCAR (circ))
27124 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27125 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27126 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27128 double r = XFLOATINT (lr);
27129 double dx = XINT (lx0) - x;
27130 double dy = XINT (ly0) - y;
27131 return (dx * dx + dy * dy <= r * r);
27134 else if (EQ (XCAR (hot_spot), Qpoly))
27136 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27137 if (VECTORP (XCDR (hot_spot)))
27139 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27140 Lisp_Object *poly = v->contents;
27141 ptrdiff_t n = v->header.size;
27142 ptrdiff_t i;
27143 int inside = 0;
27144 Lisp_Object lx, ly;
27145 int x0, y0;
27147 /* Need an even number of coordinates, and at least 3 edges. */
27148 if (n < 6 || n & 1)
27149 return 0;
27151 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27152 If count is odd, we are inside polygon. Pixels on edges
27153 may or may not be included depending on actual geometry of the
27154 polygon. */
27155 if ((lx = poly[n-2], !INTEGERP (lx))
27156 || (ly = poly[n-1], !INTEGERP (lx)))
27157 return 0;
27158 x0 = XINT (lx), y0 = XINT (ly);
27159 for (i = 0; i < n; i += 2)
27161 int x1 = x0, y1 = y0;
27162 if ((lx = poly[i], !INTEGERP (lx))
27163 || (ly = poly[i+1], !INTEGERP (ly)))
27164 return 0;
27165 x0 = XINT (lx), y0 = XINT (ly);
27167 /* Does this segment cross the X line? */
27168 if (x0 >= x)
27170 if (x1 >= x)
27171 continue;
27173 else if (x1 < x)
27174 continue;
27175 if (y > y0 && y > y1)
27176 continue;
27177 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27178 inside = !inside;
27180 return inside;
27183 return 0;
27186 Lisp_Object
27187 find_hot_spot (Lisp_Object map, int x, int y)
27189 while (CONSP (map))
27191 if (CONSP (XCAR (map))
27192 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27193 return XCAR (map);
27194 map = XCDR (map);
27197 return Qnil;
27200 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27201 3, 3, 0,
27202 doc: /* Lookup in image map MAP coordinates X and Y.
27203 An image map is an alist where each element has the format (AREA ID PLIST).
27204 An AREA is specified as either a rectangle, a circle, or a polygon:
27205 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27206 pixel coordinates of the upper left and bottom right corners.
27207 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27208 and the radius of the circle; r may be a float or integer.
27209 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27210 vector describes one corner in the polygon.
27211 Returns the alist element for the first matching AREA in MAP. */)
27212 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27214 if (NILP (map))
27215 return Qnil;
27217 CHECK_NUMBER (x);
27218 CHECK_NUMBER (y);
27220 return find_hot_spot (map,
27221 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27222 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27226 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27227 static void
27228 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27230 /* Do not change cursor shape while dragging mouse. */
27231 if (!NILP (do_mouse_tracking))
27232 return;
27234 if (!NILP (pointer))
27236 if (EQ (pointer, Qarrow))
27237 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27238 else if (EQ (pointer, Qhand))
27239 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27240 else if (EQ (pointer, Qtext))
27241 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27242 else if (EQ (pointer, intern ("hdrag")))
27243 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27244 #ifdef HAVE_X_WINDOWS
27245 else if (EQ (pointer, intern ("vdrag")))
27246 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27247 #endif
27248 else if (EQ (pointer, intern ("hourglass")))
27249 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27250 else if (EQ (pointer, Qmodeline))
27251 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27252 else
27253 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27256 if (cursor != No_Cursor)
27257 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27260 #endif /* HAVE_WINDOW_SYSTEM */
27262 /* Take proper action when mouse has moved to the mode or header line
27263 or marginal area AREA of window W, x-position X and y-position Y.
27264 X is relative to the start of the text display area of W, so the
27265 width of bitmap areas and scroll bars must be subtracted to get a
27266 position relative to the start of the mode line. */
27268 static void
27269 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27270 enum window_part area)
27272 struct window *w = XWINDOW (window);
27273 struct frame *f = XFRAME (w->frame);
27274 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27275 #ifdef HAVE_WINDOW_SYSTEM
27276 Display_Info *dpyinfo;
27277 #endif
27278 Cursor cursor = No_Cursor;
27279 Lisp_Object pointer = Qnil;
27280 int dx, dy, width, height;
27281 ptrdiff_t charpos;
27282 Lisp_Object string, object = Qnil;
27283 Lisp_Object pos IF_LINT (= Qnil), help;
27285 Lisp_Object mouse_face;
27286 int original_x_pixel = x;
27287 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27288 struct glyph_row *row IF_LINT (= 0);
27290 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27292 int x0;
27293 struct glyph *end;
27295 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27296 returns them in row/column units! */
27297 string = mode_line_string (w, area, &x, &y, &charpos,
27298 &object, &dx, &dy, &width, &height);
27300 row = (area == ON_MODE_LINE
27301 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27302 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27304 /* Find the glyph under the mouse pointer. */
27305 if (row->mode_line_p && row->enabled_p)
27307 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27308 end = glyph + row->used[TEXT_AREA];
27310 for (x0 = original_x_pixel;
27311 glyph < end && x0 >= glyph->pixel_width;
27312 ++glyph)
27313 x0 -= glyph->pixel_width;
27315 if (glyph >= end)
27316 glyph = NULL;
27319 else
27321 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27322 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27323 returns them in row/column units! */
27324 string = marginal_area_string (w, area, &x, &y, &charpos,
27325 &object, &dx, &dy, &width, &height);
27328 help = Qnil;
27330 #ifdef HAVE_WINDOW_SYSTEM
27331 if (IMAGEP (object))
27333 Lisp_Object image_map, hotspot;
27334 if ((image_map = Fplist_get (XCDR (object), QCmap),
27335 !NILP (image_map))
27336 && (hotspot = find_hot_spot (image_map, dx, dy),
27337 CONSP (hotspot))
27338 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27340 Lisp_Object plist;
27342 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27343 If so, we could look for mouse-enter, mouse-leave
27344 properties in PLIST (and do something...). */
27345 hotspot = XCDR (hotspot);
27346 if (CONSP (hotspot)
27347 && (plist = XCAR (hotspot), CONSP (plist)))
27349 pointer = Fplist_get (plist, Qpointer);
27350 if (NILP (pointer))
27351 pointer = Qhand;
27352 help = Fplist_get (plist, Qhelp_echo);
27353 if (!NILP (help))
27355 help_echo_string = help;
27356 XSETWINDOW (help_echo_window, w);
27357 help_echo_object = w->contents;
27358 help_echo_pos = charpos;
27362 if (NILP (pointer))
27363 pointer = Fplist_get (XCDR (object), QCpointer);
27365 #endif /* HAVE_WINDOW_SYSTEM */
27367 if (STRINGP (string))
27368 pos = make_number (charpos);
27370 /* Set the help text and mouse pointer. If the mouse is on a part
27371 of the mode line without any text (e.g. past the right edge of
27372 the mode line text), use the default help text and pointer. */
27373 if (STRINGP (string) || area == ON_MODE_LINE)
27375 /* Arrange to display the help by setting the global variables
27376 help_echo_string, help_echo_object, and help_echo_pos. */
27377 if (NILP (help))
27379 if (STRINGP (string))
27380 help = Fget_text_property (pos, Qhelp_echo, string);
27382 if (!NILP (help))
27384 help_echo_string = help;
27385 XSETWINDOW (help_echo_window, w);
27386 help_echo_object = string;
27387 help_echo_pos = charpos;
27389 else if (area == ON_MODE_LINE)
27391 Lisp_Object default_help
27392 = buffer_local_value_1 (Qmode_line_default_help_echo,
27393 w->contents);
27395 if (STRINGP (default_help))
27397 help_echo_string = default_help;
27398 XSETWINDOW (help_echo_window, w);
27399 help_echo_object = Qnil;
27400 help_echo_pos = -1;
27405 #ifdef HAVE_WINDOW_SYSTEM
27406 /* Change the mouse pointer according to what is under it. */
27407 if (FRAME_WINDOW_P (f))
27409 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27410 if (STRINGP (string))
27412 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27414 if (NILP (pointer))
27415 pointer = Fget_text_property (pos, Qpointer, string);
27417 /* Change the mouse pointer according to what is under X/Y. */
27418 if (NILP (pointer)
27419 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27421 Lisp_Object map;
27422 map = Fget_text_property (pos, Qlocal_map, string);
27423 if (!KEYMAPP (map))
27424 map = Fget_text_property (pos, Qkeymap, string);
27425 if (!KEYMAPP (map))
27426 cursor = dpyinfo->vertical_scroll_bar_cursor;
27429 else
27430 /* Default mode-line pointer. */
27431 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27433 #endif
27436 /* Change the mouse face according to what is under X/Y. */
27437 if (STRINGP (string))
27439 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27440 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
27441 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27442 && glyph)
27444 Lisp_Object b, e;
27446 struct glyph * tmp_glyph;
27448 int gpos;
27449 int gseq_length;
27450 int total_pixel_width;
27451 ptrdiff_t begpos, endpos, ignore;
27453 int vpos, hpos;
27455 b = Fprevious_single_property_change (make_number (charpos + 1),
27456 Qmouse_face, string, Qnil);
27457 if (NILP (b))
27458 begpos = 0;
27459 else
27460 begpos = XINT (b);
27462 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27463 if (NILP (e))
27464 endpos = SCHARS (string);
27465 else
27466 endpos = XINT (e);
27468 /* Calculate the glyph position GPOS of GLYPH in the
27469 displayed string, relative to the beginning of the
27470 highlighted part of the string.
27472 Note: GPOS is different from CHARPOS. CHARPOS is the
27473 position of GLYPH in the internal string object. A mode
27474 line string format has structures which are converted to
27475 a flattened string by the Emacs Lisp interpreter. The
27476 internal string is an element of those structures. The
27477 displayed string is the flattened string. */
27478 tmp_glyph = row_start_glyph;
27479 while (tmp_glyph < glyph
27480 && (!(EQ (tmp_glyph->object, glyph->object)
27481 && begpos <= tmp_glyph->charpos
27482 && tmp_glyph->charpos < endpos)))
27483 tmp_glyph++;
27484 gpos = glyph - tmp_glyph;
27486 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27487 the highlighted part of the displayed string to which
27488 GLYPH belongs. Note: GSEQ_LENGTH is different from
27489 SCHARS (STRING), because the latter returns the length of
27490 the internal string. */
27491 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27492 tmp_glyph > glyph
27493 && (!(EQ (tmp_glyph->object, glyph->object)
27494 && begpos <= tmp_glyph->charpos
27495 && tmp_glyph->charpos < endpos));
27496 tmp_glyph--)
27498 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27500 /* Calculate the total pixel width of all the glyphs between
27501 the beginning of the highlighted area and GLYPH. */
27502 total_pixel_width = 0;
27503 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27504 total_pixel_width += tmp_glyph->pixel_width;
27506 /* Pre calculation of re-rendering position. Note: X is in
27507 column units here, after the call to mode_line_string or
27508 marginal_area_string. */
27509 hpos = x - gpos;
27510 vpos = (area == ON_MODE_LINE
27511 ? (w->current_matrix)->nrows - 1
27512 : 0);
27514 /* If GLYPH's position is included in the region that is
27515 already drawn in mouse face, we have nothing to do. */
27516 if ( EQ (window, hlinfo->mouse_face_window)
27517 && (!row->reversed_p
27518 ? (hlinfo->mouse_face_beg_col <= hpos
27519 && hpos < hlinfo->mouse_face_end_col)
27520 /* In R2L rows we swap BEG and END, see below. */
27521 : (hlinfo->mouse_face_end_col <= hpos
27522 && hpos < hlinfo->mouse_face_beg_col))
27523 && hlinfo->mouse_face_beg_row == vpos )
27524 return;
27526 if (clear_mouse_face (hlinfo))
27527 cursor = No_Cursor;
27529 if (!row->reversed_p)
27531 hlinfo->mouse_face_beg_col = hpos;
27532 hlinfo->mouse_face_beg_x = original_x_pixel
27533 - (total_pixel_width + dx);
27534 hlinfo->mouse_face_end_col = hpos + gseq_length;
27535 hlinfo->mouse_face_end_x = 0;
27537 else
27539 /* In R2L rows, show_mouse_face expects BEG and END
27540 coordinates to be swapped. */
27541 hlinfo->mouse_face_end_col = hpos;
27542 hlinfo->mouse_face_end_x = original_x_pixel
27543 - (total_pixel_width + dx);
27544 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27545 hlinfo->mouse_face_beg_x = 0;
27548 hlinfo->mouse_face_beg_row = vpos;
27549 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27550 hlinfo->mouse_face_beg_y = 0;
27551 hlinfo->mouse_face_end_y = 0;
27552 hlinfo->mouse_face_past_end = 0;
27553 hlinfo->mouse_face_window = window;
27555 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27556 charpos,
27557 0, 0, 0,
27558 &ignore,
27559 glyph->face_id,
27561 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27563 if (NILP (pointer))
27564 pointer = Qhand;
27566 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27567 clear_mouse_face (hlinfo);
27569 #ifdef HAVE_WINDOW_SYSTEM
27570 if (FRAME_WINDOW_P (f))
27571 define_frame_cursor1 (f, cursor, pointer);
27572 #endif
27576 /* EXPORT:
27577 Take proper action when the mouse has moved to position X, Y on
27578 frame F with regards to highlighting portions of display that have
27579 mouse-face properties. Also de-highlight portions of display where
27580 the mouse was before, set the mouse pointer shape as appropriate
27581 for the mouse coordinates, and activate help echo (tooltips).
27582 X and Y can be negative or out of range. */
27584 void
27585 note_mouse_highlight (struct frame *f, int x, int y)
27587 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27588 enum window_part part = ON_NOTHING;
27589 Lisp_Object window;
27590 struct window *w;
27591 Cursor cursor = No_Cursor;
27592 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27593 struct buffer *b;
27595 /* When a menu is active, don't highlight because this looks odd. */
27596 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27597 if (popup_activated ())
27598 return;
27599 #endif
27601 if (!f->glyphs_initialized_p
27602 || f->pointer_invisible)
27603 return;
27605 hlinfo->mouse_face_mouse_x = x;
27606 hlinfo->mouse_face_mouse_y = y;
27607 hlinfo->mouse_face_mouse_frame = f;
27609 if (hlinfo->mouse_face_defer)
27610 return;
27612 /* Which window is that in? */
27613 window = window_from_coordinates (f, x, y, &part, 1);
27615 /* If displaying active text in another window, clear that. */
27616 if (! EQ (window, hlinfo->mouse_face_window)
27617 /* Also clear if we move out of text area in same window. */
27618 || (!NILP (hlinfo->mouse_face_window)
27619 && !NILP (window)
27620 && part != ON_TEXT
27621 && part != ON_MODE_LINE
27622 && part != ON_HEADER_LINE))
27623 clear_mouse_face (hlinfo);
27625 /* Not on a window -> return. */
27626 if (!WINDOWP (window))
27627 return;
27629 /* Reset help_echo_string. It will get recomputed below. */
27630 help_echo_string = Qnil;
27632 /* Convert to window-relative pixel coordinates. */
27633 w = XWINDOW (window);
27634 frame_to_window_pixel_xy (w, &x, &y);
27636 #ifdef HAVE_WINDOW_SYSTEM
27637 /* Handle tool-bar window differently since it doesn't display a
27638 buffer. */
27639 if (EQ (window, f->tool_bar_window))
27641 note_tool_bar_highlight (f, x, y);
27642 return;
27644 #endif
27646 /* Mouse is on the mode, header line or margin? */
27647 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
27648 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
27650 note_mode_line_or_margin_highlight (window, x, y, part);
27651 return;
27654 #ifdef HAVE_WINDOW_SYSTEM
27655 if (part == ON_VERTICAL_BORDER)
27657 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27658 help_echo_string = build_string ("drag-mouse-1: resize");
27660 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
27661 || part == ON_SCROLL_BAR)
27662 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27663 else
27664 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27665 #endif
27667 /* Are we in a window whose display is up to date?
27668 And verify the buffer's text has not changed. */
27669 b = XBUFFER (w->contents);
27670 if (part == ON_TEXT
27671 && w->window_end_valid
27672 && w->last_modified == BUF_MODIFF (b)
27673 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
27675 int hpos, vpos, dx, dy, area = LAST_AREA;
27676 ptrdiff_t pos;
27677 struct glyph *glyph;
27678 Lisp_Object object;
27679 Lisp_Object mouse_face = Qnil, position;
27680 Lisp_Object *overlay_vec = NULL;
27681 ptrdiff_t i, noverlays;
27682 struct buffer *obuf;
27683 ptrdiff_t obegv, ozv;
27684 int same_region;
27686 /* Find the glyph under X/Y. */
27687 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
27689 #ifdef HAVE_WINDOW_SYSTEM
27690 /* Look for :pointer property on image. */
27691 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27693 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27694 if (img != NULL && IMAGEP (img->spec))
27696 Lisp_Object image_map, hotspot;
27697 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
27698 !NILP (image_map))
27699 && (hotspot = find_hot_spot (image_map,
27700 glyph->slice.img.x + dx,
27701 glyph->slice.img.y + dy),
27702 CONSP (hotspot))
27703 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27705 Lisp_Object plist;
27707 /* Could check XCAR (hotspot) to see if we enter/leave
27708 this hot-spot.
27709 If so, we could look for mouse-enter, mouse-leave
27710 properties in PLIST (and do something...). */
27711 hotspot = XCDR (hotspot);
27712 if (CONSP (hotspot)
27713 && (plist = XCAR (hotspot), CONSP (plist)))
27715 pointer = Fplist_get (plist, Qpointer);
27716 if (NILP (pointer))
27717 pointer = Qhand;
27718 help_echo_string = Fplist_get (plist, Qhelp_echo);
27719 if (!NILP (help_echo_string))
27721 help_echo_window = window;
27722 help_echo_object = glyph->object;
27723 help_echo_pos = glyph->charpos;
27727 if (NILP (pointer))
27728 pointer = Fplist_get (XCDR (img->spec), QCpointer);
27731 #endif /* HAVE_WINDOW_SYSTEM */
27733 /* Clear mouse face if X/Y not over text. */
27734 if (glyph == NULL
27735 || area != TEXT_AREA
27736 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
27737 /* Glyph's OBJECT is an integer for glyphs inserted by the
27738 display engine for its internal purposes, like truncation
27739 and continuation glyphs and blanks beyond the end of
27740 line's text on text terminals. If we are over such a
27741 glyph, we are not over any text. */
27742 || INTEGERP (glyph->object)
27743 /* R2L rows have a stretch glyph at their front, which
27744 stands for no text, whereas L2R rows have no glyphs at
27745 all beyond the end of text. Treat such stretch glyphs
27746 like we do with NULL glyphs in L2R rows. */
27747 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
27748 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
27749 && glyph->type == STRETCH_GLYPH
27750 && glyph->avoid_cursor_p))
27752 if (clear_mouse_face (hlinfo))
27753 cursor = No_Cursor;
27754 #ifdef HAVE_WINDOW_SYSTEM
27755 if (FRAME_WINDOW_P (f) && NILP (pointer))
27757 if (area != TEXT_AREA)
27758 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27759 else
27760 pointer = Vvoid_text_area_pointer;
27762 #endif
27763 goto set_cursor;
27766 pos = glyph->charpos;
27767 object = glyph->object;
27768 if (!STRINGP (object) && !BUFFERP (object))
27769 goto set_cursor;
27771 /* If we get an out-of-range value, return now; avoid an error. */
27772 if (BUFFERP (object) && pos > BUF_Z (b))
27773 goto set_cursor;
27775 /* Make the window's buffer temporarily current for
27776 overlays_at and compute_char_face. */
27777 obuf = current_buffer;
27778 current_buffer = b;
27779 obegv = BEGV;
27780 ozv = ZV;
27781 BEGV = BEG;
27782 ZV = Z;
27784 /* Is this char mouse-active or does it have help-echo? */
27785 position = make_number (pos);
27787 if (BUFFERP (object))
27789 /* Put all the overlays we want in a vector in overlay_vec. */
27790 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27791 /* Sort overlays into increasing priority order. */
27792 noverlays = sort_overlays (overlay_vec, noverlays, w);
27794 else
27795 noverlays = 0;
27797 if (NILP (Vmouse_highlight))
27799 clear_mouse_face (hlinfo);
27800 goto check_help_echo;
27803 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27805 if (same_region)
27806 cursor = No_Cursor;
27808 /* Check mouse-face highlighting. */
27809 if (! same_region
27810 /* If there exists an overlay with mouse-face overlapping
27811 the one we are currently highlighting, we have to
27812 check if we enter the overlapping overlay, and then
27813 highlight only that. */
27814 || (OVERLAYP (hlinfo->mouse_face_overlay)
27815 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27817 /* Find the highest priority overlay with a mouse-face. */
27818 Lisp_Object overlay = Qnil;
27819 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27821 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27822 if (!NILP (mouse_face))
27823 overlay = overlay_vec[i];
27826 /* If we're highlighting the same overlay as before, there's
27827 no need to do that again. */
27828 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27829 goto check_help_echo;
27830 hlinfo->mouse_face_overlay = overlay;
27832 /* Clear the display of the old active region, if any. */
27833 if (clear_mouse_face (hlinfo))
27834 cursor = No_Cursor;
27836 /* If no overlay applies, get a text property. */
27837 if (NILP (overlay))
27838 mouse_face = Fget_text_property (position, Qmouse_face, object);
27840 /* Next, compute the bounds of the mouse highlighting and
27841 display it. */
27842 if (!NILP (mouse_face) && STRINGP (object))
27844 /* The mouse-highlighting comes from a display string
27845 with a mouse-face. */
27846 Lisp_Object s, e;
27847 ptrdiff_t ignore;
27849 s = Fprevious_single_property_change
27850 (make_number (pos + 1), Qmouse_face, object, Qnil);
27851 e = Fnext_single_property_change
27852 (position, Qmouse_face, object, Qnil);
27853 if (NILP (s))
27854 s = make_number (0);
27855 if (NILP (e))
27856 e = make_number (SCHARS (object) - 1);
27857 mouse_face_from_string_pos (w, hlinfo, object,
27858 XINT (s), XINT (e));
27859 hlinfo->mouse_face_past_end = 0;
27860 hlinfo->mouse_face_window = window;
27861 hlinfo->mouse_face_face_id
27862 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27863 glyph->face_id, 1);
27864 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27865 cursor = No_Cursor;
27867 else
27869 /* The mouse-highlighting, if any, comes from an overlay
27870 or text property in the buffer. */
27871 Lisp_Object buffer IF_LINT (= Qnil);
27872 Lisp_Object disp_string IF_LINT (= Qnil);
27874 if (STRINGP (object))
27876 /* If we are on a display string with no mouse-face,
27877 check if the text under it has one. */
27878 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27879 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27880 pos = string_buffer_position (object, start);
27881 if (pos > 0)
27883 mouse_face = get_char_property_and_overlay
27884 (make_number (pos), Qmouse_face, w->contents, &overlay);
27885 buffer = w->contents;
27886 disp_string = object;
27889 else
27891 buffer = object;
27892 disp_string = Qnil;
27895 if (!NILP (mouse_face))
27897 Lisp_Object before, after;
27898 Lisp_Object before_string, after_string;
27899 /* To correctly find the limits of mouse highlight
27900 in a bidi-reordered buffer, we must not use the
27901 optimization of limiting the search in
27902 previous-single-property-change and
27903 next-single-property-change, because
27904 rows_from_pos_range needs the real start and end
27905 positions to DTRT in this case. That's because
27906 the first row visible in a window does not
27907 necessarily display the character whose position
27908 is the smallest. */
27909 Lisp_Object lim1 =
27910 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27911 ? Fmarker_position (w->start)
27912 : Qnil;
27913 Lisp_Object lim2 =
27914 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27915 ? make_number (BUF_Z (XBUFFER (buffer))
27916 - XFASTINT (w->window_end_pos))
27917 : Qnil;
27919 if (NILP (overlay))
27921 /* Handle the text property case. */
27922 before = Fprevious_single_property_change
27923 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27924 after = Fnext_single_property_change
27925 (make_number (pos), Qmouse_face, buffer, lim2);
27926 before_string = after_string = Qnil;
27928 else
27930 /* Handle the overlay case. */
27931 before = Foverlay_start (overlay);
27932 after = Foverlay_end (overlay);
27933 before_string = Foverlay_get (overlay, Qbefore_string);
27934 after_string = Foverlay_get (overlay, Qafter_string);
27936 if (!STRINGP (before_string)) before_string = Qnil;
27937 if (!STRINGP (after_string)) after_string = Qnil;
27940 mouse_face_from_buffer_pos (window, hlinfo, pos,
27941 NILP (before)
27943 : XFASTINT (before),
27944 NILP (after)
27945 ? BUF_Z (XBUFFER (buffer))
27946 : XFASTINT (after),
27947 before_string, after_string,
27948 disp_string);
27949 cursor = No_Cursor;
27954 check_help_echo:
27956 /* Look for a `help-echo' property. */
27957 if (NILP (help_echo_string)) {
27958 Lisp_Object help, overlay;
27960 /* Check overlays first. */
27961 help = overlay = Qnil;
27962 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27964 overlay = overlay_vec[i];
27965 help = Foverlay_get (overlay, Qhelp_echo);
27968 if (!NILP (help))
27970 help_echo_string = help;
27971 help_echo_window = window;
27972 help_echo_object = overlay;
27973 help_echo_pos = pos;
27975 else
27977 Lisp_Object obj = glyph->object;
27978 ptrdiff_t charpos = glyph->charpos;
27980 /* Try text properties. */
27981 if (STRINGP (obj)
27982 && charpos >= 0
27983 && charpos < SCHARS (obj))
27985 help = Fget_text_property (make_number (charpos),
27986 Qhelp_echo, obj);
27987 if (NILP (help))
27989 /* If the string itself doesn't specify a help-echo,
27990 see if the buffer text ``under'' it does. */
27991 struct glyph_row *r
27992 = MATRIX_ROW (w->current_matrix, vpos);
27993 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27994 ptrdiff_t p = string_buffer_position (obj, start);
27995 if (p > 0)
27997 help = Fget_char_property (make_number (p),
27998 Qhelp_echo, w->contents);
27999 if (!NILP (help))
28001 charpos = p;
28002 obj = w->contents;
28007 else if (BUFFERP (obj)
28008 && charpos >= BEGV
28009 && charpos < ZV)
28010 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28011 obj);
28013 if (!NILP (help))
28015 help_echo_string = help;
28016 help_echo_window = window;
28017 help_echo_object = obj;
28018 help_echo_pos = charpos;
28023 #ifdef HAVE_WINDOW_SYSTEM
28024 /* Look for a `pointer' property. */
28025 if (FRAME_WINDOW_P (f) && NILP (pointer))
28027 /* Check overlays first. */
28028 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28029 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28031 if (NILP (pointer))
28033 Lisp_Object obj = glyph->object;
28034 ptrdiff_t charpos = glyph->charpos;
28036 /* Try text properties. */
28037 if (STRINGP (obj)
28038 && charpos >= 0
28039 && charpos < SCHARS (obj))
28041 pointer = Fget_text_property (make_number (charpos),
28042 Qpointer, obj);
28043 if (NILP (pointer))
28045 /* If the string itself doesn't specify a pointer,
28046 see if the buffer text ``under'' it does. */
28047 struct glyph_row *r
28048 = MATRIX_ROW (w->current_matrix, vpos);
28049 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28050 ptrdiff_t p = string_buffer_position (obj, start);
28051 if (p > 0)
28052 pointer = Fget_char_property (make_number (p),
28053 Qpointer, w->contents);
28056 else if (BUFFERP (obj)
28057 && charpos >= BEGV
28058 && charpos < ZV)
28059 pointer = Fget_text_property (make_number (charpos),
28060 Qpointer, obj);
28063 #endif /* HAVE_WINDOW_SYSTEM */
28065 BEGV = obegv;
28066 ZV = ozv;
28067 current_buffer = obuf;
28070 set_cursor:
28072 #ifdef HAVE_WINDOW_SYSTEM
28073 if (FRAME_WINDOW_P (f))
28074 define_frame_cursor1 (f, cursor, pointer);
28075 #else
28076 /* This is here to prevent a compiler error, about "label at end of
28077 compound statement". */
28078 return;
28079 #endif
28083 /* EXPORT for RIF:
28084 Clear any mouse-face on window W. This function is part of the
28085 redisplay interface, and is called from try_window_id and similar
28086 functions to ensure the mouse-highlight is off. */
28088 void
28089 x_clear_window_mouse_face (struct window *w)
28091 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28092 Lisp_Object window;
28094 block_input ();
28095 XSETWINDOW (window, w);
28096 if (EQ (window, hlinfo->mouse_face_window))
28097 clear_mouse_face (hlinfo);
28098 unblock_input ();
28102 /* EXPORT:
28103 Just discard the mouse face information for frame F, if any.
28104 This is used when the size of F is changed. */
28106 void
28107 cancel_mouse_face (struct frame *f)
28109 Lisp_Object window;
28110 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28112 window = hlinfo->mouse_face_window;
28113 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28115 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28116 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28117 hlinfo->mouse_face_window = Qnil;
28123 /***********************************************************************
28124 Exposure Events
28125 ***********************************************************************/
28127 #ifdef HAVE_WINDOW_SYSTEM
28129 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28130 which intersects rectangle R. R is in window-relative coordinates. */
28132 static void
28133 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28134 enum glyph_row_area area)
28136 struct glyph *first = row->glyphs[area];
28137 struct glyph *end = row->glyphs[area] + row->used[area];
28138 struct glyph *last;
28139 int first_x, start_x, x;
28141 if (area == TEXT_AREA && row->fill_line_p)
28142 /* If row extends face to end of line write the whole line. */
28143 draw_glyphs (w, 0, row, area,
28144 0, row->used[area],
28145 DRAW_NORMAL_TEXT, 0);
28146 else
28148 /* Set START_X to the window-relative start position for drawing glyphs of
28149 AREA. The first glyph of the text area can be partially visible.
28150 The first glyphs of other areas cannot. */
28151 start_x = window_box_left_offset (w, area);
28152 x = start_x;
28153 if (area == TEXT_AREA)
28154 x += row->x;
28156 /* Find the first glyph that must be redrawn. */
28157 while (first < end
28158 && x + first->pixel_width < r->x)
28160 x += first->pixel_width;
28161 ++first;
28164 /* Find the last one. */
28165 last = first;
28166 first_x = x;
28167 while (last < end
28168 && x < r->x + r->width)
28170 x += last->pixel_width;
28171 ++last;
28174 /* Repaint. */
28175 if (last > first)
28176 draw_glyphs (w, first_x - start_x, row, area,
28177 first - row->glyphs[area], last - row->glyphs[area],
28178 DRAW_NORMAL_TEXT, 0);
28183 /* Redraw the parts of the glyph row ROW on window W intersecting
28184 rectangle R. R is in window-relative coordinates. Value is
28185 non-zero if mouse-face was overwritten. */
28187 static int
28188 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28190 eassert (row->enabled_p);
28192 if (row->mode_line_p || w->pseudo_window_p)
28193 draw_glyphs (w, 0, row, TEXT_AREA,
28194 0, row->used[TEXT_AREA],
28195 DRAW_NORMAL_TEXT, 0);
28196 else
28198 if (row->used[LEFT_MARGIN_AREA])
28199 expose_area (w, row, r, LEFT_MARGIN_AREA);
28200 if (row->used[TEXT_AREA])
28201 expose_area (w, row, r, TEXT_AREA);
28202 if (row->used[RIGHT_MARGIN_AREA])
28203 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28204 draw_row_fringe_bitmaps (w, row);
28207 return row->mouse_face_p;
28211 /* Redraw those parts of glyphs rows during expose event handling that
28212 overlap other rows. Redrawing of an exposed line writes over parts
28213 of lines overlapping that exposed line; this function fixes that.
28215 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28216 row in W's current matrix that is exposed and overlaps other rows.
28217 LAST_OVERLAPPING_ROW is the last such row. */
28219 static void
28220 expose_overlaps (struct window *w,
28221 struct glyph_row *first_overlapping_row,
28222 struct glyph_row *last_overlapping_row,
28223 XRectangle *r)
28225 struct glyph_row *row;
28227 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28228 if (row->overlapping_p)
28230 eassert (row->enabled_p && !row->mode_line_p);
28232 row->clip = r;
28233 if (row->used[LEFT_MARGIN_AREA])
28234 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28236 if (row->used[TEXT_AREA])
28237 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28239 if (row->used[RIGHT_MARGIN_AREA])
28240 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28241 row->clip = NULL;
28246 /* Return non-zero if W's cursor intersects rectangle R. */
28248 static int
28249 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28251 XRectangle cr, result;
28252 struct glyph *cursor_glyph;
28253 struct glyph_row *row;
28255 if (w->phys_cursor.vpos >= 0
28256 && w->phys_cursor.vpos < w->current_matrix->nrows
28257 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28258 row->enabled_p)
28259 && row->cursor_in_fringe_p)
28261 /* Cursor is in the fringe. */
28262 cr.x = window_box_right_offset (w,
28263 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28264 ? RIGHT_MARGIN_AREA
28265 : TEXT_AREA));
28266 cr.y = row->y;
28267 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28268 cr.height = row->height;
28269 return x_intersect_rectangles (&cr, r, &result);
28272 cursor_glyph = get_phys_cursor_glyph (w);
28273 if (cursor_glyph)
28275 /* r is relative to W's box, but w->phys_cursor.x is relative
28276 to left edge of W's TEXT area. Adjust it. */
28277 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28278 cr.y = w->phys_cursor.y;
28279 cr.width = cursor_glyph->pixel_width;
28280 cr.height = w->phys_cursor_height;
28281 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28282 I assume the effect is the same -- and this is portable. */
28283 return x_intersect_rectangles (&cr, r, &result);
28285 /* If we don't understand the format, pretend we're not in the hot-spot. */
28286 return 0;
28290 /* EXPORT:
28291 Draw a vertical window border to the right of window W if W doesn't
28292 have vertical scroll bars. */
28294 void
28295 x_draw_vertical_border (struct window *w)
28297 struct frame *f = XFRAME (WINDOW_FRAME (w));
28299 /* We could do better, if we knew what type of scroll-bar the adjacent
28300 windows (on either side) have... But we don't :-(
28301 However, I think this works ok. ++KFS 2003-04-25 */
28303 /* Redraw borders between horizontally adjacent windows. Don't
28304 do it for frames with vertical scroll bars because either the
28305 right scroll bar of a window, or the left scroll bar of its
28306 neighbor will suffice as a border. */
28307 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28308 return;
28310 /* Note: It is necessary to redraw both the left and the right
28311 borders, for when only this single window W is being
28312 redisplayed. */
28313 if (!WINDOW_RIGHTMOST_P (w)
28314 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28316 int x0, x1, y0, y1;
28318 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28319 y1 -= 1;
28321 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28322 x1 -= 1;
28324 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28326 if (!WINDOW_LEFTMOST_P (w)
28327 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28329 int x0, x1, y0, y1;
28331 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28332 y1 -= 1;
28334 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28335 x0 -= 1;
28337 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28342 /* Redraw the part of window W intersection rectangle FR. Pixel
28343 coordinates in FR are frame-relative. Call this function with
28344 input blocked. Value is non-zero if the exposure overwrites
28345 mouse-face. */
28347 static int
28348 expose_window (struct window *w, XRectangle *fr)
28350 struct frame *f = XFRAME (w->frame);
28351 XRectangle wr, r;
28352 int mouse_face_overwritten_p = 0;
28354 /* If window is not yet fully initialized, do nothing. This can
28355 happen when toolkit scroll bars are used and a window is split.
28356 Reconfiguring the scroll bar will generate an expose for a newly
28357 created window. */
28358 if (w->current_matrix == NULL)
28359 return 0;
28361 /* When we're currently updating the window, display and current
28362 matrix usually don't agree. Arrange for a thorough display
28363 later. */
28364 if (w == updated_window)
28366 SET_FRAME_GARBAGED (f);
28367 return 0;
28370 /* Frame-relative pixel rectangle of W. */
28371 wr.x = WINDOW_LEFT_EDGE_X (w);
28372 wr.y = WINDOW_TOP_EDGE_Y (w);
28373 wr.width = WINDOW_TOTAL_WIDTH (w);
28374 wr.height = WINDOW_TOTAL_HEIGHT (w);
28376 if (x_intersect_rectangles (fr, &wr, &r))
28378 int yb = window_text_bottom_y (w);
28379 struct glyph_row *row;
28380 int cursor_cleared_p, phys_cursor_on_p;
28381 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28383 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28384 r.x, r.y, r.width, r.height));
28386 /* Convert to window coordinates. */
28387 r.x -= WINDOW_LEFT_EDGE_X (w);
28388 r.y -= WINDOW_TOP_EDGE_Y (w);
28390 /* Turn off the cursor. */
28391 if (!w->pseudo_window_p
28392 && phys_cursor_in_rect_p (w, &r))
28394 x_clear_cursor (w);
28395 cursor_cleared_p = 1;
28397 else
28398 cursor_cleared_p = 0;
28400 /* If the row containing the cursor extends face to end of line,
28401 then expose_area might overwrite the cursor outside the
28402 rectangle and thus notice_overwritten_cursor might clear
28403 w->phys_cursor_on_p. We remember the original value and
28404 check later if it is changed. */
28405 phys_cursor_on_p = w->phys_cursor_on_p;
28407 /* Update lines intersecting rectangle R. */
28408 first_overlapping_row = last_overlapping_row = NULL;
28409 for (row = w->current_matrix->rows;
28410 row->enabled_p;
28411 ++row)
28413 int y0 = row->y;
28414 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28416 if ((y0 >= r.y && y0 < r.y + r.height)
28417 || (y1 > r.y && y1 < r.y + r.height)
28418 || (r.y >= y0 && r.y < y1)
28419 || (r.y + r.height > y0 && r.y + r.height < y1))
28421 /* A header line may be overlapping, but there is no need
28422 to fix overlapping areas for them. KFS 2005-02-12 */
28423 if (row->overlapping_p && !row->mode_line_p)
28425 if (first_overlapping_row == NULL)
28426 first_overlapping_row = row;
28427 last_overlapping_row = row;
28430 row->clip = fr;
28431 if (expose_line (w, row, &r))
28432 mouse_face_overwritten_p = 1;
28433 row->clip = NULL;
28435 else if (row->overlapping_p)
28437 /* We must redraw a row overlapping the exposed area. */
28438 if (y0 < r.y
28439 ? y0 + row->phys_height > r.y
28440 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28442 if (first_overlapping_row == NULL)
28443 first_overlapping_row = row;
28444 last_overlapping_row = row;
28448 if (y1 >= yb)
28449 break;
28452 /* Display the mode line if there is one. */
28453 if (WINDOW_WANTS_MODELINE_P (w)
28454 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28455 row->enabled_p)
28456 && row->y < r.y + r.height)
28458 if (expose_line (w, row, &r))
28459 mouse_face_overwritten_p = 1;
28462 if (!w->pseudo_window_p)
28464 /* Fix the display of overlapping rows. */
28465 if (first_overlapping_row)
28466 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28467 fr);
28469 /* Draw border between windows. */
28470 x_draw_vertical_border (w);
28472 /* Turn the cursor on again. */
28473 if (cursor_cleared_p
28474 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28475 update_window_cursor (w, 1);
28479 return mouse_face_overwritten_p;
28484 /* Redraw (parts) of all windows in the window tree rooted at W that
28485 intersect R. R contains frame pixel coordinates. Value is
28486 non-zero if the exposure overwrites mouse-face. */
28488 static int
28489 expose_window_tree (struct window *w, XRectangle *r)
28491 struct frame *f = XFRAME (w->frame);
28492 int mouse_face_overwritten_p = 0;
28494 while (w && !FRAME_GARBAGED_P (f))
28496 if (WINDOWP (w->contents))
28497 mouse_face_overwritten_p
28498 |= expose_window_tree (XWINDOW (w->contents), r);
28499 else
28500 mouse_face_overwritten_p |= expose_window (w, r);
28502 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28505 return mouse_face_overwritten_p;
28509 /* EXPORT:
28510 Redisplay an exposed area of frame F. X and Y are the upper-left
28511 corner of the exposed rectangle. W and H are width and height of
28512 the exposed area. All are pixel values. W or H zero means redraw
28513 the entire frame. */
28515 void
28516 expose_frame (struct frame *f, int x, int y, int w, int h)
28518 XRectangle r;
28519 int mouse_face_overwritten_p = 0;
28521 TRACE ((stderr, "expose_frame "));
28523 /* No need to redraw if frame will be redrawn soon. */
28524 if (FRAME_GARBAGED_P (f))
28526 TRACE ((stderr, " garbaged\n"));
28527 return;
28530 /* If basic faces haven't been realized yet, there is no point in
28531 trying to redraw anything. This can happen when we get an expose
28532 event while Emacs is starting, e.g. by moving another window. */
28533 if (FRAME_FACE_CACHE (f) == NULL
28534 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28536 TRACE ((stderr, " no faces\n"));
28537 return;
28540 if (w == 0 || h == 0)
28542 r.x = r.y = 0;
28543 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28544 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28546 else
28548 r.x = x;
28549 r.y = y;
28550 r.width = w;
28551 r.height = h;
28554 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28555 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28557 if (WINDOWP (f->tool_bar_window))
28558 mouse_face_overwritten_p
28559 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28561 #ifdef HAVE_X_WINDOWS
28562 #ifndef MSDOS
28563 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28564 if (WINDOWP (f->menu_bar_window))
28565 mouse_face_overwritten_p
28566 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28567 #endif /* not USE_X_TOOLKIT and not USE_GTK */
28568 #endif
28569 #endif
28571 /* Some window managers support a focus-follows-mouse style with
28572 delayed raising of frames. Imagine a partially obscured frame,
28573 and moving the mouse into partially obscured mouse-face on that
28574 frame. The visible part of the mouse-face will be highlighted,
28575 then the WM raises the obscured frame. With at least one WM, KDE
28576 2.1, Emacs is not getting any event for the raising of the frame
28577 (even tried with SubstructureRedirectMask), only Expose events.
28578 These expose events will draw text normally, i.e. not
28579 highlighted. Which means we must redo the highlight here.
28580 Subsume it under ``we love X''. --gerd 2001-08-15 */
28581 /* Included in Windows version because Windows most likely does not
28582 do the right thing if any third party tool offers
28583 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28584 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28586 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28587 if (f == hlinfo->mouse_face_mouse_frame)
28589 int mouse_x = hlinfo->mouse_face_mouse_x;
28590 int mouse_y = hlinfo->mouse_face_mouse_y;
28591 clear_mouse_face (hlinfo);
28592 note_mouse_highlight (f, mouse_x, mouse_y);
28598 /* EXPORT:
28599 Determine the intersection of two rectangles R1 and R2. Return
28600 the intersection in *RESULT. Value is non-zero if RESULT is not
28601 empty. */
28604 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
28606 XRectangle *left, *right;
28607 XRectangle *upper, *lower;
28608 int intersection_p = 0;
28610 /* Rearrange so that R1 is the left-most rectangle. */
28611 if (r1->x < r2->x)
28612 left = r1, right = r2;
28613 else
28614 left = r2, right = r1;
28616 /* X0 of the intersection is right.x0, if this is inside R1,
28617 otherwise there is no intersection. */
28618 if (right->x <= left->x + left->width)
28620 result->x = right->x;
28622 /* The right end of the intersection is the minimum of
28623 the right ends of left and right. */
28624 result->width = (min (left->x + left->width, right->x + right->width)
28625 - result->x);
28627 /* Same game for Y. */
28628 if (r1->y < r2->y)
28629 upper = r1, lower = r2;
28630 else
28631 upper = r2, lower = r1;
28633 /* The upper end of the intersection is lower.y0, if this is inside
28634 of upper. Otherwise, there is no intersection. */
28635 if (lower->y <= upper->y + upper->height)
28637 result->y = lower->y;
28639 /* The lower end of the intersection is the minimum of the lower
28640 ends of upper and lower. */
28641 result->height = (min (lower->y + lower->height,
28642 upper->y + upper->height)
28643 - result->y);
28644 intersection_p = 1;
28648 return intersection_p;
28651 #endif /* HAVE_WINDOW_SYSTEM */
28654 /***********************************************************************
28655 Initialization
28656 ***********************************************************************/
28658 void
28659 syms_of_xdisp (void)
28661 Vwith_echo_area_save_vector = Qnil;
28662 staticpro (&Vwith_echo_area_save_vector);
28664 Vmessage_stack = Qnil;
28665 staticpro (&Vmessage_stack);
28667 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
28668 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
28670 message_dolog_marker1 = Fmake_marker ();
28671 staticpro (&message_dolog_marker1);
28672 message_dolog_marker2 = Fmake_marker ();
28673 staticpro (&message_dolog_marker2);
28674 message_dolog_marker3 = Fmake_marker ();
28675 staticpro (&message_dolog_marker3);
28677 #ifdef GLYPH_DEBUG
28678 defsubr (&Sdump_frame_glyph_matrix);
28679 defsubr (&Sdump_glyph_matrix);
28680 defsubr (&Sdump_glyph_row);
28681 defsubr (&Sdump_tool_bar_row);
28682 defsubr (&Strace_redisplay);
28683 defsubr (&Strace_to_stderr);
28684 #endif
28685 #ifdef HAVE_WINDOW_SYSTEM
28686 defsubr (&Stool_bar_lines_needed);
28687 defsubr (&Slookup_image_map);
28688 #endif
28689 defsubr (&Sformat_mode_line);
28690 defsubr (&Sinvisible_p);
28691 defsubr (&Scurrent_bidi_paragraph_direction);
28693 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
28694 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
28695 DEFSYM (Qoverriding_local_map, "overriding-local-map");
28696 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
28697 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
28698 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
28699 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
28700 DEFSYM (Qeval, "eval");
28701 DEFSYM (QCdata, ":data");
28702 DEFSYM (Qdisplay, "display");
28703 DEFSYM (Qspace_width, "space-width");
28704 DEFSYM (Qraise, "raise");
28705 DEFSYM (Qslice, "slice");
28706 DEFSYM (Qspace, "space");
28707 DEFSYM (Qmargin, "margin");
28708 DEFSYM (Qpointer, "pointer");
28709 DEFSYM (Qleft_margin, "left-margin");
28710 DEFSYM (Qright_margin, "right-margin");
28711 DEFSYM (Qcenter, "center");
28712 DEFSYM (Qline_height, "line-height");
28713 DEFSYM (QCalign_to, ":align-to");
28714 DEFSYM (QCrelative_width, ":relative-width");
28715 DEFSYM (QCrelative_height, ":relative-height");
28716 DEFSYM (QCeval, ":eval");
28717 DEFSYM (QCpropertize, ":propertize");
28718 DEFSYM (QCfile, ":file");
28719 DEFSYM (Qfontified, "fontified");
28720 DEFSYM (Qfontification_functions, "fontification-functions");
28721 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
28722 DEFSYM (Qescape_glyph, "escape-glyph");
28723 DEFSYM (Qnobreak_space, "nobreak-space");
28724 DEFSYM (Qimage, "image");
28725 DEFSYM (Qtext, "text");
28726 DEFSYM (Qboth, "both");
28727 DEFSYM (Qboth_horiz, "both-horiz");
28728 DEFSYM (Qtext_image_horiz, "text-image-horiz");
28729 DEFSYM (QCmap, ":map");
28730 DEFSYM (QCpointer, ":pointer");
28731 DEFSYM (Qrect, "rect");
28732 DEFSYM (Qcircle, "circle");
28733 DEFSYM (Qpoly, "poly");
28734 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
28735 DEFSYM (Qgrow_only, "grow-only");
28736 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
28737 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
28738 DEFSYM (Qposition, "position");
28739 DEFSYM (Qbuffer_position, "buffer-position");
28740 DEFSYM (Qobject, "object");
28741 DEFSYM (Qbar, "bar");
28742 DEFSYM (Qhbar, "hbar");
28743 DEFSYM (Qbox, "box");
28744 DEFSYM (Qhollow, "hollow");
28745 DEFSYM (Qhand, "hand");
28746 DEFSYM (Qarrow, "arrow");
28747 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
28749 list_of_error = Fcons (Fcons (intern_c_string ("error"),
28750 Fcons (intern_c_string ("void-variable"), Qnil)),
28751 Qnil);
28752 staticpro (&list_of_error);
28754 DEFSYM (Qlast_arrow_position, "last-arrow-position");
28755 DEFSYM (Qlast_arrow_string, "last-arrow-string");
28756 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
28757 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
28759 echo_buffer[0] = echo_buffer[1] = Qnil;
28760 staticpro (&echo_buffer[0]);
28761 staticpro (&echo_buffer[1]);
28763 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
28764 staticpro (&echo_area_buffer[0]);
28765 staticpro (&echo_area_buffer[1]);
28767 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
28768 staticpro (&Vmessages_buffer_name);
28770 mode_line_proptrans_alist = Qnil;
28771 staticpro (&mode_line_proptrans_alist);
28772 mode_line_string_list = Qnil;
28773 staticpro (&mode_line_string_list);
28774 mode_line_string_face = Qnil;
28775 staticpro (&mode_line_string_face);
28776 mode_line_string_face_prop = Qnil;
28777 staticpro (&mode_line_string_face_prop);
28778 Vmode_line_unwind_vector = Qnil;
28779 staticpro (&Vmode_line_unwind_vector);
28781 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
28783 help_echo_string = Qnil;
28784 staticpro (&help_echo_string);
28785 help_echo_object = Qnil;
28786 staticpro (&help_echo_object);
28787 help_echo_window = Qnil;
28788 staticpro (&help_echo_window);
28789 previous_help_echo_string = Qnil;
28790 staticpro (&previous_help_echo_string);
28791 help_echo_pos = -1;
28793 DEFSYM (Qright_to_left, "right-to-left");
28794 DEFSYM (Qleft_to_right, "left-to-right");
28796 #ifdef HAVE_WINDOW_SYSTEM
28797 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28798 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
28799 For example, if a block cursor is over a tab, it will be drawn as
28800 wide as that tab on the display. */);
28801 x_stretch_cursor_p = 0;
28802 #endif
28804 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28805 doc: /* Non-nil means highlight trailing whitespace.
28806 The face used for trailing whitespace is `trailing-whitespace'. */);
28807 Vshow_trailing_whitespace = Qnil;
28809 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28810 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28811 If the value is t, Emacs highlights non-ASCII chars which have the
28812 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28813 or `escape-glyph' face respectively.
28815 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28816 U+2011 (non-breaking hyphen) are affected.
28818 Any other non-nil value means to display these characters as a escape
28819 glyph followed by an ordinary space or hyphen.
28821 A value of nil means no special handling of these characters. */);
28822 Vnobreak_char_display = Qt;
28824 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28825 doc: /* The pointer shape to show in void text areas.
28826 A value of nil means to show the text pointer. Other options are `arrow',
28827 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28828 Vvoid_text_area_pointer = Qarrow;
28830 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28831 doc: /* Non-nil means don't actually do any redisplay.
28832 This is used for internal purposes. */);
28833 Vinhibit_redisplay = Qnil;
28835 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28836 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28837 Vglobal_mode_string = Qnil;
28839 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28840 doc: /* Marker for where to display an arrow on top of the buffer text.
28841 This must be the beginning of a line in order to work.
28842 See also `overlay-arrow-string'. */);
28843 Voverlay_arrow_position = Qnil;
28845 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28846 doc: /* String to display as an arrow in non-window frames.
28847 See also `overlay-arrow-position'. */);
28848 Voverlay_arrow_string = build_pure_c_string ("=>");
28850 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28851 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28852 The symbols on this list are examined during redisplay to determine
28853 where to display overlay arrows. */);
28854 Voverlay_arrow_variable_list
28855 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28857 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28858 doc: /* The number of lines to try scrolling a window by when point moves out.
28859 If that fails to bring point back on frame, point is centered instead.
28860 If this is zero, point is always centered after it moves off frame.
28861 If you want scrolling to always be a line at a time, you should set
28862 `scroll-conservatively' to a large value rather than set this to 1. */);
28864 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28865 doc: /* Scroll up to this many lines, to bring point back on screen.
28866 If point moves off-screen, redisplay will scroll by up to
28867 `scroll-conservatively' lines in order to bring point just barely
28868 onto the screen again. If that cannot be done, then redisplay
28869 recenters point as usual.
28871 If the value is greater than 100, redisplay will never recenter point,
28872 but will always scroll just enough text to bring point into view, even
28873 if you move far away.
28875 A value of zero means always recenter point if it moves off screen. */);
28876 scroll_conservatively = 0;
28878 DEFVAR_INT ("scroll-margin", scroll_margin,
28879 doc: /* Number of lines of margin at the top and bottom of a window.
28880 Recenter the window whenever point gets within this many lines
28881 of the top or bottom of the window. */);
28882 scroll_margin = 0;
28884 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28885 doc: /* Pixels per inch value for non-window system displays.
28886 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28887 Vdisplay_pixels_per_inch = make_float (72.0);
28889 #ifdef GLYPH_DEBUG
28890 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28891 #endif
28893 DEFVAR_LISP ("truncate-partial-width-windows",
28894 Vtruncate_partial_width_windows,
28895 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28896 For an integer value, truncate lines in each window narrower than the
28897 full frame width, provided the window width is less than that integer;
28898 otherwise, respect the value of `truncate-lines'.
28900 For any other non-nil value, truncate lines in all windows that do
28901 not span the full frame width.
28903 A value of nil means to respect the value of `truncate-lines'.
28905 If `word-wrap' is enabled, you might want to reduce this. */);
28906 Vtruncate_partial_width_windows = make_number (50);
28908 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28909 doc: /* Maximum buffer size for which line number should be displayed.
28910 If the buffer is bigger than this, the line number does not appear
28911 in the mode line. A value of nil means no limit. */);
28912 Vline_number_display_limit = Qnil;
28914 DEFVAR_INT ("line-number-display-limit-width",
28915 line_number_display_limit_width,
28916 doc: /* Maximum line width (in characters) for line number display.
28917 If the average length of the lines near point is bigger than this, then the
28918 line number may be omitted from the mode line. */);
28919 line_number_display_limit_width = 200;
28921 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28922 doc: /* Non-nil means highlight region even in nonselected windows. */);
28923 highlight_nonselected_windows = 0;
28925 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28926 doc: /* Non-nil if more than one frame is visible on this display.
28927 Minibuffer-only frames don't count, but iconified frames do.
28928 This variable is not guaranteed to be accurate except while processing
28929 `frame-title-format' and `icon-title-format'. */);
28931 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28932 doc: /* Template for displaying the title bar of visible frames.
28933 \(Assuming the window manager supports this feature.)
28935 This variable has the same structure as `mode-line-format', except that
28936 the %c and %l constructs are ignored. It is used only on frames for
28937 which no explicit name has been set \(see `modify-frame-parameters'). */);
28939 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28940 doc: /* Template for displaying the title bar of an iconified frame.
28941 \(Assuming the window manager supports this feature.)
28942 This variable has the same structure as `mode-line-format' (which see),
28943 and is used only on frames for which no explicit name has been set
28944 \(see `modify-frame-parameters'). */);
28945 Vicon_title_format
28946 = Vframe_title_format
28947 = listn (CONSTYPE_PURE, 3,
28948 intern_c_string ("multiple-frames"),
28949 build_pure_c_string ("%b"),
28950 listn (CONSTYPE_PURE, 4,
28951 empty_unibyte_string,
28952 intern_c_string ("invocation-name"),
28953 build_pure_c_string ("@"),
28954 intern_c_string ("system-name")));
28956 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28957 doc: /* Maximum number of lines to keep in the message log buffer.
28958 If nil, disable message logging. If t, log messages but don't truncate
28959 the buffer when it becomes large. */);
28960 Vmessage_log_max = make_number (1000);
28962 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28963 doc: /* Functions called before redisplay, if window sizes have changed.
28964 The value should be a list of functions that take one argument.
28965 Just before redisplay, for each frame, if any of its windows have changed
28966 size since the last redisplay, or have been split or deleted,
28967 all the functions in the list are called, with the frame as argument. */);
28968 Vwindow_size_change_functions = Qnil;
28970 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28971 doc: /* List of functions to call before redisplaying a window with scrolling.
28972 Each function is called with two arguments, the window and its new
28973 display-start position. Note that these functions are also called by
28974 `set-window-buffer'. Also note that the value of `window-end' is not
28975 valid when these functions are called.
28977 Warning: Do not use this feature to alter the way the window
28978 is scrolled. It is not designed for that, and such use probably won't
28979 work. */);
28980 Vwindow_scroll_functions = Qnil;
28982 DEFVAR_LISP ("window-text-change-functions",
28983 Vwindow_text_change_functions,
28984 doc: /* Functions to call in redisplay when text in the window might change. */);
28985 Vwindow_text_change_functions = Qnil;
28987 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
28988 doc: /* Functions called when redisplay of a window reaches the end trigger.
28989 Each function is called with two arguments, the window and the end trigger value.
28990 See `set-window-redisplay-end-trigger'. */);
28991 Vredisplay_end_trigger_functions = Qnil;
28993 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
28994 doc: /* Non-nil means autoselect window with mouse pointer.
28995 If nil, do not autoselect windows.
28996 A positive number means delay autoselection by that many seconds: a
28997 window is autoselected only after the mouse has remained in that
28998 window for the duration of the delay.
28999 A negative number has a similar effect, but causes windows to be
29000 autoselected only after the mouse has stopped moving. \(Because of
29001 the way Emacs compares mouse events, you will occasionally wait twice
29002 that time before the window gets selected.\)
29003 Any other value means to autoselect window instantaneously when the
29004 mouse pointer enters it.
29006 Autoselection selects the minibuffer only if it is active, and never
29007 unselects the minibuffer if it is active.
29009 When customizing this variable make sure that the actual value of
29010 `focus-follows-mouse' matches the behavior of your window manager. */);
29011 Vmouse_autoselect_window = Qnil;
29013 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29014 doc: /* Non-nil means automatically resize tool-bars.
29015 This dynamically changes the tool-bar's height to the minimum height
29016 that is needed to make all tool-bar items visible.
29017 If value is `grow-only', the tool-bar's height is only increased
29018 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29019 Vauto_resize_tool_bars = Qt;
29021 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29022 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29023 auto_raise_tool_bar_buttons_p = 1;
29025 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29026 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29027 make_cursor_line_fully_visible_p = 1;
29029 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29030 doc: /* Border below tool-bar in pixels.
29031 If an integer, use it as the height of the border.
29032 If it is one of `internal-border-width' or `border-width', use the
29033 value of the corresponding frame parameter.
29034 Otherwise, no border is added below the tool-bar. */);
29035 Vtool_bar_border = Qinternal_border_width;
29037 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29038 doc: /* Margin around tool-bar buttons in pixels.
29039 If an integer, use that for both horizontal and vertical margins.
29040 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29041 HORZ specifying the horizontal margin, and VERT specifying the
29042 vertical margin. */);
29043 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29045 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29046 doc: /* Relief thickness of tool-bar buttons. */);
29047 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29049 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29050 doc: /* Tool bar style to use.
29051 It can be one of
29052 image - show images only
29053 text - show text only
29054 both - show both, text below image
29055 both-horiz - show text to the right of the image
29056 text-image-horiz - show text to the left of the image
29057 any other - use system default or image if no system default.
29059 This variable only affects the GTK+ toolkit version of Emacs. */);
29060 Vtool_bar_style = Qnil;
29062 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29063 doc: /* Maximum number of characters a label can have to be shown.
29064 The tool bar style must also show labels for this to have any effect, see
29065 `tool-bar-style'. */);
29066 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29068 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29069 doc: /* List of functions to call to fontify regions of text.
29070 Each function is called with one argument POS. Functions must
29071 fontify a region starting at POS in the current buffer, and give
29072 fontified regions the property `fontified'. */);
29073 Vfontification_functions = Qnil;
29074 Fmake_variable_buffer_local (Qfontification_functions);
29076 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29077 unibyte_display_via_language_environment,
29078 doc: /* Non-nil means display unibyte text according to language environment.
29079 Specifically, this means that raw bytes in the range 160-255 decimal
29080 are displayed by converting them to the equivalent multibyte characters
29081 according to the current language environment. As a result, they are
29082 displayed according to the current fontset.
29084 Note that this variable affects only how these bytes are displayed,
29085 but does not change the fact they are interpreted as raw bytes. */);
29086 unibyte_display_via_language_environment = 0;
29088 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29089 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29090 If a float, it specifies a fraction of the mini-window frame's height.
29091 If an integer, it specifies a number of lines. */);
29092 Vmax_mini_window_height = make_float (0.25);
29094 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29095 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29096 A value of nil means don't automatically resize mini-windows.
29097 A value of t means resize them to fit the text displayed in them.
29098 A value of `grow-only', the default, means let mini-windows grow only;
29099 they return to their normal size when the minibuffer is closed, or the
29100 echo area becomes empty. */);
29101 Vresize_mini_windows = Qgrow_only;
29103 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29104 doc: /* Alist specifying how to blink the cursor off.
29105 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29106 `cursor-type' frame-parameter or variable equals ON-STATE,
29107 comparing using `equal', Emacs uses OFF-STATE to specify
29108 how to blink it off. ON-STATE and OFF-STATE are values for
29109 the `cursor-type' frame parameter.
29111 If a frame's ON-STATE has no entry in this list,
29112 the frame's other specifications determine how to blink the cursor off. */);
29113 Vblink_cursor_alist = Qnil;
29115 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29116 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29117 If non-nil, windows are automatically scrolled horizontally to make
29118 point visible. */);
29119 automatic_hscrolling_p = 1;
29120 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29122 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29123 doc: /* How many columns away from the window edge point is allowed to get
29124 before automatic hscrolling will horizontally scroll the window. */);
29125 hscroll_margin = 5;
29127 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29128 doc: /* How many columns to scroll the window when point gets too close to the edge.
29129 When point is less than `hscroll-margin' columns from the window
29130 edge, automatic hscrolling will scroll the window by the amount of columns
29131 determined by this variable. If its value is a positive integer, scroll that
29132 many columns. If it's a positive floating-point number, it specifies the
29133 fraction of the window's width to scroll. If it's nil or zero, point will be
29134 centered horizontally after the scroll. Any other value, including negative
29135 numbers, are treated as if the value were zero.
29137 Automatic hscrolling always moves point outside the scroll margin, so if
29138 point was more than scroll step columns inside the margin, the window will
29139 scroll more than the value given by the scroll step.
29141 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29142 and `scroll-right' overrides this variable's effect. */);
29143 Vhscroll_step = make_number (0);
29145 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29146 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29147 Bind this around calls to `message' to let it take effect. */);
29148 message_truncate_lines = 0;
29150 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29151 doc: /* Normal hook run to update the menu bar definitions.
29152 Redisplay runs this hook before it redisplays the menu bar.
29153 This is used to update submenus such as Buffers,
29154 whose contents depend on various data. */);
29155 Vmenu_bar_update_hook = Qnil;
29157 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29158 doc: /* Frame for which we are updating a menu.
29159 The enable predicate for a menu binding should check this variable. */);
29160 Vmenu_updating_frame = Qnil;
29162 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29163 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29164 inhibit_menubar_update = 0;
29166 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29167 doc: /* Prefix prepended to all continuation lines at display time.
29168 The value may be a string, an image, or a stretch-glyph; it is
29169 interpreted in the same way as the value of a `display' text property.
29171 This variable is overridden by any `wrap-prefix' text or overlay
29172 property.
29174 To add a prefix to non-continuation lines, use `line-prefix'. */);
29175 Vwrap_prefix = Qnil;
29176 DEFSYM (Qwrap_prefix, "wrap-prefix");
29177 Fmake_variable_buffer_local (Qwrap_prefix);
29179 DEFVAR_LISP ("line-prefix", Vline_prefix,
29180 doc: /* Prefix prepended to all non-continuation lines at display time.
29181 The value may be a string, an image, or a stretch-glyph; it is
29182 interpreted in the same way as the value of a `display' text property.
29184 This variable is overridden by any `line-prefix' text or overlay
29185 property.
29187 To add a prefix to continuation lines, use `wrap-prefix'. */);
29188 Vline_prefix = Qnil;
29189 DEFSYM (Qline_prefix, "line-prefix");
29190 Fmake_variable_buffer_local (Qline_prefix);
29192 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29193 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29194 inhibit_eval_during_redisplay = 0;
29196 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29197 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29198 inhibit_free_realized_faces = 0;
29200 #ifdef GLYPH_DEBUG
29201 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29202 doc: /* Inhibit try_window_id display optimization. */);
29203 inhibit_try_window_id = 0;
29205 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29206 doc: /* Inhibit try_window_reusing display optimization. */);
29207 inhibit_try_window_reusing = 0;
29209 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29210 doc: /* Inhibit try_cursor_movement display optimization. */);
29211 inhibit_try_cursor_movement = 0;
29212 #endif /* GLYPH_DEBUG */
29214 DEFVAR_INT ("overline-margin", overline_margin,
29215 doc: /* Space between overline and text, in pixels.
29216 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29217 margin to the character height. */);
29218 overline_margin = 2;
29220 DEFVAR_INT ("underline-minimum-offset",
29221 underline_minimum_offset,
29222 doc: /* Minimum distance between baseline and underline.
29223 This can improve legibility of underlined text at small font sizes,
29224 particularly when using variable `x-use-underline-position-properties'
29225 with fonts that specify an UNDERLINE_POSITION relatively close to the
29226 baseline. The default value is 1. */);
29227 underline_minimum_offset = 1;
29229 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29230 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29231 This feature only works when on a window system that can change
29232 cursor shapes. */);
29233 display_hourglass_p = 1;
29235 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29236 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29237 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29239 hourglass_atimer = NULL;
29240 hourglass_shown_p = 0;
29242 DEFSYM (Qglyphless_char, "glyphless-char");
29243 DEFSYM (Qhex_code, "hex-code");
29244 DEFSYM (Qempty_box, "empty-box");
29245 DEFSYM (Qthin_space, "thin-space");
29246 DEFSYM (Qzero_width, "zero-width");
29248 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29249 /* Intern this now in case it isn't already done.
29250 Setting this variable twice is harmless.
29251 But don't staticpro it here--that is done in alloc.c. */
29252 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29253 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29255 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29256 doc: /* Char-table defining glyphless characters.
29257 Each element, if non-nil, should be one of the following:
29258 an ASCII acronym string: display this string in a box
29259 `hex-code': display the hexadecimal code of a character in a box
29260 `empty-box': display as an empty box
29261 `thin-space': display as 1-pixel width space
29262 `zero-width': don't display
29263 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29264 display method for graphical terminals and text terminals respectively.
29265 GRAPHICAL and TEXT should each have one of the values listed above.
29267 The char-table has one extra slot to control the display of a character for
29268 which no font is found. This slot only takes effect on graphical terminals.
29269 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29270 `thin-space'. The default is `empty-box'. */);
29271 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29272 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29273 Qempty_box);
29275 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29276 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29277 Vdebug_on_message = Qnil;
29281 /* Initialize this module when Emacs starts. */
29283 void
29284 init_xdisp (void)
29286 current_header_line_height = current_mode_line_height = -1;
29288 CHARPOS (this_line_start_pos) = 0;
29290 if (!noninteractive)
29292 struct window *m = XWINDOW (minibuf_window);
29293 Lisp_Object frame = m->frame;
29294 struct frame *f = XFRAME (frame);
29295 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29296 struct window *r = XWINDOW (root);
29297 int i;
29299 echo_area_window = minibuf_window;
29301 r->top_line = FRAME_TOP_MARGIN (f);
29302 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29303 r->total_cols = FRAME_COLS (f);
29305 m->top_line = FRAME_LINES (f) - 1;
29306 m->total_lines = 1;
29307 m->total_cols = FRAME_COLS (f);
29309 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29310 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29311 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29313 /* The default ellipsis glyphs `...'. */
29314 for (i = 0; i < 3; ++i)
29315 default_invis_vector[i] = make_number ('.');
29319 /* Allocate the buffer for frame titles.
29320 Also used for `format-mode-line'. */
29321 int size = 100;
29322 mode_line_noprop_buf = xmalloc (size);
29323 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29324 mode_line_noprop_ptr = mode_line_noprop_buf;
29325 mode_line_target = MODE_LINE_DISPLAY;
29328 help_echo_showing_p = 0;
29331 /* Platform-independent portion of hourglass implementation. */
29333 /* Cancel a currently active hourglass timer, and start a new one. */
29334 void
29335 start_hourglass (void)
29337 #if defined (HAVE_WINDOW_SYSTEM)
29338 EMACS_TIME delay;
29340 cancel_hourglass ();
29342 if (INTEGERP (Vhourglass_delay)
29343 && XINT (Vhourglass_delay) > 0)
29344 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29345 TYPE_MAXIMUM (time_t)),
29347 else if (FLOATP (Vhourglass_delay)
29348 && XFLOAT_DATA (Vhourglass_delay) > 0)
29349 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29350 else
29351 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29353 #ifdef HAVE_NTGUI
29355 extern void w32_note_current_window (void);
29356 w32_note_current_window ();
29358 #endif /* HAVE_NTGUI */
29360 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29361 show_hourglass, NULL);
29362 #endif
29366 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29367 shown. */
29368 void
29369 cancel_hourglass (void)
29371 #if defined (HAVE_WINDOW_SYSTEM)
29372 if (hourglass_atimer)
29374 cancel_atimer (hourglass_atimer);
29375 hourglass_atimer = NULL;
29378 if (hourglass_shown_p)
29379 hide_hourglass ();
29380 #endif