Remove the ignore_bn_limit ``optimization''.
[emacs.git] / src / xdisp.c
blob7cf1782b83f033eb628a52d8537f32362680e237
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2014 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. (The "id" part in the function's
102 name stands for "insert/delete", not for "identification" or
103 somesuch.)
105 . try_window
107 This function performs the full redisplay of a single window
108 assuming that its fonts were not changed and that the cursor
109 will not end up in the scroll margins. (Loading fonts requires
110 re-adjustment of dimensions of glyph matrices, which makes this
111 method impossible to use.)
113 These optimizations are tried in sequence (some can be skipped if
114 it is known that they are not applicable). If none of the
115 optimizations were successful, redisplay calls redisplay_windows,
116 which performs a full redisplay of all windows.
118 Note that there's one more important optimization up Emacs's
119 sleeve, but it is related to actually redrawing the potentially
120 changed portions of the window/frame, not to reproducing the
121 desired matrices of those potentially changed portions. Namely,
122 the function update_frame and its subroutines, which you will find
123 in dispnew.c, compare the desired matrices with the current
124 matrices, and only redraw the portions that changed. So it could
125 happen that the functions in this file for some reason decide that
126 the entire desired matrix needs to be regenerated from scratch, and
127 still only parts of the Emacs display, or even nothing at all, will
128 be actually delivered to the glass, because update_frame has found
129 that the new and the old screen contents are similar or identical.
131 Desired matrices.
133 Desired matrices are always built per Emacs window. The function
134 `display_line' is the central function to look at if you are
135 interested. It constructs one row in a desired matrix given an
136 iterator structure containing both a buffer position and a
137 description of the environment in which the text is to be
138 displayed. But this is too early, read on.
140 Characters and pixmaps displayed for a range of buffer text depend
141 on various settings of buffers and windows, on overlays and text
142 properties, on display tables, on selective display. The good news
143 is that all this hairy stuff is hidden behind a small set of
144 interface functions taking an iterator structure (struct it)
145 argument.
147 Iteration over things to be displayed is then simple. It is
148 started by initializing an iterator with a call to init_iterator,
149 passing it the buffer position where to start iteration. For
150 iteration over strings, pass -1 as the position to init_iterator,
151 and call reseat_to_string when the string is ready, to initialize
152 the iterator for that string. Thereafter, calls to
153 get_next_display_element fill the iterator structure with relevant
154 information about the next thing to display. Calls to
155 set_iterator_to_next move the iterator to the next thing.
157 Besides this, an iterator also contains information about the
158 display environment in which glyphs for display elements are to be
159 produced. It has fields for the width and height of the display,
160 the information whether long lines are truncated or continued, a
161 current X and Y position, and lots of other stuff you can better
162 see in dispextern.h.
164 Glyphs in a desired matrix are normally constructed in a loop
165 calling get_next_display_element and then PRODUCE_GLYPHS. The call
166 to PRODUCE_GLYPHS will fill the iterator structure with pixel
167 information about the element being displayed and at the same time
168 produce glyphs for it. If the display element fits on the line
169 being displayed, set_iterator_to_next is called next, otherwise the
170 glyphs produced are discarded. The function display_line is the
171 workhorse of filling glyph rows in the desired matrix with glyphs.
172 In addition to producing glyphs, it also handles line truncation
173 and continuation, word wrap, and cursor positioning (for the
174 latter, see also set_cursor_from_row).
176 Frame matrices.
178 That just couldn't be all, could it? What about terminal types not
179 supporting operations on sub-windows of the screen? To update the
180 display on such a terminal, window-based glyph matrices are not
181 well suited. To be able to reuse part of the display (scrolling
182 lines up and down), we must instead have a view of the whole
183 screen. This is what `frame matrices' are for. They are a trick.
185 Frames on terminals like above have a glyph pool. Windows on such
186 a frame sub-allocate their glyph memory from their frame's glyph
187 pool. The frame itself is given its own glyph matrices. By
188 coincidence---or maybe something else---rows in window glyph
189 matrices are slices of corresponding rows in frame matrices. Thus
190 writing to window matrices implicitly updates a frame matrix which
191 provides us with the view of the whole screen that we originally
192 wanted to have without having to move many bytes around. To be
193 honest, there is a little bit more done, but not much more. If you
194 plan to extend that code, take a look at dispnew.c. The function
195 build_frame_matrix is a good starting point.
197 Bidirectional display.
199 Bidirectional display adds quite some hair to this already complex
200 design. The good news are that a large portion of that hairy stuff
201 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
202 reordering engine which is called by set_iterator_to_next and
203 returns the next character to display in the visual order. See
204 commentary on bidi.c for more details. As far as redisplay is
205 concerned, the effect of calling bidi_move_to_visually_next, the
206 main interface of the reordering engine, is that the iterator gets
207 magically placed on the buffer or string position that is to be
208 displayed next. In other words, a linear iteration through the
209 buffer/string is replaced with a non-linear one. All the rest of
210 the redisplay is oblivious to the bidi reordering.
212 Well, almost oblivious---there are still complications, most of
213 them due to the fact that buffer and string positions no longer
214 change monotonously with glyph indices in a glyph row. Moreover,
215 for continued lines, the buffer positions may not even be
216 monotonously changing with vertical positions. Also, accounting
217 for face changes, overlays, etc. becomes more complex because
218 non-linear iteration could potentially skip many positions with
219 changes, and then cross them again on the way back...
221 One other prominent effect of bidirectional display is that some
222 paragraphs of text need to be displayed starting at the right
223 margin of the window---the so-called right-to-left, or R2L
224 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
225 which have their reversed_p flag set. The bidi reordering engine
226 produces characters in such rows starting from the character which
227 should be the rightmost on display. PRODUCE_GLYPHS then reverses
228 the order, when it fills up the glyph row whose reversed_p flag is
229 set, by prepending each new glyph to what is already there, instead
230 of appending it. When the glyph row is complete, the function
231 extend_face_to_end_of_line fills the empty space to the left of the
232 leftmost character with special glyphs, which will display as,
233 well, empty. On text terminals, these special glyphs are simply
234 blank characters. On graphics terminals, there's a single stretch
235 glyph of a suitably computed width. Both the blanks and the
236 stretch glyph are given the face of the background of the line.
237 This way, the terminal-specific back-end can still draw the glyphs
238 left to right, even for R2L lines.
240 Bidirectional display and character compositions
242 Some scripts cannot be displayed by drawing each character
243 individually, because adjacent characters change each other's shape
244 on display. For example, Arabic and Indic scripts belong to this
245 category.
247 Emacs display supports this by providing "character compositions",
248 most of which is implemented in composite.c. During the buffer
249 scan that delivers characters to PRODUCE_GLYPHS, if the next
250 character to be delivered is a composed character, the iteration
251 calls composition_reseat_it and next_element_from_composition. If
252 they succeed to compose the character with one or more of the
253 following characters, the whole sequence of characters that where
254 composed is recorded in the `struct composition_it' object that is
255 part of the buffer iterator. The composed sequence could produce
256 one or more font glyphs (called "grapheme clusters") on the screen.
257 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
258 in the direction corresponding to the current bidi scan direction
259 (recorded in the scan_dir member of the `struct bidi_it' object
260 that is part of the buffer iterator). In particular, if the bidi
261 iterator currently scans the buffer backwards, the grapheme
262 clusters are delivered back to front. This reorders the grapheme
263 clusters as appropriate for the current bidi context. Note that
264 this means that the grapheme clusters are always stored in the
265 LGSTRING object (see composite.c) in the logical order.
267 Moving an iterator in bidirectional text
268 without producing glyphs
270 Note one important detail mentioned above: that the bidi reordering
271 engine, driven by the iterator, produces characters in R2L rows
272 starting at the character that will be the rightmost on display.
273 As far as the iterator is concerned, the geometry of such rows is
274 still left to right, i.e. the iterator "thinks" the first character
275 is at the leftmost pixel position. The iterator does not know that
276 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
277 delivers. This is important when functions from the move_it_*
278 family are used to get to certain screen position or to match
279 screen coordinates with buffer coordinates: these functions use the
280 iterator geometry, which is left to right even in R2L paragraphs.
281 This works well with most callers of move_it_*, because they need
282 to get to a specific column, and columns are still numbered in the
283 reading order, i.e. the rightmost character in a R2L paragraph is
284 still column zero. But some callers do not get well with this; a
285 notable example is mouse clicks that need to find the character
286 that corresponds to certain pixel coordinates. See
287 buffer_posn_from_coords in dispnew.c for how this is handled. */
289 #include <config.h>
290 #include <stdio.h>
291 #include <limits.h>
293 #include "lisp.h"
294 #include "atimer.h"
295 #include "keyboard.h"
296 #include "frame.h"
297 #include "window.h"
298 #include "termchar.h"
299 #include "dispextern.h"
300 #include "character.h"
301 #include "buffer.h"
302 #include "charset.h"
303 #include "indent.h"
304 #include "commands.h"
305 #include "keymap.h"
306 #include "macros.h"
307 #include "disptab.h"
308 #include "termhooks.h"
309 #include "termopts.h"
310 #include "intervals.h"
311 #include "coding.h"
312 #include "process.h"
313 #include "region-cache.h"
314 #include "font.h"
315 #include "fontset.h"
316 #include "blockinput.h"
317 #ifdef HAVE_WINDOW_SYSTEM
318 #include TERM_HEADER
319 #endif /* HAVE_WINDOW_SYSTEM */
321 #ifndef FRAME_X_OUTPUT
322 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
323 #endif
325 #define INFINITY 10000000
327 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
328 Lisp_Object Qwindow_scroll_functions;
329 static Lisp_Object Qwindow_text_change_functions;
330 static Lisp_Object Qredisplay_end_trigger_functions;
331 Lisp_Object Qinhibit_point_motion_hooks;
332 static Lisp_Object QCeval, QCpropertize;
333 Lisp_Object QCfile, QCdata;
334 static Lisp_Object Qfontified;
335 static Lisp_Object Qgrow_only;
336 static Lisp_Object Qinhibit_eval_during_redisplay;
337 static Lisp_Object Qbuffer_position, Qposition, Qobject;
338 static Lisp_Object Qright_to_left, Qleft_to_right;
340 /* Cursor shapes. */
341 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
343 /* Pointer shapes. */
344 static Lisp_Object Qarrow, Qhand;
345 Lisp_Object Qtext;
347 /* Holds the list (error). */
348 static Lisp_Object list_of_error;
350 static Lisp_Object Qfontification_functions;
352 static Lisp_Object Qwrap_prefix;
353 static Lisp_Object Qline_prefix;
354 static Lisp_Object Qredisplay_internal;
356 /* Non-nil means don't actually do any redisplay. */
358 Lisp_Object Qinhibit_redisplay;
360 /* Names of text properties relevant for redisplay. */
362 Lisp_Object Qdisplay;
364 Lisp_Object Qspace, QCalign_to;
365 static Lisp_Object QCrelative_width, QCrelative_height;
366 Lisp_Object Qleft_margin, Qright_margin;
367 static Lisp_Object Qspace_width, Qraise;
368 static Lisp_Object Qslice;
369 Lisp_Object Qcenter;
370 static Lisp_Object Qmargin, Qpointer;
371 static Lisp_Object Qline_height;
373 #ifdef HAVE_WINDOW_SYSTEM
375 /* Test if overflow newline into fringe. Called with iterator IT
376 at or past right window margin, and with IT->current_x set. */
378 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
379 (!NILP (Voverflow_newline_into_fringe) \
380 && FRAME_WINDOW_P ((IT)->f) \
381 && ((IT)->bidi_it.paragraph_dir == R2L \
382 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
383 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
384 && (IT)->current_x == (IT)->last_visible_x)
386 #else /* !HAVE_WINDOW_SYSTEM */
387 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
388 #endif /* HAVE_WINDOW_SYSTEM */
390 /* Test if the display element loaded in IT, or the underlying buffer
391 or string character, is a space or a TAB character. This is used
392 to determine where word wrapping can occur. */
394 #define IT_DISPLAYING_WHITESPACE(it) \
395 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
396 || ((STRINGP (it->string) \
397 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
398 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
399 || (it->s \
400 && (it->s[IT_BYTEPOS (*it)] == ' ' \
401 || it->s[IT_BYTEPOS (*it)] == '\t')) \
402 || (IT_BYTEPOS (*it) < ZV_BYTE \
403 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
404 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
406 /* Name of the face used to highlight trailing whitespace. */
408 static Lisp_Object Qtrailing_whitespace;
410 /* Name and number of the face used to highlight escape glyphs. */
412 static Lisp_Object Qescape_glyph;
414 /* Name and number of the face used to highlight non-breaking spaces. */
416 static Lisp_Object Qnobreak_space;
418 /* The symbol `image' which is the car of the lists used to represent
419 images in Lisp. Also a tool bar style. */
421 Lisp_Object Qimage;
423 /* The image map types. */
424 Lisp_Object QCmap;
425 static Lisp_Object QCpointer;
426 static Lisp_Object Qrect, Qcircle, Qpoly;
428 /* Tool bar styles */
429 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
431 /* Non-zero means print newline to stdout before next mini-buffer
432 message. */
434 bool noninteractive_need_newline;
436 /* Non-zero means print newline to message log before next message. */
438 static bool message_log_need_newline;
440 /* Three markers that message_dolog uses.
441 It could allocate them itself, but that causes trouble
442 in handling memory-full errors. */
443 static Lisp_Object message_dolog_marker1;
444 static Lisp_Object message_dolog_marker2;
445 static Lisp_Object message_dolog_marker3;
447 /* The buffer position of the first character appearing entirely or
448 partially on the line of the selected window which contains the
449 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
450 redisplay optimization in redisplay_internal. */
452 static struct text_pos this_line_start_pos;
454 /* Number of characters past the end of the line above, including the
455 terminating newline. */
457 static struct text_pos this_line_end_pos;
459 /* The vertical positions and the height of this line. */
461 static int this_line_vpos;
462 static int this_line_y;
463 static int this_line_pixel_height;
465 /* X position at which this display line starts. Usually zero;
466 negative if first character is partially visible. */
468 static int this_line_start_x;
470 /* The smallest character position seen by move_it_* functions as they
471 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
472 hscrolled lines, see display_line. */
474 static struct text_pos this_line_min_pos;
476 /* Buffer that this_line_.* variables are referring to. */
478 static struct buffer *this_line_buffer;
481 /* Values of those variables at last redisplay are stored as
482 properties on `overlay-arrow-position' symbol. However, if
483 Voverlay_arrow_position is a marker, last-arrow-position is its
484 numerical position. */
486 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
488 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
489 properties on a symbol in overlay-arrow-variable-list. */
491 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
493 Lisp_Object Qmenu_bar_update_hook;
495 /* Nonzero if an overlay arrow has been displayed in this window. */
497 static bool overlay_arrow_seen;
499 /* Vector containing glyphs for an ellipsis `...'. */
501 static Lisp_Object default_invis_vector[3];
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
507 Lisp_Object echo_area_window;
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
514 static Lisp_Object Vmessage_stack;
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
519 static bool message_enable_multibyte;
521 /* Nonzero if we should redraw the mode lines on the next redisplay.
522 If it has value REDISPLAY_SOME, then only redisplay the mode lines where
523 the `redisplay' bit has been set. Otherwise, redisplay all mode lines
524 (the number used is then only used to track down the cause for this
525 full-redisplay). */
527 int update_mode_lines;
529 /* Nonzero if window sizes or contents other than selected-window have changed
530 since last redisplay that finished.
531 If it has value REDISPLAY_SOME, then only redisplay the windows where
532 the `redisplay' bit has been set. Otherwise, redisplay all windows
533 (the number used is then only used to track down the cause for this
534 full-redisplay). */
536 int windows_or_buffers_changed;
538 /* Nonzero after display_mode_line if %l was used and it displayed a
539 line number. */
541 static bool line_number_displayed;
543 /* The name of the *Messages* buffer, a string. */
545 static Lisp_Object Vmessages_buffer_name;
547 /* Current, index 0, and last displayed echo area message. Either
548 buffers from echo_buffers, or nil to indicate no message. */
550 Lisp_Object echo_area_buffer[2];
552 /* The buffers referenced from echo_area_buffer. */
554 static Lisp_Object echo_buffer[2];
556 /* A vector saved used in with_area_buffer to reduce consing. */
558 static Lisp_Object Vwith_echo_area_save_vector;
560 /* Non-zero means display_echo_area should display the last echo area
561 message again. Set by redisplay_preserve_echo_area. */
563 static bool display_last_displayed_message_p;
565 /* Nonzero if echo area is being used by print; zero if being used by
566 message. */
568 static bool message_buf_print;
570 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
572 static Lisp_Object Qinhibit_menubar_update;
573 static Lisp_Object Qmessage_truncate_lines;
575 /* Set to 1 in clear_message to make redisplay_internal aware
576 of an emptied echo area. */
578 static bool message_cleared_p;
580 /* A scratch glyph row with contents used for generating truncation
581 glyphs. Also used in direct_output_for_insert. */
583 #define MAX_SCRATCH_GLYPHS 100
584 static struct glyph_row scratch_glyph_row;
585 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
587 /* Ascent and height of the last line processed by move_it_to. */
589 static int last_height;
591 /* Non-zero if there's a help-echo in the echo area. */
593 bool help_echo_showing_p;
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 /* Functions to mark elements as needing redisplay. */
627 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
629 void
630 redisplay_other_windows (void)
632 if (!windows_or_buffers_changed)
633 windows_or_buffers_changed = REDISPLAY_SOME;
636 void
637 wset_redisplay (struct window *w)
639 /* Beware: selected_window can be nil during early stages. */
640 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
641 redisplay_other_windows ();
642 w->redisplay = true;
645 void
646 fset_redisplay (struct frame *f)
648 redisplay_other_windows ();
649 f->redisplay = true;
652 void
653 bset_redisplay (struct buffer *b)
655 int count = buffer_window_count (b);
656 if (count > 0)
658 /* ... it's visible in other window than selected, */
659 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
660 redisplay_other_windows ();
661 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
662 so that if we later set windows_or_buffers_changed, this buffer will
663 not be omitted. */
664 b->text->redisplay = true;
668 void
669 bset_update_mode_line (struct buffer *b)
671 if (!update_mode_lines)
672 update_mode_lines = REDISPLAY_SOME;
673 b->text->redisplay = true;
676 #ifdef GLYPH_DEBUG
678 /* Non-zero means print traces of redisplay if compiled with
679 GLYPH_DEBUG defined. */
681 bool trace_redisplay_p;
683 #endif /* GLYPH_DEBUG */
685 #ifdef DEBUG_TRACE_MOVE
686 /* Non-zero means trace with TRACE_MOVE to stderr. */
687 int trace_move;
689 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
690 #else
691 #define TRACE_MOVE(x) (void) 0
692 #endif
694 static Lisp_Object Qauto_hscroll_mode;
696 /* Buffer being redisplayed -- for redisplay_window_error. */
698 static struct buffer *displayed_buffer;
700 /* Value returned from text property handlers (see below). */
702 enum prop_handled
704 HANDLED_NORMALLY,
705 HANDLED_RECOMPUTE_PROPS,
706 HANDLED_OVERLAY_STRING_CONSUMED,
707 HANDLED_RETURN
710 /* A description of text properties that redisplay is interested
711 in. */
713 struct props
715 /* The name of the property. */
716 Lisp_Object *name;
718 /* A unique index for the property. */
719 enum prop_idx idx;
721 /* A handler function called to set up iterator IT from the property
722 at IT's current position. Value is used to steer handle_stop. */
723 enum prop_handled (*handler) (struct it *it);
726 static enum prop_handled handle_face_prop (struct it *);
727 static enum prop_handled handle_invisible_prop (struct it *);
728 static enum prop_handled handle_display_prop (struct it *);
729 static enum prop_handled handle_composition_prop (struct it *);
730 static enum prop_handled handle_overlay_change (struct it *);
731 static enum prop_handled handle_fontified_prop (struct it *);
733 /* Properties handled by iterators. */
735 static struct props it_props[] =
737 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
738 /* Handle `face' before `display' because some sub-properties of
739 `display' need to know the face. */
740 {&Qface, FACE_PROP_IDX, handle_face_prop},
741 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
742 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
743 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
744 {NULL, 0, NULL}
747 /* Value is the position described by X. If X is a marker, value is
748 the marker_position of X. Otherwise, value is X. */
750 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
752 /* Enumeration returned by some move_it_.* functions internally. */
754 enum move_it_result
756 /* Not used. Undefined value. */
757 MOVE_UNDEFINED,
759 /* Move ended at the requested buffer position or ZV. */
760 MOVE_POS_MATCH_OR_ZV,
762 /* Move ended at the requested X pixel position. */
763 MOVE_X_REACHED,
765 /* Move within a line ended at the end of a line that must be
766 continued. */
767 MOVE_LINE_CONTINUED,
769 /* Move within a line ended at the end of a line that would
770 be displayed truncated. */
771 MOVE_LINE_TRUNCATED,
773 /* Move within a line ended at a line end. */
774 MOVE_NEWLINE_OR_CR
777 /* This counter is used to clear the face cache every once in a while
778 in redisplay_internal. It is incremented for each redisplay.
779 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
780 cleared. */
782 #define CLEAR_FACE_CACHE_COUNT 500
783 static int clear_face_cache_count;
785 /* Similarly for the image cache. */
787 #ifdef HAVE_WINDOW_SYSTEM
788 #define CLEAR_IMAGE_CACHE_COUNT 101
789 static int clear_image_cache_count;
791 /* Null glyph slice */
792 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
793 #endif
795 /* True while redisplay_internal is in progress. */
797 bool redisplaying_p;
799 static Lisp_Object Qinhibit_free_realized_faces;
800 static Lisp_Object Qmode_line_default_help_echo;
802 /* If a string, XTread_socket generates an event to display that string.
803 (The display is done in read_char.) */
805 Lisp_Object help_echo_string;
806 Lisp_Object help_echo_window;
807 Lisp_Object help_echo_object;
808 ptrdiff_t help_echo_pos;
810 /* Temporary variable for XTread_socket. */
812 Lisp_Object previous_help_echo_string;
814 /* Platform-independent portion of hourglass implementation. */
816 #ifdef HAVE_WINDOW_SYSTEM
818 /* Non-zero means an hourglass cursor is currently shown. */
819 static bool hourglass_shown_p;
821 /* If non-null, an asynchronous timer that, when it expires, displays
822 an hourglass cursor on all frames. */
823 static struct atimer *hourglass_atimer;
825 #endif /* HAVE_WINDOW_SYSTEM */
827 /* Name of the face used to display glyphless characters. */
828 static Lisp_Object Qglyphless_char;
830 /* Symbol for the purpose of Vglyphless_char_display. */
831 static Lisp_Object Qglyphless_char_display;
833 /* Method symbols for Vglyphless_char_display. */
834 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
836 /* Default number of seconds to wait before displaying an hourglass
837 cursor. */
838 #define DEFAULT_HOURGLASS_DELAY 1
840 #ifdef HAVE_WINDOW_SYSTEM
842 /* Default pixel width of `thin-space' display method. */
843 #define THIN_SPACE_WIDTH 1
845 #endif /* HAVE_WINDOW_SYSTEM */
847 /* Function prototypes. */
849 static void setup_for_ellipsis (struct it *, int);
850 static void set_iterator_to_next (struct it *, int);
851 static void mark_window_display_accurate_1 (struct window *, int);
852 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
853 static int display_prop_string_p (Lisp_Object, Lisp_Object);
854 static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
855 static int cursor_row_p (struct glyph_row *);
856 static int redisplay_mode_lines (Lisp_Object, bool);
857 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
859 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
861 static void handle_line_prefix (struct it *);
863 static void pint2str (char *, int, ptrdiff_t);
864 static void pint2hrstr (char *, int, ptrdiff_t);
865 static struct text_pos run_window_scroll_functions (Lisp_Object,
866 struct text_pos);
867 static int text_outside_line_unchanged_p (struct window *,
868 ptrdiff_t, ptrdiff_t);
869 static void store_mode_line_noprop_char (char);
870 static int store_mode_line_noprop (const char *, int, int);
871 static void handle_stop (struct it *);
872 static void handle_stop_backwards (struct it *, ptrdiff_t);
873 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
874 static void ensure_echo_area_buffers (void);
875 static void unwind_with_echo_area_buffer (Lisp_Object);
876 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
877 static int with_echo_area_buffer (struct window *, int,
878 int (*) (ptrdiff_t, Lisp_Object),
879 ptrdiff_t, Lisp_Object);
880 static void clear_garbaged_frames (void);
881 static int current_message_1 (ptrdiff_t, Lisp_Object);
882 static int truncate_message_1 (ptrdiff_t, Lisp_Object);
883 static void set_message (Lisp_Object);
884 static int set_message_1 (ptrdiff_t, Lisp_Object);
885 static int display_echo_area (struct window *);
886 static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
887 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
888 static void unwind_redisplay (void);
889 static int string_char_and_length (const unsigned char *, int *);
890 static struct text_pos display_prop_end (struct it *, Lisp_Object,
891 struct text_pos);
892 static int compute_window_start_on_continuation_line (struct window *);
893 static void insert_left_trunc_glyphs (struct it *);
894 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
895 Lisp_Object);
896 static void extend_face_to_end_of_line (struct it *);
897 static int append_space_for_newline (struct it *, int);
898 static int cursor_row_fully_visible_p (struct window *, int, int);
899 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
900 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
901 static int trailing_whitespace_p (ptrdiff_t);
902 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
903 static void push_it (struct it *, struct text_pos *);
904 static void iterate_out_of_display_property (struct it *);
905 static void pop_it (struct it *);
906 static void sync_frame_with_window_matrix_rows (struct window *);
907 static void redisplay_internal (void);
908 static int echo_area_display (int);
909 static void redisplay_windows (Lisp_Object);
910 static void redisplay_window (Lisp_Object, bool);
911 static Lisp_Object redisplay_window_error (Lisp_Object);
912 static Lisp_Object redisplay_window_0 (Lisp_Object);
913 static Lisp_Object redisplay_window_1 (Lisp_Object);
914 static int set_cursor_from_row (struct window *, struct glyph_row *,
915 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
916 int, int);
917 static int update_menu_bar (struct frame *, int, int);
918 static int try_window_reusing_current_matrix (struct window *);
919 static int try_window_id (struct window *);
920 static int display_line (struct it *);
921 static int display_mode_lines (struct window *);
922 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
923 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
924 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
925 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
926 static void display_menu_bar (struct window *);
927 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
928 ptrdiff_t *);
929 static int display_string (const char *, Lisp_Object, Lisp_Object,
930 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
931 static void compute_line_metrics (struct it *);
932 static void run_redisplay_end_trigger_hook (struct it *);
933 static int get_overlay_strings (struct it *, ptrdiff_t);
934 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
935 static void next_overlay_string (struct it *);
936 static void reseat (struct it *, struct text_pos, int);
937 static void reseat_1 (struct it *, struct text_pos, int);
938 static void back_to_previous_visible_line_start (struct it *);
939 static void reseat_at_next_visible_line_start (struct it *, int);
940 static int next_element_from_ellipsis (struct it *);
941 static int next_element_from_display_vector (struct it *);
942 static int next_element_from_string (struct it *);
943 static int next_element_from_c_string (struct it *);
944 static int next_element_from_buffer (struct it *);
945 static int next_element_from_composition (struct it *);
946 static int next_element_from_image (struct it *);
947 static int next_element_from_stretch (struct it *);
948 static void load_overlay_strings (struct it *, ptrdiff_t);
949 static int init_from_display_pos (struct it *, struct window *,
950 struct display_pos *);
951 static void reseat_to_string (struct it *, const char *,
952 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
953 static int get_next_display_element (struct it *);
954 static enum move_it_result
955 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
956 enum move_operation_enum);
957 static void get_visually_first_element (struct it *);
958 static void init_to_row_start (struct it *, struct window *,
959 struct glyph_row *);
960 static int init_to_row_end (struct it *, struct window *,
961 struct glyph_row *);
962 static void back_to_previous_line_start (struct it *);
963 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
964 static struct text_pos string_pos_nchars_ahead (struct text_pos,
965 Lisp_Object, ptrdiff_t);
966 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
967 static struct text_pos c_string_pos (ptrdiff_t, const char *, bool);
968 static ptrdiff_t number_of_chars (const char *, bool);
969 static void compute_stop_pos (struct it *);
970 static void compute_string_pos (struct text_pos *, struct text_pos,
971 Lisp_Object);
972 static int face_before_or_after_it_pos (struct it *, int);
973 static ptrdiff_t next_overlay_change (ptrdiff_t);
974 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
975 Lisp_Object, struct text_pos *, ptrdiff_t, int);
976 static int handle_single_display_spec (struct it *, Lisp_Object,
977 Lisp_Object, Lisp_Object,
978 struct text_pos *, ptrdiff_t, int, int);
979 static int underlying_face_id (struct it *);
980 static int in_ellipses_for_invisible_text_p (struct display_pos *,
981 struct window *);
983 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
984 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
986 #ifdef HAVE_WINDOW_SYSTEM
988 static void x_consider_frame_title (Lisp_Object);
989 static void update_tool_bar (struct frame *, int);
990 static int redisplay_tool_bar (struct frame *);
991 static void x_draw_bottom_divider (struct window *w);
992 static void notice_overwritten_cursor (struct window *,
993 enum glyph_row_area,
994 int, int, int, int);
995 static void append_stretch_glyph (struct it *, Lisp_Object,
996 int, int, int);
999 #endif /* HAVE_WINDOW_SYSTEM */
1001 static void produce_special_glyphs (struct it *, enum display_element_type);
1002 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
1003 static bool coords_in_mouse_face_p (struct window *, int, int);
1007 /***********************************************************************
1008 Window display dimensions
1009 ***********************************************************************/
1011 /* Return the bottom boundary y-position for text lines in window W.
1012 This is the first y position at which a line cannot start.
1013 It is relative to the top of the window.
1015 This is the height of W minus the height of a mode line, if any. */
1018 window_text_bottom_y (struct window *w)
1020 int height = WINDOW_PIXEL_HEIGHT (w);
1022 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1024 if (WINDOW_WANTS_MODELINE_P (w))
1025 height -= CURRENT_MODE_LINE_HEIGHT (w);
1027 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1029 return height;
1032 /* Return the pixel width of display area AREA of window W.
1033 ANY_AREA means return the total width of W, not including
1034 fringes to the left and right of the window. */
1037 window_box_width (struct window *w, enum glyph_row_area area)
1039 int width = w->pixel_width;
1041 if (!w->pseudo_window_p)
1043 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
1044 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
1046 if (area == TEXT_AREA)
1047 width -= (WINDOW_MARGINS_WIDTH (w)
1048 + WINDOW_FRINGES_WIDTH (w));
1049 else if (area == LEFT_MARGIN_AREA)
1050 width = WINDOW_LEFT_MARGIN_WIDTH (w);
1051 else if (area == RIGHT_MARGIN_AREA)
1052 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
1055 /* With wide margins, fringes, etc. we might end up with a negative
1056 width, correct that here. */
1057 return max (0, width);
1061 /* Return the pixel height of the display area of window W, not
1062 including mode lines of W, if any. */
1065 window_box_height (struct window *w)
1067 struct frame *f = XFRAME (w->frame);
1068 int height = WINDOW_PIXEL_HEIGHT (w);
1070 eassert (height >= 0);
1072 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1073 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1075 /* Note: the code below that determines the mode-line/header-line
1076 height is essentially the same as that contained in the macro
1077 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1078 the appropriate glyph row has its `mode_line_p' flag set,
1079 and if it doesn't, uses estimate_mode_line_height instead. */
1081 if (WINDOW_WANTS_MODELINE_P (w))
1083 struct glyph_row *ml_row
1084 = (w->current_matrix && w->current_matrix->rows
1085 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1086 : 0);
1087 if (ml_row && ml_row->mode_line_p)
1088 height -= ml_row->height;
1089 else
1090 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1093 if (WINDOW_WANTS_HEADER_LINE_P (w))
1095 struct glyph_row *hl_row
1096 = (w->current_matrix && w->current_matrix->rows
1097 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1098 : 0);
1099 if (hl_row && hl_row->mode_line_p)
1100 height -= hl_row->height;
1101 else
1102 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1105 /* With a very small font and a mode-line that's taller than
1106 default, we might end up with a negative height. */
1107 return max (0, height);
1110 /* Return the window-relative coordinate of the left edge of display
1111 area AREA of window W. ANY_AREA means return the left edge of the
1112 whole window, to the right of the left fringe of W. */
1115 window_box_left_offset (struct window *w, enum glyph_row_area area)
1117 int x;
1119 if (w->pseudo_window_p)
1120 return 0;
1122 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1124 if (area == TEXT_AREA)
1125 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1126 + window_box_width (w, LEFT_MARGIN_AREA));
1127 else if (area == RIGHT_MARGIN_AREA)
1128 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1129 + window_box_width (w, LEFT_MARGIN_AREA)
1130 + window_box_width (w, TEXT_AREA)
1131 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1133 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1134 else if (area == LEFT_MARGIN_AREA
1135 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1136 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1138 /* Don't return more than the window's pixel width. */
1139 return min (x, w->pixel_width);
1143 /* Return the window-relative coordinate of the right edge of display
1144 area AREA of window W. ANY_AREA means return the right edge of the
1145 whole window, to the left of the right fringe of W. */
1148 window_box_right_offset (struct window *w, enum glyph_row_area area)
1150 /* Don't return more than the window's pixel width. */
1151 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1152 w->pixel_width);
1155 /* Return the frame-relative coordinate of the left edge of display
1156 area AREA of window W. ANY_AREA means return the left edge of the
1157 whole window, to the right of the left fringe of W. */
1160 window_box_left (struct window *w, enum glyph_row_area area)
1162 struct frame *f = XFRAME (w->frame);
1163 int x;
1165 if (w->pseudo_window_p)
1166 return FRAME_INTERNAL_BORDER_WIDTH (f);
1168 x = (WINDOW_LEFT_EDGE_X (w)
1169 + window_box_left_offset (w, area));
1171 return x;
1175 /* Return the frame-relative coordinate of the right edge of display
1176 area AREA of window W. ANY_AREA means return the right edge of the
1177 whole window, to the left of the right fringe of W. */
1180 window_box_right (struct window *w, enum glyph_row_area area)
1182 return window_box_left (w, area) + window_box_width (w, area);
1185 /* Get the bounding box of the display area AREA of window W, without
1186 mode lines, in frame-relative coordinates. ANY_AREA means the
1187 whole window, not including the left and right fringes of
1188 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1189 coordinates of the upper-left corner of the box. Return in
1190 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1192 void
1193 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1194 int *box_y, int *box_width, int *box_height)
1196 if (box_width)
1197 *box_width = window_box_width (w, area);
1198 if (box_height)
1199 *box_height = window_box_height (w);
1200 if (box_x)
1201 *box_x = window_box_left (w, area);
1202 if (box_y)
1204 *box_y = WINDOW_TOP_EDGE_Y (w);
1205 if (WINDOW_WANTS_HEADER_LINE_P (w))
1206 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1210 #ifdef HAVE_WINDOW_SYSTEM
1212 /* Get the bounding box of the display area AREA of window W, without
1213 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1214 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1215 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1216 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1217 box. */
1219 static void
1220 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1221 int *bottom_right_x, int *bottom_right_y)
1223 window_box (w, ANY_AREA, top_left_x, top_left_y,
1224 bottom_right_x, bottom_right_y);
1225 *bottom_right_x += *top_left_x;
1226 *bottom_right_y += *top_left_y;
1229 #endif /* HAVE_WINDOW_SYSTEM */
1231 /***********************************************************************
1232 Utilities
1233 ***********************************************************************/
1235 /* Return the bottom y-position of the line the iterator IT is in.
1236 This can modify IT's settings. */
1239 line_bottom_y (struct it *it)
1241 int line_height = it->max_ascent + it->max_descent;
1242 int line_top_y = it->current_y;
1244 if (line_height == 0)
1246 if (last_height)
1247 line_height = last_height;
1248 else if (IT_CHARPOS (*it) < ZV)
1250 move_it_by_lines (it, 1);
1251 line_height = (it->max_ascent || it->max_descent
1252 ? it->max_ascent + it->max_descent
1253 : last_height);
1255 else
1257 struct glyph_row *row = it->glyph_row;
1259 /* Use the default character height. */
1260 it->glyph_row = NULL;
1261 it->what = IT_CHARACTER;
1262 it->c = ' ';
1263 it->len = 1;
1264 PRODUCE_GLYPHS (it);
1265 line_height = it->ascent + it->descent;
1266 it->glyph_row = row;
1270 return line_top_y + line_height;
1273 DEFUN ("line-pixel-height", Fline_pixel_height,
1274 Sline_pixel_height, 0, 0, 0,
1275 doc: /* Return height in pixels of text line in the selected window.
1277 Value is the height in pixels of the line at point. */)
1278 (void)
1280 struct it it;
1281 struct text_pos pt;
1282 struct window *w = XWINDOW (selected_window);
1283 struct buffer *old_buffer = NULL;
1284 Lisp_Object result;
1286 if (XBUFFER (w->contents) != current_buffer)
1288 old_buffer = current_buffer;
1289 set_buffer_internal_1 (XBUFFER (w->contents));
1291 SET_TEXT_POS (pt, PT, PT_BYTE);
1292 start_display (&it, w, pt);
1293 it.vpos = it.current_y = 0;
1294 last_height = 0;
1295 result = make_number (line_bottom_y (&it));
1296 if (old_buffer)
1297 set_buffer_internal_1 (old_buffer);
1299 return result;
1302 /* Return the default pixel height of text lines in window W. The
1303 value is the canonical height of the W frame's default font, plus
1304 any extra space required by the line-spacing variable or frame
1305 parameter.
1307 Implementation note: this ignores any line-spacing text properties
1308 put on the newline characters. This is because those properties
1309 only affect the _screen_ line ending in the newline (i.e., in a
1310 continued line, only the last screen line will be affected), which
1311 means only a small number of lines in a buffer can ever use this
1312 feature. Since this function is used to compute the default pixel
1313 equivalent of text lines in a window, we can safely ignore those
1314 few lines. For the same reasons, we ignore the line-height
1315 properties. */
1317 default_line_pixel_height (struct window *w)
1319 struct frame *f = WINDOW_XFRAME (w);
1320 int height = FRAME_LINE_HEIGHT (f);
1322 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1324 struct buffer *b = XBUFFER (w->contents);
1325 Lisp_Object val = BVAR (b, extra_line_spacing);
1327 if (NILP (val))
1328 val = BVAR (&buffer_defaults, extra_line_spacing);
1329 if (!NILP (val))
1331 if (RANGED_INTEGERP (0, val, INT_MAX))
1332 height += XFASTINT (val);
1333 else if (FLOATP (val))
1335 int addon = XFLOAT_DATA (val) * height + 0.5;
1337 if (addon >= 0)
1338 height += addon;
1341 else
1342 height += f->extra_line_spacing;
1345 return height;
1348 /* Subroutine of pos_visible_p below. Extracts a display string, if
1349 any, from the display spec given as its argument. */
1350 static Lisp_Object
1351 string_from_display_spec (Lisp_Object spec)
1353 if (CONSP (spec))
1355 while (CONSP (spec))
1357 if (STRINGP (XCAR (spec)))
1358 return XCAR (spec);
1359 spec = XCDR (spec);
1362 else if (VECTORP (spec))
1364 ptrdiff_t i;
1366 for (i = 0; i < ASIZE (spec); i++)
1368 if (STRINGP (AREF (spec, i)))
1369 return AREF (spec, i);
1371 return Qnil;
1374 return spec;
1378 /* Limit insanely large values of W->hscroll on frame F to the largest
1379 value that will still prevent first_visible_x and last_visible_x of
1380 'struct it' from overflowing an int. */
1381 static int
1382 window_hscroll_limited (struct window *w, struct frame *f)
1384 ptrdiff_t window_hscroll = w->hscroll;
1385 int window_text_width = window_box_width (w, TEXT_AREA);
1386 int colwidth = FRAME_COLUMN_WIDTH (f);
1388 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1389 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1391 return window_hscroll;
1394 /* Return 1 if position CHARPOS is visible in window W.
1395 CHARPOS < 0 means return info about WINDOW_END position.
1396 If visible, set *X and *Y to pixel coordinates of top left corner.
1397 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1398 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1401 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1402 int *rtop, int *rbot, int *rowh, int *vpos)
1404 struct it it;
1405 void *itdata = bidi_shelve_cache ();
1406 struct text_pos top;
1407 int visible_p = 0;
1408 struct buffer *old_buffer = NULL;
1410 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1411 return visible_p;
1413 if (XBUFFER (w->contents) != current_buffer)
1415 old_buffer = current_buffer;
1416 set_buffer_internal_1 (XBUFFER (w->contents));
1419 SET_TEXT_POS_FROM_MARKER (top, w->start);
1420 /* Scrolling a minibuffer window via scroll bar when the echo area
1421 shows long text sometimes resets the minibuffer contents behind
1422 our backs. */
1423 if (CHARPOS (top) > ZV)
1424 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1426 /* Compute exact mode line heights. */
1427 if (WINDOW_WANTS_MODELINE_P (w))
1428 w->mode_line_height
1429 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1430 BVAR (current_buffer, mode_line_format));
1432 if (WINDOW_WANTS_HEADER_LINE_P (w))
1433 w->header_line_height
1434 = display_mode_line (w, HEADER_LINE_FACE_ID,
1435 BVAR (current_buffer, header_line_format));
1437 start_display (&it, w, top);
1438 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1439 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1441 if (charpos >= 0
1442 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1443 && IT_CHARPOS (it) >= charpos)
1444 /* When scanning backwards under bidi iteration, move_it_to
1445 stops at or _before_ CHARPOS, because it stops at or to
1446 the _right_ of the character at CHARPOS. */
1447 || (it.bidi_p && it.bidi_it.scan_dir == -1
1448 && IT_CHARPOS (it) <= charpos)))
1450 /* We have reached CHARPOS, or passed it. How the call to
1451 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1452 or covered by a display property, move_it_to stops at the end
1453 of the invisible text, to the right of CHARPOS. (ii) If
1454 CHARPOS is in a display vector, move_it_to stops on its last
1455 glyph. */
1456 int top_x = it.current_x;
1457 int top_y = it.current_y;
1458 /* Calling line_bottom_y may change it.method, it.position, etc. */
1459 enum it_method it_method = it.method;
1460 int bottom_y = (last_height = 0, line_bottom_y (&it));
1461 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1463 if (top_y < window_top_y)
1464 visible_p = bottom_y > window_top_y;
1465 else if (top_y < it.last_visible_y)
1466 visible_p = true;
1467 if (bottom_y >= it.last_visible_y
1468 && it.bidi_p && it.bidi_it.scan_dir == -1
1469 && IT_CHARPOS (it) < charpos)
1471 /* When the last line of the window is scanned backwards
1472 under bidi iteration, we could be duped into thinking
1473 that we have passed CHARPOS, when in fact move_it_to
1474 simply stopped short of CHARPOS because it reached
1475 last_visible_y. To see if that's what happened, we call
1476 move_it_to again with a slightly larger vertical limit,
1477 and see if it actually moved vertically; if it did, we
1478 didn't really reach CHARPOS, which is beyond window end. */
1479 struct it save_it = it;
1480 /* Why 10? because we don't know how many canonical lines
1481 will the height of the next line(s) be. So we guess. */
1482 int ten_more_lines = 10 * default_line_pixel_height (w);
1484 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1485 MOVE_TO_POS | MOVE_TO_Y);
1486 if (it.current_y > top_y)
1487 visible_p = 0;
1489 it = save_it;
1491 if (visible_p)
1493 if (it_method == GET_FROM_DISPLAY_VECTOR)
1495 /* We stopped on the last glyph of a display vector.
1496 Try and recompute. Hack alert! */
1497 if (charpos < 2 || top.charpos >= charpos)
1498 top_x = it.glyph_row->x;
1499 else
1501 struct it it2, it2_prev;
1502 /* The idea is to get to the previous buffer
1503 position, consume the character there, and use
1504 the pixel coordinates we get after that. But if
1505 the previous buffer position is also displayed
1506 from a display vector, we need to consume all of
1507 the glyphs from that display vector. */
1508 start_display (&it2, w, top);
1509 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1510 /* If we didn't get to CHARPOS - 1, there's some
1511 replacing display property at that position, and
1512 we stopped after it. That is exactly the place
1513 whose coordinates we want. */
1514 if (IT_CHARPOS (it2) != charpos - 1)
1515 it2_prev = it2;
1516 else
1518 /* Iterate until we get out of the display
1519 vector that displays the character at
1520 CHARPOS - 1. */
1521 do {
1522 get_next_display_element (&it2);
1523 PRODUCE_GLYPHS (&it2);
1524 it2_prev = it2;
1525 set_iterator_to_next (&it2, 1);
1526 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1527 && IT_CHARPOS (it2) < charpos);
1529 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1530 || it2_prev.current_x > it2_prev.last_visible_x)
1531 top_x = it.glyph_row->x;
1532 else
1534 top_x = it2_prev.current_x;
1535 top_y = it2_prev.current_y;
1539 else if (IT_CHARPOS (it) != charpos)
1541 Lisp_Object cpos = make_number (charpos);
1542 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1543 Lisp_Object string = string_from_display_spec (spec);
1544 struct text_pos tpos;
1545 int replacing_spec_p;
1546 bool newline_in_string
1547 = (STRINGP (string)
1548 && memchr (SDATA (string), '\n', SBYTES (string)));
1550 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1551 replacing_spec_p
1552 = (!NILP (spec)
1553 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1554 charpos, FRAME_WINDOW_P (it.f)));
1555 /* The tricky code below is needed because there's a
1556 discrepancy between move_it_to and how we set cursor
1557 when PT is at the beginning of a portion of text
1558 covered by a display property or an overlay with a
1559 display property, or the display line ends in a
1560 newline from a display string. move_it_to will stop
1561 _after_ such display strings, whereas
1562 set_cursor_from_row conspires with cursor_row_p to
1563 place the cursor on the first glyph produced from the
1564 display string. */
1566 /* We have overshoot PT because it is covered by a
1567 display property that replaces the text it covers.
1568 If the string includes embedded newlines, we are also
1569 in the wrong display line. Backtrack to the correct
1570 line, where the display property begins. */
1571 if (replacing_spec_p)
1573 Lisp_Object startpos, endpos;
1574 EMACS_INT start, end;
1575 struct it it3;
1576 int it3_moved;
1578 /* Find the first and the last buffer positions
1579 covered by the display string. */
1580 endpos =
1581 Fnext_single_char_property_change (cpos, Qdisplay,
1582 Qnil, Qnil);
1583 startpos =
1584 Fprevious_single_char_property_change (endpos, Qdisplay,
1585 Qnil, Qnil);
1586 start = XFASTINT (startpos);
1587 end = XFASTINT (endpos);
1588 /* Move to the last buffer position before the
1589 display property. */
1590 start_display (&it3, w, top);
1591 if (start > CHARPOS (top))
1592 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1593 /* Move forward one more line if the position before
1594 the display string is a newline or if it is the
1595 rightmost character on a line that is
1596 continued or word-wrapped. */
1597 if (it3.method == GET_FROM_BUFFER
1598 && (it3.c == '\n'
1599 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1600 move_it_by_lines (&it3, 1);
1601 else if (move_it_in_display_line_to (&it3, -1,
1602 it3.current_x
1603 + it3.pixel_width,
1604 MOVE_TO_X)
1605 == MOVE_LINE_CONTINUED)
1607 move_it_by_lines (&it3, 1);
1608 /* When we are under word-wrap, the #$@%!
1609 move_it_by_lines moves 2 lines, so we need to
1610 fix that up. */
1611 if (it3.line_wrap == WORD_WRAP)
1612 move_it_by_lines (&it3, -1);
1615 /* Record the vertical coordinate of the display
1616 line where we wound up. */
1617 top_y = it3.current_y;
1618 if (it3.bidi_p)
1620 /* When characters are reordered for display,
1621 the character displayed to the left of the
1622 display string could be _after_ the display
1623 property in the logical order. Use the
1624 smallest vertical position of these two. */
1625 start_display (&it3, w, top);
1626 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1627 if (it3.current_y < top_y)
1628 top_y = it3.current_y;
1630 /* Move from the top of the window to the beginning
1631 of the display line where the display string
1632 begins. */
1633 start_display (&it3, w, top);
1634 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1635 /* If it3_moved stays zero after the 'while' loop
1636 below, that means we already were at a newline
1637 before the loop (e.g., the display string begins
1638 with a newline), so we don't need to (and cannot)
1639 inspect the glyphs of it3.glyph_row, because
1640 PRODUCE_GLYPHS will not produce anything for a
1641 newline, and thus it3.glyph_row stays at its
1642 stale content it got at top of the window. */
1643 it3_moved = 0;
1644 /* Finally, advance the iterator until we hit the
1645 first display element whose character position is
1646 CHARPOS, or until the first newline from the
1647 display string, which signals the end of the
1648 display line. */
1649 while (get_next_display_element (&it3))
1651 PRODUCE_GLYPHS (&it3);
1652 if (IT_CHARPOS (it3) == charpos
1653 || ITERATOR_AT_END_OF_LINE_P (&it3))
1654 break;
1655 it3_moved = 1;
1656 set_iterator_to_next (&it3, 0);
1658 top_x = it3.current_x - it3.pixel_width;
1659 /* Normally, we would exit the above loop because we
1660 found the display element whose character
1661 position is CHARPOS. For the contingency that we
1662 didn't, and stopped at the first newline from the
1663 display string, move back over the glyphs
1664 produced from the string, until we find the
1665 rightmost glyph not from the string. */
1666 if (it3_moved
1667 && newline_in_string
1668 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1670 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1671 + it3.glyph_row->used[TEXT_AREA];
1673 while (EQ ((g - 1)->object, string))
1675 --g;
1676 top_x -= g->pixel_width;
1678 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1679 + it3.glyph_row->used[TEXT_AREA]);
1684 *x = top_x;
1685 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1686 *rtop = max (0, window_top_y - top_y);
1687 *rbot = max (0, bottom_y - it.last_visible_y);
1688 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1689 - max (top_y, window_top_y)));
1690 *vpos = it.vpos;
1693 else
1695 /* Either we were asked to provide info about WINDOW_END, or
1696 CHARPOS is in the partially visible glyph row at end of
1697 window. */
1698 struct it it2;
1699 void *it2data = NULL;
1701 SAVE_IT (it2, it, it2data);
1702 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1703 move_it_by_lines (&it, 1);
1704 if (charpos < IT_CHARPOS (it)
1705 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1707 visible_p = true;
1708 RESTORE_IT (&it2, &it2, it2data);
1709 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1710 *x = it2.current_x;
1711 *y = it2.current_y + it2.max_ascent - it2.ascent;
1712 *rtop = max (0, -it2.current_y);
1713 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1714 - it.last_visible_y));
1715 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1716 it.last_visible_y)
1717 - max (it2.current_y,
1718 WINDOW_HEADER_LINE_HEIGHT (w))));
1719 *vpos = it2.vpos;
1721 else
1722 bidi_unshelve_cache (it2data, 1);
1724 bidi_unshelve_cache (itdata, 0);
1726 if (old_buffer)
1727 set_buffer_internal_1 (old_buffer);
1729 if (visible_p && w->hscroll > 0)
1730 *x -=
1731 window_hscroll_limited (w, WINDOW_XFRAME (w))
1732 * WINDOW_FRAME_COLUMN_WIDTH (w);
1734 #if 0
1735 /* Debugging code. */
1736 if (visible_p)
1737 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1738 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1739 else
1740 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1741 #endif
1743 return visible_p;
1747 /* Return the next character from STR. Return in *LEN the length of
1748 the character. This is like STRING_CHAR_AND_LENGTH but never
1749 returns an invalid character. If we find one, we return a `?', but
1750 with the length of the invalid character. */
1752 static int
1753 string_char_and_length (const unsigned char *str, int *len)
1755 int c;
1757 c = STRING_CHAR_AND_LENGTH (str, *len);
1758 if (!CHAR_VALID_P (c))
1759 /* We may not change the length here because other places in Emacs
1760 don't use this function, i.e. they silently accept invalid
1761 characters. */
1762 c = '?';
1764 return c;
1769 /* Given a position POS containing a valid character and byte position
1770 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1772 static struct text_pos
1773 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1775 eassert (STRINGP (string) && nchars >= 0);
1777 if (STRING_MULTIBYTE (string))
1779 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1780 int len;
1782 while (nchars--)
1784 string_char_and_length (p, &len);
1785 p += len;
1786 CHARPOS (pos) += 1;
1787 BYTEPOS (pos) += len;
1790 else
1791 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1793 return pos;
1797 /* Value is the text position, i.e. character and byte position,
1798 for character position CHARPOS in STRING. */
1800 static struct text_pos
1801 string_pos (ptrdiff_t charpos, Lisp_Object string)
1803 struct text_pos pos;
1804 eassert (STRINGP (string));
1805 eassert (charpos >= 0);
1806 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1807 return pos;
1811 /* Value is a text position, i.e. character and byte position, for
1812 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1813 means recognize multibyte characters. */
1815 static struct text_pos
1816 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1818 struct text_pos pos;
1820 eassert (s != NULL);
1821 eassert (charpos >= 0);
1823 if (multibyte_p)
1825 int len;
1827 SET_TEXT_POS (pos, 0, 0);
1828 while (charpos--)
1830 string_char_and_length ((const unsigned char *) s, &len);
1831 s += len;
1832 CHARPOS (pos) += 1;
1833 BYTEPOS (pos) += len;
1836 else
1837 SET_TEXT_POS (pos, charpos, charpos);
1839 return pos;
1843 /* Value is the number of characters in C string S. MULTIBYTE_P
1844 non-zero means recognize multibyte characters. */
1846 static ptrdiff_t
1847 number_of_chars (const char *s, bool multibyte_p)
1849 ptrdiff_t nchars;
1851 if (multibyte_p)
1853 ptrdiff_t rest = strlen (s);
1854 int len;
1855 const unsigned char *p = (const unsigned char *) s;
1857 for (nchars = 0; rest > 0; ++nchars)
1859 string_char_and_length (p, &len);
1860 rest -= len, p += len;
1863 else
1864 nchars = strlen (s);
1866 return nchars;
1870 /* Compute byte position NEWPOS->bytepos corresponding to
1871 NEWPOS->charpos. POS is a known position in string STRING.
1872 NEWPOS->charpos must be >= POS.charpos. */
1874 static void
1875 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1877 eassert (STRINGP (string));
1878 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1880 if (STRING_MULTIBYTE (string))
1881 *newpos = string_pos_nchars_ahead (pos, string,
1882 CHARPOS (*newpos) - CHARPOS (pos));
1883 else
1884 BYTEPOS (*newpos) = CHARPOS (*newpos);
1887 /* EXPORT:
1888 Return an estimation of the pixel height of mode or header lines on
1889 frame F. FACE_ID specifies what line's height to estimate. */
1892 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1894 #ifdef HAVE_WINDOW_SYSTEM
1895 if (FRAME_WINDOW_P (f))
1897 int height = FONT_HEIGHT (FRAME_FONT (f));
1899 /* This function is called so early when Emacs starts that the face
1900 cache and mode line face are not yet initialized. */
1901 if (FRAME_FACE_CACHE (f))
1903 struct face *face = FACE_FROM_ID (f, face_id);
1904 if (face)
1906 if (face->font)
1907 height = FONT_HEIGHT (face->font);
1908 if (face->box_line_width > 0)
1909 height += 2 * face->box_line_width;
1913 return height;
1915 #endif
1917 return 1;
1920 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1921 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1922 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1923 not force the value into range. */
1925 void
1926 pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1927 int *x, int *y, NativeRectangle *bounds, int noclip)
1930 #ifdef HAVE_WINDOW_SYSTEM
1931 if (FRAME_WINDOW_P (f))
1933 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1934 even for negative values. */
1935 if (pix_x < 0)
1936 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1937 if (pix_y < 0)
1938 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1940 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1941 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1943 if (bounds)
1944 STORE_NATIVE_RECT (*bounds,
1945 FRAME_COL_TO_PIXEL_X (f, pix_x),
1946 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1947 FRAME_COLUMN_WIDTH (f) - 1,
1948 FRAME_LINE_HEIGHT (f) - 1);
1950 /* PXW: Should we clip pixels before converting to columns/lines? */
1951 if (!noclip)
1953 if (pix_x < 0)
1954 pix_x = 0;
1955 else if (pix_x > FRAME_TOTAL_COLS (f))
1956 pix_x = FRAME_TOTAL_COLS (f);
1958 if (pix_y < 0)
1959 pix_y = 0;
1960 else if (pix_y > FRAME_TOTAL_LINES (f))
1961 pix_y = FRAME_TOTAL_LINES (f);
1964 #endif
1966 *x = pix_x;
1967 *y = pix_y;
1971 /* Find the glyph under window-relative coordinates X/Y in window W.
1972 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1973 strings. Return in *HPOS and *VPOS the row and column number of
1974 the glyph found. Return in *AREA the glyph area containing X.
1975 Value is a pointer to the glyph found or null if X/Y is not on
1976 text, or we can't tell because W's current matrix is not up to
1977 date. */
1979 static struct glyph *
1980 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1981 int *dx, int *dy, int *area)
1983 struct glyph *glyph, *end;
1984 struct glyph_row *row = NULL;
1985 int x0, i;
1987 /* Find row containing Y. Give up if some row is not enabled. */
1988 for (i = 0; i < w->current_matrix->nrows; ++i)
1990 row = MATRIX_ROW (w->current_matrix, i);
1991 if (!row->enabled_p)
1992 return NULL;
1993 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1994 break;
1997 *vpos = i;
1998 *hpos = 0;
2000 /* Give up if Y is not in the window. */
2001 if (i == w->current_matrix->nrows)
2002 return NULL;
2004 /* Get the glyph area containing X. */
2005 if (w->pseudo_window_p)
2007 *area = TEXT_AREA;
2008 x0 = 0;
2010 else
2012 if (x < window_box_left_offset (w, TEXT_AREA))
2014 *area = LEFT_MARGIN_AREA;
2015 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2017 else if (x < window_box_right_offset (w, TEXT_AREA))
2019 *area = TEXT_AREA;
2020 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2022 else
2024 *area = RIGHT_MARGIN_AREA;
2025 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2029 /* Find glyph containing X. */
2030 glyph = row->glyphs[*area];
2031 end = glyph + row->used[*area];
2032 x -= x0;
2033 while (glyph < end && x >= glyph->pixel_width)
2035 x -= glyph->pixel_width;
2036 ++glyph;
2039 if (glyph == end)
2040 return NULL;
2042 if (dx)
2044 *dx = x;
2045 *dy = y - (row->y + row->ascent - glyph->ascent);
2048 *hpos = glyph - row->glyphs[*area];
2049 return glyph;
2052 /* Convert frame-relative x/y to coordinates relative to window W.
2053 Takes pseudo-windows into account. */
2055 static void
2056 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2058 if (w->pseudo_window_p)
2060 /* A pseudo-window is always full-width, and starts at the
2061 left edge of the frame, plus a frame border. */
2062 struct frame *f = XFRAME (w->frame);
2063 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2064 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2066 else
2068 *x -= WINDOW_LEFT_EDGE_X (w);
2069 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2073 #ifdef HAVE_WINDOW_SYSTEM
2075 /* EXPORT:
2076 Return in RECTS[] at most N clipping rectangles for glyph string S.
2077 Return the number of stored rectangles. */
2080 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2082 XRectangle r;
2084 if (n <= 0)
2085 return 0;
2087 if (s->row->full_width_p)
2089 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2090 r.x = WINDOW_LEFT_EDGE_X (s->w);
2091 if (s->row->mode_line_p)
2092 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2093 else
2094 r.width = WINDOW_PIXEL_WIDTH (s->w);
2096 /* Unless displaying a mode or menu bar line, which are always
2097 fully visible, clip to the visible part of the row. */
2098 if (s->w->pseudo_window_p)
2099 r.height = s->row->visible_height;
2100 else
2101 r.height = s->height;
2103 else
2105 /* This is a text line that may be partially visible. */
2106 r.x = window_box_left (s->w, s->area);
2107 r.width = window_box_width (s->w, s->area);
2108 r.height = s->row->visible_height;
2111 if (s->clip_head)
2112 if (r.x < s->clip_head->x)
2114 if (r.width >= s->clip_head->x - r.x)
2115 r.width -= s->clip_head->x - r.x;
2116 else
2117 r.width = 0;
2118 r.x = s->clip_head->x;
2120 if (s->clip_tail)
2121 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2123 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2124 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2125 else
2126 r.width = 0;
2129 /* If S draws overlapping rows, it's sufficient to use the top and
2130 bottom of the window for clipping because this glyph string
2131 intentionally draws over other lines. */
2132 if (s->for_overlaps)
2134 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2135 r.height = window_text_bottom_y (s->w) - r.y;
2137 /* Alas, the above simple strategy does not work for the
2138 environments with anti-aliased text: if the same text is
2139 drawn onto the same place multiple times, it gets thicker.
2140 If the overlap we are processing is for the erased cursor, we
2141 take the intersection with the rectangle of the cursor. */
2142 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2144 XRectangle rc, r_save = r;
2146 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2147 rc.y = s->w->phys_cursor.y;
2148 rc.width = s->w->phys_cursor_width;
2149 rc.height = s->w->phys_cursor_height;
2151 x_intersect_rectangles (&r_save, &rc, &r);
2154 else
2156 /* Don't use S->y for clipping because it doesn't take partially
2157 visible lines into account. For example, it can be negative for
2158 partially visible lines at the top of a window. */
2159 if (!s->row->full_width_p
2160 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2161 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2162 else
2163 r.y = max (0, s->row->y);
2166 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2168 /* If drawing the cursor, don't let glyph draw outside its
2169 advertised boundaries. Cleartype does this under some circumstances. */
2170 if (s->hl == DRAW_CURSOR)
2172 struct glyph *glyph = s->first_glyph;
2173 int height, max_y;
2175 if (s->x > r.x)
2177 r.width -= s->x - r.x;
2178 r.x = s->x;
2180 r.width = min (r.width, glyph->pixel_width);
2182 /* If r.y is below window bottom, ensure that we still see a cursor. */
2183 height = min (glyph->ascent + glyph->descent,
2184 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2185 max_y = window_text_bottom_y (s->w) - height;
2186 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2187 if (s->ybase - glyph->ascent > max_y)
2189 r.y = max_y;
2190 r.height = height;
2192 else
2194 /* Don't draw cursor glyph taller than our actual glyph. */
2195 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2196 if (height < r.height)
2198 max_y = r.y + r.height;
2199 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2200 r.height = min (max_y - r.y, height);
2205 if (s->row->clip)
2207 XRectangle r_save = r;
2209 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2210 r.width = 0;
2213 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2214 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2216 #ifdef CONVERT_FROM_XRECT
2217 CONVERT_FROM_XRECT (r, *rects);
2218 #else
2219 *rects = r;
2220 #endif
2221 return 1;
2223 else
2225 /* If we are processing overlapping and allowed to return
2226 multiple clipping rectangles, we exclude the row of the glyph
2227 string from the clipping rectangle. This is to avoid drawing
2228 the same text on the environment with anti-aliasing. */
2229 #ifdef CONVERT_FROM_XRECT
2230 XRectangle rs[2];
2231 #else
2232 XRectangle *rs = rects;
2233 #endif
2234 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2236 if (s->for_overlaps & OVERLAPS_PRED)
2238 rs[i] = r;
2239 if (r.y + r.height > row_y)
2241 if (r.y < row_y)
2242 rs[i].height = row_y - r.y;
2243 else
2244 rs[i].height = 0;
2246 i++;
2248 if (s->for_overlaps & OVERLAPS_SUCC)
2250 rs[i] = r;
2251 if (r.y < row_y + s->row->visible_height)
2253 if (r.y + r.height > row_y + s->row->visible_height)
2255 rs[i].y = row_y + s->row->visible_height;
2256 rs[i].height = r.y + r.height - rs[i].y;
2258 else
2259 rs[i].height = 0;
2261 i++;
2264 n = i;
2265 #ifdef CONVERT_FROM_XRECT
2266 for (i = 0; i < n; i++)
2267 CONVERT_FROM_XRECT (rs[i], rects[i]);
2268 #endif
2269 return n;
2273 /* EXPORT:
2274 Return in *NR the clipping rectangle for glyph string S. */
2276 void
2277 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2279 get_glyph_string_clip_rects (s, nr, 1);
2283 /* EXPORT:
2284 Return the position and height of the phys cursor in window W.
2285 Set w->phys_cursor_width to width of phys cursor.
2288 void
2289 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2290 struct glyph *glyph, int *xp, int *yp, int *heightp)
2292 struct frame *f = XFRAME (WINDOW_FRAME (w));
2293 int x, y, wd, h, h0, y0;
2295 /* Compute the width of the rectangle to draw. If on a stretch
2296 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2297 rectangle as wide as the glyph, but use a canonical character
2298 width instead. */
2299 wd = glyph->pixel_width - 1;
2300 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2301 wd++; /* Why? */
2302 #endif
2304 x = w->phys_cursor.x;
2305 if (x < 0)
2307 wd += x;
2308 x = 0;
2311 if (glyph->type == STRETCH_GLYPH
2312 && !x_stretch_cursor_p)
2313 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2314 w->phys_cursor_width = wd;
2316 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2318 /* If y is below window bottom, ensure that we still see a cursor. */
2319 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2321 h = max (h0, glyph->ascent + glyph->descent);
2322 h0 = min (h0, glyph->ascent + glyph->descent);
2324 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2325 if (y < y0)
2327 h = max (h - (y0 - y) + 1, h0);
2328 y = y0 - 1;
2330 else
2332 y0 = window_text_bottom_y (w) - h0;
2333 if (y > y0)
2335 h += y - y0;
2336 y = y0;
2340 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2341 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2342 *heightp = h;
2346 * Remember which glyph the mouse is over.
2349 void
2350 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2352 Lisp_Object window;
2353 struct window *w;
2354 struct glyph_row *r, *gr, *end_row;
2355 enum window_part part;
2356 enum glyph_row_area area;
2357 int x, y, width, height;
2359 /* Try to determine frame pixel position and size of the glyph under
2360 frame pixel coordinates X/Y on frame F. */
2362 if (window_resize_pixelwise)
2364 width = height = 1;
2365 goto virtual_glyph;
2367 else if (!f->glyphs_initialized_p
2368 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2369 NILP (window)))
2371 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2372 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2373 goto virtual_glyph;
2376 w = XWINDOW (window);
2377 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2378 height = WINDOW_FRAME_LINE_HEIGHT (w);
2380 x = window_relative_x_coord (w, part, gx);
2381 y = gy - WINDOW_TOP_EDGE_Y (w);
2383 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2384 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2386 if (w->pseudo_window_p)
2388 area = TEXT_AREA;
2389 part = ON_MODE_LINE; /* Don't adjust margin. */
2390 goto text_glyph;
2393 switch (part)
2395 case ON_LEFT_MARGIN:
2396 area = LEFT_MARGIN_AREA;
2397 goto text_glyph;
2399 case ON_RIGHT_MARGIN:
2400 area = RIGHT_MARGIN_AREA;
2401 goto text_glyph;
2403 case ON_HEADER_LINE:
2404 case ON_MODE_LINE:
2405 gr = (part == ON_HEADER_LINE
2406 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2407 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2408 gy = gr->y;
2409 area = TEXT_AREA;
2410 goto text_glyph_row_found;
2412 case ON_TEXT:
2413 area = TEXT_AREA;
2415 text_glyph:
2416 gr = 0; gy = 0;
2417 for (; r <= end_row && r->enabled_p; ++r)
2418 if (r->y + r->height > y)
2420 gr = r; gy = r->y;
2421 break;
2424 text_glyph_row_found:
2425 if (gr && gy <= y)
2427 struct glyph *g = gr->glyphs[area];
2428 struct glyph *end = g + gr->used[area];
2430 height = gr->height;
2431 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2432 if (gx + g->pixel_width > x)
2433 break;
2435 if (g < end)
2437 if (g->type == IMAGE_GLYPH)
2439 /* Don't remember when mouse is over image, as
2440 image may have hot-spots. */
2441 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2442 return;
2444 width = g->pixel_width;
2446 else
2448 /* Use nominal char spacing at end of line. */
2449 x -= gx;
2450 gx += (x / width) * width;
2453 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2455 gx += window_box_left_offset (w, area);
2456 /* Don't expand over the modeline to make sure the vertical
2457 drag cursor is shown early enough. */
2458 height = min (height,
2459 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2462 else
2464 /* Use nominal line height at end of window. */
2465 gx = (x / width) * width;
2466 y -= gy;
2467 gy += (y / height) * height;
2468 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2469 /* See comment above. */
2470 height = min (height,
2471 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2473 break;
2475 case ON_LEFT_FRINGE:
2476 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2477 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2478 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2479 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2480 goto row_glyph;
2482 case ON_RIGHT_FRINGE:
2483 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2484 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2485 : window_box_right_offset (w, TEXT_AREA));
2486 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2487 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2488 && !WINDOW_RIGHTMOST_P (w))
2489 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2490 /* Make sure the vertical border can get her own glyph to the
2491 right of the one we build here. */
2492 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2493 else
2494 width = WINDOW_PIXEL_WIDTH (w) - gx;
2495 else
2496 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2498 goto row_glyph;
2500 case ON_VERTICAL_BORDER:
2501 gx = WINDOW_PIXEL_WIDTH (w) - width;
2502 goto row_glyph;
2504 case ON_VERTICAL_SCROLL_BAR:
2505 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2507 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2508 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2509 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2510 : 0)));
2511 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2513 row_glyph:
2514 gr = 0, gy = 0;
2515 for (; r <= end_row && r->enabled_p; ++r)
2516 if (r->y + r->height > y)
2518 gr = r; gy = r->y;
2519 break;
2522 if (gr && gy <= y)
2523 height = gr->height;
2524 else
2526 /* Use nominal line height at end of window. */
2527 y -= gy;
2528 gy += (y / height) * height;
2530 break;
2532 case ON_RIGHT_DIVIDER:
2533 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2534 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2535 gy = 0;
2536 /* The bottom divider prevails. */
2537 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2538 goto add_edge;;
2540 case ON_BOTTOM_DIVIDER:
2541 gx = 0;
2542 width = WINDOW_PIXEL_WIDTH (w);
2543 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2544 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2545 goto add_edge;
2547 default:
2549 virtual_glyph:
2550 /* If there is no glyph under the mouse, then we divide the screen
2551 into a grid of the smallest glyph in the frame, and use that
2552 as our "glyph". */
2554 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2555 round down even for negative values. */
2556 if (gx < 0)
2557 gx -= width - 1;
2558 if (gy < 0)
2559 gy -= height - 1;
2561 gx = (gx / width) * width;
2562 gy = (gy / height) * height;
2564 goto store_rect;
2567 add_edge:
2568 gx += WINDOW_LEFT_EDGE_X (w);
2569 gy += WINDOW_TOP_EDGE_Y (w);
2571 store_rect:
2572 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2574 /* Visible feedback for debugging. */
2575 #if 0
2576 #if HAVE_X_WINDOWS
2577 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2578 f->output_data.x->normal_gc,
2579 gx, gy, width, height);
2580 #endif
2581 #endif
2585 #endif /* HAVE_WINDOW_SYSTEM */
2587 static void
2588 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2590 eassert (w);
2591 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2592 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2593 w->window_end_vpos
2594 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2597 /***********************************************************************
2598 Lisp form evaluation
2599 ***********************************************************************/
2601 /* Error handler for safe_eval and safe_call. */
2603 static Lisp_Object
2604 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2606 add_to_log ("Error during redisplay: %S signaled %S",
2607 Flist (nargs, args), arg);
2608 return Qnil;
2611 /* Call function FUNC with the rest of NARGS - 1 arguments
2612 following. Return the result, or nil if something went
2613 wrong. Prevent redisplay during the evaluation. */
2615 static Lisp_Object
2616 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2618 Lisp_Object val;
2620 if (inhibit_eval_during_redisplay)
2621 val = Qnil;
2622 else
2624 ptrdiff_t i;
2625 ptrdiff_t count = SPECPDL_INDEX ();
2626 struct gcpro gcpro1;
2627 Lisp_Object *args = alloca (nargs * word_size);
2629 args[0] = func;
2630 for (i = 1; i < nargs; i++)
2631 args[i] = va_arg (ap, Lisp_Object);
2633 GCPRO1 (args[0]);
2634 gcpro1.nvars = nargs;
2635 specbind (Qinhibit_redisplay, Qt);
2636 if (inhibit_quit)
2637 specbind (Qinhibit_quit, Qt);
2638 /* Use Qt to ensure debugger does not run,
2639 so there is no possibility of wanting to redisplay. */
2640 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2641 safe_eval_handler);
2642 UNGCPRO;
2643 val = unbind_to (count, val);
2646 return val;
2649 Lisp_Object
2650 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2652 Lisp_Object retval;
2653 va_list ap;
2655 va_start (ap, func);
2656 retval = safe__call (false, nargs, func, ap);
2657 va_end (ap);
2658 return retval;
2661 /* Call function FN with one argument ARG.
2662 Return the result, or nil if something went wrong. */
2664 Lisp_Object
2665 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2667 return safe_call (2, fn, arg);
2670 static Lisp_Object
2671 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2673 Lisp_Object retval;
2674 va_list ap;
2676 va_start (ap, fn);
2677 retval = safe__call (inhibit_quit, 2, fn, ap);
2678 va_end (ap);
2679 return retval;
2682 static Lisp_Object Qeval;
2684 Lisp_Object
2685 safe_eval (Lisp_Object sexpr)
2687 return safe__call1 (false, Qeval, sexpr);
2690 static Lisp_Object
2691 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2693 return safe__call1 (inhibit_quit, Qeval, sexpr);
2696 /* Call function FN with two arguments ARG1 and ARG2.
2697 Return the result, or nil if something went wrong. */
2699 Lisp_Object
2700 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2702 return safe_call (3, fn, arg1, arg2);
2707 /***********************************************************************
2708 Debugging
2709 ***********************************************************************/
2711 #if 0
2713 /* Define CHECK_IT to perform sanity checks on iterators.
2714 This is for debugging. It is too slow to do unconditionally. */
2716 static void
2717 check_it (struct it *it)
2719 if (it->method == GET_FROM_STRING)
2721 eassert (STRINGP (it->string));
2722 eassert (IT_STRING_CHARPOS (*it) >= 0);
2724 else
2726 eassert (IT_STRING_CHARPOS (*it) < 0);
2727 if (it->method == GET_FROM_BUFFER)
2729 /* Check that character and byte positions agree. */
2730 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2734 if (it->dpvec)
2735 eassert (it->current.dpvec_index >= 0);
2736 else
2737 eassert (it->current.dpvec_index < 0);
2740 #define CHECK_IT(IT) check_it ((IT))
2742 #else /* not 0 */
2744 #define CHECK_IT(IT) (void) 0
2746 #endif /* not 0 */
2749 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2751 /* Check that the window end of window W is what we expect it
2752 to be---the last row in the current matrix displaying text. */
2754 static void
2755 check_window_end (struct window *w)
2757 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2759 struct glyph_row *row;
2760 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2761 !row->enabled_p
2762 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2763 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2767 #define CHECK_WINDOW_END(W) check_window_end ((W))
2769 #else
2771 #define CHECK_WINDOW_END(W) (void) 0
2773 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2775 /***********************************************************************
2776 Iterator initialization
2777 ***********************************************************************/
2779 /* Initialize IT for displaying current_buffer in window W, starting
2780 at character position CHARPOS. CHARPOS < 0 means that no buffer
2781 position is specified which is useful when the iterator is assigned
2782 a position later. BYTEPOS is the byte position corresponding to
2783 CHARPOS.
2785 If ROW is not null, calls to produce_glyphs with IT as parameter
2786 will produce glyphs in that row.
2788 BASE_FACE_ID is the id of a base face to use. It must be one of
2789 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2790 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2791 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2793 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2794 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2795 will be initialized to use the corresponding mode line glyph row of
2796 the desired matrix of W. */
2798 void
2799 init_iterator (struct it *it, struct window *w,
2800 ptrdiff_t charpos, ptrdiff_t bytepos,
2801 struct glyph_row *row, enum face_id base_face_id)
2803 enum face_id remapped_base_face_id = base_face_id;
2805 /* Some precondition checks. */
2806 eassert (w != NULL && it != NULL);
2807 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2808 && charpos <= ZV));
2810 /* If face attributes have been changed since the last redisplay,
2811 free realized faces now because they depend on face definitions
2812 that might have changed. Don't free faces while there might be
2813 desired matrices pending which reference these faces. */
2814 if (face_change_count && !inhibit_free_realized_faces)
2816 face_change_count = 0;
2817 free_all_realized_faces (Qnil);
2820 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2821 if (! NILP (Vface_remapping_alist))
2822 remapped_base_face_id
2823 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2825 /* Use one of the mode line rows of W's desired matrix if
2826 appropriate. */
2827 if (row == NULL)
2829 if (base_face_id == MODE_LINE_FACE_ID
2830 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2831 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2832 else if (base_face_id == HEADER_LINE_FACE_ID)
2833 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2836 /* Clear IT. */
2837 memset (it, 0, sizeof *it);
2838 it->current.overlay_string_index = -1;
2839 it->current.dpvec_index = -1;
2840 it->base_face_id = remapped_base_face_id;
2841 it->string = Qnil;
2842 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2843 it->paragraph_embedding = L2R;
2844 it->bidi_it.string.lstring = Qnil;
2845 it->bidi_it.string.s = NULL;
2846 it->bidi_it.string.bufpos = 0;
2847 it->bidi_it.w = w;
2849 /* The window in which we iterate over current_buffer: */
2850 XSETWINDOW (it->window, w);
2851 it->w = w;
2852 it->f = XFRAME (w->frame);
2854 it->cmp_it.id = -1;
2856 /* Extra space between lines (on window systems only). */
2857 if (base_face_id == DEFAULT_FACE_ID
2858 && FRAME_WINDOW_P (it->f))
2860 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2861 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2862 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2863 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2864 * FRAME_LINE_HEIGHT (it->f));
2865 else if (it->f->extra_line_spacing > 0)
2866 it->extra_line_spacing = it->f->extra_line_spacing;
2867 it->max_extra_line_spacing = 0;
2870 /* If realized faces have been removed, e.g. because of face
2871 attribute changes of named faces, recompute them. When running
2872 in batch mode, the face cache of the initial frame is null. If
2873 we happen to get called, make a dummy face cache. */
2874 if (FRAME_FACE_CACHE (it->f) == NULL)
2875 init_frame_faces (it->f);
2876 if (FRAME_FACE_CACHE (it->f)->used == 0)
2877 recompute_basic_faces (it->f);
2879 /* Current value of the `slice', `space-width', and 'height' properties. */
2880 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2881 it->space_width = Qnil;
2882 it->font_height = Qnil;
2883 it->override_ascent = -1;
2885 /* Are control characters displayed as `^C'? */
2886 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2888 /* -1 means everything between a CR and the following line end
2889 is invisible. >0 means lines indented more than this value are
2890 invisible. */
2891 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2892 ? (clip_to_bounds
2893 (-1, XINT (BVAR (current_buffer, selective_display)),
2894 PTRDIFF_MAX))
2895 : (!NILP (BVAR (current_buffer, selective_display))
2896 ? -1 : 0));
2897 it->selective_display_ellipsis_p
2898 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2900 /* Display table to use. */
2901 it->dp = window_display_table (w);
2903 /* Are multibyte characters enabled in current_buffer? */
2904 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2906 /* Get the position at which the redisplay_end_trigger hook should
2907 be run, if it is to be run at all. */
2908 if (MARKERP (w->redisplay_end_trigger)
2909 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2910 it->redisplay_end_trigger_charpos
2911 = marker_position (w->redisplay_end_trigger);
2912 else if (INTEGERP (w->redisplay_end_trigger))
2913 it->redisplay_end_trigger_charpos
2914 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2915 PTRDIFF_MAX);
2917 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2919 /* Are lines in the display truncated? */
2920 if (base_face_id != DEFAULT_FACE_ID
2921 || it->w->hscroll
2922 || (! WINDOW_FULL_WIDTH_P (it->w)
2923 && ((!NILP (Vtruncate_partial_width_windows)
2924 && !INTEGERP (Vtruncate_partial_width_windows))
2925 || (INTEGERP (Vtruncate_partial_width_windows)
2926 /* PXW: Shall we do something about this? */
2927 && (WINDOW_TOTAL_COLS (it->w)
2928 < XINT (Vtruncate_partial_width_windows))))))
2929 it->line_wrap = TRUNCATE;
2930 else if (NILP (BVAR (current_buffer, truncate_lines)))
2931 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2932 ? WINDOW_WRAP : WORD_WRAP;
2933 else
2934 it->line_wrap = TRUNCATE;
2936 /* Get dimensions of truncation and continuation glyphs. These are
2937 displayed as fringe bitmaps under X, but we need them for such
2938 frames when the fringes are turned off. But leave the dimensions
2939 zero for tooltip frames, as these glyphs look ugly there and also
2940 sabotage calculations of tooltip dimensions in x-show-tip. */
2941 #ifdef HAVE_WINDOW_SYSTEM
2942 if (!(FRAME_WINDOW_P (it->f)
2943 && FRAMEP (tip_frame)
2944 && it->f == XFRAME (tip_frame)))
2945 #endif
2947 if (it->line_wrap == TRUNCATE)
2949 /* We will need the truncation glyph. */
2950 eassert (it->glyph_row == NULL);
2951 produce_special_glyphs (it, IT_TRUNCATION);
2952 it->truncation_pixel_width = it->pixel_width;
2954 else
2956 /* We will need the continuation glyph. */
2957 eassert (it->glyph_row == NULL);
2958 produce_special_glyphs (it, IT_CONTINUATION);
2959 it->continuation_pixel_width = it->pixel_width;
2963 /* Reset these values to zero because the produce_special_glyphs
2964 above has changed them. */
2965 it->pixel_width = it->ascent = it->descent = 0;
2966 it->phys_ascent = it->phys_descent = 0;
2968 /* Set this after getting the dimensions of truncation and
2969 continuation glyphs, so that we don't produce glyphs when calling
2970 produce_special_glyphs, above. */
2971 it->glyph_row = row;
2972 it->area = TEXT_AREA;
2974 /* Get the dimensions of the display area. The display area
2975 consists of the visible window area plus a horizontally scrolled
2976 part to the left of the window. All x-values are relative to the
2977 start of this total display area. */
2978 if (base_face_id != DEFAULT_FACE_ID)
2980 /* Mode lines, menu bar in terminal frames. */
2981 it->first_visible_x = 0;
2982 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2984 else
2986 it->first_visible_x
2987 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2988 it->last_visible_x = (it->first_visible_x
2989 + window_box_width (w, TEXT_AREA));
2991 /* If we truncate lines, leave room for the truncation glyph(s) at
2992 the right margin. Otherwise, leave room for the continuation
2993 glyph(s). Done only if the window has no fringes. Since we
2994 don't know at this point whether there will be any R2L lines in
2995 the window, we reserve space for truncation/continuation glyphs
2996 even if only one of the fringes is absent. */
2997 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2998 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
3000 if (it->line_wrap == TRUNCATE)
3001 it->last_visible_x -= it->truncation_pixel_width;
3002 else
3003 it->last_visible_x -= it->continuation_pixel_width;
3006 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
3007 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
3010 /* Leave room for a border glyph. */
3011 if (!FRAME_WINDOW_P (it->f)
3012 && !WINDOW_RIGHTMOST_P (it->w))
3013 it->last_visible_x -= 1;
3015 it->last_visible_y = window_text_bottom_y (w);
3017 /* For mode lines and alike, arrange for the first glyph having a
3018 left box line if the face specifies a box. */
3019 if (base_face_id != DEFAULT_FACE_ID)
3021 struct face *face;
3023 it->face_id = remapped_base_face_id;
3025 /* If we have a boxed mode line, make the first character appear
3026 with a left box line. */
3027 face = FACE_FROM_ID (it->f, remapped_base_face_id);
3028 if (face && face->box != FACE_NO_BOX)
3029 it->start_of_box_run_p = true;
3032 /* If a buffer position was specified, set the iterator there,
3033 getting overlays and face properties from that position. */
3034 if (charpos >= BUF_BEG (current_buffer))
3036 it->stop_charpos = charpos;
3037 it->end_charpos = ZV;
3038 eassert (charpos == BYTE_TO_CHAR (bytepos));
3039 IT_CHARPOS (*it) = charpos;
3040 IT_BYTEPOS (*it) = bytepos;
3042 /* We will rely on `reseat' to set this up properly, via
3043 handle_face_prop. */
3044 it->face_id = it->base_face_id;
3046 it->start = it->current;
3047 /* Do we need to reorder bidirectional text? Not if this is a
3048 unibyte buffer: by definition, none of the single-byte
3049 characters are strong R2L, so no reordering is needed. And
3050 bidi.c doesn't support unibyte buffers anyway. Also, don't
3051 reorder while we are loading loadup.el, since the tables of
3052 character properties needed for reordering are not yet
3053 available. */
3054 it->bidi_p =
3055 NILP (Vpurify_flag)
3056 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3057 && it->multibyte_p;
3059 /* If we are to reorder bidirectional text, init the bidi
3060 iterator. */
3061 if (it->bidi_p)
3063 /* Note the paragraph direction that this buffer wants to
3064 use. */
3065 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3066 Qleft_to_right))
3067 it->paragraph_embedding = L2R;
3068 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3069 Qright_to_left))
3070 it->paragraph_embedding = R2L;
3071 else
3072 it->paragraph_embedding = NEUTRAL_DIR;
3073 bidi_unshelve_cache (NULL, 0);
3074 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3075 &it->bidi_it);
3078 /* Compute faces etc. */
3079 reseat (it, it->current.pos, 1);
3082 CHECK_IT (it);
3086 /* Initialize IT for the display of window W with window start POS. */
3088 void
3089 start_display (struct it *it, struct window *w, struct text_pos pos)
3091 struct glyph_row *row;
3092 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
3094 row = w->desired_matrix->rows + first_vpos;
3095 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3096 it->first_vpos = first_vpos;
3098 /* Don't reseat to previous visible line start if current start
3099 position is in a string or image. */
3100 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3102 int start_at_line_beg_p;
3103 int first_y = it->current_y;
3105 /* If window start is not at a line start, skip forward to POS to
3106 get the correct continuation lines width. */
3107 start_at_line_beg_p = (CHARPOS (pos) == BEGV
3108 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3109 if (!start_at_line_beg_p)
3111 int new_x;
3113 reseat_at_previous_visible_line_start (it);
3114 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3116 new_x = it->current_x + it->pixel_width;
3118 /* If lines are continued, this line may end in the middle
3119 of a multi-glyph character (e.g. a control character
3120 displayed as \003, or in the middle of an overlay
3121 string). In this case move_it_to above will not have
3122 taken us to the start of the continuation line but to the
3123 end of the continued line. */
3124 if (it->current_x > 0
3125 && it->line_wrap != TRUNCATE /* Lines are continued. */
3126 && (/* And glyph doesn't fit on the line. */
3127 new_x > it->last_visible_x
3128 /* Or it fits exactly and we're on a window
3129 system frame. */
3130 || (new_x == it->last_visible_x
3131 && FRAME_WINDOW_P (it->f)
3132 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3133 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3134 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3136 if ((it->current.dpvec_index >= 0
3137 || it->current.overlay_string_index >= 0)
3138 /* If we are on a newline from a display vector or
3139 overlay string, then we are already at the end of
3140 a screen line; no need to go to the next line in
3141 that case, as this line is not really continued.
3142 (If we do go to the next line, C-e will not DTRT.) */
3143 && it->c != '\n')
3145 set_iterator_to_next (it, 1);
3146 move_it_in_display_line_to (it, -1, -1, 0);
3149 it->continuation_lines_width += it->current_x;
3151 /* If the character at POS is displayed via a display
3152 vector, move_it_to above stops at the final glyph of
3153 IT->dpvec. To make the caller redisplay that character
3154 again (a.k.a. start at POS), we need to reset the
3155 dpvec_index to the beginning of IT->dpvec. */
3156 else if (it->current.dpvec_index >= 0)
3157 it->current.dpvec_index = 0;
3159 /* We're starting a new display line, not affected by the
3160 height of the continued line, so clear the appropriate
3161 fields in the iterator structure. */
3162 it->max_ascent = it->max_descent = 0;
3163 it->max_phys_ascent = it->max_phys_descent = 0;
3165 it->current_y = first_y;
3166 it->vpos = 0;
3167 it->current_x = it->hpos = 0;
3173 /* Return 1 if POS is a position in ellipses displayed for invisible
3174 text. W is the window we display, for text property lookup. */
3176 static int
3177 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3179 Lisp_Object prop, window;
3180 int ellipses_p = 0;
3181 ptrdiff_t charpos = CHARPOS (pos->pos);
3183 /* If POS specifies a position in a display vector, this might
3184 be for an ellipsis displayed for invisible text. We won't
3185 get the iterator set up for delivering that ellipsis unless
3186 we make sure that it gets aware of the invisible text. */
3187 if (pos->dpvec_index >= 0
3188 && pos->overlay_string_index < 0
3189 && CHARPOS (pos->string_pos) < 0
3190 && charpos > BEGV
3191 && (XSETWINDOW (window, w),
3192 prop = Fget_char_property (make_number (charpos),
3193 Qinvisible, window),
3194 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3196 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3197 window);
3198 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3201 return ellipses_p;
3205 /* Initialize IT for stepping through current_buffer in window W,
3206 starting at position POS that includes overlay string and display
3207 vector/ control character translation position information. Value
3208 is zero if there are overlay strings with newlines at POS. */
3210 static int
3211 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3213 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3214 int i, overlay_strings_with_newlines = 0;
3216 /* If POS specifies a position in a display vector, this might
3217 be for an ellipsis displayed for invisible text. We won't
3218 get the iterator set up for delivering that ellipsis unless
3219 we make sure that it gets aware of the invisible text. */
3220 if (in_ellipses_for_invisible_text_p (pos, w))
3222 --charpos;
3223 bytepos = 0;
3226 /* Keep in mind: the call to reseat in init_iterator skips invisible
3227 text, so we might end up at a position different from POS. This
3228 is only a problem when POS is a row start after a newline and an
3229 overlay starts there with an after-string, and the overlay has an
3230 invisible property. Since we don't skip invisible text in
3231 display_line and elsewhere immediately after consuming the
3232 newline before the row start, such a POS will not be in a string,
3233 but the call to init_iterator below will move us to the
3234 after-string. */
3235 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3237 /* This only scans the current chunk -- it should scan all chunks.
3238 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3239 to 16 in 22.1 to make this a lesser problem. */
3240 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3242 const char *s = SSDATA (it->overlay_strings[i]);
3243 const char *e = s + SBYTES (it->overlay_strings[i]);
3245 while (s < e && *s != '\n')
3246 ++s;
3248 if (s < e)
3250 overlay_strings_with_newlines = 1;
3251 break;
3255 /* If position is within an overlay string, set up IT to the right
3256 overlay string. */
3257 if (pos->overlay_string_index >= 0)
3259 int relative_index;
3261 /* If the first overlay string happens to have a `display'
3262 property for an image, the iterator will be set up for that
3263 image, and we have to undo that setup first before we can
3264 correct the overlay string index. */
3265 if (it->method == GET_FROM_IMAGE)
3266 pop_it (it);
3268 /* We already have the first chunk of overlay strings in
3269 IT->overlay_strings. Load more until the one for
3270 pos->overlay_string_index is in IT->overlay_strings. */
3271 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3273 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3274 it->current.overlay_string_index = 0;
3275 while (n--)
3277 load_overlay_strings (it, 0);
3278 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3282 it->current.overlay_string_index = pos->overlay_string_index;
3283 relative_index = (it->current.overlay_string_index
3284 % OVERLAY_STRING_CHUNK_SIZE);
3285 it->string = it->overlay_strings[relative_index];
3286 eassert (STRINGP (it->string));
3287 it->current.string_pos = pos->string_pos;
3288 it->method = GET_FROM_STRING;
3289 it->end_charpos = SCHARS (it->string);
3290 /* Set up the bidi iterator for this overlay string. */
3291 if (it->bidi_p)
3293 it->bidi_it.string.lstring = it->string;
3294 it->bidi_it.string.s = NULL;
3295 it->bidi_it.string.schars = SCHARS (it->string);
3296 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3297 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3298 it->bidi_it.string.unibyte = !it->multibyte_p;
3299 it->bidi_it.w = it->w;
3300 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3301 FRAME_WINDOW_P (it->f), &it->bidi_it);
3303 /* Synchronize the state of the bidi iterator with
3304 pos->string_pos. For any string position other than
3305 zero, this will be done automagically when we resume
3306 iteration over the string and get_visually_first_element
3307 is called. But if string_pos is zero, and the string is
3308 to be reordered for display, we need to resync manually,
3309 since it could be that the iteration state recorded in
3310 pos ended at string_pos of 0 moving backwards in string. */
3311 if (CHARPOS (pos->string_pos) == 0)
3313 get_visually_first_element (it);
3314 if (IT_STRING_CHARPOS (*it) != 0)
3315 do {
3316 /* Paranoia. */
3317 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3318 bidi_move_to_visually_next (&it->bidi_it);
3319 } while (it->bidi_it.charpos != 0);
3321 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3322 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3326 if (CHARPOS (pos->string_pos) >= 0)
3328 /* Recorded position is not in an overlay string, but in another
3329 string. This can only be a string from a `display' property.
3330 IT should already be filled with that string. */
3331 it->current.string_pos = pos->string_pos;
3332 eassert (STRINGP (it->string));
3333 if (it->bidi_p)
3334 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3335 FRAME_WINDOW_P (it->f), &it->bidi_it);
3338 /* Restore position in display vector translations, control
3339 character translations or ellipses. */
3340 if (pos->dpvec_index >= 0)
3342 if (it->dpvec == NULL)
3343 get_next_display_element (it);
3344 eassert (it->dpvec && it->current.dpvec_index == 0);
3345 it->current.dpvec_index = pos->dpvec_index;
3348 CHECK_IT (it);
3349 return !overlay_strings_with_newlines;
3353 /* Initialize IT for stepping through current_buffer in window W
3354 starting at ROW->start. */
3356 static void
3357 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3359 init_from_display_pos (it, w, &row->start);
3360 it->start = row->start;
3361 it->continuation_lines_width = row->continuation_lines_width;
3362 CHECK_IT (it);
3366 /* Initialize IT for stepping through current_buffer in window W
3367 starting in the line following ROW, i.e. starting at ROW->end.
3368 Value is zero if there are overlay strings with newlines at ROW's
3369 end position. */
3371 static int
3372 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3374 int success = 0;
3376 if (init_from_display_pos (it, w, &row->end))
3378 if (row->continued_p)
3379 it->continuation_lines_width
3380 = row->continuation_lines_width + row->pixel_width;
3381 CHECK_IT (it);
3382 success = 1;
3385 return success;
3391 /***********************************************************************
3392 Text properties
3393 ***********************************************************************/
3395 /* Called when IT reaches IT->stop_charpos. Handle text property and
3396 overlay changes. Set IT->stop_charpos to the next position where
3397 to stop. */
3399 static void
3400 handle_stop (struct it *it)
3402 enum prop_handled handled;
3403 int handle_overlay_change_p;
3404 struct props *p;
3406 it->dpvec = NULL;
3407 it->current.dpvec_index = -1;
3408 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3409 it->ignore_overlay_strings_at_pos_p = 0;
3410 it->ellipsis_p = 0;
3412 /* Use face of preceding text for ellipsis (if invisible) */
3413 if (it->selective_display_ellipsis_p)
3414 it->saved_face_id = it->face_id;
3418 handled = HANDLED_NORMALLY;
3420 /* Call text property handlers. */
3421 for (p = it_props; p->handler; ++p)
3423 handled = p->handler (it);
3425 if (handled == HANDLED_RECOMPUTE_PROPS)
3426 break;
3427 else if (handled == HANDLED_RETURN)
3429 /* We still want to show before and after strings from
3430 overlays even if the actual buffer text is replaced. */
3431 if (!handle_overlay_change_p
3432 || it->sp > 1
3433 /* Don't call get_overlay_strings_1 if we already
3434 have overlay strings loaded, because doing so
3435 will load them again and push the iterator state
3436 onto the stack one more time, which is not
3437 expected by the rest of the code that processes
3438 overlay strings. */
3439 || (it->current.overlay_string_index < 0
3440 ? !get_overlay_strings_1 (it, 0, 0)
3441 : 0))
3443 if (it->ellipsis_p)
3444 setup_for_ellipsis (it, 0);
3445 /* When handling a display spec, we might load an
3446 empty string. In that case, discard it here. We
3447 used to discard it in handle_single_display_spec,
3448 but that causes get_overlay_strings_1, above, to
3449 ignore overlay strings that we must check. */
3450 if (STRINGP (it->string) && !SCHARS (it->string))
3451 pop_it (it);
3452 return;
3454 else if (STRINGP (it->string) && !SCHARS (it->string))
3455 pop_it (it);
3456 else
3458 it->ignore_overlay_strings_at_pos_p = true;
3459 it->string_from_display_prop_p = 0;
3460 it->from_disp_prop_p = 0;
3461 handle_overlay_change_p = 0;
3463 handled = HANDLED_RECOMPUTE_PROPS;
3464 break;
3466 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3467 handle_overlay_change_p = 0;
3470 if (handled != HANDLED_RECOMPUTE_PROPS)
3472 /* Don't check for overlay strings below when set to deliver
3473 characters from a display vector. */
3474 if (it->method == GET_FROM_DISPLAY_VECTOR)
3475 handle_overlay_change_p = 0;
3477 /* Handle overlay changes.
3478 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3479 if it finds overlays. */
3480 if (handle_overlay_change_p)
3481 handled = handle_overlay_change (it);
3484 if (it->ellipsis_p)
3486 setup_for_ellipsis (it, 0);
3487 break;
3490 while (handled == HANDLED_RECOMPUTE_PROPS);
3492 /* Determine where to stop next. */
3493 if (handled == HANDLED_NORMALLY)
3494 compute_stop_pos (it);
3498 /* Compute IT->stop_charpos from text property and overlay change
3499 information for IT's current position. */
3501 static void
3502 compute_stop_pos (struct it *it)
3504 register INTERVAL iv, next_iv;
3505 Lisp_Object object, limit, position;
3506 ptrdiff_t charpos, bytepos;
3508 if (STRINGP (it->string))
3510 /* Strings are usually short, so don't limit the search for
3511 properties. */
3512 it->stop_charpos = it->end_charpos;
3513 object = it->string;
3514 limit = Qnil;
3515 charpos = IT_STRING_CHARPOS (*it);
3516 bytepos = IT_STRING_BYTEPOS (*it);
3518 else
3520 ptrdiff_t pos;
3522 /* If end_charpos is out of range for some reason, such as a
3523 misbehaving display function, rationalize it (Bug#5984). */
3524 if (it->end_charpos > ZV)
3525 it->end_charpos = ZV;
3526 it->stop_charpos = it->end_charpos;
3528 /* If next overlay change is in front of the current stop pos
3529 (which is IT->end_charpos), stop there. Note: value of
3530 next_overlay_change is point-max if no overlay change
3531 follows. */
3532 charpos = IT_CHARPOS (*it);
3533 bytepos = IT_BYTEPOS (*it);
3534 pos = next_overlay_change (charpos);
3535 if (pos < it->stop_charpos)
3536 it->stop_charpos = pos;
3538 /* Set up variables for computing the stop position from text
3539 property changes. */
3540 XSETBUFFER (object, current_buffer);
3541 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3544 /* Get the interval containing IT's position. Value is a null
3545 interval if there isn't such an interval. */
3546 position = make_number (charpos);
3547 iv = validate_interval_range (object, &position, &position, 0);
3548 if (iv)
3550 Lisp_Object values_here[LAST_PROP_IDX];
3551 struct props *p;
3553 /* Get properties here. */
3554 for (p = it_props; p->handler; ++p)
3555 values_here[p->idx] = textget (iv->plist, *p->name);
3557 /* Look for an interval following iv that has different
3558 properties. */
3559 for (next_iv = next_interval (iv);
3560 (next_iv
3561 && (NILP (limit)
3562 || XFASTINT (limit) > next_iv->position));
3563 next_iv = next_interval (next_iv))
3565 for (p = it_props; p->handler; ++p)
3567 Lisp_Object new_value;
3569 new_value = textget (next_iv->plist, *p->name);
3570 if (!EQ (values_here[p->idx], new_value))
3571 break;
3574 if (p->handler)
3575 break;
3578 if (next_iv)
3580 if (INTEGERP (limit)
3581 && next_iv->position >= XFASTINT (limit))
3582 /* No text property change up to limit. */
3583 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3584 else
3585 /* Text properties change in next_iv. */
3586 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3590 if (it->cmp_it.id < 0)
3592 ptrdiff_t stoppos = it->end_charpos;
3594 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3595 stoppos = -1;
3596 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3597 stoppos, it->string);
3600 eassert (STRINGP (it->string)
3601 || (it->stop_charpos >= BEGV
3602 && it->stop_charpos >= IT_CHARPOS (*it)));
3606 /* Return the position of the next overlay change after POS in
3607 current_buffer. Value is point-max if no overlay change
3608 follows. This is like `next-overlay-change' but doesn't use
3609 xmalloc. */
3611 static ptrdiff_t
3612 next_overlay_change (ptrdiff_t pos)
3614 ptrdiff_t i, noverlays;
3615 ptrdiff_t endpos;
3616 Lisp_Object *overlays;
3618 /* Get all overlays at the given position. */
3619 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3621 /* If any of these overlays ends before endpos,
3622 use its ending point instead. */
3623 for (i = 0; i < noverlays; ++i)
3625 Lisp_Object oend;
3626 ptrdiff_t oendpos;
3628 oend = OVERLAY_END (overlays[i]);
3629 oendpos = OVERLAY_POSITION (oend);
3630 endpos = min (endpos, oendpos);
3633 return endpos;
3636 /* How many characters forward to search for a display property or
3637 display string. Searching too far forward makes the bidi display
3638 sluggish, especially in small windows. */
3639 #define MAX_DISP_SCAN 250
3641 /* Return the character position of a display string at or after
3642 position specified by POSITION. If no display string exists at or
3643 after POSITION, return ZV. A display string is either an overlay
3644 with `display' property whose value is a string, or a `display'
3645 text property whose value is a string. STRING is data about the
3646 string to iterate; if STRING->lstring is nil, we are iterating a
3647 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3648 on a GUI frame. DISP_PROP is set to zero if we searched
3649 MAX_DISP_SCAN characters forward without finding any display
3650 strings, non-zero otherwise. It is set to 2 if the display string
3651 uses any kind of `(space ...)' spec that will produce a stretch of
3652 white space in the text area. */
3653 ptrdiff_t
3654 compute_display_string_pos (struct text_pos *position,
3655 struct bidi_string_data *string,
3656 struct window *w,
3657 int frame_window_p, int *disp_prop)
3659 /* OBJECT = nil means current buffer. */
3660 Lisp_Object object, object1;
3661 Lisp_Object pos, spec, limpos;
3662 int string_p = (string && (STRINGP (string->lstring) || string->s));
3663 ptrdiff_t eob = string_p ? string->schars : ZV;
3664 ptrdiff_t begb = string_p ? 0 : BEGV;
3665 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3666 ptrdiff_t lim =
3667 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3668 struct text_pos tpos;
3669 int rv = 0;
3671 if (string && STRINGP (string->lstring))
3672 object1 = object = string->lstring;
3673 else if (w && !string_p)
3675 XSETWINDOW (object, w);
3676 object1 = Qnil;
3678 else
3679 object1 = object = Qnil;
3681 *disp_prop = 1;
3683 if (charpos >= eob
3684 /* We don't support display properties whose values are strings
3685 that have display string properties. */
3686 || string->from_disp_str
3687 /* C strings cannot have display properties. */
3688 || (string->s && !STRINGP (object)))
3690 *disp_prop = 0;
3691 return eob;
3694 /* If the character at CHARPOS is where the display string begins,
3695 return CHARPOS. */
3696 pos = make_number (charpos);
3697 if (STRINGP (object))
3698 bufpos = string->bufpos;
3699 else
3700 bufpos = charpos;
3701 tpos = *position;
3702 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3703 && (charpos <= begb
3704 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3705 object),
3706 spec))
3707 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3708 frame_window_p)))
3710 if (rv == 2)
3711 *disp_prop = 2;
3712 return charpos;
3715 /* Look forward for the first character with a `display' property
3716 that will replace the underlying text when displayed. */
3717 limpos = make_number (lim);
3718 do {
3719 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3720 CHARPOS (tpos) = XFASTINT (pos);
3721 if (CHARPOS (tpos) >= lim)
3723 *disp_prop = 0;
3724 break;
3726 if (STRINGP (object))
3727 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3728 else
3729 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3730 spec = Fget_char_property (pos, Qdisplay, object);
3731 if (!STRINGP (object))
3732 bufpos = CHARPOS (tpos);
3733 } while (NILP (spec)
3734 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3735 bufpos, frame_window_p)));
3736 if (rv == 2)
3737 *disp_prop = 2;
3739 return CHARPOS (tpos);
3742 /* Return the character position of the end of the display string that
3743 started at CHARPOS. If there's no display string at CHARPOS,
3744 return -1. A display string is either an overlay with `display'
3745 property whose value is a string or a `display' text property whose
3746 value is a string. */
3747 ptrdiff_t
3748 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3750 /* OBJECT = nil means current buffer. */
3751 Lisp_Object object =
3752 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3753 Lisp_Object pos = make_number (charpos);
3754 ptrdiff_t eob =
3755 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3757 if (charpos >= eob || (string->s && !STRINGP (object)))
3758 return eob;
3760 /* It could happen that the display property or overlay was removed
3761 since we found it in compute_display_string_pos above. One way
3762 this can happen is if JIT font-lock was called (through
3763 handle_fontified_prop), and jit-lock-functions remove text
3764 properties or overlays from the portion of buffer that includes
3765 CHARPOS. Muse mode is known to do that, for example. In this
3766 case, we return -1 to the caller, to signal that no display
3767 string is actually present at CHARPOS. See bidi_fetch_char for
3768 how this is handled.
3770 An alternative would be to never look for display properties past
3771 it->stop_charpos. But neither compute_display_string_pos nor
3772 bidi_fetch_char that calls it know or care where the next
3773 stop_charpos is. */
3774 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3775 return -1;
3777 /* Look forward for the first character where the `display' property
3778 changes. */
3779 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3781 return XFASTINT (pos);
3786 /***********************************************************************
3787 Fontification
3788 ***********************************************************************/
3790 /* Handle changes in the `fontified' property of the current buffer by
3791 calling hook functions from Qfontification_functions to fontify
3792 regions of text. */
3794 static enum prop_handled
3795 handle_fontified_prop (struct it *it)
3797 Lisp_Object prop, pos;
3798 enum prop_handled handled = HANDLED_NORMALLY;
3800 if (!NILP (Vmemory_full))
3801 return handled;
3803 /* Get the value of the `fontified' property at IT's current buffer
3804 position. (The `fontified' property doesn't have a special
3805 meaning in strings.) If the value is nil, call functions from
3806 Qfontification_functions. */
3807 if (!STRINGP (it->string)
3808 && it->s == NULL
3809 && !NILP (Vfontification_functions)
3810 && !NILP (Vrun_hooks)
3811 && (pos = make_number (IT_CHARPOS (*it)),
3812 prop = Fget_char_property (pos, Qfontified, Qnil),
3813 /* Ignore the special cased nil value always present at EOB since
3814 no amount of fontifying will be able to change it. */
3815 NILP (prop) && IT_CHARPOS (*it) < Z))
3817 ptrdiff_t count = SPECPDL_INDEX ();
3818 Lisp_Object val;
3819 struct buffer *obuf = current_buffer;
3820 ptrdiff_t begv = BEGV, zv = ZV;
3821 bool old_clip_changed = current_buffer->clip_changed;
3823 val = Vfontification_functions;
3824 specbind (Qfontification_functions, Qnil);
3826 eassert (it->end_charpos == ZV);
3828 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3829 safe_call1 (val, pos);
3830 else
3832 Lisp_Object fns, fn;
3833 struct gcpro gcpro1, gcpro2;
3835 fns = Qnil;
3836 GCPRO2 (val, fns);
3838 for (; CONSP (val); val = XCDR (val))
3840 fn = XCAR (val);
3842 if (EQ (fn, Qt))
3844 /* A value of t indicates this hook has a local
3845 binding; it means to run the global binding too.
3846 In a global value, t should not occur. If it
3847 does, we must ignore it to avoid an endless
3848 loop. */
3849 for (fns = Fdefault_value (Qfontification_functions);
3850 CONSP (fns);
3851 fns = XCDR (fns))
3853 fn = XCAR (fns);
3854 if (!EQ (fn, Qt))
3855 safe_call1 (fn, pos);
3858 else
3859 safe_call1 (fn, pos);
3862 UNGCPRO;
3865 unbind_to (count, Qnil);
3867 /* Fontification functions routinely call `save-restriction'.
3868 Normally, this tags clip_changed, which can confuse redisplay
3869 (see discussion in Bug#6671). Since we don't perform any
3870 special handling of fontification changes in the case where
3871 `save-restriction' isn't called, there's no point doing so in
3872 this case either. So, if the buffer's restrictions are
3873 actually left unchanged, reset clip_changed. */
3874 if (obuf == current_buffer)
3876 if (begv == BEGV && zv == ZV)
3877 current_buffer->clip_changed = old_clip_changed;
3879 /* There isn't much we can reasonably do to protect against
3880 misbehaving fontification, but here's a fig leaf. */
3881 else if (BUFFER_LIVE_P (obuf))
3882 set_buffer_internal_1 (obuf);
3884 /* The fontification code may have added/removed text.
3885 It could do even a lot worse, but let's at least protect against
3886 the most obvious case where only the text past `pos' gets changed',
3887 as is/was done in grep.el where some escapes sequences are turned
3888 into face properties (bug#7876). */
3889 it->end_charpos = ZV;
3891 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3892 something. This avoids an endless loop if they failed to
3893 fontify the text for which reason ever. */
3894 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3895 handled = HANDLED_RECOMPUTE_PROPS;
3898 return handled;
3903 /***********************************************************************
3904 Faces
3905 ***********************************************************************/
3907 /* Set up iterator IT from face properties at its current position.
3908 Called from handle_stop. */
3910 static enum prop_handled
3911 handle_face_prop (struct it *it)
3913 int new_face_id;
3914 ptrdiff_t next_stop;
3916 if (!STRINGP (it->string))
3918 new_face_id
3919 = face_at_buffer_position (it->w,
3920 IT_CHARPOS (*it),
3921 &next_stop,
3922 (IT_CHARPOS (*it)
3923 + TEXT_PROP_DISTANCE_LIMIT),
3924 0, it->base_face_id);
3926 /* Is this a start of a run of characters with box face?
3927 Caveat: this can be called for a freshly initialized
3928 iterator; face_id is -1 in this case. We know that the new
3929 face will not change until limit, i.e. if the new face has a
3930 box, all characters up to limit will have one. But, as
3931 usual, we don't know whether limit is really the end. */
3932 if (new_face_id != it->face_id)
3934 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3935 /* If it->face_id is -1, old_face below will be NULL, see
3936 the definition of FACE_FROM_ID. This will happen if this
3937 is the initial call that gets the face. */
3938 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3940 /* If the value of face_id of the iterator is -1, we have to
3941 look in front of IT's position and see whether there is a
3942 face there that's different from new_face_id. */
3943 if (!old_face && IT_CHARPOS (*it) > BEG)
3945 int prev_face_id = face_before_it_pos (it);
3947 old_face = FACE_FROM_ID (it->f, prev_face_id);
3950 /* If the new face has a box, but the old face does not,
3951 this is the start of a run of characters with box face,
3952 i.e. this character has a shadow on the left side. */
3953 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3954 && (old_face == NULL || !old_face->box));
3955 it->face_box_p = new_face->box != FACE_NO_BOX;
3958 else
3960 int base_face_id;
3961 ptrdiff_t bufpos;
3962 int i;
3963 Lisp_Object from_overlay
3964 = (it->current.overlay_string_index >= 0
3965 ? it->string_overlays[it->current.overlay_string_index
3966 % OVERLAY_STRING_CHUNK_SIZE]
3967 : Qnil);
3969 /* See if we got to this string directly or indirectly from
3970 an overlay property. That includes the before-string or
3971 after-string of an overlay, strings in display properties
3972 provided by an overlay, their text properties, etc.
3974 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3975 if (! NILP (from_overlay))
3976 for (i = it->sp - 1; i >= 0; i--)
3978 if (it->stack[i].current.overlay_string_index >= 0)
3979 from_overlay
3980 = it->string_overlays[it->stack[i].current.overlay_string_index
3981 % OVERLAY_STRING_CHUNK_SIZE];
3982 else if (! NILP (it->stack[i].from_overlay))
3983 from_overlay = it->stack[i].from_overlay;
3985 if (!NILP (from_overlay))
3986 break;
3989 if (! NILP (from_overlay))
3991 bufpos = IT_CHARPOS (*it);
3992 /* For a string from an overlay, the base face depends
3993 only on text properties and ignores overlays. */
3994 base_face_id
3995 = face_for_overlay_string (it->w,
3996 IT_CHARPOS (*it),
3997 &next_stop,
3998 (IT_CHARPOS (*it)
3999 + TEXT_PROP_DISTANCE_LIMIT),
4001 from_overlay);
4003 else
4005 bufpos = 0;
4007 /* For strings from a `display' property, use the face at
4008 IT's current buffer position as the base face to merge
4009 with, so that overlay strings appear in the same face as
4010 surrounding text, unless they specify their own faces.
4011 For strings from wrap-prefix and line-prefix properties,
4012 use the default face, possibly remapped via
4013 Vface_remapping_alist. */
4014 /* Note that the fact that we use the face at _buffer_
4015 position means that a 'display' property on an overlay
4016 string will not inherit the face of that overlay string,
4017 but will instead revert to the face of buffer text
4018 covered by the overlay. This is visible, e.g., when the
4019 overlay specifies a box face, but neither the buffer nor
4020 the display string do. This sounds like a design bug,
4021 but Emacs always did that since v21.1, so changing that
4022 might be a big deal. */
4023 base_face_id = it->string_from_prefix_prop_p
4024 ? (!NILP (Vface_remapping_alist)
4025 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4026 : DEFAULT_FACE_ID)
4027 : underlying_face_id (it);
4030 new_face_id = face_at_string_position (it->w,
4031 it->string,
4032 IT_STRING_CHARPOS (*it),
4033 bufpos,
4034 &next_stop,
4035 base_face_id, 0);
4037 /* Is this a start of a run of characters with box? Caveat:
4038 this can be called for a freshly allocated iterator; face_id
4039 is -1 is this case. We know that the new face will not
4040 change until the next check pos, i.e. if the new face has a
4041 box, all characters up to that position will have a
4042 box. But, as usual, we don't know whether that position
4043 is really the end. */
4044 if (new_face_id != it->face_id)
4046 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4047 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
4049 /* If new face has a box but old face hasn't, this is the
4050 start of a run of characters with box, i.e. it has a
4051 shadow on the left side. */
4052 it->start_of_box_run_p
4053 = new_face->box && (old_face == NULL || !old_face->box);
4054 it->face_box_p = new_face->box != FACE_NO_BOX;
4058 it->face_id = new_face_id;
4059 return HANDLED_NORMALLY;
4063 /* Return the ID of the face ``underlying'' IT's current position,
4064 which is in a string. If the iterator is associated with a
4065 buffer, return the face at IT's current buffer position.
4066 Otherwise, use the iterator's base_face_id. */
4068 static int
4069 underlying_face_id (struct it *it)
4071 int face_id = it->base_face_id, i;
4073 eassert (STRINGP (it->string));
4075 for (i = it->sp - 1; i >= 0; --i)
4076 if (NILP (it->stack[i].string))
4077 face_id = it->stack[i].face_id;
4079 return face_id;
4083 /* Compute the face one character before or after the current position
4084 of IT, in the visual order. BEFORE_P non-zero means get the face
4085 in front (to the left in L2R paragraphs, to the right in R2L
4086 paragraphs) of IT's screen position. Value is the ID of the face. */
4088 static int
4089 face_before_or_after_it_pos (struct it *it, int before_p)
4091 int face_id, limit;
4092 ptrdiff_t next_check_charpos;
4093 struct it it_copy;
4094 void *it_copy_data = NULL;
4096 eassert (it->s == NULL);
4098 if (STRINGP (it->string))
4100 ptrdiff_t bufpos, charpos;
4101 int base_face_id;
4103 /* No face change past the end of the string (for the case
4104 we are padding with spaces). No face change before the
4105 string start. */
4106 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4107 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4108 return it->face_id;
4110 if (!it->bidi_p)
4112 /* Set charpos to the position before or after IT's current
4113 position, in the logical order, which in the non-bidi
4114 case is the same as the visual order. */
4115 if (before_p)
4116 charpos = IT_STRING_CHARPOS (*it) - 1;
4117 else if (it->what == IT_COMPOSITION)
4118 /* For composition, we must check the character after the
4119 composition. */
4120 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4121 else
4122 charpos = IT_STRING_CHARPOS (*it) + 1;
4124 else
4126 if (before_p)
4128 /* With bidi iteration, the character before the current
4129 in the visual order cannot be found by simple
4130 iteration, because "reverse" reordering is not
4131 supported. Instead, we need to use the move_it_*
4132 family of functions. */
4133 /* Ignore face changes before the first visible
4134 character on this display line. */
4135 if (it->current_x <= it->first_visible_x)
4136 return it->face_id;
4137 SAVE_IT (it_copy, *it, it_copy_data);
4138 /* Implementation note: Since move_it_in_display_line
4139 works in the iterator geometry, and thinks the first
4140 character is always the leftmost, even in R2L lines,
4141 we don't need to distinguish between the R2L and L2R
4142 cases here. */
4143 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
4144 it_copy.current_x - 1, MOVE_TO_X);
4145 charpos = IT_STRING_CHARPOS (it_copy);
4146 RESTORE_IT (it, it, it_copy_data);
4148 else
4150 /* Set charpos to the string position of the character
4151 that comes after IT's current position in the visual
4152 order. */
4153 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4155 it_copy = *it;
4156 while (n--)
4157 bidi_move_to_visually_next (&it_copy.bidi_it);
4159 charpos = it_copy.bidi_it.charpos;
4162 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4164 if (it->current.overlay_string_index >= 0)
4165 bufpos = IT_CHARPOS (*it);
4166 else
4167 bufpos = 0;
4169 base_face_id = underlying_face_id (it);
4171 /* Get the face for ASCII, or unibyte. */
4172 face_id = face_at_string_position (it->w,
4173 it->string,
4174 charpos,
4175 bufpos,
4176 &next_check_charpos,
4177 base_face_id, 0);
4179 /* Correct the face for charsets different from ASCII. Do it
4180 for the multibyte case only. The face returned above is
4181 suitable for unibyte text if IT->string is unibyte. */
4182 if (STRING_MULTIBYTE (it->string))
4184 struct text_pos pos1 = string_pos (charpos, it->string);
4185 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4186 int c, len;
4187 struct face *face = FACE_FROM_ID (it->f, face_id);
4189 c = string_char_and_length (p, &len);
4190 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4193 else
4195 struct text_pos pos;
4197 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4198 || (IT_CHARPOS (*it) <= BEGV && before_p))
4199 return it->face_id;
4201 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4202 pos = it->current.pos;
4204 if (!it->bidi_p)
4206 if (before_p)
4207 DEC_TEXT_POS (pos, it->multibyte_p);
4208 else
4210 if (it->what == IT_COMPOSITION)
4212 /* For composition, we must check the position after
4213 the composition. */
4214 pos.charpos += it->cmp_it.nchars;
4215 pos.bytepos += it->len;
4217 else
4218 INC_TEXT_POS (pos, it->multibyte_p);
4221 else
4223 if (before_p)
4225 /* With bidi iteration, the character before the current
4226 in the visual order cannot be found by simple
4227 iteration, because "reverse" reordering is not
4228 supported. Instead, we need to use the move_it_*
4229 family of functions. */
4230 /* Ignore face changes before the first visible
4231 character on this display line. */
4232 if (it->current_x <= it->first_visible_x)
4233 return it->face_id;
4234 SAVE_IT (it_copy, *it, it_copy_data);
4235 /* Implementation note: Since move_it_in_display_line
4236 works in the iterator geometry, and thinks the first
4237 character is always the leftmost, even in R2L lines,
4238 we don't need to distinguish between the R2L and L2R
4239 cases here. */
4240 move_it_in_display_line (&it_copy, ZV,
4241 it_copy.current_x - 1, MOVE_TO_X);
4242 pos = it_copy.current.pos;
4243 RESTORE_IT (it, it, it_copy_data);
4245 else
4247 /* Set charpos to the buffer position of the character
4248 that comes after IT's current position in the visual
4249 order. */
4250 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4252 it_copy = *it;
4253 while (n--)
4254 bidi_move_to_visually_next (&it_copy.bidi_it);
4256 SET_TEXT_POS (pos,
4257 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4260 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4262 /* Determine face for CHARSET_ASCII, or unibyte. */
4263 face_id = face_at_buffer_position (it->w,
4264 CHARPOS (pos),
4265 &next_check_charpos,
4266 limit, 0, -1);
4268 /* Correct the face for charsets different from ASCII. Do it
4269 for the multibyte case only. The face returned above is
4270 suitable for unibyte text if current_buffer is unibyte. */
4271 if (it->multibyte_p)
4273 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4274 struct face *face = FACE_FROM_ID (it->f, face_id);
4275 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4279 return face_id;
4284 /***********************************************************************
4285 Invisible text
4286 ***********************************************************************/
4288 /* Set up iterator IT from invisible properties at its current
4289 position. Called from handle_stop. */
4291 static enum prop_handled
4292 handle_invisible_prop (struct it *it)
4294 enum prop_handled handled = HANDLED_NORMALLY;
4295 int invis_p;
4296 Lisp_Object prop;
4298 if (STRINGP (it->string))
4300 Lisp_Object end_charpos, limit, charpos;
4302 /* Get the value of the invisible text property at the
4303 current position. Value will be nil if there is no such
4304 property. */
4305 charpos = make_number (IT_STRING_CHARPOS (*it));
4306 prop = Fget_text_property (charpos, Qinvisible, it->string);
4307 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4309 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4311 /* Record whether we have to display an ellipsis for the
4312 invisible text. */
4313 int display_ellipsis_p = (invis_p == 2);
4314 ptrdiff_t len, endpos;
4316 handled = HANDLED_RECOMPUTE_PROPS;
4318 /* Get the position at which the next visible text can be
4319 found in IT->string, if any. */
4320 endpos = len = SCHARS (it->string);
4321 XSETINT (limit, len);
4324 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4325 it->string, limit);
4326 if (INTEGERP (end_charpos))
4328 endpos = XFASTINT (end_charpos);
4329 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4330 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4331 if (invis_p == 2)
4332 display_ellipsis_p = true;
4335 while (invis_p && endpos < len);
4337 if (display_ellipsis_p)
4338 it->ellipsis_p = true;
4340 if (endpos < len)
4342 /* Text at END_CHARPOS is visible. Move IT there. */
4343 struct text_pos old;
4344 ptrdiff_t oldpos;
4346 old = it->current.string_pos;
4347 oldpos = CHARPOS (old);
4348 if (it->bidi_p)
4350 if (it->bidi_it.first_elt
4351 && it->bidi_it.charpos < SCHARS (it->string))
4352 bidi_paragraph_init (it->paragraph_embedding,
4353 &it->bidi_it, 1);
4354 /* Bidi-iterate out of the invisible text. */
4357 bidi_move_to_visually_next (&it->bidi_it);
4359 while (oldpos <= it->bidi_it.charpos
4360 && it->bidi_it.charpos < endpos);
4362 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4363 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4364 if (IT_CHARPOS (*it) >= endpos)
4365 it->prev_stop = endpos;
4367 else
4369 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4370 compute_string_pos (&it->current.string_pos, old, it->string);
4373 else
4375 /* The rest of the string is invisible. If this is an
4376 overlay string, proceed with the next overlay string
4377 or whatever comes and return a character from there. */
4378 if (it->current.overlay_string_index >= 0
4379 && !display_ellipsis_p)
4381 next_overlay_string (it);
4382 /* Don't check for overlay strings when we just
4383 finished processing them. */
4384 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4386 else
4388 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4389 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4394 else
4396 ptrdiff_t newpos, next_stop, start_charpos, tem;
4397 Lisp_Object pos, overlay;
4399 /* First of all, is there invisible text at this position? */
4400 tem = start_charpos = IT_CHARPOS (*it);
4401 pos = make_number (tem);
4402 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4403 &overlay);
4404 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4406 /* If we are on invisible text, skip over it. */
4407 if (invis_p && start_charpos < it->end_charpos)
4409 /* Record whether we have to display an ellipsis for the
4410 invisible text. */
4411 int display_ellipsis_p = invis_p == 2;
4413 handled = HANDLED_RECOMPUTE_PROPS;
4415 /* Loop skipping over invisible text. The loop is left at
4416 ZV or with IT on the first char being visible again. */
4419 /* Try to skip some invisible text. Return value is the
4420 position reached which can be equal to where we start
4421 if there is nothing invisible there. This skips both
4422 over invisible text properties and overlays with
4423 invisible property. */
4424 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4426 /* If we skipped nothing at all we weren't at invisible
4427 text in the first place. If everything to the end of
4428 the buffer was skipped, end the loop. */
4429 if (newpos == tem || newpos >= ZV)
4430 invis_p = 0;
4431 else
4433 /* We skipped some characters but not necessarily
4434 all there are. Check if we ended up on visible
4435 text. Fget_char_property returns the property of
4436 the char before the given position, i.e. if we
4437 get invis_p = 0, this means that the char at
4438 newpos is visible. */
4439 pos = make_number (newpos);
4440 prop = Fget_char_property (pos, Qinvisible, it->window);
4441 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4444 /* If we ended up on invisible text, proceed to
4445 skip starting with next_stop. */
4446 if (invis_p)
4447 tem = next_stop;
4449 /* If there are adjacent invisible texts, don't lose the
4450 second one's ellipsis. */
4451 if (invis_p == 2)
4452 display_ellipsis_p = true;
4454 while (invis_p);
4456 /* The position newpos is now either ZV or on visible text. */
4457 if (it->bidi_p)
4459 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4460 int on_newline
4461 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4462 int after_newline
4463 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4465 /* If the invisible text ends on a newline or on a
4466 character after a newline, we can avoid the costly,
4467 character by character, bidi iteration to NEWPOS, and
4468 instead simply reseat the iterator there. That's
4469 because all bidi reordering information is tossed at
4470 the newline. This is a big win for modes that hide
4471 complete lines, like Outline, Org, etc. */
4472 if (on_newline || after_newline)
4474 struct text_pos tpos;
4475 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4477 SET_TEXT_POS (tpos, newpos, bpos);
4478 reseat_1 (it, tpos, 0);
4479 /* If we reseat on a newline/ZV, we need to prep the
4480 bidi iterator for advancing to the next character
4481 after the newline/EOB, keeping the current paragraph
4482 direction (so that PRODUCE_GLYPHS does TRT wrt
4483 prepending/appending glyphs to a glyph row). */
4484 if (on_newline)
4486 it->bidi_it.first_elt = 0;
4487 it->bidi_it.paragraph_dir = pdir;
4488 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4489 it->bidi_it.nchars = 1;
4490 it->bidi_it.ch_len = 1;
4493 else /* Must use the slow method. */
4495 /* With bidi iteration, the region of invisible text
4496 could start and/or end in the middle of a
4497 non-base embedding level. Therefore, we need to
4498 skip invisible text using the bidi iterator,
4499 starting at IT's current position, until we find
4500 ourselves outside of the invisible text.
4501 Skipping invisible text _after_ bidi iteration
4502 avoids affecting the visual order of the
4503 displayed text when invisible properties are
4504 added or removed. */
4505 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4507 /* If we were `reseat'ed to a new paragraph,
4508 determine the paragraph base direction. We
4509 need to do it now because
4510 next_element_from_buffer may not have a
4511 chance to do it, if we are going to skip any
4512 text at the beginning, which resets the
4513 FIRST_ELT flag. */
4514 bidi_paragraph_init (it->paragraph_embedding,
4515 &it->bidi_it, 1);
4519 bidi_move_to_visually_next (&it->bidi_it);
4521 while (it->stop_charpos <= it->bidi_it.charpos
4522 && it->bidi_it.charpos < newpos);
4523 IT_CHARPOS (*it) = it->bidi_it.charpos;
4524 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4525 /* If we overstepped NEWPOS, record its position in
4526 the iterator, so that we skip invisible text if
4527 later the bidi iteration lands us in the
4528 invisible region again. */
4529 if (IT_CHARPOS (*it) >= newpos)
4530 it->prev_stop = newpos;
4533 else
4535 IT_CHARPOS (*it) = newpos;
4536 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4539 /* If there are before-strings at the start of invisible
4540 text, and the text is invisible because of a text
4541 property, arrange to show before-strings because 20.x did
4542 it that way. (If the text is invisible because of an
4543 overlay property instead of a text property, this is
4544 already handled in the overlay code.) */
4545 if (NILP (overlay)
4546 && get_overlay_strings (it, it->stop_charpos))
4548 handled = HANDLED_RECOMPUTE_PROPS;
4549 if (it->sp > 0)
4551 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4552 /* The call to get_overlay_strings above recomputes
4553 it->stop_charpos, but it only considers changes
4554 in properties and overlays beyond iterator's
4555 current position. This causes us to miss changes
4556 that happen exactly where the invisible property
4557 ended. So we play it safe here and force the
4558 iterator to check for potential stop positions
4559 immediately after the invisible text. Note that
4560 if get_overlay_strings returns non-zero, it
4561 normally also pushed the iterator stack, so we
4562 need to update the stop position in the slot
4563 below the current one. */
4564 it->stack[it->sp - 1].stop_charpos
4565 = CHARPOS (it->stack[it->sp - 1].current.pos);
4568 else if (display_ellipsis_p)
4570 /* Make sure that the glyphs of the ellipsis will get
4571 correct `charpos' values. If we would not update
4572 it->position here, the glyphs would belong to the
4573 last visible character _before_ the invisible
4574 text, which confuses `set_cursor_from_row'.
4576 We use the last invisible position instead of the
4577 first because this way the cursor is always drawn on
4578 the first "." of the ellipsis, whenever PT is inside
4579 the invisible text. Otherwise the cursor would be
4580 placed _after_ the ellipsis when the point is after the
4581 first invisible character. */
4582 if (!STRINGP (it->object))
4584 it->position.charpos = newpos - 1;
4585 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4587 it->ellipsis_p = true;
4588 /* Let the ellipsis display before
4589 considering any properties of the following char.
4590 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4591 handled = HANDLED_RETURN;
4596 return handled;
4600 /* Make iterator IT return `...' next.
4601 Replaces LEN characters from buffer. */
4603 static void
4604 setup_for_ellipsis (struct it *it, int len)
4606 /* Use the display table definition for `...'. Invalid glyphs
4607 will be handled by the method returning elements from dpvec. */
4608 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4610 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4611 it->dpvec = v->contents;
4612 it->dpend = v->contents + v->header.size;
4614 else
4616 /* Default `...'. */
4617 it->dpvec = default_invis_vector;
4618 it->dpend = default_invis_vector + 3;
4621 it->dpvec_char_len = len;
4622 it->current.dpvec_index = 0;
4623 it->dpvec_face_id = -1;
4625 /* Remember the current face id in case glyphs specify faces.
4626 IT's face is restored in set_iterator_to_next.
4627 saved_face_id was set to preceding char's face in handle_stop. */
4628 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4629 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4631 it->method = GET_FROM_DISPLAY_VECTOR;
4632 it->ellipsis_p = true;
4637 /***********************************************************************
4638 'display' property
4639 ***********************************************************************/
4641 /* Set up iterator IT from `display' property at its current position.
4642 Called from handle_stop.
4643 We return HANDLED_RETURN if some part of the display property
4644 overrides the display of the buffer text itself.
4645 Otherwise we return HANDLED_NORMALLY. */
4647 static enum prop_handled
4648 handle_display_prop (struct it *it)
4650 Lisp_Object propval, object, overlay;
4651 struct text_pos *position;
4652 ptrdiff_t bufpos;
4653 /* Nonzero if some property replaces the display of the text itself. */
4654 int display_replaced_p = 0;
4656 if (STRINGP (it->string))
4658 object = it->string;
4659 position = &it->current.string_pos;
4660 bufpos = CHARPOS (it->current.pos);
4662 else
4664 XSETWINDOW (object, it->w);
4665 position = &it->current.pos;
4666 bufpos = CHARPOS (*position);
4669 /* Reset those iterator values set from display property values. */
4670 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4671 it->space_width = Qnil;
4672 it->font_height = Qnil;
4673 it->voffset = 0;
4675 /* We don't support recursive `display' properties, i.e. string
4676 values that have a string `display' property, that have a string
4677 `display' property etc. */
4678 if (!it->string_from_display_prop_p)
4679 it->area = TEXT_AREA;
4681 propval = get_char_property_and_overlay (make_number (position->charpos),
4682 Qdisplay, object, &overlay);
4683 if (NILP (propval))
4684 return HANDLED_NORMALLY;
4685 /* Now OVERLAY is the overlay that gave us this property, or nil
4686 if it was a text property. */
4688 if (!STRINGP (it->string))
4689 object = it->w->contents;
4691 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4692 position, bufpos,
4693 FRAME_WINDOW_P (it->f));
4695 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4698 /* Subroutine of handle_display_prop. Returns non-zero if the display
4699 specification in SPEC is a replacing specification, i.e. it would
4700 replace the text covered by `display' property with something else,
4701 such as an image or a display string. If SPEC includes any kind or
4702 `(space ...) specification, the value is 2; this is used by
4703 compute_display_string_pos, which see.
4705 See handle_single_display_spec for documentation of arguments.
4706 frame_window_p is non-zero if the window being redisplayed is on a
4707 GUI frame; this argument is used only if IT is NULL, see below.
4709 IT can be NULL, if this is called by the bidi reordering code
4710 through compute_display_string_pos, which see. In that case, this
4711 function only examines SPEC, but does not otherwise "handle" it, in
4712 the sense that it doesn't set up members of IT from the display
4713 spec. */
4714 static int
4715 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4716 Lisp_Object overlay, struct text_pos *position,
4717 ptrdiff_t bufpos, int frame_window_p)
4719 int replacing_p = 0;
4720 int rv;
4722 if (CONSP (spec)
4723 /* Simple specifications. */
4724 && !EQ (XCAR (spec), Qimage)
4725 && !EQ (XCAR (spec), Qspace)
4726 && !EQ (XCAR (spec), Qwhen)
4727 && !EQ (XCAR (spec), Qslice)
4728 && !EQ (XCAR (spec), Qspace_width)
4729 && !EQ (XCAR (spec), Qheight)
4730 && !EQ (XCAR (spec), Qraise)
4731 /* Marginal area specifications. */
4732 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4733 && !EQ (XCAR (spec), Qleft_fringe)
4734 && !EQ (XCAR (spec), Qright_fringe)
4735 && !NILP (XCAR (spec)))
4737 for (; CONSP (spec); spec = XCDR (spec))
4739 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4740 overlay, position, bufpos,
4741 replacing_p, frame_window_p)))
4743 replacing_p = rv;
4744 /* If some text in a string is replaced, `position' no
4745 longer points to the position of `object'. */
4746 if (!it || STRINGP (object))
4747 break;
4751 else if (VECTORP (spec))
4753 ptrdiff_t i;
4754 for (i = 0; i < ASIZE (spec); ++i)
4755 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4756 overlay, position, bufpos,
4757 replacing_p, frame_window_p)))
4759 replacing_p = rv;
4760 /* If some text in a string is replaced, `position' no
4761 longer points to the position of `object'. */
4762 if (!it || STRINGP (object))
4763 break;
4766 else
4768 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4769 position, bufpos, 0,
4770 frame_window_p)))
4771 replacing_p = rv;
4774 return replacing_p;
4777 /* Value is the position of the end of the `display' property starting
4778 at START_POS in OBJECT. */
4780 static struct text_pos
4781 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4783 Lisp_Object end;
4784 struct text_pos end_pos;
4786 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4787 Qdisplay, object, Qnil);
4788 CHARPOS (end_pos) = XFASTINT (end);
4789 if (STRINGP (object))
4790 compute_string_pos (&end_pos, start_pos, it->string);
4791 else
4792 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4794 return end_pos;
4798 /* Set up IT from a single `display' property specification SPEC. OBJECT
4799 is the object in which the `display' property was found. *POSITION
4800 is the position in OBJECT at which the `display' property was found.
4801 BUFPOS is the buffer position of OBJECT (different from POSITION if
4802 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4803 previously saw a display specification which already replaced text
4804 display with something else, for example an image; we ignore such
4805 properties after the first one has been processed.
4807 OVERLAY is the overlay this `display' property came from,
4808 or nil if it was a text property.
4810 If SPEC is a `space' or `image' specification, and in some other
4811 cases too, set *POSITION to the position where the `display'
4812 property ends.
4814 If IT is NULL, only examine the property specification in SPEC, but
4815 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4816 is intended to be displayed in a window on a GUI frame.
4818 Value is non-zero if something was found which replaces the display
4819 of buffer or string text. */
4821 static int
4822 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4823 Lisp_Object overlay, struct text_pos *position,
4824 ptrdiff_t bufpos, int display_replaced_p,
4825 int frame_window_p)
4827 Lisp_Object form;
4828 Lisp_Object location, value;
4829 struct text_pos start_pos = *position;
4830 int valid_p;
4832 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4833 If the result is non-nil, use VALUE instead of SPEC. */
4834 form = Qt;
4835 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4837 spec = XCDR (spec);
4838 if (!CONSP (spec))
4839 return 0;
4840 form = XCAR (spec);
4841 spec = XCDR (spec);
4844 if (!NILP (form) && !EQ (form, Qt))
4846 ptrdiff_t count = SPECPDL_INDEX ();
4847 struct gcpro gcpro1;
4849 /* Bind `object' to the object having the `display' property, a
4850 buffer or string. Bind `position' to the position in the
4851 object where the property was found, and `buffer-position'
4852 to the current position in the buffer. */
4854 if (NILP (object))
4855 XSETBUFFER (object, current_buffer);
4856 specbind (Qobject, object);
4857 specbind (Qposition, make_number (CHARPOS (*position)));
4858 specbind (Qbuffer_position, make_number (bufpos));
4859 GCPRO1 (form);
4860 form = safe_eval (form);
4861 UNGCPRO;
4862 unbind_to (count, Qnil);
4865 if (NILP (form))
4866 return 0;
4868 /* Handle `(height HEIGHT)' specifications. */
4869 if (CONSP (spec)
4870 && EQ (XCAR (spec), Qheight)
4871 && CONSP (XCDR (spec)))
4873 if (it)
4875 if (!FRAME_WINDOW_P (it->f))
4876 return 0;
4878 it->font_height = XCAR (XCDR (spec));
4879 if (!NILP (it->font_height))
4881 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4882 int new_height = -1;
4884 if (CONSP (it->font_height)
4885 && (EQ (XCAR (it->font_height), Qplus)
4886 || EQ (XCAR (it->font_height), Qminus))
4887 && CONSP (XCDR (it->font_height))
4888 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4890 /* `(+ N)' or `(- N)' where N is an integer. */
4891 int steps = XINT (XCAR (XCDR (it->font_height)));
4892 if (EQ (XCAR (it->font_height), Qplus))
4893 steps = - steps;
4894 it->face_id = smaller_face (it->f, it->face_id, steps);
4896 else if (FUNCTIONP (it->font_height))
4898 /* Call function with current height as argument.
4899 Value is the new height. */
4900 Lisp_Object height;
4901 height = safe_call1 (it->font_height,
4902 face->lface[LFACE_HEIGHT_INDEX]);
4903 if (NUMBERP (height))
4904 new_height = XFLOATINT (height);
4906 else if (NUMBERP (it->font_height))
4908 /* Value is a multiple of the canonical char height. */
4909 struct face *f;
4911 f = FACE_FROM_ID (it->f,
4912 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4913 new_height = (XFLOATINT (it->font_height)
4914 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4916 else
4918 /* Evaluate IT->font_height with `height' bound to the
4919 current specified height to get the new height. */
4920 ptrdiff_t count = SPECPDL_INDEX ();
4922 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4923 value = safe_eval (it->font_height);
4924 unbind_to (count, Qnil);
4926 if (NUMBERP (value))
4927 new_height = XFLOATINT (value);
4930 if (new_height > 0)
4931 it->face_id = face_with_height (it->f, it->face_id, new_height);
4935 return 0;
4938 /* Handle `(space-width WIDTH)'. */
4939 if (CONSP (spec)
4940 && EQ (XCAR (spec), Qspace_width)
4941 && CONSP (XCDR (spec)))
4943 if (it)
4945 if (!FRAME_WINDOW_P (it->f))
4946 return 0;
4948 value = XCAR (XCDR (spec));
4949 if (NUMBERP (value) && XFLOATINT (value) > 0)
4950 it->space_width = value;
4953 return 0;
4956 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4957 if (CONSP (spec)
4958 && EQ (XCAR (spec), Qslice))
4960 Lisp_Object tem;
4962 if (it)
4964 if (!FRAME_WINDOW_P (it->f))
4965 return 0;
4967 if (tem = XCDR (spec), CONSP (tem))
4969 it->slice.x = XCAR (tem);
4970 if (tem = XCDR (tem), CONSP (tem))
4972 it->slice.y = XCAR (tem);
4973 if (tem = XCDR (tem), CONSP (tem))
4975 it->slice.width = XCAR (tem);
4976 if (tem = XCDR (tem), CONSP (tem))
4977 it->slice.height = XCAR (tem);
4983 return 0;
4986 /* Handle `(raise FACTOR)'. */
4987 if (CONSP (spec)
4988 && EQ (XCAR (spec), Qraise)
4989 && CONSP (XCDR (spec)))
4991 if (it)
4993 if (!FRAME_WINDOW_P (it->f))
4994 return 0;
4996 #ifdef HAVE_WINDOW_SYSTEM
4997 value = XCAR (XCDR (spec));
4998 if (NUMBERP (value))
5000 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5001 it->voffset = - (XFLOATINT (value)
5002 * (FONT_HEIGHT (face->font)));
5004 #endif /* HAVE_WINDOW_SYSTEM */
5007 return 0;
5010 /* Don't handle the other kinds of display specifications
5011 inside a string that we got from a `display' property. */
5012 if (it && it->string_from_display_prop_p)
5013 return 0;
5015 /* Characters having this form of property are not displayed, so
5016 we have to find the end of the property. */
5017 if (it)
5019 start_pos = *position;
5020 *position = display_prop_end (it, object, start_pos);
5022 value = Qnil;
5024 /* Stop the scan at that end position--we assume that all
5025 text properties change there. */
5026 if (it)
5027 it->stop_charpos = position->charpos;
5029 /* Handle `(left-fringe BITMAP [FACE])'
5030 and `(right-fringe BITMAP [FACE])'. */
5031 if (CONSP (spec)
5032 && (EQ (XCAR (spec), Qleft_fringe)
5033 || EQ (XCAR (spec), Qright_fringe))
5034 && CONSP (XCDR (spec)))
5036 int fringe_bitmap;
5038 if (it)
5040 if (!FRAME_WINDOW_P (it->f))
5041 /* If we return here, POSITION has been advanced
5042 across the text with this property. */
5044 /* Synchronize the bidi iterator with POSITION. This is
5045 needed because we are not going to push the iterator
5046 on behalf of this display property, so there will be
5047 no pop_it call to do this synchronization for us. */
5048 if (it->bidi_p)
5050 it->position = *position;
5051 iterate_out_of_display_property (it);
5052 *position = it->position;
5054 return 1;
5057 else if (!frame_window_p)
5058 return 1;
5060 #ifdef HAVE_WINDOW_SYSTEM
5061 value = XCAR (XCDR (spec));
5062 if (!SYMBOLP (value)
5063 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
5064 /* If we return here, POSITION has been advanced
5065 across the text with this property. */
5067 if (it && it->bidi_p)
5069 it->position = *position;
5070 iterate_out_of_display_property (it);
5071 *position = it->position;
5073 return 1;
5076 if (it)
5078 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
5080 if (CONSP (XCDR (XCDR (spec))))
5082 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5083 int face_id2 = lookup_derived_face (it->f, face_name,
5084 FRINGE_FACE_ID, 0);
5085 if (face_id2 >= 0)
5086 face_id = face_id2;
5089 /* Save current settings of IT so that we can restore them
5090 when we are finished with the glyph property value. */
5091 push_it (it, position);
5093 it->area = TEXT_AREA;
5094 it->what = IT_IMAGE;
5095 it->image_id = -1; /* no image */
5096 it->position = start_pos;
5097 it->object = NILP (object) ? it->w->contents : object;
5098 it->method = GET_FROM_IMAGE;
5099 it->from_overlay = Qnil;
5100 it->face_id = face_id;
5101 it->from_disp_prop_p = true;
5103 /* Say that we haven't consumed the characters with
5104 `display' property yet. The call to pop_it in
5105 set_iterator_to_next will clean this up. */
5106 *position = start_pos;
5108 if (EQ (XCAR (spec), Qleft_fringe))
5110 it->left_user_fringe_bitmap = fringe_bitmap;
5111 it->left_user_fringe_face_id = face_id;
5113 else
5115 it->right_user_fringe_bitmap = fringe_bitmap;
5116 it->right_user_fringe_face_id = face_id;
5119 #endif /* HAVE_WINDOW_SYSTEM */
5120 return 1;
5123 /* Prepare to handle `((margin left-margin) ...)',
5124 `((margin right-margin) ...)' and `((margin nil) ...)'
5125 prefixes for display specifications. */
5126 location = Qunbound;
5127 if (CONSP (spec) && CONSP (XCAR (spec)))
5129 Lisp_Object tem;
5131 value = XCDR (spec);
5132 if (CONSP (value))
5133 value = XCAR (value);
5135 tem = XCAR (spec);
5136 if (EQ (XCAR (tem), Qmargin)
5137 && (tem = XCDR (tem),
5138 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5139 (NILP (tem)
5140 || EQ (tem, Qleft_margin)
5141 || EQ (tem, Qright_margin))))
5142 location = tem;
5145 if (EQ (location, Qunbound))
5147 location = Qnil;
5148 value = spec;
5151 /* After this point, VALUE is the property after any
5152 margin prefix has been stripped. It must be a string,
5153 an image specification, or `(space ...)'.
5155 LOCATION specifies where to display: `left-margin',
5156 `right-margin' or nil. */
5158 valid_p = (STRINGP (value)
5159 #ifdef HAVE_WINDOW_SYSTEM
5160 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5161 && valid_image_p (value))
5162 #endif /* not HAVE_WINDOW_SYSTEM */
5163 || (CONSP (value) && EQ (XCAR (value), Qspace)));
5165 if (valid_p && !display_replaced_p)
5167 int retval = 1;
5169 if (!it)
5171 /* Callers need to know whether the display spec is any kind
5172 of `(space ...)' spec that is about to affect text-area
5173 display. */
5174 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5175 retval = 2;
5176 return retval;
5179 /* Save current settings of IT so that we can restore them
5180 when we are finished with the glyph property value. */
5181 push_it (it, position);
5182 it->from_overlay = overlay;
5183 it->from_disp_prop_p = true;
5185 if (NILP (location))
5186 it->area = TEXT_AREA;
5187 else if (EQ (location, Qleft_margin))
5188 it->area = LEFT_MARGIN_AREA;
5189 else
5190 it->area = RIGHT_MARGIN_AREA;
5192 if (STRINGP (value))
5194 it->string = value;
5195 it->multibyte_p = STRING_MULTIBYTE (it->string);
5196 it->current.overlay_string_index = -1;
5197 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5198 it->end_charpos = it->string_nchars = SCHARS (it->string);
5199 it->method = GET_FROM_STRING;
5200 it->stop_charpos = 0;
5201 it->prev_stop = 0;
5202 it->base_level_stop = 0;
5203 it->string_from_display_prop_p = true;
5204 /* Say that we haven't consumed the characters with
5205 `display' property yet. The call to pop_it in
5206 set_iterator_to_next will clean this up. */
5207 if (BUFFERP (object))
5208 *position = start_pos;
5210 /* Force paragraph direction to be that of the parent
5211 object. If the parent object's paragraph direction is
5212 not yet determined, default to L2R. */
5213 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5214 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5215 else
5216 it->paragraph_embedding = L2R;
5218 /* Set up the bidi iterator for this display string. */
5219 if (it->bidi_p)
5221 it->bidi_it.string.lstring = it->string;
5222 it->bidi_it.string.s = NULL;
5223 it->bidi_it.string.schars = it->end_charpos;
5224 it->bidi_it.string.bufpos = bufpos;
5225 it->bidi_it.string.from_disp_str = 1;
5226 it->bidi_it.string.unibyte = !it->multibyte_p;
5227 it->bidi_it.w = it->w;
5228 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5231 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5233 it->method = GET_FROM_STRETCH;
5234 it->object = value;
5235 *position = it->position = start_pos;
5236 retval = 1 + (it->area == TEXT_AREA);
5238 #ifdef HAVE_WINDOW_SYSTEM
5239 else
5241 it->what = IT_IMAGE;
5242 it->image_id = lookup_image (it->f, value);
5243 it->position = start_pos;
5244 it->object = NILP (object) ? it->w->contents : object;
5245 it->method = GET_FROM_IMAGE;
5247 /* Say that we haven't consumed the characters with
5248 `display' property yet. The call to pop_it in
5249 set_iterator_to_next will clean this up. */
5250 *position = start_pos;
5252 #endif /* HAVE_WINDOW_SYSTEM */
5254 return retval;
5257 /* Invalid property or property not supported. Restore
5258 POSITION to what it was before. */
5259 *position = start_pos;
5260 return 0;
5263 /* Check if PROP is a display property value whose text should be
5264 treated as intangible. OVERLAY is the overlay from which PROP
5265 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5266 specify the buffer position covered by PROP. */
5269 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5270 ptrdiff_t charpos, ptrdiff_t bytepos)
5272 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5273 struct text_pos position;
5275 SET_TEXT_POS (position, charpos, bytepos);
5276 return handle_display_spec (NULL, prop, Qnil, overlay,
5277 &position, charpos, frame_window_p);
5281 /* Return 1 if PROP is a display sub-property value containing STRING.
5283 Implementation note: this and the following function are really
5284 special cases of handle_display_spec and
5285 handle_single_display_spec, and should ideally use the same code.
5286 Until they do, these two pairs must be consistent and must be
5287 modified in sync. */
5289 static int
5290 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5292 if (EQ (string, prop))
5293 return 1;
5295 /* Skip over `when FORM'. */
5296 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5298 prop = XCDR (prop);
5299 if (!CONSP (prop))
5300 return 0;
5301 /* Actually, the condition following `when' should be eval'ed,
5302 like handle_single_display_spec does, and we should return
5303 zero if it evaluates to nil. However, this function is
5304 called only when the buffer was already displayed and some
5305 glyph in the glyph matrix was found to come from a display
5306 string. Therefore, the condition was already evaluated, and
5307 the result was non-nil, otherwise the display string wouldn't
5308 have been displayed and we would have never been called for
5309 this property. Thus, we can skip the evaluation and assume
5310 its result is non-nil. */
5311 prop = XCDR (prop);
5314 if (CONSP (prop))
5315 /* Skip over `margin LOCATION'. */
5316 if (EQ (XCAR (prop), Qmargin))
5318 prop = XCDR (prop);
5319 if (!CONSP (prop))
5320 return 0;
5322 prop = XCDR (prop);
5323 if (!CONSP (prop))
5324 return 0;
5327 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5331 /* Return 1 if STRING appears in the `display' property PROP. */
5333 static int
5334 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5336 if (CONSP (prop)
5337 && !EQ (XCAR (prop), Qwhen)
5338 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5340 /* A list of sub-properties. */
5341 while (CONSP (prop))
5343 if (single_display_spec_string_p (XCAR (prop), string))
5344 return 1;
5345 prop = XCDR (prop);
5348 else if (VECTORP (prop))
5350 /* A vector of sub-properties. */
5351 ptrdiff_t i;
5352 for (i = 0; i < ASIZE (prop); ++i)
5353 if (single_display_spec_string_p (AREF (prop, i), string))
5354 return 1;
5356 else
5357 return single_display_spec_string_p (prop, string);
5359 return 0;
5362 /* Look for STRING in overlays and text properties in the current
5363 buffer, between character positions FROM and TO (excluding TO).
5364 BACK_P non-zero means look back (in this case, TO is supposed to be
5365 less than FROM).
5366 Value is the first character position where STRING was found, or
5367 zero if it wasn't found before hitting TO.
5369 This function may only use code that doesn't eval because it is
5370 called asynchronously from note_mouse_highlight. */
5372 static ptrdiff_t
5373 string_buffer_position_lim (Lisp_Object string,
5374 ptrdiff_t from, ptrdiff_t to, int back_p)
5376 Lisp_Object limit, prop, pos;
5377 int found = 0;
5379 pos = make_number (max (from, BEGV));
5381 if (!back_p) /* looking forward */
5383 limit = make_number (min (to, ZV));
5384 while (!found && !EQ (pos, limit))
5386 prop = Fget_char_property (pos, Qdisplay, Qnil);
5387 if (!NILP (prop) && display_prop_string_p (prop, string))
5388 found = 1;
5389 else
5390 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5391 limit);
5394 else /* looking back */
5396 limit = make_number (max (to, BEGV));
5397 while (!found && !EQ (pos, limit))
5399 prop = Fget_char_property (pos, Qdisplay, Qnil);
5400 if (!NILP (prop) && display_prop_string_p (prop, string))
5401 found = 1;
5402 else
5403 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5404 limit);
5408 return found ? XINT (pos) : 0;
5411 /* Determine which buffer position in current buffer STRING comes from.
5412 AROUND_CHARPOS is an approximate position where it could come from.
5413 Value is the buffer position or 0 if it couldn't be determined.
5415 This function is necessary because we don't record buffer positions
5416 in glyphs generated from strings (to keep struct glyph small).
5417 This function may only use code that doesn't eval because it is
5418 called asynchronously from note_mouse_highlight. */
5420 static ptrdiff_t
5421 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5423 const int MAX_DISTANCE = 1000;
5424 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5425 around_charpos + MAX_DISTANCE,
5428 if (!found)
5429 found = string_buffer_position_lim (string, around_charpos,
5430 around_charpos - MAX_DISTANCE, 1);
5431 return found;
5436 /***********************************************************************
5437 `composition' property
5438 ***********************************************************************/
5440 /* Set up iterator IT from `composition' property at its current
5441 position. Called from handle_stop. */
5443 static enum prop_handled
5444 handle_composition_prop (struct it *it)
5446 Lisp_Object prop, string;
5447 ptrdiff_t pos, pos_byte, start, end;
5449 if (STRINGP (it->string))
5451 unsigned char *s;
5453 pos = IT_STRING_CHARPOS (*it);
5454 pos_byte = IT_STRING_BYTEPOS (*it);
5455 string = it->string;
5456 s = SDATA (string) + pos_byte;
5457 it->c = STRING_CHAR (s);
5459 else
5461 pos = IT_CHARPOS (*it);
5462 pos_byte = IT_BYTEPOS (*it);
5463 string = Qnil;
5464 it->c = FETCH_CHAR (pos_byte);
5467 /* If there's a valid composition and point is not inside of the
5468 composition (in the case that the composition is from the current
5469 buffer), draw a glyph composed from the composition components. */
5470 if (find_composition (pos, -1, &start, &end, &prop, string)
5471 && composition_valid_p (start, end, prop)
5472 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5474 if (start < pos)
5475 /* As we can't handle this situation (perhaps font-lock added
5476 a new composition), we just return here hoping that next
5477 redisplay will detect this composition much earlier. */
5478 return HANDLED_NORMALLY;
5479 if (start != pos)
5481 if (STRINGP (it->string))
5482 pos_byte = string_char_to_byte (it->string, start);
5483 else
5484 pos_byte = CHAR_TO_BYTE (start);
5486 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5487 prop, string);
5489 if (it->cmp_it.id >= 0)
5491 it->cmp_it.ch = -1;
5492 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5493 it->cmp_it.nglyphs = -1;
5497 return HANDLED_NORMALLY;
5502 /***********************************************************************
5503 Overlay strings
5504 ***********************************************************************/
5506 /* The following structure is used to record overlay strings for
5507 later sorting in load_overlay_strings. */
5509 struct overlay_entry
5511 Lisp_Object overlay;
5512 Lisp_Object string;
5513 EMACS_INT priority;
5514 int after_string_p;
5518 /* Set up iterator IT from overlay strings at its current position.
5519 Called from handle_stop. */
5521 static enum prop_handled
5522 handle_overlay_change (struct it *it)
5524 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5525 return HANDLED_RECOMPUTE_PROPS;
5526 else
5527 return HANDLED_NORMALLY;
5531 /* Set up the next overlay string for delivery by IT, if there is an
5532 overlay string to deliver. Called by set_iterator_to_next when the
5533 end of the current overlay string is reached. If there are more
5534 overlay strings to display, IT->string and
5535 IT->current.overlay_string_index are set appropriately here.
5536 Otherwise IT->string is set to nil. */
5538 static void
5539 next_overlay_string (struct it *it)
5541 ++it->current.overlay_string_index;
5542 if (it->current.overlay_string_index == it->n_overlay_strings)
5544 /* No more overlay strings. Restore IT's settings to what
5545 they were before overlay strings were processed, and
5546 continue to deliver from current_buffer. */
5548 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5549 pop_it (it);
5550 eassert (it->sp > 0
5551 || (NILP (it->string)
5552 && it->method == GET_FROM_BUFFER
5553 && it->stop_charpos >= BEGV
5554 && it->stop_charpos <= it->end_charpos));
5555 it->current.overlay_string_index = -1;
5556 it->n_overlay_strings = 0;
5557 it->overlay_strings_charpos = -1;
5558 /* If there's an empty display string on the stack, pop the
5559 stack, to resync the bidi iterator with IT's position. Such
5560 empty strings are pushed onto the stack in
5561 get_overlay_strings_1. */
5562 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5563 pop_it (it);
5565 /* If we're at the end of the buffer, record that we have
5566 processed the overlay strings there already, so that
5567 next_element_from_buffer doesn't try it again. */
5568 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5569 it->overlay_strings_at_end_processed_p = true;
5571 else
5573 /* There are more overlay strings to process. If
5574 IT->current.overlay_string_index has advanced to a position
5575 where we must load IT->overlay_strings with more strings, do
5576 it. We must load at the IT->overlay_strings_charpos where
5577 IT->n_overlay_strings was originally computed; when invisible
5578 text is present, this might not be IT_CHARPOS (Bug#7016). */
5579 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5581 if (it->current.overlay_string_index && i == 0)
5582 load_overlay_strings (it, it->overlay_strings_charpos);
5584 /* Initialize IT to deliver display elements from the overlay
5585 string. */
5586 it->string = it->overlay_strings[i];
5587 it->multibyte_p = STRING_MULTIBYTE (it->string);
5588 SET_TEXT_POS (it->current.string_pos, 0, 0);
5589 it->method = GET_FROM_STRING;
5590 it->stop_charpos = 0;
5591 it->end_charpos = SCHARS (it->string);
5592 if (it->cmp_it.stop_pos >= 0)
5593 it->cmp_it.stop_pos = 0;
5594 it->prev_stop = 0;
5595 it->base_level_stop = 0;
5597 /* Set up the bidi iterator for this overlay string. */
5598 if (it->bidi_p)
5600 it->bidi_it.string.lstring = it->string;
5601 it->bidi_it.string.s = NULL;
5602 it->bidi_it.string.schars = SCHARS (it->string);
5603 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5604 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5605 it->bidi_it.string.unibyte = !it->multibyte_p;
5606 it->bidi_it.w = it->w;
5607 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5611 CHECK_IT (it);
5615 /* Compare two overlay_entry structures E1 and E2. Used as a
5616 comparison function for qsort in load_overlay_strings. Overlay
5617 strings for the same position are sorted so that
5619 1. All after-strings come in front of before-strings, except
5620 when they come from the same overlay.
5622 2. Within after-strings, strings are sorted so that overlay strings
5623 from overlays with higher priorities come first.
5625 2. Within before-strings, strings are sorted so that overlay
5626 strings from overlays with higher priorities come last.
5628 Value is analogous to strcmp. */
5631 static int
5632 compare_overlay_entries (const void *e1, const void *e2)
5634 struct overlay_entry const *entry1 = e1;
5635 struct overlay_entry const *entry2 = e2;
5636 int result;
5638 if (entry1->after_string_p != entry2->after_string_p)
5640 /* Let after-strings appear in front of before-strings if
5641 they come from different overlays. */
5642 if (EQ (entry1->overlay, entry2->overlay))
5643 result = entry1->after_string_p ? 1 : -1;
5644 else
5645 result = entry1->after_string_p ? -1 : 1;
5647 else if (entry1->priority != entry2->priority)
5649 if (entry1->after_string_p)
5650 /* After-strings sorted in order of decreasing priority. */
5651 result = entry2->priority < entry1->priority ? -1 : 1;
5652 else
5653 /* Before-strings sorted in order of increasing priority. */
5654 result = entry1->priority < entry2->priority ? -1 : 1;
5656 else
5657 result = 0;
5659 return result;
5663 /* Load the vector IT->overlay_strings with overlay strings from IT's
5664 current buffer position, or from CHARPOS if that is > 0. Set
5665 IT->n_overlays to the total number of overlay strings found.
5667 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5668 a time. On entry into load_overlay_strings,
5669 IT->current.overlay_string_index gives the number of overlay
5670 strings that have already been loaded by previous calls to this
5671 function.
5673 IT->add_overlay_start contains an additional overlay start
5674 position to consider for taking overlay strings from, if non-zero.
5675 This position comes into play when the overlay has an `invisible'
5676 property, and both before and after-strings. When we've skipped to
5677 the end of the overlay, because of its `invisible' property, we
5678 nevertheless want its before-string to appear.
5679 IT->add_overlay_start will contain the overlay start position
5680 in this case.
5682 Overlay strings are sorted so that after-string strings come in
5683 front of before-string strings. Within before and after-strings,
5684 strings are sorted by overlay priority. See also function
5685 compare_overlay_entries. */
5687 static void
5688 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5690 Lisp_Object overlay, window, str, invisible;
5691 struct Lisp_Overlay *ov;
5692 ptrdiff_t start, end;
5693 ptrdiff_t size = 20;
5694 ptrdiff_t n = 0, i, j;
5695 int invis_p;
5696 struct overlay_entry *entries = alloca (size * sizeof *entries);
5697 USE_SAFE_ALLOCA;
5699 if (charpos <= 0)
5700 charpos = IT_CHARPOS (*it);
5702 /* Append the overlay string STRING of overlay OVERLAY to vector
5703 `entries' which has size `size' and currently contains `n'
5704 elements. AFTER_P non-zero means STRING is an after-string of
5705 OVERLAY. */
5706 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5707 do \
5709 Lisp_Object priority; \
5711 if (n == size) \
5713 struct overlay_entry *old = entries; \
5714 SAFE_NALLOCA (entries, 2, size); \
5715 memcpy (entries, old, size * sizeof *entries); \
5716 size *= 2; \
5719 entries[n].string = (STRING); \
5720 entries[n].overlay = (OVERLAY); \
5721 priority = Foverlay_get ((OVERLAY), Qpriority); \
5722 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5723 entries[n].after_string_p = (AFTER_P); \
5724 ++n; \
5726 while (0)
5728 /* Process overlay before the overlay center. */
5729 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5731 XSETMISC (overlay, ov);
5732 eassert (OVERLAYP (overlay));
5733 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5734 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5736 if (end < charpos)
5737 break;
5739 /* Skip this overlay if it doesn't start or end at IT's current
5740 position. */
5741 if (end != charpos && start != charpos)
5742 continue;
5744 /* Skip this overlay if it doesn't apply to IT->w. */
5745 window = Foverlay_get (overlay, Qwindow);
5746 if (WINDOWP (window) && XWINDOW (window) != it->w)
5747 continue;
5749 /* If the text ``under'' the overlay is invisible, both before-
5750 and after-strings from this overlay are visible; start and
5751 end position are indistinguishable. */
5752 invisible = Foverlay_get (overlay, Qinvisible);
5753 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5755 /* If overlay has a non-empty before-string, record it. */
5756 if ((start == charpos || (end == charpos && invis_p))
5757 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5758 && SCHARS (str))
5759 RECORD_OVERLAY_STRING (overlay, str, 0);
5761 /* If overlay has a non-empty after-string, record it. */
5762 if ((end == charpos || (start == charpos && invis_p))
5763 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5764 && SCHARS (str))
5765 RECORD_OVERLAY_STRING (overlay, str, 1);
5768 /* Process overlays after the overlay center. */
5769 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5771 XSETMISC (overlay, ov);
5772 eassert (OVERLAYP (overlay));
5773 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5774 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5776 if (start > charpos)
5777 break;
5779 /* Skip this overlay if it doesn't start or end at IT's current
5780 position. */
5781 if (end != charpos && start != charpos)
5782 continue;
5784 /* Skip this overlay if it doesn't apply to IT->w. */
5785 window = Foverlay_get (overlay, Qwindow);
5786 if (WINDOWP (window) && XWINDOW (window) != it->w)
5787 continue;
5789 /* If the text ``under'' the overlay is invisible, it has a zero
5790 dimension, and both before- and after-strings apply. */
5791 invisible = Foverlay_get (overlay, Qinvisible);
5792 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5794 /* If overlay has a non-empty before-string, record it. */
5795 if ((start == charpos || (end == charpos && invis_p))
5796 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5797 && SCHARS (str))
5798 RECORD_OVERLAY_STRING (overlay, str, 0);
5800 /* If overlay has a non-empty after-string, record it. */
5801 if ((end == charpos || (start == charpos && invis_p))
5802 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5803 && SCHARS (str))
5804 RECORD_OVERLAY_STRING (overlay, str, 1);
5807 #undef RECORD_OVERLAY_STRING
5809 /* Sort entries. */
5810 if (n > 1)
5811 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5813 /* Record number of overlay strings, and where we computed it. */
5814 it->n_overlay_strings = n;
5815 it->overlay_strings_charpos = charpos;
5817 /* IT->current.overlay_string_index is the number of overlay strings
5818 that have already been consumed by IT. Copy some of the
5819 remaining overlay strings to IT->overlay_strings. */
5820 i = 0;
5821 j = it->current.overlay_string_index;
5822 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5824 it->overlay_strings[i] = entries[j].string;
5825 it->string_overlays[i++] = entries[j++].overlay;
5828 CHECK_IT (it);
5829 SAFE_FREE ();
5833 /* Get the first chunk of overlay strings at IT's current buffer
5834 position, or at CHARPOS if that is > 0. Value is non-zero if at
5835 least one overlay string was found. */
5837 static int
5838 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5840 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5841 process. This fills IT->overlay_strings with strings, and sets
5842 IT->n_overlay_strings to the total number of strings to process.
5843 IT->pos.overlay_string_index has to be set temporarily to zero
5844 because load_overlay_strings needs this; it must be set to -1
5845 when no overlay strings are found because a zero value would
5846 indicate a position in the first overlay string. */
5847 it->current.overlay_string_index = 0;
5848 load_overlay_strings (it, charpos);
5850 /* If we found overlay strings, set up IT to deliver display
5851 elements from the first one. Otherwise set up IT to deliver
5852 from current_buffer. */
5853 if (it->n_overlay_strings)
5855 /* Make sure we know settings in current_buffer, so that we can
5856 restore meaningful values when we're done with the overlay
5857 strings. */
5858 if (compute_stop_p)
5859 compute_stop_pos (it);
5860 eassert (it->face_id >= 0);
5862 /* Save IT's settings. They are restored after all overlay
5863 strings have been processed. */
5864 eassert (!compute_stop_p || it->sp == 0);
5866 /* When called from handle_stop, there might be an empty display
5867 string loaded. In that case, don't bother saving it. But
5868 don't use this optimization with the bidi iterator, since we
5869 need the corresponding pop_it call to resync the bidi
5870 iterator's position with IT's position, after we are done
5871 with the overlay strings. (The corresponding call to pop_it
5872 in case of an empty display string is in
5873 next_overlay_string.) */
5874 if (!(!it->bidi_p
5875 && STRINGP (it->string) && !SCHARS (it->string)))
5876 push_it (it, NULL);
5878 /* Set up IT to deliver display elements from the first overlay
5879 string. */
5880 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5881 it->string = it->overlay_strings[0];
5882 it->from_overlay = Qnil;
5883 it->stop_charpos = 0;
5884 eassert (STRINGP (it->string));
5885 it->end_charpos = SCHARS (it->string);
5886 it->prev_stop = 0;
5887 it->base_level_stop = 0;
5888 it->multibyte_p = STRING_MULTIBYTE (it->string);
5889 it->method = GET_FROM_STRING;
5890 it->from_disp_prop_p = 0;
5892 /* Force paragraph direction to be that of the parent
5893 buffer. */
5894 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5895 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5896 else
5897 it->paragraph_embedding = L2R;
5899 /* Set up the bidi iterator for this overlay string. */
5900 if (it->bidi_p)
5902 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5904 it->bidi_it.string.lstring = it->string;
5905 it->bidi_it.string.s = NULL;
5906 it->bidi_it.string.schars = SCHARS (it->string);
5907 it->bidi_it.string.bufpos = pos;
5908 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5909 it->bidi_it.string.unibyte = !it->multibyte_p;
5910 it->bidi_it.w = it->w;
5911 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5913 return 1;
5916 it->current.overlay_string_index = -1;
5917 return 0;
5920 static int
5921 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5923 it->string = Qnil;
5924 it->method = GET_FROM_BUFFER;
5926 (void) get_overlay_strings_1 (it, charpos, 1);
5928 CHECK_IT (it);
5930 /* Value is non-zero if we found at least one overlay string. */
5931 return STRINGP (it->string);
5936 /***********************************************************************
5937 Saving and restoring state
5938 ***********************************************************************/
5940 /* Save current settings of IT on IT->stack. Called, for example,
5941 before setting up IT for an overlay string, to be able to restore
5942 IT's settings to what they were after the overlay string has been
5943 processed. If POSITION is non-NULL, it is the position to save on
5944 the stack instead of IT->position. */
5946 static void
5947 push_it (struct it *it, struct text_pos *position)
5949 struct iterator_stack_entry *p;
5951 eassert (it->sp < IT_STACK_SIZE);
5952 p = it->stack + it->sp;
5954 p->stop_charpos = it->stop_charpos;
5955 p->prev_stop = it->prev_stop;
5956 p->base_level_stop = it->base_level_stop;
5957 p->cmp_it = it->cmp_it;
5958 eassert (it->face_id >= 0);
5959 p->face_id = it->face_id;
5960 p->string = it->string;
5961 p->method = it->method;
5962 p->from_overlay = it->from_overlay;
5963 switch (p->method)
5965 case GET_FROM_IMAGE:
5966 p->u.image.object = it->object;
5967 p->u.image.image_id = it->image_id;
5968 p->u.image.slice = it->slice;
5969 break;
5970 case GET_FROM_STRETCH:
5971 p->u.stretch.object = it->object;
5972 break;
5974 p->position = position ? *position : it->position;
5975 p->current = it->current;
5976 p->end_charpos = it->end_charpos;
5977 p->string_nchars = it->string_nchars;
5978 p->area = it->area;
5979 p->multibyte_p = it->multibyte_p;
5980 p->avoid_cursor_p = it->avoid_cursor_p;
5981 p->space_width = it->space_width;
5982 p->font_height = it->font_height;
5983 p->voffset = it->voffset;
5984 p->string_from_display_prop_p = it->string_from_display_prop_p;
5985 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5986 p->display_ellipsis_p = 0;
5987 p->line_wrap = it->line_wrap;
5988 p->bidi_p = it->bidi_p;
5989 p->paragraph_embedding = it->paragraph_embedding;
5990 p->from_disp_prop_p = it->from_disp_prop_p;
5991 ++it->sp;
5993 /* Save the state of the bidi iterator as well. */
5994 if (it->bidi_p)
5995 bidi_push_it (&it->bidi_it);
5998 static void
5999 iterate_out_of_display_property (struct it *it)
6001 int buffer_p = !STRINGP (it->string);
6002 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6003 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6005 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6007 /* Maybe initialize paragraph direction. If we are at the beginning
6008 of a new paragraph, next_element_from_buffer may not have a
6009 chance to do that. */
6010 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6011 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6012 /* prev_stop can be zero, so check against BEGV as well. */
6013 while (it->bidi_it.charpos >= bob
6014 && it->prev_stop <= it->bidi_it.charpos
6015 && it->bidi_it.charpos < CHARPOS (it->position)
6016 && it->bidi_it.charpos < eob)
6017 bidi_move_to_visually_next (&it->bidi_it);
6018 /* Record the stop_pos we just crossed, for when we cross it
6019 back, maybe. */
6020 if (it->bidi_it.charpos > CHARPOS (it->position))
6021 it->prev_stop = CHARPOS (it->position);
6022 /* If we ended up not where pop_it put us, resync IT's
6023 positional members with the bidi iterator. */
6024 if (it->bidi_it.charpos != CHARPOS (it->position))
6025 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6026 if (buffer_p)
6027 it->current.pos = it->position;
6028 else
6029 it->current.string_pos = it->position;
6032 /* Restore IT's settings from IT->stack. Called, for example, when no
6033 more overlay strings must be processed, and we return to delivering
6034 display elements from a buffer, or when the end of a string from a
6035 `display' property is reached and we return to delivering display
6036 elements from an overlay string, or from a buffer. */
6038 static void
6039 pop_it (struct it *it)
6041 struct iterator_stack_entry *p;
6042 int from_display_prop = it->from_disp_prop_p;
6044 eassert (it->sp > 0);
6045 --it->sp;
6046 p = it->stack + it->sp;
6047 it->stop_charpos = p->stop_charpos;
6048 it->prev_stop = p->prev_stop;
6049 it->base_level_stop = p->base_level_stop;
6050 it->cmp_it = p->cmp_it;
6051 it->face_id = p->face_id;
6052 it->current = p->current;
6053 it->position = p->position;
6054 it->string = p->string;
6055 it->from_overlay = p->from_overlay;
6056 if (NILP (it->string))
6057 SET_TEXT_POS (it->current.string_pos, -1, -1);
6058 it->method = p->method;
6059 switch (it->method)
6061 case GET_FROM_IMAGE:
6062 it->image_id = p->u.image.image_id;
6063 it->object = p->u.image.object;
6064 it->slice = p->u.image.slice;
6065 break;
6066 case GET_FROM_STRETCH:
6067 it->object = p->u.stretch.object;
6068 break;
6069 case GET_FROM_BUFFER:
6070 it->object = it->w->contents;
6071 break;
6072 case GET_FROM_STRING:
6074 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6076 /* Restore the face_box_p flag, since it could have been
6077 overwritten by the face of the object that we just finished
6078 displaying. */
6079 if (face)
6080 it->face_box_p = face->box != FACE_NO_BOX;
6081 it->object = it->string;
6083 break;
6084 case GET_FROM_DISPLAY_VECTOR:
6085 if (it->s)
6086 it->method = GET_FROM_C_STRING;
6087 else if (STRINGP (it->string))
6088 it->method = GET_FROM_STRING;
6089 else
6091 it->method = GET_FROM_BUFFER;
6092 it->object = it->w->contents;
6095 it->end_charpos = p->end_charpos;
6096 it->string_nchars = p->string_nchars;
6097 it->area = p->area;
6098 it->multibyte_p = p->multibyte_p;
6099 it->avoid_cursor_p = p->avoid_cursor_p;
6100 it->space_width = p->space_width;
6101 it->font_height = p->font_height;
6102 it->voffset = p->voffset;
6103 it->string_from_display_prop_p = p->string_from_display_prop_p;
6104 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6105 it->line_wrap = p->line_wrap;
6106 it->bidi_p = p->bidi_p;
6107 it->paragraph_embedding = p->paragraph_embedding;
6108 it->from_disp_prop_p = p->from_disp_prop_p;
6109 if (it->bidi_p)
6111 bidi_pop_it (&it->bidi_it);
6112 /* Bidi-iterate until we get out of the portion of text, if any,
6113 covered by a `display' text property or by an overlay with
6114 `display' property. (We cannot just jump there, because the
6115 internal coherency of the bidi iterator state can not be
6116 preserved across such jumps.) We also must determine the
6117 paragraph base direction if the overlay we just processed is
6118 at the beginning of a new paragraph. */
6119 if (from_display_prop
6120 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6121 iterate_out_of_display_property (it);
6123 eassert ((BUFFERP (it->object)
6124 && IT_CHARPOS (*it) == it->bidi_it.charpos
6125 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6126 || (STRINGP (it->object)
6127 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6128 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6129 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6135 /***********************************************************************
6136 Moving over lines
6137 ***********************************************************************/
6139 /* Set IT's current position to the previous line start. */
6141 static void
6142 back_to_previous_line_start (struct it *it)
6144 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6146 DEC_BOTH (cp, bp);
6147 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6151 /* Move IT to the next line start.
6153 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
6154 we skipped over part of the text (as opposed to moving the iterator
6155 continuously over the text). Otherwise, don't change the value
6156 of *SKIPPED_P.
6158 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6159 iterator on the newline, if it was found.
6161 Newlines may come from buffer text, overlay strings, or strings
6162 displayed via the `display' property. That's the reason we can't
6163 simply use find_newline_no_quit.
6165 Note that this function may not skip over invisible text that is so
6166 because of text properties and immediately follows a newline. If
6167 it would, function reseat_at_next_visible_line_start, when called
6168 from set_iterator_to_next, would effectively make invisible
6169 characters following a newline part of the wrong glyph row, which
6170 leads to wrong cursor motion. */
6172 static int
6173 forward_to_next_line_start (struct it *it, int *skipped_p,
6174 struct bidi_it *bidi_it_prev)
6176 ptrdiff_t old_selective;
6177 int newline_found_p, n;
6178 const int MAX_NEWLINE_DISTANCE = 500;
6180 /* If already on a newline, just consume it to avoid unintended
6181 skipping over invisible text below. */
6182 if (it->what == IT_CHARACTER
6183 && it->c == '\n'
6184 && CHARPOS (it->position) == IT_CHARPOS (*it))
6186 if (it->bidi_p && bidi_it_prev)
6187 *bidi_it_prev = it->bidi_it;
6188 set_iterator_to_next (it, 0);
6189 it->c = 0;
6190 return 1;
6193 /* Don't handle selective display in the following. It's (a)
6194 unnecessary because it's done by the caller, and (b) leads to an
6195 infinite recursion because next_element_from_ellipsis indirectly
6196 calls this function. */
6197 old_selective = it->selective;
6198 it->selective = 0;
6200 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6201 from buffer text. */
6202 for (n = newline_found_p = 0;
6203 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6204 n += STRINGP (it->string) ? 0 : 1)
6206 if (!get_next_display_element (it))
6207 return 0;
6208 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6209 if (newline_found_p && it->bidi_p && bidi_it_prev)
6210 *bidi_it_prev = it->bidi_it;
6211 set_iterator_to_next (it, 0);
6214 /* If we didn't find a newline near enough, see if we can use a
6215 short-cut. */
6216 if (!newline_found_p)
6218 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6219 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6220 1, &bytepos);
6221 Lisp_Object pos;
6223 eassert (!STRINGP (it->string));
6225 /* If there isn't any `display' property in sight, and no
6226 overlays, we can just use the position of the newline in
6227 buffer text. */
6228 if (it->stop_charpos >= limit
6229 || ((pos = Fnext_single_property_change (make_number (start),
6230 Qdisplay, Qnil,
6231 make_number (limit)),
6232 NILP (pos))
6233 && next_overlay_change (start) == ZV))
6235 if (!it->bidi_p)
6237 IT_CHARPOS (*it) = limit;
6238 IT_BYTEPOS (*it) = bytepos;
6240 else
6242 struct bidi_it bprev;
6244 /* Help bidi.c avoid expensive searches for display
6245 properties and overlays, by telling it that there are
6246 none up to `limit'. */
6247 if (it->bidi_it.disp_pos < limit)
6249 it->bidi_it.disp_pos = limit;
6250 it->bidi_it.disp_prop = 0;
6252 do {
6253 bprev = it->bidi_it;
6254 bidi_move_to_visually_next (&it->bidi_it);
6255 } while (it->bidi_it.charpos != limit);
6256 IT_CHARPOS (*it) = limit;
6257 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6258 if (bidi_it_prev)
6259 *bidi_it_prev = bprev;
6261 *skipped_p = newline_found_p = true;
6263 else
6265 while (get_next_display_element (it)
6266 && !newline_found_p)
6268 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6269 if (newline_found_p && it->bidi_p && bidi_it_prev)
6270 *bidi_it_prev = it->bidi_it;
6271 set_iterator_to_next (it, 0);
6276 it->selective = old_selective;
6277 return newline_found_p;
6281 /* Set IT's current position to the previous visible line start. Skip
6282 invisible text that is so either due to text properties or due to
6283 selective display. Caution: this does not change IT->current_x and
6284 IT->hpos. */
6286 static void
6287 back_to_previous_visible_line_start (struct it *it)
6289 while (IT_CHARPOS (*it) > BEGV)
6291 back_to_previous_line_start (it);
6293 if (IT_CHARPOS (*it) <= BEGV)
6294 break;
6296 /* If selective > 0, then lines indented more than its value are
6297 invisible. */
6298 if (it->selective > 0
6299 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6300 it->selective))
6301 continue;
6303 /* Check the newline before point for invisibility. */
6305 Lisp_Object prop;
6306 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6307 Qinvisible, it->window);
6308 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6309 continue;
6312 if (IT_CHARPOS (*it) <= BEGV)
6313 break;
6316 struct it it2;
6317 void *it2data = NULL;
6318 ptrdiff_t pos;
6319 ptrdiff_t beg, end;
6320 Lisp_Object val, overlay;
6322 SAVE_IT (it2, *it, it2data);
6324 /* If newline is part of a composition, continue from start of composition */
6325 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6326 && beg < IT_CHARPOS (*it))
6327 goto replaced;
6329 /* If newline is replaced by a display property, find start of overlay
6330 or interval and continue search from that point. */
6331 pos = --IT_CHARPOS (it2);
6332 --IT_BYTEPOS (it2);
6333 it2.sp = 0;
6334 bidi_unshelve_cache (NULL, 0);
6335 it2.string_from_display_prop_p = 0;
6336 it2.from_disp_prop_p = 0;
6337 if (handle_display_prop (&it2) == HANDLED_RETURN
6338 && !NILP (val = get_char_property_and_overlay
6339 (make_number (pos), Qdisplay, Qnil, &overlay))
6340 && (OVERLAYP (overlay)
6341 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6342 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6344 RESTORE_IT (it, it, it2data);
6345 goto replaced;
6348 /* Newline is not replaced by anything -- so we are done. */
6349 RESTORE_IT (it, it, it2data);
6350 break;
6352 replaced:
6353 if (beg < BEGV)
6354 beg = BEGV;
6355 IT_CHARPOS (*it) = beg;
6356 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6360 it->continuation_lines_width = 0;
6362 eassert (IT_CHARPOS (*it) >= BEGV);
6363 eassert (IT_CHARPOS (*it) == BEGV
6364 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6365 CHECK_IT (it);
6369 /* Reseat iterator IT at the previous visible line start. Skip
6370 invisible text that is so either due to text properties or due to
6371 selective display. At the end, update IT's overlay information,
6372 face information etc. */
6374 void
6375 reseat_at_previous_visible_line_start (struct it *it)
6377 back_to_previous_visible_line_start (it);
6378 reseat (it, it->current.pos, 1);
6379 CHECK_IT (it);
6383 /* Reseat iterator IT on the next visible line start in the current
6384 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6385 preceding the line start. Skip over invisible text that is so
6386 because of selective display. Compute faces, overlays etc at the
6387 new position. Note that this function does not skip over text that
6388 is invisible because of text properties. */
6390 static void
6391 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6393 int newline_found_p, skipped_p = 0;
6394 struct bidi_it bidi_it_prev;
6396 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6398 /* Skip over lines that are invisible because they are indented
6399 more than the value of IT->selective. */
6400 if (it->selective > 0)
6401 while (IT_CHARPOS (*it) < ZV
6402 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6403 it->selective))
6405 eassert (IT_BYTEPOS (*it) == BEGV
6406 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6407 newline_found_p =
6408 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6411 /* Position on the newline if that's what's requested. */
6412 if (on_newline_p && newline_found_p)
6414 if (STRINGP (it->string))
6416 if (IT_STRING_CHARPOS (*it) > 0)
6418 if (!it->bidi_p)
6420 --IT_STRING_CHARPOS (*it);
6421 --IT_STRING_BYTEPOS (*it);
6423 else
6425 /* We need to restore the bidi iterator to the state
6426 it had on the newline, and resync the IT's
6427 position with that. */
6428 it->bidi_it = bidi_it_prev;
6429 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6430 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6434 else if (IT_CHARPOS (*it) > BEGV)
6436 if (!it->bidi_p)
6438 --IT_CHARPOS (*it);
6439 --IT_BYTEPOS (*it);
6441 else
6443 /* We need to restore the bidi iterator to the state it
6444 had on the newline and resync IT with that. */
6445 it->bidi_it = bidi_it_prev;
6446 IT_CHARPOS (*it) = it->bidi_it.charpos;
6447 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6449 reseat (it, it->current.pos, 0);
6452 else if (skipped_p)
6453 reseat (it, it->current.pos, 0);
6455 CHECK_IT (it);
6460 /***********************************************************************
6461 Changing an iterator's position
6462 ***********************************************************************/
6464 /* Change IT's current position to POS in current_buffer. If FORCE_P
6465 is non-zero, always check for text properties at the new position.
6466 Otherwise, text properties are only looked up if POS >=
6467 IT->check_charpos of a property. */
6469 static void
6470 reseat (struct it *it, struct text_pos pos, int force_p)
6472 ptrdiff_t original_pos = IT_CHARPOS (*it);
6474 reseat_1 (it, pos, 0);
6476 /* Determine where to check text properties. Avoid doing it
6477 where possible because text property lookup is very expensive. */
6478 if (force_p
6479 || CHARPOS (pos) > it->stop_charpos
6480 || CHARPOS (pos) < original_pos)
6482 if (it->bidi_p)
6484 /* For bidi iteration, we need to prime prev_stop and
6485 base_level_stop with our best estimations. */
6486 /* Implementation note: Of course, POS is not necessarily a
6487 stop position, so assigning prev_pos to it is a lie; we
6488 should have called compute_stop_backwards. However, if
6489 the current buffer does not include any R2L characters,
6490 that call would be a waste of cycles, because the
6491 iterator will never move back, and thus never cross this
6492 "fake" stop position. So we delay that backward search
6493 until the time we really need it, in next_element_from_buffer. */
6494 if (CHARPOS (pos) != it->prev_stop)
6495 it->prev_stop = CHARPOS (pos);
6496 if (CHARPOS (pos) < it->base_level_stop)
6497 it->base_level_stop = 0; /* meaning it's unknown */
6498 handle_stop (it);
6500 else
6502 handle_stop (it);
6503 it->prev_stop = it->base_level_stop = 0;
6508 CHECK_IT (it);
6512 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6513 IT->stop_pos to POS, also. */
6515 static void
6516 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6518 /* Don't call this function when scanning a C string. */
6519 eassert (it->s == NULL);
6521 /* POS must be a reasonable value. */
6522 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6524 it->current.pos = it->position = pos;
6525 it->end_charpos = ZV;
6526 it->dpvec = NULL;
6527 it->current.dpvec_index = -1;
6528 it->current.overlay_string_index = -1;
6529 IT_STRING_CHARPOS (*it) = -1;
6530 IT_STRING_BYTEPOS (*it) = -1;
6531 it->string = Qnil;
6532 it->method = GET_FROM_BUFFER;
6533 it->object = it->w->contents;
6534 it->area = TEXT_AREA;
6535 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6536 it->sp = 0;
6537 it->string_from_display_prop_p = 0;
6538 it->string_from_prefix_prop_p = 0;
6540 it->from_disp_prop_p = 0;
6541 it->face_before_selective_p = 0;
6542 if (it->bidi_p)
6544 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6545 &it->bidi_it);
6546 bidi_unshelve_cache (NULL, 0);
6547 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6548 it->bidi_it.string.s = NULL;
6549 it->bidi_it.string.lstring = Qnil;
6550 it->bidi_it.string.bufpos = 0;
6551 it->bidi_it.string.from_disp_str = 0;
6552 it->bidi_it.string.unibyte = 0;
6553 it->bidi_it.w = it->w;
6556 if (set_stop_p)
6558 it->stop_charpos = CHARPOS (pos);
6559 it->base_level_stop = CHARPOS (pos);
6561 /* This make the information stored in it->cmp_it invalidate. */
6562 it->cmp_it.id = -1;
6566 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6567 If S is non-null, it is a C string to iterate over. Otherwise,
6568 STRING gives a Lisp string to iterate over.
6570 If PRECISION > 0, don't return more then PRECISION number of
6571 characters from the string.
6573 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6574 characters have been returned. FIELD_WIDTH < 0 means an infinite
6575 field width.
6577 MULTIBYTE = 0 means disable processing of multibyte characters,
6578 MULTIBYTE > 0 means enable it,
6579 MULTIBYTE < 0 means use IT->multibyte_p.
6581 IT must be initialized via a prior call to init_iterator before
6582 calling this function. */
6584 static void
6585 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6586 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6587 int multibyte)
6589 /* No text property checks performed by default, but see below. */
6590 it->stop_charpos = -1;
6592 /* Set iterator position and end position. */
6593 memset (&it->current, 0, sizeof it->current);
6594 it->current.overlay_string_index = -1;
6595 it->current.dpvec_index = -1;
6596 eassert (charpos >= 0);
6598 /* If STRING is specified, use its multibyteness, otherwise use the
6599 setting of MULTIBYTE, if specified. */
6600 if (multibyte >= 0)
6601 it->multibyte_p = multibyte > 0;
6603 /* Bidirectional reordering of strings is controlled by the default
6604 value of bidi-display-reordering. Don't try to reorder while
6605 loading loadup.el, as the necessary character property tables are
6606 not yet available. */
6607 it->bidi_p =
6608 NILP (Vpurify_flag)
6609 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6611 if (s == NULL)
6613 eassert (STRINGP (string));
6614 it->string = string;
6615 it->s = NULL;
6616 it->end_charpos = it->string_nchars = SCHARS (string);
6617 it->method = GET_FROM_STRING;
6618 it->current.string_pos = string_pos (charpos, string);
6620 if (it->bidi_p)
6622 it->bidi_it.string.lstring = string;
6623 it->bidi_it.string.s = NULL;
6624 it->bidi_it.string.schars = it->end_charpos;
6625 it->bidi_it.string.bufpos = 0;
6626 it->bidi_it.string.from_disp_str = 0;
6627 it->bidi_it.string.unibyte = !it->multibyte_p;
6628 it->bidi_it.w = it->w;
6629 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6630 FRAME_WINDOW_P (it->f), &it->bidi_it);
6633 else
6635 it->s = (const unsigned char *) s;
6636 it->string = Qnil;
6638 /* Note that we use IT->current.pos, not it->current.string_pos,
6639 for displaying C strings. */
6640 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6641 if (it->multibyte_p)
6643 it->current.pos = c_string_pos (charpos, s, 1);
6644 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6646 else
6648 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6649 it->end_charpos = it->string_nchars = strlen (s);
6652 if (it->bidi_p)
6654 it->bidi_it.string.lstring = Qnil;
6655 it->bidi_it.string.s = (const unsigned char *) s;
6656 it->bidi_it.string.schars = it->end_charpos;
6657 it->bidi_it.string.bufpos = 0;
6658 it->bidi_it.string.from_disp_str = 0;
6659 it->bidi_it.string.unibyte = !it->multibyte_p;
6660 it->bidi_it.w = it->w;
6661 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6662 &it->bidi_it);
6664 it->method = GET_FROM_C_STRING;
6667 /* PRECISION > 0 means don't return more than PRECISION characters
6668 from the string. */
6669 if (precision > 0 && it->end_charpos - charpos > precision)
6671 it->end_charpos = it->string_nchars = charpos + precision;
6672 if (it->bidi_p)
6673 it->bidi_it.string.schars = it->end_charpos;
6676 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6677 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6678 FIELD_WIDTH < 0 means infinite field width. This is useful for
6679 padding with `-' at the end of a mode line. */
6680 if (field_width < 0)
6681 field_width = INFINITY;
6682 /* Implementation note: We deliberately don't enlarge
6683 it->bidi_it.string.schars here to fit it->end_charpos, because
6684 the bidi iterator cannot produce characters out of thin air. */
6685 if (field_width > it->end_charpos - charpos)
6686 it->end_charpos = charpos + field_width;
6688 /* Use the standard display table for displaying strings. */
6689 if (DISP_TABLE_P (Vstandard_display_table))
6690 it->dp = XCHAR_TABLE (Vstandard_display_table);
6692 it->stop_charpos = charpos;
6693 it->prev_stop = charpos;
6694 it->base_level_stop = 0;
6695 if (it->bidi_p)
6697 it->bidi_it.first_elt = 1;
6698 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6699 it->bidi_it.disp_pos = -1;
6701 if (s == NULL && it->multibyte_p)
6703 ptrdiff_t endpos = SCHARS (it->string);
6704 if (endpos > it->end_charpos)
6705 endpos = it->end_charpos;
6706 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6707 it->string);
6709 CHECK_IT (it);
6714 /***********************************************************************
6715 Iteration
6716 ***********************************************************************/
6718 /* Map enum it_method value to corresponding next_element_from_* function. */
6720 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6722 next_element_from_buffer,
6723 next_element_from_display_vector,
6724 next_element_from_string,
6725 next_element_from_c_string,
6726 next_element_from_image,
6727 next_element_from_stretch
6730 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6733 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6734 (possibly with the following characters). */
6736 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6737 ((IT)->cmp_it.id >= 0 \
6738 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6739 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6740 END_CHARPOS, (IT)->w, \
6741 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6742 (IT)->string)))
6745 /* Lookup the char-table Vglyphless_char_display for character C (-1
6746 if we want information for no-font case), and return the display
6747 method symbol. By side-effect, update it->what and
6748 it->glyphless_method. This function is called from
6749 get_next_display_element for each character element, and from
6750 x_produce_glyphs when no suitable font was found. */
6752 Lisp_Object
6753 lookup_glyphless_char_display (int c, struct it *it)
6755 Lisp_Object glyphless_method = Qnil;
6757 if (CHAR_TABLE_P (Vglyphless_char_display)
6758 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6760 if (c >= 0)
6762 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6763 if (CONSP (glyphless_method))
6764 glyphless_method = FRAME_WINDOW_P (it->f)
6765 ? XCAR (glyphless_method)
6766 : XCDR (glyphless_method);
6768 else
6769 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6772 retry:
6773 if (NILP (glyphless_method))
6775 if (c >= 0)
6776 /* The default is to display the character by a proper font. */
6777 return Qnil;
6778 /* The default for the no-font case is to display an empty box. */
6779 glyphless_method = Qempty_box;
6781 if (EQ (glyphless_method, Qzero_width))
6783 if (c >= 0)
6784 return glyphless_method;
6785 /* This method can't be used for the no-font case. */
6786 glyphless_method = Qempty_box;
6788 if (EQ (glyphless_method, Qthin_space))
6789 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6790 else if (EQ (glyphless_method, Qempty_box))
6791 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6792 else if (EQ (glyphless_method, Qhex_code))
6793 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6794 else if (STRINGP (glyphless_method))
6795 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6796 else
6798 /* Invalid value. We use the default method. */
6799 glyphless_method = Qnil;
6800 goto retry;
6802 it->what = IT_GLYPHLESS;
6803 return glyphless_method;
6806 /* Merge escape glyph face and cache the result. */
6808 static struct frame *last_escape_glyph_frame = NULL;
6809 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6810 static int last_escape_glyph_merged_face_id = 0;
6812 static int
6813 merge_escape_glyph_face (struct it *it)
6815 int face_id;
6817 if (it->f == last_escape_glyph_frame
6818 && it->face_id == last_escape_glyph_face_id)
6819 face_id = last_escape_glyph_merged_face_id;
6820 else
6822 /* Merge the `escape-glyph' face into the current face. */
6823 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6824 last_escape_glyph_frame = it->f;
6825 last_escape_glyph_face_id = it->face_id;
6826 last_escape_glyph_merged_face_id = face_id;
6828 return face_id;
6831 /* Likewise for glyphless glyph face. */
6833 static struct frame *last_glyphless_glyph_frame = NULL;
6834 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6835 static int last_glyphless_glyph_merged_face_id = 0;
6838 merge_glyphless_glyph_face (struct it *it)
6840 int face_id;
6842 if (it->f == last_glyphless_glyph_frame
6843 && it->face_id == last_glyphless_glyph_face_id)
6844 face_id = last_glyphless_glyph_merged_face_id;
6845 else
6847 /* Merge the `glyphless-char' face into the current face. */
6848 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6849 last_glyphless_glyph_frame = it->f;
6850 last_glyphless_glyph_face_id = it->face_id;
6851 last_glyphless_glyph_merged_face_id = face_id;
6853 return face_id;
6856 /* Load IT's display element fields with information about the next
6857 display element from the current position of IT. Value is zero if
6858 end of buffer (or C string) is reached. */
6860 static int
6861 get_next_display_element (struct it *it)
6863 /* Non-zero means that we found a display element. Zero means that
6864 we hit the end of what we iterate over. Performance note: the
6865 function pointer `method' used here turns out to be faster than
6866 using a sequence of if-statements. */
6867 int success_p;
6869 get_next:
6870 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6872 if (it->what == IT_CHARACTER)
6874 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6875 and only if (a) the resolved directionality of that character
6876 is R..." */
6877 /* FIXME: Do we need an exception for characters from display
6878 tables? */
6879 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6880 it->c = bidi_mirror_char (it->c);
6881 /* Map via display table or translate control characters.
6882 IT->c, IT->len etc. have been set to the next character by
6883 the function call above. If we have a display table, and it
6884 contains an entry for IT->c, translate it. Don't do this if
6885 IT->c itself comes from a display table, otherwise we could
6886 end up in an infinite recursion. (An alternative could be to
6887 count the recursion depth of this function and signal an
6888 error when a certain maximum depth is reached.) Is it worth
6889 it? */
6890 if (success_p && it->dpvec == NULL)
6892 Lisp_Object dv;
6893 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6894 int nonascii_space_p = 0;
6895 int nonascii_hyphen_p = 0;
6896 int c = it->c; /* This is the character to display. */
6898 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6900 eassert (SINGLE_BYTE_CHAR_P (c));
6901 if (unibyte_display_via_language_environment)
6903 c = DECODE_CHAR (unibyte, c);
6904 if (c < 0)
6905 c = BYTE8_TO_CHAR (it->c);
6907 else
6908 c = BYTE8_TO_CHAR (it->c);
6911 if (it->dp
6912 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6913 VECTORP (dv)))
6915 struct Lisp_Vector *v = XVECTOR (dv);
6917 /* Return the first character from the display table
6918 entry, if not empty. If empty, don't display the
6919 current character. */
6920 if (v->header.size)
6922 it->dpvec_char_len = it->len;
6923 it->dpvec = v->contents;
6924 it->dpend = v->contents + v->header.size;
6925 it->current.dpvec_index = 0;
6926 it->dpvec_face_id = -1;
6927 it->saved_face_id = it->face_id;
6928 it->method = GET_FROM_DISPLAY_VECTOR;
6929 it->ellipsis_p = 0;
6931 else
6933 set_iterator_to_next (it, 0);
6935 goto get_next;
6938 if (! NILP (lookup_glyphless_char_display (c, it)))
6940 if (it->what == IT_GLYPHLESS)
6941 goto done;
6942 /* Don't display this character. */
6943 set_iterator_to_next (it, 0);
6944 goto get_next;
6947 /* If `nobreak-char-display' is non-nil, we display
6948 non-ASCII spaces and hyphens specially. */
6949 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6951 if (c == 0xA0)
6952 nonascii_space_p = true;
6953 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6954 nonascii_hyphen_p = true;
6957 /* Translate control characters into `\003' or `^C' form.
6958 Control characters coming from a display table entry are
6959 currently not translated because we use IT->dpvec to hold
6960 the translation. This could easily be changed but I
6961 don't believe that it is worth doing.
6963 The characters handled by `nobreak-char-display' must be
6964 translated too.
6966 Non-printable characters and raw-byte characters are also
6967 translated to octal form. */
6968 if (((c < ' ' || c == 127) /* ASCII control chars. */
6969 ? (it->area != TEXT_AREA
6970 /* In mode line, treat \n, \t like other crl chars. */
6971 || (c != '\t'
6972 && it->glyph_row
6973 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6974 || (c != '\n' && c != '\t'))
6975 : (nonascii_space_p
6976 || nonascii_hyphen_p
6977 || CHAR_BYTE8_P (c)
6978 || ! CHAR_PRINTABLE_P (c))))
6980 /* C is a control character, non-ASCII space/hyphen,
6981 raw-byte, or a non-printable character which must be
6982 displayed either as '\003' or as `^C' where the '\\'
6983 and '^' can be defined in the display table. Fill
6984 IT->ctl_chars with glyphs for what we have to
6985 display. Then, set IT->dpvec to these glyphs. */
6986 Lisp_Object gc;
6987 int ctl_len;
6988 int face_id;
6989 int lface_id = 0;
6990 int escape_glyph;
6992 /* Handle control characters with ^. */
6994 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6996 int g;
6998 g = '^'; /* default glyph for Control */
6999 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7000 if (it->dp
7001 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7003 g = GLYPH_CODE_CHAR (gc);
7004 lface_id = GLYPH_CODE_FACE (gc);
7007 face_id = (lface_id
7008 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7009 : merge_escape_glyph_face (it));
7011 XSETINT (it->ctl_chars[0], g);
7012 XSETINT (it->ctl_chars[1], c ^ 0100);
7013 ctl_len = 2;
7014 goto display_control;
7017 /* Handle non-ascii space in the mode where it only gets
7018 highlighting. */
7020 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7022 /* Merge `nobreak-space' into the current face. */
7023 face_id = merge_faces (it->f, Qnobreak_space, 0,
7024 it->face_id);
7025 XSETINT (it->ctl_chars[0], ' ');
7026 ctl_len = 1;
7027 goto display_control;
7030 /* Handle sequences that start with the "escape glyph". */
7032 /* the default escape glyph is \. */
7033 escape_glyph = '\\';
7035 if (it->dp
7036 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7038 escape_glyph = GLYPH_CODE_CHAR (gc);
7039 lface_id = GLYPH_CODE_FACE (gc);
7042 face_id = (lface_id
7043 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7044 : merge_escape_glyph_face (it));
7046 /* Draw non-ASCII hyphen with just highlighting: */
7048 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7050 XSETINT (it->ctl_chars[0], '-');
7051 ctl_len = 1;
7052 goto display_control;
7055 /* Draw non-ASCII space/hyphen with escape glyph: */
7057 if (nonascii_space_p || nonascii_hyphen_p)
7059 XSETINT (it->ctl_chars[0], escape_glyph);
7060 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7061 ctl_len = 2;
7062 goto display_control;
7066 char str[10];
7067 int len, i;
7069 if (CHAR_BYTE8_P (c))
7070 /* Display \200 instead of \17777600. */
7071 c = CHAR_TO_BYTE8 (c);
7072 len = sprintf (str, "%03o", c);
7074 XSETINT (it->ctl_chars[0], escape_glyph);
7075 for (i = 0; i < len; i++)
7076 XSETINT (it->ctl_chars[i + 1], str[i]);
7077 ctl_len = len + 1;
7080 display_control:
7081 /* Set up IT->dpvec and return first character from it. */
7082 it->dpvec_char_len = it->len;
7083 it->dpvec = it->ctl_chars;
7084 it->dpend = it->dpvec + ctl_len;
7085 it->current.dpvec_index = 0;
7086 it->dpvec_face_id = face_id;
7087 it->saved_face_id = it->face_id;
7088 it->method = GET_FROM_DISPLAY_VECTOR;
7089 it->ellipsis_p = 0;
7090 goto get_next;
7092 it->char_to_display = c;
7094 else if (success_p)
7096 it->char_to_display = it->c;
7100 #ifdef HAVE_WINDOW_SYSTEM
7101 /* Adjust face id for a multibyte character. There are no multibyte
7102 character in unibyte text. */
7103 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7104 && it->multibyte_p
7105 && success_p
7106 && FRAME_WINDOW_P (it->f))
7108 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7110 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7112 /* Automatic composition with glyph-string. */
7113 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7115 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7117 else
7119 ptrdiff_t pos = (it->s ? -1
7120 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7121 : IT_CHARPOS (*it));
7122 int c;
7124 if (it->what == IT_CHARACTER)
7125 c = it->char_to_display;
7126 else
7128 struct composition *cmp = composition_table[it->cmp_it.id];
7129 int i;
7131 c = ' ';
7132 for (i = 0; i < cmp->glyph_len; i++)
7133 /* TAB in a composition means display glyphs with
7134 padding space on the left or right. */
7135 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7136 break;
7138 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7141 #endif /* HAVE_WINDOW_SYSTEM */
7143 done:
7144 /* Is this character the last one of a run of characters with
7145 box? If yes, set IT->end_of_box_run_p to 1. */
7146 if (it->face_box_p
7147 && it->s == NULL)
7149 if (it->method == GET_FROM_STRING && it->sp)
7151 int face_id = underlying_face_id (it);
7152 struct face *face = FACE_FROM_ID (it->f, face_id);
7154 if (face)
7156 if (face->box == FACE_NO_BOX)
7158 /* If the box comes from face properties in a
7159 display string, check faces in that string. */
7160 int string_face_id = face_after_it_pos (it);
7161 it->end_of_box_run_p
7162 = (FACE_FROM_ID (it->f, string_face_id)->box
7163 == FACE_NO_BOX);
7165 /* Otherwise, the box comes from the underlying face.
7166 If this is the last string character displayed, check
7167 the next buffer location. */
7168 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7169 /* n_overlay_strings is unreliable unless
7170 overlay_string_index is non-negative. */
7171 && ((it->current.overlay_string_index >= 0
7172 && (it->current.overlay_string_index
7173 == it->n_overlay_strings - 1))
7174 /* A string from display property. */
7175 || it->from_disp_prop_p))
7177 ptrdiff_t ignore;
7178 int next_face_id;
7179 struct text_pos pos = it->current.pos;
7181 /* For a string from a display property, the next
7182 buffer position is stored in the 'position'
7183 member of the iteration stack slot below the
7184 current one, see handle_single_display_spec. By
7185 contrast, it->current.pos was is not yet updated
7186 to point to that buffer position; that will
7187 happen in pop_it, after we finish displaying the
7188 current string. Note that we already checked
7189 above that it->sp is positive, so subtracting one
7190 from it is safe. */
7191 if (it->from_disp_prop_p)
7192 pos = (it->stack + it->sp - 1)->position;
7193 else
7194 INC_TEXT_POS (pos, it->multibyte_p);
7196 if (CHARPOS (pos) >= ZV)
7197 it->end_of_box_run_p = true;
7198 else
7200 next_face_id = face_at_buffer_position
7201 (it->w, CHARPOS (pos), &ignore,
7202 CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1);
7203 it->end_of_box_run_p
7204 = (FACE_FROM_ID (it->f, next_face_id)->box
7205 == FACE_NO_BOX);
7210 /* next_element_from_display_vector sets this flag according to
7211 faces of the display vector glyphs, see there. */
7212 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7214 int face_id = face_after_it_pos (it);
7215 it->end_of_box_run_p
7216 = (face_id != it->face_id
7217 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7220 /* If we reached the end of the object we've been iterating (e.g., a
7221 display string or an overlay string), and there's something on
7222 IT->stack, proceed with what's on the stack. It doesn't make
7223 sense to return zero if there's unprocessed stuff on the stack,
7224 because otherwise that stuff will never be displayed. */
7225 if (!success_p && it->sp > 0)
7227 set_iterator_to_next (it, 0);
7228 success_p = get_next_display_element (it);
7231 /* Value is 0 if end of buffer or string reached. */
7232 return success_p;
7236 /* Move IT to the next display element.
7238 RESEAT_P non-zero means if called on a newline in buffer text,
7239 skip to the next visible line start.
7241 Functions get_next_display_element and set_iterator_to_next are
7242 separate because I find this arrangement easier to handle than a
7243 get_next_display_element function that also increments IT's
7244 position. The way it is we can first look at an iterator's current
7245 display element, decide whether it fits on a line, and if it does,
7246 increment the iterator position. The other way around we probably
7247 would either need a flag indicating whether the iterator has to be
7248 incremented the next time, or we would have to implement a
7249 decrement position function which would not be easy to write. */
7251 void
7252 set_iterator_to_next (struct it *it, int reseat_p)
7254 /* Reset flags indicating start and end of a sequence of characters
7255 with box. Reset them at the start of this function because
7256 moving the iterator to a new position might set them. */
7257 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7259 switch (it->method)
7261 case GET_FROM_BUFFER:
7262 /* The current display element of IT is a character from
7263 current_buffer. Advance in the buffer, and maybe skip over
7264 invisible lines that are so because of selective display. */
7265 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7266 reseat_at_next_visible_line_start (it, 0);
7267 else if (it->cmp_it.id >= 0)
7269 /* We are currently getting glyphs from a composition. */
7270 int i;
7272 if (! it->bidi_p)
7274 IT_CHARPOS (*it) += it->cmp_it.nchars;
7275 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7276 if (it->cmp_it.to < it->cmp_it.nglyphs)
7278 it->cmp_it.from = it->cmp_it.to;
7280 else
7282 it->cmp_it.id = -1;
7283 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7284 IT_BYTEPOS (*it),
7285 it->end_charpos, Qnil);
7288 else if (! it->cmp_it.reversed_p)
7290 /* Composition created while scanning forward. */
7291 /* Update IT's char/byte positions to point to the first
7292 character of the next grapheme cluster, or to the
7293 character visually after the current composition. */
7294 for (i = 0; i < it->cmp_it.nchars; i++)
7295 bidi_move_to_visually_next (&it->bidi_it);
7296 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7297 IT_CHARPOS (*it) = it->bidi_it.charpos;
7299 if (it->cmp_it.to < it->cmp_it.nglyphs)
7301 /* Proceed to the next grapheme cluster. */
7302 it->cmp_it.from = it->cmp_it.to;
7304 else
7306 /* No more grapheme clusters in this composition.
7307 Find the next stop position. */
7308 ptrdiff_t stop = it->end_charpos;
7309 if (it->bidi_it.scan_dir < 0)
7310 /* Now we are scanning backward and don't know
7311 where to stop. */
7312 stop = -1;
7313 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7314 IT_BYTEPOS (*it), stop, Qnil);
7317 else
7319 /* Composition created while scanning backward. */
7320 /* Update IT's char/byte positions to point to the last
7321 character of the previous grapheme cluster, or the
7322 character visually after the current composition. */
7323 for (i = 0; i < it->cmp_it.nchars; i++)
7324 bidi_move_to_visually_next (&it->bidi_it);
7325 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7326 IT_CHARPOS (*it) = it->bidi_it.charpos;
7327 if (it->cmp_it.from > 0)
7329 /* Proceed to the previous grapheme cluster. */
7330 it->cmp_it.to = it->cmp_it.from;
7332 else
7334 /* No more grapheme clusters in this composition.
7335 Find the next stop position. */
7336 ptrdiff_t stop = it->end_charpos;
7337 if (it->bidi_it.scan_dir < 0)
7338 /* Now we are scanning backward and don't know
7339 where to stop. */
7340 stop = -1;
7341 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7342 IT_BYTEPOS (*it), stop, Qnil);
7346 else
7348 eassert (it->len != 0);
7350 if (!it->bidi_p)
7352 IT_BYTEPOS (*it) += it->len;
7353 IT_CHARPOS (*it) += 1;
7355 else
7357 int prev_scan_dir = it->bidi_it.scan_dir;
7358 /* If this is a new paragraph, determine its base
7359 direction (a.k.a. its base embedding level). */
7360 if (it->bidi_it.new_paragraph)
7361 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7362 bidi_move_to_visually_next (&it->bidi_it);
7363 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7364 IT_CHARPOS (*it) = it->bidi_it.charpos;
7365 if (prev_scan_dir != it->bidi_it.scan_dir)
7367 /* As the scan direction was changed, we must
7368 re-compute the stop position for composition. */
7369 ptrdiff_t stop = it->end_charpos;
7370 if (it->bidi_it.scan_dir < 0)
7371 stop = -1;
7372 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7373 IT_BYTEPOS (*it), stop, Qnil);
7376 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7378 break;
7380 case GET_FROM_C_STRING:
7381 /* Current display element of IT is from a C string. */
7382 if (!it->bidi_p
7383 /* If the string position is beyond string's end, it means
7384 next_element_from_c_string is padding the string with
7385 blanks, in which case we bypass the bidi iterator,
7386 because it cannot deal with such virtual characters. */
7387 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7389 IT_BYTEPOS (*it) += it->len;
7390 IT_CHARPOS (*it) += 1;
7392 else
7394 bidi_move_to_visually_next (&it->bidi_it);
7395 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7396 IT_CHARPOS (*it) = it->bidi_it.charpos;
7398 break;
7400 case GET_FROM_DISPLAY_VECTOR:
7401 /* Current display element of IT is from a display table entry.
7402 Advance in the display table definition. Reset it to null if
7403 end reached, and continue with characters from buffers/
7404 strings. */
7405 ++it->current.dpvec_index;
7407 /* Restore face of the iterator to what they were before the
7408 display vector entry (these entries may contain faces). */
7409 it->face_id = it->saved_face_id;
7411 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7413 int recheck_faces = it->ellipsis_p;
7415 if (it->s)
7416 it->method = GET_FROM_C_STRING;
7417 else if (STRINGP (it->string))
7418 it->method = GET_FROM_STRING;
7419 else
7421 it->method = GET_FROM_BUFFER;
7422 it->object = it->w->contents;
7425 it->dpvec = NULL;
7426 it->current.dpvec_index = -1;
7428 /* Skip over characters which were displayed via IT->dpvec. */
7429 if (it->dpvec_char_len < 0)
7430 reseat_at_next_visible_line_start (it, 1);
7431 else if (it->dpvec_char_len > 0)
7433 if (it->method == GET_FROM_STRING
7434 && it->current.overlay_string_index >= 0
7435 && it->n_overlay_strings > 0)
7436 it->ignore_overlay_strings_at_pos_p = true;
7437 it->len = it->dpvec_char_len;
7438 set_iterator_to_next (it, reseat_p);
7441 /* Maybe recheck faces after display vector. */
7442 if (recheck_faces)
7443 it->stop_charpos = IT_CHARPOS (*it);
7445 break;
7447 case GET_FROM_STRING:
7448 /* Current display element is a character from a Lisp string. */
7449 eassert (it->s == NULL && STRINGP (it->string));
7450 /* Don't advance past string end. These conditions are true
7451 when set_iterator_to_next is called at the end of
7452 get_next_display_element, in which case the Lisp string is
7453 already exhausted, and all we want is pop the iterator
7454 stack. */
7455 if (it->current.overlay_string_index >= 0)
7457 /* This is an overlay string, so there's no padding with
7458 spaces, and the number of characters in the string is
7459 where the string ends. */
7460 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7461 goto consider_string_end;
7463 else
7465 /* Not an overlay string. There could be padding, so test
7466 against it->end_charpos. */
7467 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7468 goto consider_string_end;
7470 if (it->cmp_it.id >= 0)
7472 int i;
7474 if (! it->bidi_p)
7476 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7477 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7478 if (it->cmp_it.to < it->cmp_it.nglyphs)
7479 it->cmp_it.from = it->cmp_it.to;
7480 else
7482 it->cmp_it.id = -1;
7483 composition_compute_stop_pos (&it->cmp_it,
7484 IT_STRING_CHARPOS (*it),
7485 IT_STRING_BYTEPOS (*it),
7486 it->end_charpos, it->string);
7489 else if (! it->cmp_it.reversed_p)
7491 for (i = 0; i < it->cmp_it.nchars; i++)
7492 bidi_move_to_visually_next (&it->bidi_it);
7493 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7494 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7496 if (it->cmp_it.to < it->cmp_it.nglyphs)
7497 it->cmp_it.from = it->cmp_it.to;
7498 else
7500 ptrdiff_t stop = it->end_charpos;
7501 if (it->bidi_it.scan_dir < 0)
7502 stop = -1;
7503 composition_compute_stop_pos (&it->cmp_it,
7504 IT_STRING_CHARPOS (*it),
7505 IT_STRING_BYTEPOS (*it), stop,
7506 it->string);
7509 else
7511 for (i = 0; i < it->cmp_it.nchars; i++)
7512 bidi_move_to_visually_next (&it->bidi_it);
7513 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7514 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7515 if (it->cmp_it.from > 0)
7516 it->cmp_it.to = it->cmp_it.from;
7517 else
7519 ptrdiff_t stop = it->end_charpos;
7520 if (it->bidi_it.scan_dir < 0)
7521 stop = -1;
7522 composition_compute_stop_pos (&it->cmp_it,
7523 IT_STRING_CHARPOS (*it),
7524 IT_STRING_BYTEPOS (*it), stop,
7525 it->string);
7529 else
7531 if (!it->bidi_p
7532 /* If the string position is beyond string's end, it
7533 means next_element_from_string is padding the string
7534 with blanks, in which case we bypass the bidi
7535 iterator, because it cannot deal with such virtual
7536 characters. */
7537 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7539 IT_STRING_BYTEPOS (*it) += it->len;
7540 IT_STRING_CHARPOS (*it) += 1;
7542 else
7544 int prev_scan_dir = it->bidi_it.scan_dir;
7546 bidi_move_to_visually_next (&it->bidi_it);
7547 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7548 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7549 if (prev_scan_dir != it->bidi_it.scan_dir)
7551 ptrdiff_t stop = it->end_charpos;
7553 if (it->bidi_it.scan_dir < 0)
7554 stop = -1;
7555 composition_compute_stop_pos (&it->cmp_it,
7556 IT_STRING_CHARPOS (*it),
7557 IT_STRING_BYTEPOS (*it), stop,
7558 it->string);
7563 consider_string_end:
7565 if (it->current.overlay_string_index >= 0)
7567 /* IT->string is an overlay string. Advance to the
7568 next, if there is one. */
7569 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7571 it->ellipsis_p = 0;
7572 next_overlay_string (it);
7573 if (it->ellipsis_p)
7574 setup_for_ellipsis (it, 0);
7577 else
7579 /* IT->string is not an overlay string. If we reached
7580 its end, and there is something on IT->stack, proceed
7581 with what is on the stack. This can be either another
7582 string, this time an overlay string, or a buffer. */
7583 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7584 && it->sp > 0)
7586 pop_it (it);
7587 if (it->method == GET_FROM_STRING)
7588 goto consider_string_end;
7591 break;
7593 case GET_FROM_IMAGE:
7594 case GET_FROM_STRETCH:
7595 /* The position etc with which we have to proceed are on
7596 the stack. The position may be at the end of a string,
7597 if the `display' property takes up the whole string. */
7598 eassert (it->sp > 0);
7599 pop_it (it);
7600 if (it->method == GET_FROM_STRING)
7601 goto consider_string_end;
7602 break;
7604 default:
7605 /* There are no other methods defined, so this should be a bug. */
7606 emacs_abort ();
7609 eassert (it->method != GET_FROM_STRING
7610 || (STRINGP (it->string)
7611 && IT_STRING_CHARPOS (*it) >= 0));
7614 /* Load IT's display element fields with information about the next
7615 display element which comes from a display table entry or from the
7616 result of translating a control character to one of the forms `^C'
7617 or `\003'.
7619 IT->dpvec holds the glyphs to return as characters.
7620 IT->saved_face_id holds the face id before the display vector--it
7621 is restored into IT->face_id in set_iterator_to_next. */
7623 static int
7624 next_element_from_display_vector (struct it *it)
7626 Lisp_Object gc;
7627 int prev_face_id = it->face_id;
7628 int next_face_id;
7630 /* Precondition. */
7631 eassert (it->dpvec && it->current.dpvec_index >= 0);
7633 it->face_id = it->saved_face_id;
7635 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7636 That seemed totally bogus - so I changed it... */
7637 gc = it->dpvec[it->current.dpvec_index];
7639 if (GLYPH_CODE_P (gc))
7641 struct face *this_face, *prev_face, *next_face;
7643 it->c = GLYPH_CODE_CHAR (gc);
7644 it->len = CHAR_BYTES (it->c);
7646 /* The entry may contain a face id to use. Such a face id is
7647 the id of a Lisp face, not a realized face. A face id of
7648 zero means no face is specified. */
7649 if (it->dpvec_face_id >= 0)
7650 it->face_id = it->dpvec_face_id;
7651 else
7653 int lface_id = GLYPH_CODE_FACE (gc);
7654 if (lface_id > 0)
7655 it->face_id = merge_faces (it->f, Qt, lface_id,
7656 it->saved_face_id);
7659 /* Glyphs in the display vector could have the box face, so we
7660 need to set the related flags in the iterator, as
7661 appropriate. */
7662 this_face = FACE_FROM_ID (it->f, it->face_id);
7663 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7665 /* Is this character the first character of a box-face run? */
7666 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7667 && (!prev_face
7668 || prev_face->box == FACE_NO_BOX));
7670 /* For the last character of the box-face run, we need to look
7671 either at the next glyph from the display vector, or at the
7672 face we saw before the display vector. */
7673 next_face_id = it->saved_face_id;
7674 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7676 if (it->dpvec_face_id >= 0)
7677 next_face_id = it->dpvec_face_id;
7678 else
7680 int lface_id =
7681 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7683 if (lface_id > 0)
7684 next_face_id = merge_faces (it->f, Qt, lface_id,
7685 it->saved_face_id);
7688 next_face = FACE_FROM_ID (it->f, next_face_id);
7689 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7690 && (!next_face
7691 || next_face->box == FACE_NO_BOX));
7692 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7694 else
7695 /* Display table entry is invalid. Return a space. */
7696 it->c = ' ', it->len = 1;
7698 /* Don't change position and object of the iterator here. They are
7699 still the values of the character that had this display table
7700 entry or was translated, and that's what we want. */
7701 it->what = IT_CHARACTER;
7702 return 1;
7705 /* Get the first element of string/buffer in the visual order, after
7706 being reseated to a new position in a string or a buffer. */
7707 static void
7708 get_visually_first_element (struct it *it)
7710 int string_p = STRINGP (it->string) || it->s;
7711 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7712 ptrdiff_t bob = (string_p ? 0 : BEGV);
7714 if (STRINGP (it->string))
7716 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7717 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7719 else
7721 it->bidi_it.charpos = IT_CHARPOS (*it);
7722 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7725 if (it->bidi_it.charpos == eob)
7727 /* Nothing to do, but reset the FIRST_ELT flag, like
7728 bidi_paragraph_init does, because we are not going to
7729 call it. */
7730 it->bidi_it.first_elt = 0;
7732 else if (it->bidi_it.charpos == bob
7733 || (!string_p
7734 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7735 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7737 /* If we are at the beginning of a line/string, we can produce
7738 the next element right away. */
7739 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7740 bidi_move_to_visually_next (&it->bidi_it);
7742 else
7744 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7746 /* We need to prime the bidi iterator starting at the line's or
7747 string's beginning, before we will be able to produce the
7748 next element. */
7749 if (string_p)
7750 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7751 else
7752 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7753 IT_BYTEPOS (*it), -1,
7754 &it->bidi_it.bytepos);
7755 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7758 /* Now return to buffer/string position where we were asked
7759 to get the next display element, and produce that. */
7760 bidi_move_to_visually_next (&it->bidi_it);
7762 while (it->bidi_it.bytepos != orig_bytepos
7763 && it->bidi_it.charpos < eob);
7766 /* Adjust IT's position information to where we ended up. */
7767 if (STRINGP (it->string))
7769 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7770 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7772 else
7774 IT_CHARPOS (*it) = it->bidi_it.charpos;
7775 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7778 if (STRINGP (it->string) || !it->s)
7780 ptrdiff_t stop, charpos, bytepos;
7782 if (STRINGP (it->string))
7784 eassert (!it->s);
7785 stop = SCHARS (it->string);
7786 if (stop > it->end_charpos)
7787 stop = it->end_charpos;
7788 charpos = IT_STRING_CHARPOS (*it);
7789 bytepos = IT_STRING_BYTEPOS (*it);
7791 else
7793 stop = it->end_charpos;
7794 charpos = IT_CHARPOS (*it);
7795 bytepos = IT_BYTEPOS (*it);
7797 if (it->bidi_it.scan_dir < 0)
7798 stop = -1;
7799 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7800 it->string);
7804 /* Load IT with the next display element from Lisp string IT->string.
7805 IT->current.string_pos is the current position within the string.
7806 If IT->current.overlay_string_index >= 0, the Lisp string is an
7807 overlay string. */
7809 static int
7810 next_element_from_string (struct it *it)
7812 struct text_pos position;
7814 eassert (STRINGP (it->string));
7815 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7816 eassert (IT_STRING_CHARPOS (*it) >= 0);
7817 position = it->current.string_pos;
7819 /* With bidi reordering, the character to display might not be the
7820 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7821 that we were reseat()ed to a new string, whose paragraph
7822 direction is not known. */
7823 if (it->bidi_p && it->bidi_it.first_elt)
7825 get_visually_first_element (it);
7826 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7829 /* Time to check for invisible text? */
7830 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7832 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7834 if (!(!it->bidi_p
7835 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7836 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7838 /* With bidi non-linear iteration, we could find
7839 ourselves far beyond the last computed stop_charpos,
7840 with several other stop positions in between that we
7841 missed. Scan them all now, in buffer's logical
7842 order, until we find and handle the last stop_charpos
7843 that precedes our current position. */
7844 handle_stop_backwards (it, it->stop_charpos);
7845 return GET_NEXT_DISPLAY_ELEMENT (it);
7847 else
7849 if (it->bidi_p)
7851 /* Take note of the stop position we just moved
7852 across, for when we will move back across it. */
7853 it->prev_stop = it->stop_charpos;
7854 /* If we are at base paragraph embedding level, take
7855 note of the last stop position seen at this
7856 level. */
7857 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7858 it->base_level_stop = it->stop_charpos;
7860 handle_stop (it);
7862 /* Since a handler may have changed IT->method, we must
7863 recurse here. */
7864 return GET_NEXT_DISPLAY_ELEMENT (it);
7867 else if (it->bidi_p
7868 /* If we are before prev_stop, we may have overstepped
7869 on our way backwards a stop_pos, and if so, we need
7870 to handle that stop_pos. */
7871 && IT_STRING_CHARPOS (*it) < it->prev_stop
7872 /* We can sometimes back up for reasons that have nothing
7873 to do with bidi reordering. E.g., compositions. The
7874 code below is only needed when we are above the base
7875 embedding level, so test for that explicitly. */
7876 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7878 /* If we lost track of base_level_stop, we have no better
7879 place for handle_stop_backwards to start from than string
7880 beginning. This happens, e.g., when we were reseated to
7881 the previous screenful of text by vertical-motion. */
7882 if (it->base_level_stop <= 0
7883 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7884 it->base_level_stop = 0;
7885 handle_stop_backwards (it, it->base_level_stop);
7886 return GET_NEXT_DISPLAY_ELEMENT (it);
7890 if (it->current.overlay_string_index >= 0)
7892 /* Get the next character from an overlay string. In overlay
7893 strings, there is no field width or padding with spaces to
7894 do. */
7895 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7897 it->what = IT_EOB;
7898 return 0;
7900 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7901 IT_STRING_BYTEPOS (*it),
7902 it->bidi_it.scan_dir < 0
7903 ? -1
7904 : SCHARS (it->string))
7905 && next_element_from_composition (it))
7907 return 1;
7909 else if (STRING_MULTIBYTE (it->string))
7911 const unsigned char *s = (SDATA (it->string)
7912 + IT_STRING_BYTEPOS (*it));
7913 it->c = string_char_and_length (s, &it->len);
7915 else
7917 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7918 it->len = 1;
7921 else
7923 /* Get the next character from a Lisp string that is not an
7924 overlay string. Such strings come from the mode line, for
7925 example. We may have to pad with spaces, or truncate the
7926 string. See also next_element_from_c_string. */
7927 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7929 it->what = IT_EOB;
7930 return 0;
7932 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7934 /* Pad with spaces. */
7935 it->c = ' ', it->len = 1;
7936 CHARPOS (position) = BYTEPOS (position) = -1;
7938 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7939 IT_STRING_BYTEPOS (*it),
7940 it->bidi_it.scan_dir < 0
7941 ? -1
7942 : it->string_nchars)
7943 && next_element_from_composition (it))
7945 return 1;
7947 else if (STRING_MULTIBYTE (it->string))
7949 const unsigned char *s = (SDATA (it->string)
7950 + IT_STRING_BYTEPOS (*it));
7951 it->c = string_char_and_length (s, &it->len);
7953 else
7955 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7956 it->len = 1;
7960 /* Record what we have and where it came from. */
7961 it->what = IT_CHARACTER;
7962 it->object = it->string;
7963 it->position = position;
7964 return 1;
7968 /* Load IT with next display element from C string IT->s.
7969 IT->string_nchars is the maximum number of characters to return
7970 from the string. IT->end_charpos may be greater than
7971 IT->string_nchars when this function is called, in which case we
7972 may have to return padding spaces. Value is zero if end of string
7973 reached, including padding spaces. */
7975 static int
7976 next_element_from_c_string (struct it *it)
7978 bool success_p = true;
7980 eassert (it->s);
7981 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7982 it->what = IT_CHARACTER;
7983 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7984 it->object = Qnil;
7986 /* With bidi reordering, the character to display might not be the
7987 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7988 we were reseated to a new string, whose paragraph direction is
7989 not known. */
7990 if (it->bidi_p && it->bidi_it.first_elt)
7991 get_visually_first_element (it);
7993 /* IT's position can be greater than IT->string_nchars in case a
7994 field width or precision has been specified when the iterator was
7995 initialized. */
7996 if (IT_CHARPOS (*it) >= it->end_charpos)
7998 /* End of the game. */
7999 it->what = IT_EOB;
8000 success_p = 0;
8002 else if (IT_CHARPOS (*it) >= it->string_nchars)
8004 /* Pad with spaces. */
8005 it->c = ' ', it->len = 1;
8006 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8008 else if (it->multibyte_p)
8009 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8010 else
8011 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8013 return success_p;
8017 /* Set up IT to return characters from an ellipsis, if appropriate.
8018 The definition of the ellipsis glyphs may come from a display table
8019 entry. This function fills IT with the first glyph from the
8020 ellipsis if an ellipsis is to be displayed. */
8022 static int
8023 next_element_from_ellipsis (struct it *it)
8025 if (it->selective_display_ellipsis_p)
8026 setup_for_ellipsis (it, it->len);
8027 else
8029 /* The face at the current position may be different from the
8030 face we find after the invisible text. Remember what it
8031 was in IT->saved_face_id, and signal that it's there by
8032 setting face_before_selective_p. */
8033 it->saved_face_id = it->face_id;
8034 it->method = GET_FROM_BUFFER;
8035 it->object = it->w->contents;
8036 reseat_at_next_visible_line_start (it, 1);
8037 it->face_before_selective_p = true;
8040 return GET_NEXT_DISPLAY_ELEMENT (it);
8044 /* Deliver an image display element. The iterator IT is already
8045 filled with image information (done in handle_display_prop). Value
8046 is always 1. */
8049 static int
8050 next_element_from_image (struct it *it)
8052 it->what = IT_IMAGE;
8053 it->ignore_overlay_strings_at_pos_p = 0;
8054 return 1;
8058 /* Fill iterator IT with next display element from a stretch glyph
8059 property. IT->object is the value of the text property. Value is
8060 always 1. */
8062 static int
8063 next_element_from_stretch (struct it *it)
8065 it->what = IT_STRETCH;
8066 return 1;
8069 /* Scan backwards from IT's current position until we find a stop
8070 position, or until BEGV. This is called when we find ourself
8071 before both the last known prev_stop and base_level_stop while
8072 reordering bidirectional text. */
8074 static void
8075 compute_stop_pos_backwards (struct it *it)
8077 const int SCAN_BACK_LIMIT = 1000;
8078 struct text_pos pos;
8079 struct display_pos save_current = it->current;
8080 struct text_pos save_position = it->position;
8081 ptrdiff_t charpos = IT_CHARPOS (*it);
8082 ptrdiff_t where_we_are = charpos;
8083 ptrdiff_t save_stop_pos = it->stop_charpos;
8084 ptrdiff_t save_end_pos = it->end_charpos;
8086 eassert (NILP (it->string) && !it->s);
8087 eassert (it->bidi_p);
8088 it->bidi_p = 0;
8091 it->end_charpos = min (charpos + 1, ZV);
8092 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8093 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8094 reseat_1 (it, pos, 0);
8095 compute_stop_pos (it);
8096 /* We must advance forward, right? */
8097 if (it->stop_charpos <= charpos)
8098 emacs_abort ();
8100 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8102 if (it->stop_charpos <= where_we_are)
8103 it->prev_stop = it->stop_charpos;
8104 else
8105 it->prev_stop = BEGV;
8106 it->bidi_p = true;
8107 it->current = save_current;
8108 it->position = save_position;
8109 it->stop_charpos = save_stop_pos;
8110 it->end_charpos = save_end_pos;
8113 /* Scan forward from CHARPOS in the current buffer/string, until we
8114 find a stop position > current IT's position. Then handle the stop
8115 position before that. This is called when we bump into a stop
8116 position while reordering bidirectional text. CHARPOS should be
8117 the last previously processed stop_pos (or BEGV/0, if none were
8118 processed yet) whose position is less that IT's current
8119 position. */
8121 static void
8122 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8124 int bufp = !STRINGP (it->string);
8125 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8126 struct display_pos save_current = it->current;
8127 struct text_pos save_position = it->position;
8128 struct text_pos pos1;
8129 ptrdiff_t next_stop;
8131 /* Scan in strict logical order. */
8132 eassert (it->bidi_p);
8133 it->bidi_p = 0;
8136 it->prev_stop = charpos;
8137 if (bufp)
8139 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8140 reseat_1 (it, pos1, 0);
8142 else
8143 it->current.string_pos = string_pos (charpos, it->string);
8144 compute_stop_pos (it);
8145 /* We must advance forward, right? */
8146 if (it->stop_charpos <= it->prev_stop)
8147 emacs_abort ();
8148 charpos = it->stop_charpos;
8150 while (charpos <= where_we_are);
8152 it->bidi_p = true;
8153 it->current = save_current;
8154 it->position = save_position;
8155 next_stop = it->stop_charpos;
8156 it->stop_charpos = it->prev_stop;
8157 handle_stop (it);
8158 it->stop_charpos = next_stop;
8161 /* Load IT with the next display element from current_buffer. Value
8162 is zero if end of buffer reached. IT->stop_charpos is the next
8163 position at which to stop and check for text properties or buffer
8164 end. */
8166 static int
8167 next_element_from_buffer (struct it *it)
8169 bool success_p = true;
8171 eassert (IT_CHARPOS (*it) >= BEGV);
8172 eassert (NILP (it->string) && !it->s);
8173 eassert (!it->bidi_p
8174 || (EQ (it->bidi_it.string.lstring, Qnil)
8175 && it->bidi_it.string.s == NULL));
8177 /* With bidi reordering, the character to display might not be the
8178 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
8179 we were reseat()ed to a new buffer position, which is potentially
8180 a different paragraph. */
8181 if (it->bidi_p && it->bidi_it.first_elt)
8183 get_visually_first_element (it);
8184 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8187 if (IT_CHARPOS (*it) >= it->stop_charpos)
8189 if (IT_CHARPOS (*it) >= it->end_charpos)
8191 int overlay_strings_follow_p;
8193 /* End of the game, except when overlay strings follow that
8194 haven't been returned yet. */
8195 if (it->overlay_strings_at_end_processed_p)
8196 overlay_strings_follow_p = 0;
8197 else
8199 it->overlay_strings_at_end_processed_p = true;
8200 overlay_strings_follow_p = get_overlay_strings (it, 0);
8203 if (overlay_strings_follow_p)
8204 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8205 else
8207 it->what = IT_EOB;
8208 it->position = it->current.pos;
8209 success_p = 0;
8212 else if (!(!it->bidi_p
8213 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8214 || IT_CHARPOS (*it) == it->stop_charpos))
8216 /* With bidi non-linear iteration, we could find ourselves
8217 far beyond the last computed stop_charpos, with several
8218 other stop positions in between that we missed. Scan
8219 them all now, in buffer's logical order, until we find
8220 and handle the last stop_charpos that precedes our
8221 current position. */
8222 handle_stop_backwards (it, it->stop_charpos);
8223 return GET_NEXT_DISPLAY_ELEMENT (it);
8225 else
8227 if (it->bidi_p)
8229 /* Take note of the stop position we just moved across,
8230 for when we will move back across it. */
8231 it->prev_stop = it->stop_charpos;
8232 /* If we are at base paragraph embedding level, take
8233 note of the last stop position seen at this
8234 level. */
8235 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8236 it->base_level_stop = it->stop_charpos;
8238 handle_stop (it);
8239 return GET_NEXT_DISPLAY_ELEMENT (it);
8242 else if (it->bidi_p
8243 /* If we are before prev_stop, we may have overstepped on
8244 our way backwards a stop_pos, and if so, we need to
8245 handle that stop_pos. */
8246 && IT_CHARPOS (*it) < it->prev_stop
8247 /* We can sometimes back up for reasons that have nothing
8248 to do with bidi reordering. E.g., compositions. The
8249 code below is only needed when we are above the base
8250 embedding level, so test for that explicitly. */
8251 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8253 if (it->base_level_stop <= 0
8254 || IT_CHARPOS (*it) < it->base_level_stop)
8256 /* If we lost track of base_level_stop, we need to find
8257 prev_stop by looking backwards. This happens, e.g., when
8258 we were reseated to the previous screenful of text by
8259 vertical-motion. */
8260 it->base_level_stop = BEGV;
8261 compute_stop_pos_backwards (it);
8262 handle_stop_backwards (it, it->prev_stop);
8264 else
8265 handle_stop_backwards (it, it->base_level_stop);
8266 return GET_NEXT_DISPLAY_ELEMENT (it);
8268 else
8270 /* No face changes, overlays etc. in sight, so just return a
8271 character from current_buffer. */
8272 unsigned char *p;
8273 ptrdiff_t stop;
8275 /* Maybe run the redisplay end trigger hook. Performance note:
8276 This doesn't seem to cost measurable time. */
8277 if (it->redisplay_end_trigger_charpos
8278 && it->glyph_row
8279 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8280 run_redisplay_end_trigger_hook (it);
8282 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8283 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8284 stop)
8285 && next_element_from_composition (it))
8287 return 1;
8290 /* Get the next character, maybe multibyte. */
8291 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8292 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8293 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8294 else
8295 it->c = *p, it->len = 1;
8297 /* Record what we have and where it came from. */
8298 it->what = IT_CHARACTER;
8299 it->object = it->w->contents;
8300 it->position = it->current.pos;
8302 /* Normally we return the character found above, except when we
8303 really want to return an ellipsis for selective display. */
8304 if (it->selective)
8306 if (it->c == '\n')
8308 /* A value of selective > 0 means hide lines indented more
8309 than that number of columns. */
8310 if (it->selective > 0
8311 && IT_CHARPOS (*it) + 1 < ZV
8312 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8313 IT_BYTEPOS (*it) + 1,
8314 it->selective))
8316 success_p = next_element_from_ellipsis (it);
8317 it->dpvec_char_len = -1;
8320 else if (it->c == '\r' && it->selective == -1)
8322 /* A value of selective == -1 means that everything from the
8323 CR to the end of the line is invisible, with maybe an
8324 ellipsis displayed for it. */
8325 success_p = next_element_from_ellipsis (it);
8326 it->dpvec_char_len = -1;
8331 /* Value is zero if end of buffer reached. */
8332 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8333 return success_p;
8337 /* Run the redisplay end trigger hook for IT. */
8339 static void
8340 run_redisplay_end_trigger_hook (struct it *it)
8342 Lisp_Object args[3];
8344 /* IT->glyph_row should be non-null, i.e. we should be actually
8345 displaying something, or otherwise we should not run the hook. */
8346 eassert (it->glyph_row);
8348 /* Set up hook arguments. */
8349 args[0] = Qredisplay_end_trigger_functions;
8350 args[1] = it->window;
8351 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8352 it->redisplay_end_trigger_charpos = 0;
8354 /* Since we are *trying* to run these functions, don't try to run
8355 them again, even if they get an error. */
8356 wset_redisplay_end_trigger (it->w, Qnil);
8357 Frun_hook_with_args (3, args);
8359 /* Notice if it changed the face of the character we are on. */
8360 handle_face_prop (it);
8364 /* Deliver a composition display element. Unlike the other
8365 next_element_from_XXX, this function is not registered in the array
8366 get_next_element[]. It is called from next_element_from_buffer and
8367 next_element_from_string when necessary. */
8369 static int
8370 next_element_from_composition (struct it *it)
8372 it->what = IT_COMPOSITION;
8373 it->len = it->cmp_it.nbytes;
8374 if (STRINGP (it->string))
8376 if (it->c < 0)
8378 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8379 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8380 return 0;
8382 it->position = it->current.string_pos;
8383 it->object = it->string;
8384 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8385 IT_STRING_BYTEPOS (*it), it->string);
8387 else
8389 if (it->c < 0)
8391 IT_CHARPOS (*it) += it->cmp_it.nchars;
8392 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8393 if (it->bidi_p)
8395 if (it->bidi_it.new_paragraph)
8396 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8397 /* Resync the bidi iterator with IT's new position.
8398 FIXME: this doesn't support bidirectional text. */
8399 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8400 bidi_move_to_visually_next (&it->bidi_it);
8402 return 0;
8404 it->position = it->current.pos;
8405 it->object = it->w->contents;
8406 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8407 IT_BYTEPOS (*it), Qnil);
8409 return 1;
8414 /***********************************************************************
8415 Moving an iterator without producing glyphs
8416 ***********************************************************************/
8418 /* Check if iterator is at a position corresponding to a valid buffer
8419 position after some move_it_ call. */
8421 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8422 ((it)->method == GET_FROM_STRING \
8423 ? IT_STRING_CHARPOS (*it) == 0 \
8424 : 1)
8427 /* Move iterator IT to a specified buffer or X position within one
8428 line on the display without producing glyphs.
8430 OP should be a bit mask including some or all of these bits:
8431 MOVE_TO_X: Stop upon reaching x-position TO_X.
8432 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8433 Regardless of OP's value, stop upon reaching the end of the display line.
8435 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8436 This means, in particular, that TO_X includes window's horizontal
8437 scroll amount.
8439 The return value has several possible values that
8440 say what condition caused the scan to stop:
8442 MOVE_POS_MATCH_OR_ZV
8443 - when TO_POS or ZV was reached.
8445 MOVE_X_REACHED
8446 -when TO_X was reached before TO_POS or ZV were reached.
8448 MOVE_LINE_CONTINUED
8449 - when we reached the end of the display area and the line must
8450 be continued.
8452 MOVE_LINE_TRUNCATED
8453 - when we reached the end of the display area and the line is
8454 truncated.
8456 MOVE_NEWLINE_OR_CR
8457 - when we stopped at a line end, i.e. a newline or a CR and selective
8458 display is on. */
8460 static enum move_it_result
8461 move_it_in_display_line_to (struct it *it,
8462 ptrdiff_t to_charpos, int to_x,
8463 enum move_operation_enum op)
8465 enum move_it_result result = MOVE_UNDEFINED;
8466 struct glyph_row *saved_glyph_row;
8467 struct it wrap_it, atpos_it, atx_it, ppos_it;
8468 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8469 void *ppos_data = NULL;
8470 int may_wrap = 0;
8471 enum it_method prev_method = it->method;
8472 ptrdiff_t closest_pos IF_LINT (= 0), prev_pos = IT_CHARPOS (*it);
8473 int saw_smaller_pos = prev_pos < to_charpos;
8475 /* Don't produce glyphs in produce_glyphs. */
8476 saved_glyph_row = it->glyph_row;
8477 it->glyph_row = NULL;
8479 /* Use wrap_it to save a copy of IT wherever a word wrap could
8480 occur. Use atpos_it to save a copy of IT at the desired buffer
8481 position, if found, so that we can scan ahead and check if the
8482 word later overshoots the window edge. Use atx_it similarly, for
8483 pixel positions. */
8484 wrap_it.sp = -1;
8485 atpos_it.sp = -1;
8486 atx_it.sp = -1;
8488 /* Use ppos_it under bidi reordering to save a copy of IT for the
8489 initial position. We restore that position in IT when we have
8490 scanned the entire display line without finding a match for
8491 TO_CHARPOS and all the character positions are greater than
8492 TO_CHARPOS. We then restart the scan from the initial position,
8493 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8494 the closest to TO_CHARPOS. */
8495 if (it->bidi_p)
8497 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8499 SAVE_IT (ppos_it, *it, ppos_data);
8500 closest_pos = IT_CHARPOS (*it);
8502 else
8503 closest_pos = ZV;
8506 #define BUFFER_POS_REACHED_P() \
8507 ((op & MOVE_TO_POS) != 0 \
8508 && BUFFERP (it->object) \
8509 && (IT_CHARPOS (*it) == to_charpos \
8510 || ((!it->bidi_p \
8511 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8512 && IT_CHARPOS (*it) > to_charpos) \
8513 || (it->what == IT_COMPOSITION \
8514 && ((IT_CHARPOS (*it) > to_charpos \
8515 && to_charpos >= it->cmp_it.charpos) \
8516 || (IT_CHARPOS (*it) < to_charpos \
8517 && to_charpos <= it->cmp_it.charpos)))) \
8518 && (it->method == GET_FROM_BUFFER \
8519 || (it->method == GET_FROM_DISPLAY_VECTOR \
8520 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8522 /* If there's a line-/wrap-prefix, handle it. */
8523 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8524 && it->current_y < it->last_visible_y)
8525 handle_line_prefix (it);
8527 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8528 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8530 while (1)
8532 int x, i, ascent = 0, descent = 0;
8534 /* Utility macro to reset an iterator with x, ascent, and descent. */
8535 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8536 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8537 (IT)->max_descent = descent)
8539 /* Stop if we move beyond TO_CHARPOS (after an image or a
8540 display string or stretch glyph). */
8541 if ((op & MOVE_TO_POS) != 0
8542 && BUFFERP (it->object)
8543 && it->method == GET_FROM_BUFFER
8544 && (((!it->bidi_p
8545 /* When the iterator is at base embedding level, we
8546 are guaranteed that characters are delivered for
8547 display in strictly increasing order of their
8548 buffer positions. */
8549 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8550 && IT_CHARPOS (*it) > to_charpos)
8551 || (it->bidi_p
8552 && (prev_method == GET_FROM_IMAGE
8553 || prev_method == GET_FROM_STRETCH
8554 || prev_method == GET_FROM_STRING)
8555 /* Passed TO_CHARPOS from left to right. */
8556 && ((prev_pos < to_charpos
8557 && IT_CHARPOS (*it) > to_charpos)
8558 /* Passed TO_CHARPOS from right to left. */
8559 || (prev_pos > to_charpos
8560 && IT_CHARPOS (*it) < to_charpos)))))
8562 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8564 result = MOVE_POS_MATCH_OR_ZV;
8565 break;
8567 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8568 /* If wrap_it is valid, the current position might be in a
8569 word that is wrapped. So, save the iterator in
8570 atpos_it and continue to see if wrapping happens. */
8571 SAVE_IT (atpos_it, *it, atpos_data);
8574 /* Stop when ZV reached.
8575 We used to stop here when TO_CHARPOS reached as well, but that is
8576 too soon if this glyph does not fit on this line. So we handle it
8577 explicitly below. */
8578 if (!get_next_display_element (it))
8580 result = MOVE_POS_MATCH_OR_ZV;
8581 break;
8584 if (it->line_wrap == TRUNCATE)
8586 if (BUFFER_POS_REACHED_P ())
8588 result = MOVE_POS_MATCH_OR_ZV;
8589 break;
8592 else
8594 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8596 if (IT_DISPLAYING_WHITESPACE (it))
8597 may_wrap = 1;
8598 else if (may_wrap)
8600 /* We have reached a glyph that follows one or more
8601 whitespace characters. If the position is
8602 already found, we are done. */
8603 if (atpos_it.sp >= 0)
8605 RESTORE_IT (it, &atpos_it, atpos_data);
8606 result = MOVE_POS_MATCH_OR_ZV;
8607 goto done;
8609 if (atx_it.sp >= 0)
8611 RESTORE_IT (it, &atx_it, atx_data);
8612 result = MOVE_X_REACHED;
8613 goto done;
8615 /* Otherwise, we can wrap here. */
8616 SAVE_IT (wrap_it, *it, wrap_data);
8617 may_wrap = 0;
8622 /* Remember the line height for the current line, in case
8623 the next element doesn't fit on the line. */
8624 ascent = it->max_ascent;
8625 descent = it->max_descent;
8627 /* The call to produce_glyphs will get the metrics of the
8628 display element IT is loaded with. Record the x-position
8629 before this display element, in case it doesn't fit on the
8630 line. */
8631 x = it->current_x;
8633 PRODUCE_GLYPHS (it);
8635 if (it->area != TEXT_AREA)
8637 prev_method = it->method;
8638 if (it->method == GET_FROM_BUFFER)
8639 prev_pos = IT_CHARPOS (*it);
8640 set_iterator_to_next (it, 1);
8641 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8642 SET_TEXT_POS (this_line_min_pos,
8643 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8644 if (it->bidi_p
8645 && (op & MOVE_TO_POS)
8646 && IT_CHARPOS (*it) > to_charpos
8647 && IT_CHARPOS (*it) < closest_pos)
8648 closest_pos = IT_CHARPOS (*it);
8649 continue;
8652 /* The number of glyphs we get back in IT->nglyphs will normally
8653 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8654 character on a terminal frame, or (iii) a line end. For the
8655 second case, IT->nglyphs - 1 padding glyphs will be present.
8656 (On X frames, there is only one glyph produced for a
8657 composite character.)
8659 The behavior implemented below means, for continuation lines,
8660 that as many spaces of a TAB as fit on the current line are
8661 displayed there. For terminal frames, as many glyphs of a
8662 multi-glyph character are displayed in the current line, too.
8663 This is what the old redisplay code did, and we keep it that
8664 way. Under X, the whole shape of a complex character must
8665 fit on the line or it will be completely displayed in the
8666 next line.
8668 Note that both for tabs and padding glyphs, all glyphs have
8669 the same width. */
8670 if (it->nglyphs)
8672 /* More than one glyph or glyph doesn't fit on line. All
8673 glyphs have the same width. */
8674 int single_glyph_width = it->pixel_width / it->nglyphs;
8675 int new_x;
8676 int x_before_this_char = x;
8677 int hpos_before_this_char = it->hpos;
8679 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8681 new_x = x + single_glyph_width;
8683 /* We want to leave anything reaching TO_X to the caller. */
8684 if ((op & MOVE_TO_X) && new_x > to_x)
8686 if (BUFFER_POS_REACHED_P ())
8688 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8689 goto buffer_pos_reached;
8690 if (atpos_it.sp < 0)
8692 SAVE_IT (atpos_it, *it, atpos_data);
8693 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8696 else
8698 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8700 it->current_x = x;
8701 result = MOVE_X_REACHED;
8702 break;
8704 if (atx_it.sp < 0)
8706 SAVE_IT (atx_it, *it, atx_data);
8707 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8712 if (/* Lines are continued. */
8713 it->line_wrap != TRUNCATE
8714 && (/* And glyph doesn't fit on the line. */
8715 new_x > it->last_visible_x
8716 /* Or it fits exactly and we're on a window
8717 system frame. */
8718 || (new_x == it->last_visible_x
8719 && FRAME_WINDOW_P (it->f)
8720 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8721 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8722 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8724 if (/* IT->hpos == 0 means the very first glyph
8725 doesn't fit on the line, e.g. a wide image. */
8726 it->hpos == 0
8727 || (new_x == it->last_visible_x
8728 && FRAME_WINDOW_P (it->f)
8729 /* When word-wrap is ON and we have a valid
8730 wrap point, we don't allow the last glyph
8731 to "just barely fit" on the line. */
8732 && (it->line_wrap != WORD_WRAP
8733 || wrap_it.sp < 0)))
8735 ++it->hpos;
8736 it->current_x = new_x;
8738 /* The character's last glyph just barely fits
8739 in this row. */
8740 if (i == it->nglyphs - 1)
8742 /* If this is the destination position,
8743 return a position *before* it in this row,
8744 now that we know it fits in this row. */
8745 if (BUFFER_POS_REACHED_P ())
8747 if (it->line_wrap != WORD_WRAP
8748 || wrap_it.sp < 0)
8750 it->hpos = hpos_before_this_char;
8751 it->current_x = x_before_this_char;
8752 result = MOVE_POS_MATCH_OR_ZV;
8753 break;
8755 if (it->line_wrap == WORD_WRAP
8756 && atpos_it.sp < 0)
8758 SAVE_IT (atpos_it, *it, atpos_data);
8759 atpos_it.current_x = x_before_this_char;
8760 atpos_it.hpos = hpos_before_this_char;
8764 prev_method = it->method;
8765 if (it->method == GET_FROM_BUFFER)
8766 prev_pos = IT_CHARPOS (*it);
8767 set_iterator_to_next (it, 1);
8768 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8769 SET_TEXT_POS (this_line_min_pos,
8770 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8771 /* On graphical terminals, newlines may
8772 "overflow" into the fringe if
8773 overflow-newline-into-fringe is non-nil.
8774 On text terminals, and on graphical
8775 terminals with no right margin, newlines
8776 may overflow into the last glyph on the
8777 display line.*/
8778 if (!FRAME_WINDOW_P (it->f)
8779 || ((it->bidi_p
8780 && it->bidi_it.paragraph_dir == R2L)
8781 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8782 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8783 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8785 if (!get_next_display_element (it))
8787 result = MOVE_POS_MATCH_OR_ZV;
8788 break;
8790 if (BUFFER_POS_REACHED_P ())
8792 if (ITERATOR_AT_END_OF_LINE_P (it))
8793 result = MOVE_POS_MATCH_OR_ZV;
8794 else
8795 result = MOVE_LINE_CONTINUED;
8796 break;
8798 if (ITERATOR_AT_END_OF_LINE_P (it)
8799 && (it->line_wrap != WORD_WRAP
8800 || wrap_it.sp < 0))
8802 result = MOVE_NEWLINE_OR_CR;
8803 break;
8808 else
8809 IT_RESET_X_ASCENT_DESCENT (it);
8811 if (wrap_it.sp >= 0)
8813 RESTORE_IT (it, &wrap_it, wrap_data);
8814 atpos_it.sp = -1;
8815 atx_it.sp = -1;
8818 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8819 IT_CHARPOS (*it)));
8820 result = MOVE_LINE_CONTINUED;
8821 break;
8824 if (BUFFER_POS_REACHED_P ())
8826 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8827 goto buffer_pos_reached;
8828 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8830 SAVE_IT (atpos_it, *it, atpos_data);
8831 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8835 if (new_x > it->first_visible_x)
8837 /* Glyph is visible. Increment number of glyphs that
8838 would be displayed. */
8839 ++it->hpos;
8843 if (result != MOVE_UNDEFINED)
8844 break;
8846 else if (BUFFER_POS_REACHED_P ())
8848 buffer_pos_reached:
8849 IT_RESET_X_ASCENT_DESCENT (it);
8850 result = MOVE_POS_MATCH_OR_ZV;
8851 break;
8853 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8855 /* Stop when TO_X specified and reached. This check is
8856 necessary here because of lines consisting of a line end,
8857 only. The line end will not produce any glyphs and we
8858 would never get MOVE_X_REACHED. */
8859 eassert (it->nglyphs == 0);
8860 result = MOVE_X_REACHED;
8861 break;
8864 /* Is this a line end? If yes, we're done. */
8865 if (ITERATOR_AT_END_OF_LINE_P (it))
8867 /* If we are past TO_CHARPOS, but never saw any character
8868 positions smaller than TO_CHARPOS, return
8869 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8870 did. */
8871 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8873 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8875 if (closest_pos < ZV)
8877 RESTORE_IT (it, &ppos_it, ppos_data);
8878 /* Don't recurse if closest_pos is equal to
8879 to_charpos, since we have just tried that. */
8880 if (closest_pos != to_charpos)
8881 move_it_in_display_line_to (it, closest_pos, -1,
8882 MOVE_TO_POS);
8883 result = MOVE_POS_MATCH_OR_ZV;
8885 else
8886 goto buffer_pos_reached;
8888 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8889 && IT_CHARPOS (*it) > to_charpos)
8890 goto buffer_pos_reached;
8891 else
8892 result = MOVE_NEWLINE_OR_CR;
8894 else
8895 result = MOVE_NEWLINE_OR_CR;
8896 break;
8899 prev_method = it->method;
8900 if (it->method == GET_FROM_BUFFER)
8901 prev_pos = IT_CHARPOS (*it);
8902 /* The current display element has been consumed. Advance
8903 to the next. */
8904 set_iterator_to_next (it, 1);
8905 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8906 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8907 if (IT_CHARPOS (*it) < to_charpos)
8908 saw_smaller_pos = 1;
8909 if (it->bidi_p
8910 && (op & MOVE_TO_POS)
8911 && IT_CHARPOS (*it) >= to_charpos
8912 && IT_CHARPOS (*it) < closest_pos)
8913 closest_pos = IT_CHARPOS (*it);
8915 /* Stop if lines are truncated and IT's current x-position is
8916 past the right edge of the window now. */
8917 if (it->line_wrap == TRUNCATE
8918 && it->current_x >= it->last_visible_x)
8920 if (!FRAME_WINDOW_P (it->f)
8921 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8922 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8923 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8924 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8926 int at_eob_p = 0;
8928 if ((at_eob_p = !get_next_display_element (it))
8929 || BUFFER_POS_REACHED_P ()
8930 /* If we are past TO_CHARPOS, but never saw any
8931 character positions smaller than TO_CHARPOS,
8932 return MOVE_POS_MATCH_OR_ZV, like the
8933 unidirectional display did. */
8934 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8935 && !saw_smaller_pos
8936 && IT_CHARPOS (*it) > to_charpos))
8938 if (it->bidi_p
8939 && !BUFFER_POS_REACHED_P ()
8940 && !at_eob_p && closest_pos < ZV)
8942 RESTORE_IT (it, &ppos_it, ppos_data);
8943 if (closest_pos != to_charpos)
8944 move_it_in_display_line_to (it, closest_pos, -1,
8945 MOVE_TO_POS);
8947 result = MOVE_POS_MATCH_OR_ZV;
8948 break;
8950 if (ITERATOR_AT_END_OF_LINE_P (it))
8952 result = MOVE_NEWLINE_OR_CR;
8953 break;
8956 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8957 && !saw_smaller_pos
8958 && IT_CHARPOS (*it) > to_charpos)
8960 if (closest_pos < ZV)
8962 RESTORE_IT (it, &ppos_it, ppos_data);
8963 if (closest_pos != to_charpos)
8964 move_it_in_display_line_to (it, closest_pos, -1,
8965 MOVE_TO_POS);
8967 result = MOVE_POS_MATCH_OR_ZV;
8968 break;
8970 result = MOVE_LINE_TRUNCATED;
8971 break;
8973 #undef IT_RESET_X_ASCENT_DESCENT
8976 #undef BUFFER_POS_REACHED_P
8978 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8979 restore the saved iterator. */
8980 if (atpos_it.sp >= 0)
8981 RESTORE_IT (it, &atpos_it, atpos_data);
8982 else if (atx_it.sp >= 0)
8983 RESTORE_IT (it, &atx_it, atx_data);
8985 done:
8987 if (atpos_data)
8988 bidi_unshelve_cache (atpos_data, 1);
8989 if (atx_data)
8990 bidi_unshelve_cache (atx_data, 1);
8991 if (wrap_data)
8992 bidi_unshelve_cache (wrap_data, 1);
8993 if (ppos_data)
8994 bidi_unshelve_cache (ppos_data, 1);
8996 /* Restore the iterator settings altered at the beginning of this
8997 function. */
8998 it->glyph_row = saved_glyph_row;
8999 return result;
9002 /* For external use. */
9003 void
9004 move_it_in_display_line (struct it *it,
9005 ptrdiff_t to_charpos, int to_x,
9006 enum move_operation_enum op)
9008 if (it->line_wrap == WORD_WRAP
9009 && (op & MOVE_TO_X))
9011 struct it save_it;
9012 void *save_data = NULL;
9013 int skip;
9015 SAVE_IT (save_it, *it, save_data);
9016 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9017 /* When word-wrap is on, TO_X may lie past the end
9018 of a wrapped line. Then it->current is the
9019 character on the next line, so backtrack to the
9020 space before the wrap point. */
9021 if (skip == MOVE_LINE_CONTINUED)
9023 int prev_x = max (it->current_x - 1, 0);
9024 RESTORE_IT (it, &save_it, save_data);
9025 move_it_in_display_line_to
9026 (it, -1, prev_x, MOVE_TO_X);
9028 else
9029 bidi_unshelve_cache (save_data, 1);
9031 else
9032 move_it_in_display_line_to (it, to_charpos, to_x, op);
9036 /* Move IT forward until it satisfies one or more of the criteria in
9037 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9039 OP is a bit-mask that specifies where to stop, and in particular,
9040 which of those four position arguments makes a difference. See the
9041 description of enum move_operation_enum.
9043 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9044 screen line, this function will set IT to the next position that is
9045 displayed to the right of TO_CHARPOS on the screen.
9047 Return the maximum pixel length of any line scanned but never more
9048 than it.last_visible_x. */
9051 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9053 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9054 int line_height, line_start_x = 0, reached = 0;
9055 int max_current_x = 0;
9056 void *backup_data = NULL;
9058 for (;;)
9060 if (op & MOVE_TO_VPOS)
9062 /* If no TO_CHARPOS and no TO_X specified, stop at the
9063 start of the line TO_VPOS. */
9064 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9066 if (it->vpos == to_vpos)
9068 reached = 1;
9069 break;
9071 else
9072 skip = move_it_in_display_line_to (it, -1, -1, 0);
9074 else
9076 /* TO_VPOS >= 0 means stop at TO_X in the line at
9077 TO_VPOS, or at TO_POS, whichever comes first. */
9078 if (it->vpos == to_vpos)
9080 reached = 2;
9081 break;
9084 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9086 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9088 reached = 3;
9089 break;
9091 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9093 /* We have reached TO_X but not in the line we want. */
9094 skip = move_it_in_display_line_to (it, to_charpos,
9095 -1, MOVE_TO_POS);
9096 if (skip == MOVE_POS_MATCH_OR_ZV)
9098 reached = 4;
9099 break;
9104 else if (op & MOVE_TO_Y)
9106 struct it it_backup;
9108 if (it->line_wrap == WORD_WRAP)
9109 SAVE_IT (it_backup, *it, backup_data);
9111 /* TO_Y specified means stop at TO_X in the line containing
9112 TO_Y---or at TO_CHARPOS if this is reached first. The
9113 problem is that we can't really tell whether the line
9114 contains TO_Y before we have completely scanned it, and
9115 this may skip past TO_X. What we do is to first scan to
9116 TO_X.
9118 If TO_X is not specified, use a TO_X of zero. The reason
9119 is to make the outcome of this function more predictable.
9120 If we didn't use TO_X == 0, we would stop at the end of
9121 the line which is probably not what a caller would expect
9122 to happen. */
9123 skip = move_it_in_display_line_to
9124 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9125 (MOVE_TO_X | (op & MOVE_TO_POS)));
9127 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9128 if (skip == MOVE_POS_MATCH_OR_ZV)
9129 reached = 5;
9130 else if (skip == MOVE_X_REACHED)
9132 /* If TO_X was reached, we want to know whether TO_Y is
9133 in the line. We know this is the case if the already
9134 scanned glyphs make the line tall enough. Otherwise,
9135 we must check by scanning the rest of the line. */
9136 line_height = it->max_ascent + it->max_descent;
9137 if (to_y >= it->current_y
9138 && to_y < it->current_y + line_height)
9140 reached = 6;
9141 break;
9143 SAVE_IT (it_backup, *it, backup_data);
9144 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9145 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9146 op & MOVE_TO_POS);
9147 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9148 line_height = it->max_ascent + it->max_descent;
9149 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9151 if (to_y >= it->current_y
9152 && to_y < it->current_y + line_height)
9154 /* If TO_Y is in this line and TO_X was reached
9155 above, we scanned too far. We have to restore
9156 IT's settings to the ones before skipping. But
9157 keep the more accurate values of max_ascent and
9158 max_descent we've found while skipping the rest
9159 of the line, for the sake of callers, such as
9160 pos_visible_p, that need to know the line
9161 height. */
9162 int max_ascent = it->max_ascent;
9163 int max_descent = it->max_descent;
9165 RESTORE_IT (it, &it_backup, backup_data);
9166 it->max_ascent = max_ascent;
9167 it->max_descent = max_descent;
9168 reached = 6;
9170 else
9172 skip = skip2;
9173 if (skip == MOVE_POS_MATCH_OR_ZV)
9174 reached = 7;
9177 else
9179 /* Check whether TO_Y is in this line. */
9180 line_height = it->max_ascent + it->max_descent;
9181 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9183 if (to_y >= it->current_y
9184 && to_y < it->current_y + line_height)
9186 if (to_y > it->current_y)
9187 max_current_x = max (it->current_x, max_current_x);
9189 /* When word-wrap is on, TO_X may lie past the end
9190 of a wrapped line. Then it->current is the
9191 character on the next line, so backtrack to the
9192 space before the wrap point. */
9193 if (skip == MOVE_LINE_CONTINUED
9194 && it->line_wrap == WORD_WRAP)
9196 int prev_x = max (it->current_x - 1, 0);
9197 RESTORE_IT (it, &it_backup, backup_data);
9198 skip = move_it_in_display_line_to
9199 (it, -1, prev_x, MOVE_TO_X);
9202 reached = 6;
9206 if (reached)
9208 max_current_x = max (it->current_x, max_current_x);
9209 break;
9212 else if (BUFFERP (it->object)
9213 && (it->method == GET_FROM_BUFFER
9214 || it->method == GET_FROM_STRETCH)
9215 && IT_CHARPOS (*it) >= to_charpos
9216 /* Under bidi iteration, a call to set_iterator_to_next
9217 can scan far beyond to_charpos if the initial
9218 portion of the next line needs to be reordered. In
9219 that case, give move_it_in_display_line_to another
9220 chance below. */
9221 && !(it->bidi_p
9222 && it->bidi_it.scan_dir == -1))
9223 skip = MOVE_POS_MATCH_OR_ZV;
9224 else
9225 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9227 switch (skip)
9229 case MOVE_POS_MATCH_OR_ZV:
9230 max_current_x = max (it->current_x, max_current_x);
9231 reached = 8;
9232 goto out;
9234 case MOVE_NEWLINE_OR_CR:
9235 max_current_x = max (it->current_x, max_current_x);
9236 set_iterator_to_next (it, 1);
9237 it->continuation_lines_width = 0;
9238 break;
9240 case MOVE_LINE_TRUNCATED:
9241 max_current_x = it->last_visible_x;
9242 it->continuation_lines_width = 0;
9243 reseat_at_next_visible_line_start (it, 0);
9244 if ((op & MOVE_TO_POS) != 0
9245 && IT_CHARPOS (*it) > to_charpos)
9247 reached = 9;
9248 goto out;
9250 break;
9252 case MOVE_LINE_CONTINUED:
9253 max_current_x = it->last_visible_x;
9254 /* For continued lines ending in a tab, some of the glyphs
9255 associated with the tab are displayed on the current
9256 line. Since it->current_x does not include these glyphs,
9257 we use it->last_visible_x instead. */
9258 if (it->c == '\t')
9260 it->continuation_lines_width += it->last_visible_x;
9261 /* When moving by vpos, ensure that the iterator really
9262 advances to the next line (bug#847, bug#969). Fixme:
9263 do we need to do this in other circumstances? */
9264 if (it->current_x != it->last_visible_x
9265 && (op & MOVE_TO_VPOS)
9266 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9268 line_start_x = it->current_x + it->pixel_width
9269 - it->last_visible_x;
9270 if (FRAME_WINDOW_P (it->f))
9272 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9273 struct font *face_font = face->font;
9275 /* When display_line produces a continued line
9276 that ends in a TAB, it skips a tab stop that
9277 is closer than the font's space character
9278 width (see x_produce_glyphs where it produces
9279 the stretch glyph which represents a TAB).
9280 We need to reproduce the same logic here. */
9281 eassert (face_font);
9282 if (face_font)
9284 if (line_start_x < face_font->space_width)
9285 line_start_x
9286 += it->tab_width * face_font->space_width;
9289 set_iterator_to_next (it, 0);
9292 else
9293 it->continuation_lines_width += it->current_x;
9294 break;
9296 default:
9297 emacs_abort ();
9300 /* Reset/increment for the next run. */
9301 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9302 it->current_x = line_start_x;
9303 line_start_x = 0;
9304 it->hpos = 0;
9305 it->current_y += it->max_ascent + it->max_descent;
9306 ++it->vpos;
9307 last_height = it->max_ascent + it->max_descent;
9308 it->max_ascent = it->max_descent = 0;
9311 out:
9313 /* On text terminals, we may stop at the end of a line in the middle
9314 of a multi-character glyph. If the glyph itself is continued,
9315 i.e. it is actually displayed on the next line, don't treat this
9316 stopping point as valid; move to the next line instead (unless
9317 that brings us offscreen). */
9318 if (!FRAME_WINDOW_P (it->f)
9319 && op & MOVE_TO_POS
9320 && IT_CHARPOS (*it) == to_charpos
9321 && it->what == IT_CHARACTER
9322 && it->nglyphs > 1
9323 && it->line_wrap == WINDOW_WRAP
9324 && it->current_x == it->last_visible_x - 1
9325 && it->c != '\n'
9326 && it->c != '\t'
9327 && it->vpos < it->w->window_end_vpos)
9329 it->continuation_lines_width += it->current_x;
9330 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9331 it->current_y += it->max_ascent + it->max_descent;
9332 ++it->vpos;
9333 last_height = it->max_ascent + it->max_descent;
9336 if (backup_data)
9337 bidi_unshelve_cache (backup_data, 1);
9339 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9341 return max_current_x;
9345 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9347 If DY > 0, move IT backward at least that many pixels. DY = 0
9348 means move IT backward to the preceding line start or BEGV. This
9349 function may move over more than DY pixels if IT->current_y - DY
9350 ends up in the middle of a line; in this case IT->current_y will be
9351 set to the top of the line moved to. */
9353 void
9354 move_it_vertically_backward (struct it *it, int dy)
9356 int nlines, h;
9357 struct it it2, it3;
9358 void *it2data = NULL, *it3data = NULL;
9359 ptrdiff_t start_pos;
9360 int nchars_per_row
9361 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9362 ptrdiff_t pos_limit;
9364 move_further_back:
9365 eassert (dy >= 0);
9367 start_pos = IT_CHARPOS (*it);
9369 /* Estimate how many newlines we must move back. */
9370 nlines = max (1, dy / default_line_pixel_height (it->w));
9371 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9372 pos_limit = BEGV;
9373 else
9374 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9376 /* Set the iterator's position that many lines back. But don't go
9377 back more than NLINES full screen lines -- this wins a day with
9378 buffers which have very long lines. */
9379 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9380 back_to_previous_visible_line_start (it);
9382 /* Reseat the iterator here. When moving backward, we don't want
9383 reseat to skip forward over invisible text, set up the iterator
9384 to deliver from overlay strings at the new position etc. So,
9385 use reseat_1 here. */
9386 reseat_1 (it, it->current.pos, 1);
9388 /* We are now surely at a line start. */
9389 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9390 reordering is in effect. */
9391 it->continuation_lines_width = 0;
9393 /* Move forward and see what y-distance we moved. First move to the
9394 start of the next line so that we get its height. We need this
9395 height to be able to tell whether we reached the specified
9396 y-distance. */
9397 SAVE_IT (it2, *it, it2data);
9398 it2.max_ascent = it2.max_descent = 0;
9401 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9402 MOVE_TO_POS | MOVE_TO_VPOS);
9404 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9405 /* If we are in a display string which starts at START_POS,
9406 and that display string includes a newline, and we are
9407 right after that newline (i.e. at the beginning of a
9408 display line), exit the loop, because otherwise we will
9409 infloop, since move_it_to will see that it is already at
9410 START_POS and will not move. */
9411 || (it2.method == GET_FROM_STRING
9412 && IT_CHARPOS (it2) == start_pos
9413 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9414 eassert (IT_CHARPOS (*it) >= BEGV);
9415 SAVE_IT (it3, it2, it3data);
9417 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9418 eassert (IT_CHARPOS (*it) >= BEGV);
9419 /* H is the actual vertical distance from the position in *IT
9420 and the starting position. */
9421 h = it2.current_y - it->current_y;
9422 /* NLINES is the distance in number of lines. */
9423 nlines = it2.vpos - it->vpos;
9425 /* Correct IT's y and vpos position
9426 so that they are relative to the starting point. */
9427 it->vpos -= nlines;
9428 it->current_y -= h;
9430 if (dy == 0)
9432 /* DY == 0 means move to the start of the screen line. The
9433 value of nlines is > 0 if continuation lines were involved,
9434 or if the original IT position was at start of a line. */
9435 RESTORE_IT (it, it, it2data);
9436 if (nlines > 0)
9437 move_it_by_lines (it, nlines);
9438 /* The above code moves us to some position NLINES down,
9439 usually to its first glyph (leftmost in an L2R line), but
9440 that's not necessarily the start of the line, under bidi
9441 reordering. We want to get to the character position
9442 that is immediately after the newline of the previous
9443 line. */
9444 if (it->bidi_p
9445 && !it->continuation_lines_width
9446 && !STRINGP (it->string)
9447 && IT_CHARPOS (*it) > BEGV
9448 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9450 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9452 DEC_BOTH (cp, bp);
9453 cp = find_newline_no_quit (cp, bp, -1, NULL);
9454 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9456 bidi_unshelve_cache (it3data, 1);
9458 else
9460 /* The y-position we try to reach, relative to *IT.
9461 Note that H has been subtracted in front of the if-statement. */
9462 int target_y = it->current_y + h - dy;
9463 int y0 = it3.current_y;
9464 int y1;
9465 int line_height;
9467 RESTORE_IT (&it3, &it3, it3data);
9468 y1 = line_bottom_y (&it3);
9469 line_height = y1 - y0;
9470 RESTORE_IT (it, it, it2data);
9471 /* If we did not reach target_y, try to move further backward if
9472 we can. If we moved too far backward, try to move forward. */
9473 if (target_y < it->current_y
9474 /* This is heuristic. In a window that's 3 lines high, with
9475 a line height of 13 pixels each, recentering with point
9476 on the bottom line will try to move -39/2 = 19 pixels
9477 backward. Try to avoid moving into the first line. */
9478 && (it->current_y - target_y
9479 > min (window_box_height (it->w), line_height * 2 / 3))
9480 && IT_CHARPOS (*it) > BEGV)
9482 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9483 target_y - it->current_y));
9484 dy = it->current_y - target_y;
9485 goto move_further_back;
9487 else if (target_y >= it->current_y + line_height
9488 && IT_CHARPOS (*it) < ZV)
9490 /* Should move forward by at least one line, maybe more.
9492 Note: Calling move_it_by_lines can be expensive on
9493 terminal frames, where compute_motion is used (via
9494 vmotion) to do the job, when there are very long lines
9495 and truncate-lines is nil. That's the reason for
9496 treating terminal frames specially here. */
9498 if (!FRAME_WINDOW_P (it->f))
9499 move_it_vertically (it, target_y - (it->current_y + line_height));
9500 else
9504 move_it_by_lines (it, 1);
9506 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9513 /* Move IT by a specified amount of pixel lines DY. DY negative means
9514 move backwards. DY = 0 means move to start of screen line. At the
9515 end, IT will be on the start of a screen line. */
9517 void
9518 move_it_vertically (struct it *it, int dy)
9520 if (dy <= 0)
9521 move_it_vertically_backward (it, -dy);
9522 else
9524 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9525 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9526 MOVE_TO_POS | MOVE_TO_Y);
9527 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9529 /* If buffer ends in ZV without a newline, move to the start of
9530 the line to satisfy the post-condition. */
9531 if (IT_CHARPOS (*it) == ZV
9532 && ZV > BEGV
9533 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9534 move_it_by_lines (it, 0);
9539 /* Move iterator IT past the end of the text line it is in. */
9541 void
9542 move_it_past_eol (struct it *it)
9544 enum move_it_result rc;
9546 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9547 if (rc == MOVE_NEWLINE_OR_CR)
9548 set_iterator_to_next (it, 0);
9552 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9553 negative means move up. DVPOS == 0 means move to the start of the
9554 screen line.
9556 Optimization idea: If we would know that IT->f doesn't use
9557 a face with proportional font, we could be faster for
9558 truncate-lines nil. */
9560 void
9561 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9564 /* The commented-out optimization uses vmotion on terminals. This
9565 gives bad results, because elements like it->what, on which
9566 callers such as pos_visible_p rely, aren't updated. */
9567 /* struct position pos;
9568 if (!FRAME_WINDOW_P (it->f))
9570 struct text_pos textpos;
9572 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9573 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9574 reseat (it, textpos, 1);
9575 it->vpos += pos.vpos;
9576 it->current_y += pos.vpos;
9578 else */
9580 if (dvpos == 0)
9582 /* DVPOS == 0 means move to the start of the screen line. */
9583 move_it_vertically_backward (it, 0);
9584 /* Let next call to line_bottom_y calculate real line height. */
9585 last_height = 0;
9587 else if (dvpos > 0)
9589 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9590 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9592 /* Only move to the next buffer position if we ended up in a
9593 string from display property, not in an overlay string
9594 (before-string or after-string). That is because the
9595 latter don't conceal the underlying buffer position, so
9596 we can ask to move the iterator to the exact position we
9597 are interested in. Note that, even if we are already at
9598 IT_CHARPOS (*it), the call below is not a no-op, as it
9599 will detect that we are at the end of the string, pop the
9600 iterator, and compute it->current_x and it->hpos
9601 correctly. */
9602 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9603 -1, -1, -1, MOVE_TO_POS);
9606 else
9608 struct it it2;
9609 void *it2data = NULL;
9610 ptrdiff_t start_charpos, i;
9611 int nchars_per_row
9612 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9613 bool hit_pos_limit = false;
9614 ptrdiff_t pos_limit;
9616 /* Start at the beginning of the screen line containing IT's
9617 position. This may actually move vertically backwards,
9618 in case of overlays, so adjust dvpos accordingly. */
9619 dvpos += it->vpos;
9620 move_it_vertically_backward (it, 0);
9621 dvpos -= it->vpos;
9623 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9624 screen lines, and reseat the iterator there. */
9625 start_charpos = IT_CHARPOS (*it);
9626 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9627 pos_limit = BEGV;
9628 else
9629 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9631 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9632 back_to_previous_visible_line_start (it);
9633 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9634 hit_pos_limit = true;
9635 reseat (it, it->current.pos, 1);
9637 /* Move further back if we end up in a string or an image. */
9638 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9640 /* First try to move to start of display line. */
9641 dvpos += it->vpos;
9642 move_it_vertically_backward (it, 0);
9643 dvpos -= it->vpos;
9644 if (IT_POS_VALID_AFTER_MOVE_P (it))
9645 break;
9646 /* If start of line is still in string or image,
9647 move further back. */
9648 back_to_previous_visible_line_start (it);
9649 reseat (it, it->current.pos, 1);
9650 dvpos--;
9653 it->current_x = it->hpos = 0;
9655 /* Above call may have moved too far if continuation lines
9656 are involved. Scan forward and see if it did. */
9657 SAVE_IT (it2, *it, it2data);
9658 it2.vpos = it2.current_y = 0;
9659 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9660 it->vpos -= it2.vpos;
9661 it->current_y -= it2.current_y;
9662 it->current_x = it->hpos = 0;
9664 /* If we moved too far back, move IT some lines forward. */
9665 if (it2.vpos > -dvpos)
9667 int delta = it2.vpos + dvpos;
9669 RESTORE_IT (&it2, &it2, it2data);
9670 SAVE_IT (it2, *it, it2data);
9671 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9672 /* Move back again if we got too far ahead. */
9673 if (IT_CHARPOS (*it) >= start_charpos)
9674 RESTORE_IT (it, &it2, it2data);
9675 else
9676 bidi_unshelve_cache (it2data, 1);
9678 else if (hit_pos_limit && pos_limit > BEGV
9679 && dvpos < 0 && it2.vpos < -dvpos)
9681 /* If we hit the limit, but still didn't make it far enough
9682 back, that means there's a display string with a newline
9683 covering a large chunk of text, and that caused
9684 back_to_previous_visible_line_start try to go too far.
9685 Punish those who commit such atrocities by going back
9686 until we've reached DVPOS, after lifting the limit, which
9687 could make it slow for very long lines. "If it hurts,
9688 don't do that!" */
9689 dvpos += it2.vpos;
9690 RESTORE_IT (it, it, it2data);
9691 for (i = -dvpos; i > 0; --i)
9693 back_to_previous_visible_line_start (it);
9694 it->vpos--;
9697 else
9698 RESTORE_IT (it, it, it2data);
9702 /* Return true if IT points into the middle of a display vector. */
9704 bool
9705 in_display_vector_p (struct it *it)
9707 return (it->method == GET_FROM_DISPLAY_VECTOR
9708 && it->current.dpvec_index > 0
9709 && it->dpvec + it->current.dpvec_index != it->dpend);
9712 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9713 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9714 WINDOW must be a live window and defaults to the selected one. The
9715 return value is a cons of the maximum pixel-width of any text line and
9716 the maximum pixel-height of all text lines.
9718 The optional argument FROM, if non-nil, specifies the first text
9719 position and defaults to the minimum accessible position of the buffer.
9720 If FROM is t, use the minimum accessible position that is not a newline
9721 character. TO, if non-nil, specifies the last text position and
9722 defaults to the maximum accessible position of the buffer. If TO is t,
9723 use the maximum accessible position that is not a newline character.
9725 The optional argument X-LIMIT, if non-nil, specifies the maximum text
9726 width that can be returned. X-LIMIT nil or omitted, means to use the
9727 pixel-width of WINDOW's body; use this if you do not intend to change
9728 the width of WINDOW. Use the maximum width WINDOW may assume if you
9729 intend to change WINDOW's width. In any case, text whose x-coordinate
9730 is beyond X-LIMIT is ignored. Since calculating the width of long lines
9731 can take some time, it's always a good idea to make this argument as
9732 small as possible; in particular, if the buffer contains long lines that
9733 shall be truncated anyway.
9735 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
9736 height that can be returned. Text lines whose y-coordinate is beyond
9737 Y-LIMIT are ignored. Since calculating the text height of a large
9738 buffer can take some time, it makes sense to specify this argument if
9739 the size of the buffer is unknown.
9741 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9742 include the height of the mode- or header-line of WINDOW in the return
9743 value. If it is either the symbol `mode-line' or `header-line', include
9744 only the height of that line, if present, in the return value. If t,
9745 include the height of both, if present, in the return value. */)
9746 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
9747 Lisp_Object mode_and_header_line)
9749 struct window *w = decode_live_window (window);
9750 Lisp_Object buf;
9751 struct buffer *b;
9752 struct it it;
9753 struct buffer *old_buffer = NULL;
9754 ptrdiff_t start, end, pos;
9755 struct text_pos startp;
9756 void *itdata = NULL;
9757 int c, max_y = -1, x = 0, y = 0;
9759 buf = w->contents;
9760 CHECK_BUFFER (buf);
9761 b = XBUFFER (buf);
9763 if (b != current_buffer)
9765 old_buffer = current_buffer;
9766 set_buffer_internal (b);
9769 if (NILP (from))
9770 start = BEGV;
9771 else if (EQ (from, Qt))
9773 start = pos = BEGV;
9774 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9775 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9776 start = pos;
9777 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9778 start = pos;
9780 else
9782 CHECK_NUMBER_COERCE_MARKER (from);
9783 start = min (max (XINT (from), BEGV), ZV);
9786 if (NILP (to))
9787 end = ZV;
9788 else if (EQ (to, Qt))
9790 end = pos = ZV;
9791 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9792 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9793 end = pos;
9794 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9795 end = pos;
9797 else
9799 CHECK_NUMBER_COERCE_MARKER (to);
9800 end = max (start, min (XINT (to), ZV));
9803 if (!NILP (y_limit))
9805 CHECK_NUMBER (y_limit);
9806 max_y = min (XINT (y_limit), INT_MAX);
9809 itdata = bidi_shelve_cache ();
9810 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9811 start_display (&it, w, startp);
9813 if (NILP (x_limit))
9814 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9815 else
9817 CHECK_NUMBER (x_limit);
9818 it.last_visible_x = min (XINT (x_limit), INFINITY);
9819 /* Actually, we never want move_it_to stop at to_x. But to make
9820 sure that move_it_in_display_line_to always moves far enough,
9821 we set it to INT_MAX and specify MOVE_TO_X. */
9822 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9823 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9826 y = it.current_y + it.max_ascent + it.max_descent;
9828 if (!EQ (mode_and_header_line, Qheader_line)
9829 && !EQ (mode_and_header_line, Qt))
9830 /* Do not count the header-line which was counted automatically by
9831 start_display. */
9832 y = y - WINDOW_HEADER_LINE_HEIGHT (w);
9834 if (EQ (mode_and_header_line, Qmode_line)
9835 || EQ (mode_and_header_line, Qt))
9836 /* Do count the mode-line which is not included automatically by
9837 start_display. */
9838 y = y + WINDOW_MODE_LINE_HEIGHT (w);
9840 bidi_unshelve_cache (itdata, 0);
9842 if (old_buffer)
9843 set_buffer_internal (old_buffer);
9845 return Fcons (make_number (x), make_number (y));
9848 /***********************************************************************
9849 Messages
9850 ***********************************************************************/
9853 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9854 to *Messages*. */
9856 void
9857 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9859 Lisp_Object args[3];
9860 Lisp_Object msg, fmt;
9861 char *buffer;
9862 ptrdiff_t len;
9863 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9864 USE_SAFE_ALLOCA;
9866 fmt = msg = Qnil;
9867 GCPRO4 (fmt, msg, arg1, arg2);
9869 args[0] = fmt = build_string (format);
9870 args[1] = arg1;
9871 args[2] = arg2;
9872 msg = Fformat (3, args);
9874 len = SBYTES (msg) + 1;
9875 buffer = SAFE_ALLOCA (len);
9876 memcpy (buffer, SDATA (msg), len);
9878 message_dolog (buffer, len - 1, 1, 0);
9879 SAFE_FREE ();
9881 UNGCPRO;
9885 /* Output a newline in the *Messages* buffer if "needs" one. */
9887 void
9888 message_log_maybe_newline (void)
9890 if (message_log_need_newline)
9891 message_dolog ("", 0, 1, 0);
9895 /* Add a string M of length NBYTES to the message log, optionally
9896 terminated with a newline when NLFLAG is true. MULTIBYTE, if
9897 true, means interpret the contents of M as multibyte. This
9898 function calls low-level routines in order to bypass text property
9899 hooks, etc. which might not be safe to run.
9901 This may GC (insert may run before/after change hooks),
9902 so the buffer M must NOT point to a Lisp string. */
9904 void
9905 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9907 const unsigned char *msg = (const unsigned char *) m;
9909 if (!NILP (Vmemory_full))
9910 return;
9912 if (!NILP (Vmessage_log_max))
9914 struct buffer *oldbuf;
9915 Lisp_Object oldpoint, oldbegv, oldzv;
9916 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9917 ptrdiff_t point_at_end = 0;
9918 ptrdiff_t zv_at_end = 0;
9919 Lisp_Object old_deactivate_mark;
9920 struct gcpro gcpro1;
9922 old_deactivate_mark = Vdeactivate_mark;
9923 oldbuf = current_buffer;
9925 /* Ensure the Messages buffer exists, and switch to it.
9926 If we created it, set the major-mode. */
9928 int newbuffer = 0;
9929 if (NILP (Fget_buffer (Vmessages_buffer_name))) newbuffer = 1;
9931 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9933 if (newbuffer
9934 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9935 call0 (intern ("messages-buffer-mode"));
9938 bset_undo_list (current_buffer, Qt);
9939 bset_cache_long_scans (current_buffer, Qnil);
9941 oldpoint = message_dolog_marker1;
9942 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
9943 oldbegv = message_dolog_marker2;
9944 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
9945 oldzv = message_dolog_marker3;
9946 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
9947 GCPRO1 (old_deactivate_mark);
9949 if (PT == Z)
9950 point_at_end = 1;
9951 if (ZV == Z)
9952 zv_at_end = 1;
9954 BEGV = BEG;
9955 BEGV_BYTE = BEG_BYTE;
9956 ZV = Z;
9957 ZV_BYTE = Z_BYTE;
9958 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9960 /* Insert the string--maybe converting multibyte to single byte
9961 or vice versa, so that all the text fits the buffer. */
9962 if (multibyte
9963 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9965 ptrdiff_t i;
9966 int c, char_bytes;
9967 char work[1];
9969 /* Convert a multibyte string to single-byte
9970 for the *Message* buffer. */
9971 for (i = 0; i < nbytes; i += char_bytes)
9973 c = string_char_and_length (msg + i, &char_bytes);
9974 work[0] = CHAR_TO_BYTE8 (c);
9975 insert_1_both (work, 1, 1, 1, 0, 0);
9978 else if (! multibyte
9979 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9981 ptrdiff_t i;
9982 int c, char_bytes;
9983 unsigned char str[MAX_MULTIBYTE_LENGTH];
9984 /* Convert a single-byte string to multibyte
9985 for the *Message* buffer. */
9986 for (i = 0; i < nbytes; i++)
9988 c = msg[i];
9989 MAKE_CHAR_MULTIBYTE (c);
9990 char_bytes = CHAR_STRING (c, str);
9991 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9994 else if (nbytes)
9995 insert_1_both (m, chars_in_text (msg, nbytes), nbytes, 1, 0, 0);
9997 if (nlflag)
9999 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10000 printmax_t dups;
10002 insert_1_both ("\n", 1, 1, 1, 0, 0);
10004 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
10005 this_bol = PT;
10006 this_bol_byte = PT_BYTE;
10008 /* See if this line duplicates the previous one.
10009 If so, combine duplicates. */
10010 if (this_bol > BEG)
10012 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
10013 prev_bol = PT;
10014 prev_bol_byte = PT_BYTE;
10016 dups = message_log_check_duplicate (prev_bol_byte,
10017 this_bol_byte);
10018 if (dups)
10020 del_range_both (prev_bol, prev_bol_byte,
10021 this_bol, this_bol_byte, 0);
10022 if (dups > 1)
10024 char dupstr[sizeof " [ times]"
10025 + INT_STRLEN_BOUND (printmax_t)];
10027 /* If you change this format, don't forget to also
10028 change message_log_check_duplicate. */
10029 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10030 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10031 insert_1_both (dupstr, duplen, duplen, 1, 0, 1);
10036 /* If we have more than the desired maximum number of lines
10037 in the *Messages* buffer now, delete the oldest ones.
10038 This is safe because we don't have undo in this buffer. */
10040 if (NATNUMP (Vmessage_log_max))
10042 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10043 -XFASTINT (Vmessage_log_max) - 1, 0);
10044 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
10047 BEGV = marker_position (oldbegv);
10048 BEGV_BYTE = marker_byte_position (oldbegv);
10050 if (zv_at_end)
10052 ZV = Z;
10053 ZV_BYTE = Z_BYTE;
10055 else
10057 ZV = marker_position (oldzv);
10058 ZV_BYTE = marker_byte_position (oldzv);
10061 if (point_at_end)
10062 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10063 else
10064 /* We can't do Fgoto_char (oldpoint) because it will run some
10065 Lisp code. */
10066 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10067 marker_byte_position (oldpoint));
10069 UNGCPRO;
10070 unchain_marker (XMARKER (oldpoint));
10071 unchain_marker (XMARKER (oldbegv));
10072 unchain_marker (XMARKER (oldzv));
10074 /* We called insert_1_both above with its 5th argument (PREPARE)
10075 zero, which prevents insert_1_both from calling
10076 prepare_to_modify_buffer, which in turns prevents us from
10077 incrementing windows_or_buffers_changed even if *Messages* is
10078 shown in some window. So we must manually set
10079 windows_or_buffers_changed here to make up for that. */
10080 windows_or_buffers_changed = old_windows_or_buffers_changed;
10081 bset_redisplay (current_buffer);
10083 set_buffer_internal (oldbuf);
10085 message_log_need_newline = !nlflag;
10086 Vdeactivate_mark = old_deactivate_mark;
10091 /* We are at the end of the buffer after just having inserted a newline.
10092 (Note: We depend on the fact we won't be crossing the gap.)
10093 Check to see if the most recent message looks a lot like the previous one.
10094 Return 0 if different, 1 if the new one should just replace it, or a
10095 value N > 1 if we should also append " [N times]". */
10097 static intmax_t
10098 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10100 ptrdiff_t i;
10101 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10102 int seen_dots = 0;
10103 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10104 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10106 for (i = 0; i < len; i++)
10108 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10109 seen_dots = 1;
10110 if (p1[i] != p2[i])
10111 return seen_dots;
10113 p1 += len;
10114 if (*p1 == '\n')
10115 return 2;
10116 if (*p1++ == ' ' && *p1++ == '[')
10118 char *pend;
10119 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10120 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10121 return n + 1;
10123 return 0;
10127 /* Display an echo area message M with a specified length of NBYTES
10128 bytes. The string may include null characters. If M is not a
10129 string, clear out any existing message, and let the mini-buffer
10130 text show through.
10132 This function cancels echoing. */
10134 void
10135 message3 (Lisp_Object m)
10137 struct gcpro gcpro1;
10139 GCPRO1 (m);
10140 clear_message (true, true);
10141 cancel_echoing ();
10143 /* First flush out any partial line written with print. */
10144 message_log_maybe_newline ();
10145 if (STRINGP (m))
10147 ptrdiff_t nbytes = SBYTES (m);
10148 bool multibyte = STRING_MULTIBYTE (m);
10149 USE_SAFE_ALLOCA;
10150 char *buffer = SAFE_ALLOCA (nbytes);
10151 memcpy (buffer, SDATA (m), nbytes);
10152 message_dolog (buffer, nbytes, 1, multibyte);
10153 SAFE_FREE ();
10155 message3_nolog (m);
10157 UNGCPRO;
10161 /* The non-logging version of message3.
10162 This does not cancel echoing, because it is used for echoing.
10163 Perhaps we need to make a separate function for echoing
10164 and make this cancel echoing. */
10166 void
10167 message3_nolog (Lisp_Object m)
10169 struct frame *sf = SELECTED_FRAME ();
10171 if (FRAME_INITIAL_P (sf))
10173 if (noninteractive_need_newline)
10174 putc ('\n', stderr);
10175 noninteractive_need_newline = 0;
10176 if (STRINGP (m))
10178 Lisp_Object s = ENCODE_SYSTEM (m);
10180 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10182 if (cursor_in_echo_area == 0)
10183 fprintf (stderr, "\n");
10184 fflush (stderr);
10186 /* Error messages get reported properly by cmd_error, so this must be just an
10187 informative message; if the frame hasn't really been initialized yet, just
10188 toss it. */
10189 else if (INTERACTIVE && sf->glyphs_initialized_p)
10191 /* Get the frame containing the mini-buffer
10192 that the selected frame is using. */
10193 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10194 Lisp_Object frame = XWINDOW (mini_window)->frame;
10195 struct frame *f = XFRAME (frame);
10197 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10198 Fmake_frame_visible (frame);
10200 if (STRINGP (m) && SCHARS (m) > 0)
10202 set_message (m);
10203 if (minibuffer_auto_raise)
10204 Fraise_frame (frame);
10205 /* Assume we are not echoing.
10206 (If we are, echo_now will override this.) */
10207 echo_message_buffer = Qnil;
10209 else
10210 clear_message (true, true);
10212 do_pending_window_change (0);
10213 echo_area_display (1);
10214 do_pending_window_change (0);
10215 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10216 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10221 /* Display a null-terminated echo area message M. If M is 0, clear
10222 out any existing message, and let the mini-buffer text show through.
10224 The buffer M must continue to exist until after the echo area gets
10225 cleared or some other message gets displayed there. Do not pass
10226 text that is stored in a Lisp string. Do not pass text in a buffer
10227 that was alloca'd. */
10229 void
10230 message1 (const char *m)
10232 message3 (m ? build_unibyte_string (m) : Qnil);
10236 /* The non-logging counterpart of message1. */
10238 void
10239 message1_nolog (const char *m)
10241 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10244 /* Display a message M which contains a single %s
10245 which gets replaced with STRING. */
10247 void
10248 message_with_string (const char *m, Lisp_Object string, int log)
10250 CHECK_STRING (string);
10252 if (noninteractive)
10254 if (m)
10256 /* ENCODE_SYSTEM below can GC and/or relocate the
10257 Lisp data, so make sure we don't use it here. */
10258 eassert (relocatable_string_data_p (m) != 1);
10260 if (noninteractive_need_newline)
10261 putc ('\n', stderr);
10262 noninteractive_need_newline = 0;
10263 fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
10264 if (!cursor_in_echo_area)
10265 fprintf (stderr, "\n");
10266 fflush (stderr);
10269 else if (INTERACTIVE)
10271 /* The frame whose minibuffer we're going to display the message on.
10272 It may be larger than the selected frame, so we need
10273 to use its buffer, not the selected frame's buffer. */
10274 Lisp_Object mini_window;
10275 struct frame *f, *sf = SELECTED_FRAME ();
10277 /* Get the frame containing the minibuffer
10278 that the selected frame is using. */
10279 mini_window = FRAME_MINIBUF_WINDOW (sf);
10280 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10282 /* Error messages get reported properly by cmd_error, so this must be
10283 just an informative message; if the frame hasn't really been
10284 initialized yet, just toss it. */
10285 if (f->glyphs_initialized_p)
10287 Lisp_Object args[2], msg;
10288 struct gcpro gcpro1, gcpro2;
10290 args[0] = build_string (m);
10291 args[1] = msg = string;
10292 GCPRO2 (args[0], msg);
10293 gcpro1.nvars = 2;
10295 msg = Fformat (2, args);
10297 if (log)
10298 message3 (msg);
10299 else
10300 message3_nolog (msg);
10302 UNGCPRO;
10304 /* Print should start at the beginning of the message
10305 buffer next time. */
10306 message_buf_print = 0;
10312 /* Dump an informative message to the minibuf. If M is 0, clear out
10313 any existing message, and let the mini-buffer text show through. */
10315 static void
10316 vmessage (const char *m, va_list ap)
10318 if (noninteractive)
10320 if (m)
10322 if (noninteractive_need_newline)
10323 putc ('\n', stderr);
10324 noninteractive_need_newline = 0;
10325 vfprintf (stderr, m, ap);
10326 if (cursor_in_echo_area == 0)
10327 fprintf (stderr, "\n");
10328 fflush (stderr);
10331 else if (INTERACTIVE)
10333 /* The frame whose mini-buffer we're going to display the message
10334 on. It may be larger than the selected frame, so we need to
10335 use its buffer, not the selected frame's buffer. */
10336 Lisp_Object mini_window;
10337 struct frame *f, *sf = SELECTED_FRAME ();
10339 /* Get the frame containing the mini-buffer
10340 that the selected frame is using. */
10341 mini_window = FRAME_MINIBUF_WINDOW (sf);
10342 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10344 /* Error messages get reported properly by cmd_error, so this must be
10345 just an informative message; if the frame hasn't really been
10346 initialized yet, just toss it. */
10347 if (f->glyphs_initialized_p)
10349 if (m)
10351 ptrdiff_t len;
10352 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10353 char *message_buf = alloca (maxsize + 1);
10355 len = doprnt (message_buf, maxsize, m, 0, ap);
10357 message3 (make_string (message_buf, len));
10359 else
10360 message1 (0);
10362 /* Print should start at the beginning of the message
10363 buffer next time. */
10364 message_buf_print = 0;
10369 void
10370 message (const char *m, ...)
10372 va_list ap;
10373 va_start (ap, m);
10374 vmessage (m, ap);
10375 va_end (ap);
10379 #if 0
10380 /* The non-logging version of message. */
10382 void
10383 message_nolog (const char *m, ...)
10385 Lisp_Object old_log_max;
10386 va_list ap;
10387 va_start (ap, m);
10388 old_log_max = Vmessage_log_max;
10389 Vmessage_log_max = Qnil;
10390 vmessage (m, ap);
10391 Vmessage_log_max = old_log_max;
10392 va_end (ap);
10394 #endif
10397 /* Display the current message in the current mini-buffer. This is
10398 only called from error handlers in process.c, and is not time
10399 critical. */
10401 void
10402 update_echo_area (void)
10404 if (!NILP (echo_area_buffer[0]))
10406 Lisp_Object string;
10407 string = Fcurrent_message ();
10408 message3 (string);
10413 /* Make sure echo area buffers in `echo_buffers' are live.
10414 If they aren't, make new ones. */
10416 static void
10417 ensure_echo_area_buffers (void)
10419 int i;
10421 for (i = 0; i < 2; ++i)
10422 if (!BUFFERP (echo_buffer[i])
10423 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10425 char name[30];
10426 Lisp_Object old_buffer;
10427 int j;
10429 old_buffer = echo_buffer[i];
10430 echo_buffer[i] = Fget_buffer_create
10431 (make_formatted_string (name, " *Echo Area %d*", i));
10432 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10433 /* to force word wrap in echo area -
10434 it was decided to postpone this*/
10435 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10437 for (j = 0; j < 2; ++j)
10438 if (EQ (old_buffer, echo_area_buffer[j]))
10439 echo_area_buffer[j] = echo_buffer[i];
10444 /* Call FN with args A1..A2 with either the current or last displayed
10445 echo_area_buffer as current buffer.
10447 WHICH zero means use the current message buffer
10448 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10449 from echo_buffer[] and clear it.
10451 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10452 suitable buffer from echo_buffer[] and clear it.
10454 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10455 that the current message becomes the last displayed one, make
10456 choose a suitable buffer for echo_area_buffer[0], and clear it.
10458 Value is what FN returns. */
10460 static int
10461 with_echo_area_buffer (struct window *w, int which,
10462 int (*fn) (ptrdiff_t, Lisp_Object),
10463 ptrdiff_t a1, Lisp_Object a2)
10465 Lisp_Object buffer;
10466 int this_one, the_other, clear_buffer_p, rc;
10467 ptrdiff_t count = SPECPDL_INDEX ();
10469 /* If buffers aren't live, make new ones. */
10470 ensure_echo_area_buffers ();
10472 clear_buffer_p = 0;
10474 if (which == 0)
10475 this_one = 0, the_other = 1;
10476 else if (which > 0)
10477 this_one = 1, the_other = 0;
10478 else
10480 this_one = 0, the_other = 1;
10481 clear_buffer_p = true;
10483 /* We need a fresh one in case the current echo buffer equals
10484 the one containing the last displayed echo area message. */
10485 if (!NILP (echo_area_buffer[this_one])
10486 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10487 echo_area_buffer[this_one] = Qnil;
10490 /* Choose a suitable buffer from echo_buffer[] is we don't
10491 have one. */
10492 if (NILP (echo_area_buffer[this_one]))
10494 echo_area_buffer[this_one]
10495 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10496 ? echo_buffer[the_other]
10497 : echo_buffer[this_one]);
10498 clear_buffer_p = true;
10501 buffer = echo_area_buffer[this_one];
10503 /* Don't get confused by reusing the buffer used for echoing
10504 for a different purpose. */
10505 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10506 cancel_echoing ();
10508 record_unwind_protect (unwind_with_echo_area_buffer,
10509 with_echo_area_buffer_unwind_data (w));
10511 /* Make the echo area buffer current. Note that for display
10512 purposes, it is not necessary that the displayed window's buffer
10513 == current_buffer, except for text property lookup. So, let's
10514 only set that buffer temporarily here without doing a full
10515 Fset_window_buffer. We must also change w->pointm, though,
10516 because otherwise an assertions in unshow_buffer fails, and Emacs
10517 aborts. */
10518 set_buffer_internal_1 (XBUFFER (buffer));
10519 if (w)
10521 wset_buffer (w, buffer);
10522 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10523 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10526 bset_undo_list (current_buffer, Qt);
10527 bset_read_only (current_buffer, Qnil);
10528 specbind (Qinhibit_read_only, Qt);
10529 specbind (Qinhibit_modification_hooks, Qt);
10531 if (clear_buffer_p && Z > BEG)
10532 del_range (BEG, Z);
10534 eassert (BEGV >= BEG);
10535 eassert (ZV <= Z && ZV >= BEGV);
10537 rc = fn (a1, a2);
10539 eassert (BEGV >= BEG);
10540 eassert (ZV <= Z && ZV >= BEGV);
10542 unbind_to (count, Qnil);
10543 return rc;
10547 /* Save state that should be preserved around the call to the function
10548 FN called in with_echo_area_buffer. */
10550 static Lisp_Object
10551 with_echo_area_buffer_unwind_data (struct window *w)
10553 int i = 0;
10554 Lisp_Object vector, tmp;
10556 /* Reduce consing by keeping one vector in
10557 Vwith_echo_area_save_vector. */
10558 vector = Vwith_echo_area_save_vector;
10559 Vwith_echo_area_save_vector = Qnil;
10561 if (NILP (vector))
10562 vector = Fmake_vector (make_number (11), Qnil);
10564 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10565 ASET (vector, i, Vdeactivate_mark); ++i;
10566 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10568 if (w)
10570 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10571 ASET (vector, i, w->contents); ++i;
10572 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10573 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10574 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10575 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10576 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10577 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10579 else
10581 int end = i + 8;
10582 for (; i < end; ++i)
10583 ASET (vector, i, Qnil);
10586 eassert (i == ASIZE (vector));
10587 return vector;
10591 /* Restore global state from VECTOR which was created by
10592 with_echo_area_buffer_unwind_data. */
10594 static void
10595 unwind_with_echo_area_buffer (Lisp_Object vector)
10597 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10598 Vdeactivate_mark = AREF (vector, 1);
10599 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10601 if (WINDOWP (AREF (vector, 3)))
10603 struct window *w;
10604 Lisp_Object buffer;
10606 w = XWINDOW (AREF (vector, 3));
10607 buffer = AREF (vector, 4);
10609 wset_buffer (w, buffer);
10610 set_marker_both (w->pointm, buffer,
10611 XFASTINT (AREF (vector, 5)),
10612 XFASTINT (AREF (vector, 6)));
10613 set_marker_both (w->old_pointm, buffer,
10614 XFASTINT (AREF (vector, 7)),
10615 XFASTINT (AREF (vector, 8)));
10616 set_marker_both (w->start, buffer,
10617 XFASTINT (AREF (vector, 9)),
10618 XFASTINT (AREF (vector, 10)));
10621 Vwith_echo_area_save_vector = vector;
10625 /* Set up the echo area for use by print functions. MULTIBYTE_P
10626 non-zero means we will print multibyte. */
10628 void
10629 setup_echo_area_for_printing (int multibyte_p)
10631 /* If we can't find an echo area any more, exit. */
10632 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10633 Fkill_emacs (Qnil);
10635 ensure_echo_area_buffers ();
10637 if (!message_buf_print)
10639 /* A message has been output since the last time we printed.
10640 Choose a fresh echo area buffer. */
10641 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10642 echo_area_buffer[0] = echo_buffer[1];
10643 else
10644 echo_area_buffer[0] = echo_buffer[0];
10646 /* Switch to that buffer and clear it. */
10647 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10648 bset_truncate_lines (current_buffer, Qnil);
10650 if (Z > BEG)
10652 ptrdiff_t count = SPECPDL_INDEX ();
10653 specbind (Qinhibit_read_only, Qt);
10654 /* Note that undo recording is always disabled. */
10655 del_range (BEG, Z);
10656 unbind_to (count, Qnil);
10658 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10660 /* Set up the buffer for the multibyteness we need. */
10661 if (multibyte_p
10662 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10663 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10665 /* Raise the frame containing the echo area. */
10666 if (minibuffer_auto_raise)
10668 struct frame *sf = SELECTED_FRAME ();
10669 Lisp_Object mini_window;
10670 mini_window = FRAME_MINIBUF_WINDOW (sf);
10671 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10674 message_log_maybe_newline ();
10675 message_buf_print = 1;
10677 else
10679 if (NILP (echo_area_buffer[0]))
10681 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10682 echo_area_buffer[0] = echo_buffer[1];
10683 else
10684 echo_area_buffer[0] = echo_buffer[0];
10687 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10689 /* Someone switched buffers between print requests. */
10690 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10691 bset_truncate_lines (current_buffer, Qnil);
10697 /* Display an echo area message in window W. Value is non-zero if W's
10698 height is changed. If display_last_displayed_message_p is
10699 non-zero, display the message that was last displayed, otherwise
10700 display the current message. */
10702 static int
10703 display_echo_area (struct window *w)
10705 int i, no_message_p, window_height_changed_p;
10707 /* Temporarily disable garbage collections while displaying the echo
10708 area. This is done because a GC can print a message itself.
10709 That message would modify the echo area buffer's contents while a
10710 redisplay of the buffer is going on, and seriously confuse
10711 redisplay. */
10712 ptrdiff_t count = inhibit_garbage_collection ();
10714 /* If there is no message, we must call display_echo_area_1
10715 nevertheless because it resizes the window. But we will have to
10716 reset the echo_area_buffer in question to nil at the end because
10717 with_echo_area_buffer will sets it to an empty buffer. */
10718 i = display_last_displayed_message_p ? 1 : 0;
10719 no_message_p = NILP (echo_area_buffer[i]);
10721 window_height_changed_p
10722 = with_echo_area_buffer (w, display_last_displayed_message_p,
10723 display_echo_area_1,
10724 (intptr_t) w, Qnil);
10726 if (no_message_p)
10727 echo_area_buffer[i] = Qnil;
10729 unbind_to (count, Qnil);
10730 return window_height_changed_p;
10734 /* Helper for display_echo_area. Display the current buffer which
10735 contains the current echo area message in window W, a mini-window,
10736 a pointer to which is passed in A1. A2..A4 are currently not used.
10737 Change the height of W so that all of the message is displayed.
10738 Value is non-zero if height of W was changed. */
10740 static int
10741 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10743 intptr_t i1 = a1;
10744 struct window *w = (struct window *) i1;
10745 Lisp_Object window;
10746 struct text_pos start;
10747 int window_height_changed_p = 0;
10749 /* Do this before displaying, so that we have a large enough glyph
10750 matrix for the display. If we can't get enough space for the
10751 whole text, display the last N lines. That works by setting w->start. */
10752 window_height_changed_p = resize_mini_window (w, 0);
10754 /* Use the starting position chosen by resize_mini_window. */
10755 SET_TEXT_POS_FROM_MARKER (start, w->start);
10757 /* Display. */
10758 clear_glyph_matrix (w->desired_matrix);
10759 XSETWINDOW (window, w);
10760 try_window (window, start, 0);
10762 return window_height_changed_p;
10766 /* Resize the echo area window to exactly the size needed for the
10767 currently displayed message, if there is one. If a mini-buffer
10768 is active, don't shrink it. */
10770 void
10771 resize_echo_area_exactly (void)
10773 if (BUFFERP (echo_area_buffer[0])
10774 && WINDOWP (echo_area_window))
10776 struct window *w = XWINDOW (echo_area_window);
10777 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10778 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10779 (intptr_t) w, resize_exactly);
10780 if (resized_p)
10782 windows_or_buffers_changed = 42;
10783 update_mode_lines = 30;
10784 redisplay_internal ();
10790 /* Callback function for with_echo_area_buffer, when used from
10791 resize_echo_area_exactly. A1 contains a pointer to the window to
10792 resize, EXACTLY non-nil means resize the mini-window exactly to the
10793 size of the text displayed. A3 and A4 are not used. Value is what
10794 resize_mini_window returns. */
10796 static int
10797 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
10799 intptr_t i1 = a1;
10800 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10804 /* Resize mini-window W to fit the size of its contents. EXACT_P
10805 means size the window exactly to the size needed. Otherwise, it's
10806 only enlarged until W's buffer is empty.
10808 Set W->start to the right place to begin display. If the whole
10809 contents fit, start at the beginning. Otherwise, start so as
10810 to make the end of the contents appear. This is particularly
10811 important for y-or-n-p, but seems desirable generally.
10813 Value is non-zero if the window height has been changed. */
10816 resize_mini_window (struct window *w, int exact_p)
10818 struct frame *f = XFRAME (w->frame);
10819 int window_height_changed_p = 0;
10821 eassert (MINI_WINDOW_P (w));
10823 /* By default, start display at the beginning. */
10824 set_marker_both (w->start, w->contents,
10825 BUF_BEGV (XBUFFER (w->contents)),
10826 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10828 /* Don't resize windows while redisplaying a window; it would
10829 confuse redisplay functions when the size of the window they are
10830 displaying changes from under them. Such a resizing can happen,
10831 for instance, when which-func prints a long message while
10832 we are running fontification-functions. We're running these
10833 functions with safe_call which binds inhibit-redisplay to t. */
10834 if (!NILP (Vinhibit_redisplay))
10835 return 0;
10837 /* Nil means don't try to resize. */
10838 if (NILP (Vresize_mini_windows)
10839 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10840 return 0;
10842 if (!FRAME_MINIBUF_ONLY_P (f))
10844 struct it it;
10845 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
10846 + WINDOW_PIXEL_HEIGHT (w));
10847 int unit = FRAME_LINE_HEIGHT (f);
10848 int height, max_height;
10849 struct text_pos start;
10850 struct buffer *old_current_buffer = NULL;
10852 if (current_buffer != XBUFFER (w->contents))
10854 old_current_buffer = current_buffer;
10855 set_buffer_internal (XBUFFER (w->contents));
10858 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10860 /* Compute the max. number of lines specified by the user. */
10861 if (FLOATP (Vmax_mini_window_height))
10862 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
10863 else if (INTEGERP (Vmax_mini_window_height))
10864 max_height = XINT (Vmax_mini_window_height) * unit;
10865 else
10866 max_height = total_height / 4;
10868 /* Correct that max. height if it's bogus. */
10869 max_height = clip_to_bounds (unit, max_height, total_height);
10871 /* Find out the height of the text in the window. */
10872 if (it.line_wrap == TRUNCATE)
10873 height = unit;
10874 else
10876 last_height = 0;
10877 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10878 if (it.max_ascent == 0 && it.max_descent == 0)
10879 height = it.current_y + last_height;
10880 else
10881 height = it.current_y + it.max_ascent + it.max_descent;
10882 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10885 /* Compute a suitable window start. */
10886 if (height > max_height)
10888 height = (max_height / unit) * unit;
10889 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10890 move_it_vertically_backward (&it, height - unit);
10891 start = it.current.pos;
10893 else
10894 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10895 SET_MARKER_FROM_TEXT_POS (w->start, start);
10897 if (EQ (Vresize_mini_windows, Qgrow_only))
10899 /* Let it grow only, until we display an empty message, in which
10900 case the window shrinks again. */
10901 if (height > WINDOW_PIXEL_HEIGHT (w))
10903 int old_height = WINDOW_PIXEL_HEIGHT (w);
10905 FRAME_WINDOWS_FROZEN (f) = 1;
10906 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10907 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10909 else if (height < WINDOW_PIXEL_HEIGHT (w)
10910 && (exact_p || BEGV == ZV))
10912 int old_height = WINDOW_PIXEL_HEIGHT (w);
10914 FRAME_WINDOWS_FROZEN (f) = 0;
10915 shrink_mini_window (w, 1);
10916 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10919 else
10921 /* Always resize to exact size needed. */
10922 if (height > WINDOW_PIXEL_HEIGHT (w))
10924 int old_height = WINDOW_PIXEL_HEIGHT (w);
10926 FRAME_WINDOWS_FROZEN (f) = 1;
10927 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10928 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10930 else if (height < WINDOW_PIXEL_HEIGHT (w))
10932 int old_height = WINDOW_PIXEL_HEIGHT (w);
10934 FRAME_WINDOWS_FROZEN (f) = 0;
10935 shrink_mini_window (w, 1);
10937 if (height)
10939 FRAME_WINDOWS_FROZEN (f) = 1;
10940 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10943 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10947 if (old_current_buffer)
10948 set_buffer_internal (old_current_buffer);
10951 return window_height_changed_p;
10955 /* Value is the current message, a string, or nil if there is no
10956 current message. */
10958 Lisp_Object
10959 current_message (void)
10961 Lisp_Object msg;
10963 if (!BUFFERP (echo_area_buffer[0]))
10964 msg = Qnil;
10965 else
10967 with_echo_area_buffer (0, 0, current_message_1,
10968 (intptr_t) &msg, Qnil);
10969 if (NILP (msg))
10970 echo_area_buffer[0] = Qnil;
10973 return msg;
10977 static int
10978 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
10980 intptr_t i1 = a1;
10981 Lisp_Object *msg = (Lisp_Object *) i1;
10983 if (Z > BEG)
10984 *msg = make_buffer_string (BEG, Z, 1);
10985 else
10986 *msg = Qnil;
10987 return 0;
10991 /* Push the current message on Vmessage_stack for later restoration
10992 by restore_message. Value is non-zero if the current message isn't
10993 empty. This is a relatively infrequent operation, so it's not
10994 worth optimizing. */
10996 bool
10997 push_message (void)
10999 Lisp_Object msg = current_message ();
11000 Vmessage_stack = Fcons (msg, Vmessage_stack);
11001 return STRINGP (msg);
11005 /* Restore message display from the top of Vmessage_stack. */
11007 void
11008 restore_message (void)
11010 eassert (CONSP (Vmessage_stack));
11011 message3_nolog (XCAR (Vmessage_stack));
11015 /* Handler for unwind-protect calling pop_message. */
11017 void
11018 pop_message_unwind (void)
11020 /* Pop the top-most entry off Vmessage_stack. */
11021 eassert (CONSP (Vmessage_stack));
11022 Vmessage_stack = XCDR (Vmessage_stack);
11026 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11027 exits. If the stack is not empty, we have a missing pop_message
11028 somewhere. */
11030 void
11031 check_message_stack (void)
11033 if (!NILP (Vmessage_stack))
11034 emacs_abort ();
11038 /* Truncate to NCHARS what will be displayed in the echo area the next
11039 time we display it---but don't redisplay it now. */
11041 void
11042 truncate_echo_area (ptrdiff_t nchars)
11044 if (nchars == 0)
11045 echo_area_buffer[0] = Qnil;
11046 else if (!noninteractive
11047 && INTERACTIVE
11048 && !NILP (echo_area_buffer[0]))
11050 struct frame *sf = SELECTED_FRAME ();
11051 /* Error messages get reported properly by cmd_error, so this must be
11052 just an informative message; if the frame hasn't really been
11053 initialized yet, just toss it. */
11054 if (sf->glyphs_initialized_p)
11055 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11060 /* Helper function for truncate_echo_area. Truncate the current
11061 message to at most NCHARS characters. */
11063 static int
11064 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11066 if (BEG + nchars < Z)
11067 del_range (BEG + nchars, Z);
11068 if (Z == BEG)
11069 echo_area_buffer[0] = Qnil;
11070 return 0;
11073 /* Set the current message to STRING. */
11075 static void
11076 set_message (Lisp_Object string)
11078 eassert (STRINGP (string));
11080 message_enable_multibyte = STRING_MULTIBYTE (string);
11082 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11083 message_buf_print = 0;
11084 help_echo_showing_p = 0;
11086 if (STRINGP (Vdebug_on_message)
11087 && STRINGP (string)
11088 && fast_string_match (Vdebug_on_message, string) >= 0)
11089 call_debugger (list2 (Qerror, string));
11093 /* Helper function for set_message. First argument is ignored and second
11094 argument has the same meaning as for set_message.
11095 This function is called with the echo area buffer being current. */
11097 static int
11098 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11100 eassert (STRINGP (string));
11102 /* Change multibyteness of the echo buffer appropriately. */
11103 if (message_enable_multibyte
11104 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11105 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11107 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11108 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11109 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11111 /* Insert new message at BEG. */
11112 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11114 /* This function takes care of single/multibyte conversion.
11115 We just have to ensure that the echo area buffer has the right
11116 setting of enable_multibyte_characters. */
11117 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
11119 return 0;
11123 /* Clear messages. CURRENT_P non-zero means clear the current
11124 message. LAST_DISPLAYED_P non-zero means clear the message
11125 last displayed. */
11127 void
11128 clear_message (bool current_p, bool last_displayed_p)
11130 if (current_p)
11132 echo_area_buffer[0] = Qnil;
11133 message_cleared_p = true;
11136 if (last_displayed_p)
11137 echo_area_buffer[1] = Qnil;
11139 message_buf_print = 0;
11142 /* Clear garbaged frames.
11144 This function is used where the old redisplay called
11145 redraw_garbaged_frames which in turn called redraw_frame which in
11146 turn called clear_frame. The call to clear_frame was a source of
11147 flickering. I believe a clear_frame is not necessary. It should
11148 suffice in the new redisplay to invalidate all current matrices,
11149 and ensure a complete redisplay of all windows. */
11151 static void
11152 clear_garbaged_frames (void)
11154 if (frame_garbaged)
11156 Lisp_Object tail, frame;
11158 FOR_EACH_FRAME (tail, frame)
11160 struct frame *f = XFRAME (frame);
11162 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11164 if (f->resized_p)
11165 redraw_frame (f);
11166 else
11167 clear_current_matrices (f);
11168 fset_redisplay (f);
11169 f->garbaged = false;
11170 f->resized_p = false;
11174 frame_garbaged = false;
11179 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
11180 is non-zero update selected_frame. Value is non-zero if the
11181 mini-windows height has been changed. */
11183 static int
11184 echo_area_display (int update_frame_p)
11186 Lisp_Object mini_window;
11187 struct window *w;
11188 struct frame *f;
11189 int window_height_changed_p = 0;
11190 struct frame *sf = SELECTED_FRAME ();
11192 mini_window = FRAME_MINIBUF_WINDOW (sf);
11193 w = XWINDOW (mini_window);
11194 f = XFRAME (WINDOW_FRAME (w));
11196 /* Don't display if frame is invisible or not yet initialized. */
11197 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11198 return 0;
11200 #ifdef HAVE_WINDOW_SYSTEM
11201 /* When Emacs starts, selected_frame may be the initial terminal
11202 frame. If we let this through, a message would be displayed on
11203 the terminal. */
11204 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11205 return 0;
11206 #endif /* HAVE_WINDOW_SYSTEM */
11208 /* Redraw garbaged frames. */
11209 clear_garbaged_frames ();
11211 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11213 echo_area_window = mini_window;
11214 window_height_changed_p = display_echo_area (w);
11215 w->must_be_updated_p = true;
11217 /* Update the display, unless called from redisplay_internal.
11218 Also don't update the screen during redisplay itself. The
11219 update will happen at the end of redisplay, and an update
11220 here could cause confusion. */
11221 if (update_frame_p && !redisplaying_p)
11223 int n = 0;
11225 /* If the display update has been interrupted by pending
11226 input, update mode lines in the frame. Due to the
11227 pending input, it might have been that redisplay hasn't
11228 been called, so that mode lines above the echo area are
11229 garbaged. This looks odd, so we prevent it here. */
11230 if (!display_completed)
11231 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11233 if (window_height_changed_p
11234 /* Don't do this if Emacs is shutting down. Redisplay
11235 needs to run hooks. */
11236 && !NILP (Vrun_hooks))
11238 /* Must update other windows. Likewise as in other
11239 cases, don't let this update be interrupted by
11240 pending input. */
11241 ptrdiff_t count = SPECPDL_INDEX ();
11242 specbind (Qredisplay_dont_pause, Qt);
11243 windows_or_buffers_changed = 44;
11244 redisplay_internal ();
11245 unbind_to (count, Qnil);
11247 else if (FRAME_WINDOW_P (f) && n == 0)
11249 /* Window configuration is the same as before.
11250 Can do with a display update of the echo area,
11251 unless we displayed some mode lines. */
11252 update_single_window (w, 1);
11253 flush_frame (f);
11255 else
11256 update_frame (f, 1, 1);
11258 /* If cursor is in the echo area, make sure that the next
11259 redisplay displays the minibuffer, so that the cursor will
11260 be replaced with what the minibuffer wants. */
11261 if (cursor_in_echo_area)
11262 wset_redisplay (XWINDOW (mini_window));
11265 else if (!EQ (mini_window, selected_window))
11266 wset_redisplay (XWINDOW (mini_window));
11268 /* Last displayed message is now the current message. */
11269 echo_area_buffer[1] = echo_area_buffer[0];
11270 /* Inform read_char that we're not echoing. */
11271 echo_message_buffer = Qnil;
11273 /* Prevent redisplay optimization in redisplay_internal by resetting
11274 this_line_start_pos. This is done because the mini-buffer now
11275 displays the message instead of its buffer text. */
11276 if (EQ (mini_window, selected_window))
11277 CHARPOS (this_line_start_pos) = 0;
11279 return window_height_changed_p;
11282 /* Nonzero if W's buffer was changed but not saved. */
11284 static int
11285 window_buffer_changed (struct window *w)
11287 struct buffer *b = XBUFFER (w->contents);
11289 eassert (BUFFER_LIVE_P (b));
11291 return (((BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star));
11294 /* Nonzero if W has %c in its mode line and mode line should be updated. */
11296 static int
11297 mode_line_update_needed (struct window *w)
11299 return (w->column_number_displayed != -1
11300 && !(PT == w->last_point && !window_outdated (w))
11301 && (w->column_number_displayed != current_column ()));
11304 /* Nonzero if window start of W is frozen and may not be changed during
11305 redisplay. */
11307 static bool
11308 window_frozen_p (struct window *w)
11310 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11312 Lisp_Object window;
11314 XSETWINDOW (window, w);
11315 if (MINI_WINDOW_P (w))
11316 return 0;
11317 else if (EQ (window, selected_window))
11318 return 0;
11319 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11320 && EQ (window, Vminibuf_scroll_window))
11321 /* This special window can't be frozen too. */
11322 return 0;
11323 else
11324 return 1;
11326 return 0;
11329 /***********************************************************************
11330 Mode Lines and Frame Titles
11331 ***********************************************************************/
11333 /* A buffer for constructing non-propertized mode-line strings and
11334 frame titles in it; allocated from the heap in init_xdisp and
11335 resized as needed in store_mode_line_noprop_char. */
11337 static char *mode_line_noprop_buf;
11339 /* The buffer's end, and a current output position in it. */
11341 static char *mode_line_noprop_buf_end;
11342 static char *mode_line_noprop_ptr;
11344 #define MODE_LINE_NOPROP_LEN(start) \
11345 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11347 static enum {
11348 MODE_LINE_DISPLAY = 0,
11349 MODE_LINE_TITLE,
11350 MODE_LINE_NOPROP,
11351 MODE_LINE_STRING
11352 } mode_line_target;
11354 /* Alist that caches the results of :propertize.
11355 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11356 static Lisp_Object mode_line_proptrans_alist;
11358 /* List of strings making up the mode-line. */
11359 static Lisp_Object mode_line_string_list;
11361 /* Base face property when building propertized mode line string. */
11362 static Lisp_Object mode_line_string_face;
11363 static Lisp_Object mode_line_string_face_prop;
11366 /* Unwind data for mode line strings */
11368 static Lisp_Object Vmode_line_unwind_vector;
11370 static Lisp_Object
11371 format_mode_line_unwind_data (struct frame *target_frame,
11372 struct buffer *obuf,
11373 Lisp_Object owin,
11374 int save_proptrans)
11376 Lisp_Object vector, tmp;
11378 /* Reduce consing by keeping one vector in
11379 Vwith_echo_area_save_vector. */
11380 vector = Vmode_line_unwind_vector;
11381 Vmode_line_unwind_vector = Qnil;
11383 if (NILP (vector))
11384 vector = Fmake_vector (make_number (10), Qnil);
11386 ASET (vector, 0, make_number (mode_line_target));
11387 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11388 ASET (vector, 2, mode_line_string_list);
11389 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11390 ASET (vector, 4, mode_line_string_face);
11391 ASET (vector, 5, mode_line_string_face_prop);
11393 if (obuf)
11394 XSETBUFFER (tmp, obuf);
11395 else
11396 tmp = Qnil;
11397 ASET (vector, 6, tmp);
11398 ASET (vector, 7, owin);
11399 if (target_frame)
11401 /* Similarly to `with-selected-window', if the operation selects
11402 a window on another frame, we must restore that frame's
11403 selected window, and (for a tty) the top-frame. */
11404 ASET (vector, 8, target_frame->selected_window);
11405 if (FRAME_TERMCAP_P (target_frame))
11406 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11409 return vector;
11412 static void
11413 unwind_format_mode_line (Lisp_Object vector)
11415 Lisp_Object old_window = AREF (vector, 7);
11416 Lisp_Object target_frame_window = AREF (vector, 8);
11417 Lisp_Object old_top_frame = AREF (vector, 9);
11419 mode_line_target = XINT (AREF (vector, 0));
11420 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11421 mode_line_string_list = AREF (vector, 2);
11422 if (! EQ (AREF (vector, 3), Qt))
11423 mode_line_proptrans_alist = AREF (vector, 3);
11424 mode_line_string_face = AREF (vector, 4);
11425 mode_line_string_face_prop = AREF (vector, 5);
11427 /* Select window before buffer, since it may change the buffer. */
11428 if (!NILP (old_window))
11430 /* If the operation that we are unwinding had selected a window
11431 on a different frame, reset its frame-selected-window. For a
11432 text terminal, reset its top-frame if necessary. */
11433 if (!NILP (target_frame_window))
11435 Lisp_Object frame
11436 = WINDOW_FRAME (XWINDOW (target_frame_window));
11438 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11439 Fselect_window (target_frame_window, Qt);
11441 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11442 Fselect_frame (old_top_frame, Qt);
11445 Fselect_window (old_window, Qt);
11448 if (!NILP (AREF (vector, 6)))
11450 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11451 ASET (vector, 6, Qnil);
11454 Vmode_line_unwind_vector = vector;
11458 /* Store a single character C for the frame title in mode_line_noprop_buf.
11459 Re-allocate mode_line_noprop_buf if necessary. */
11461 static void
11462 store_mode_line_noprop_char (char c)
11464 /* If output position has reached the end of the allocated buffer,
11465 increase the buffer's size. */
11466 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11468 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11469 ptrdiff_t size = len;
11470 mode_line_noprop_buf =
11471 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11472 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11473 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11476 *mode_line_noprop_ptr++ = c;
11480 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11481 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11482 characters that yield more columns than PRECISION; PRECISION <= 0
11483 means copy the whole string. Pad with spaces until FIELD_WIDTH
11484 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11485 pad. Called from display_mode_element when it is used to build a
11486 frame title. */
11488 static int
11489 store_mode_line_noprop (const char *string, int field_width, int precision)
11491 const unsigned char *str = (const unsigned char *) string;
11492 int n = 0;
11493 ptrdiff_t dummy, nbytes;
11495 /* Copy at most PRECISION chars from STR. */
11496 nbytes = strlen (string);
11497 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11498 while (nbytes--)
11499 store_mode_line_noprop_char (*str++);
11501 /* Fill up with spaces until FIELD_WIDTH reached. */
11502 while (field_width > 0
11503 && n < field_width)
11505 store_mode_line_noprop_char (' ');
11506 ++n;
11509 return n;
11512 /***********************************************************************
11513 Frame Titles
11514 ***********************************************************************/
11516 #ifdef HAVE_WINDOW_SYSTEM
11518 /* Set the title of FRAME, if it has changed. The title format is
11519 Vicon_title_format if FRAME is iconified, otherwise it is
11520 frame_title_format. */
11522 static void
11523 x_consider_frame_title (Lisp_Object frame)
11525 struct frame *f = XFRAME (frame);
11527 if (FRAME_WINDOW_P (f)
11528 || FRAME_MINIBUF_ONLY_P (f)
11529 || f->explicit_name)
11531 /* Do we have more than one visible frame on this X display? */
11532 Lisp_Object tail, other_frame, fmt;
11533 ptrdiff_t title_start;
11534 char *title;
11535 ptrdiff_t len;
11536 struct it it;
11537 ptrdiff_t count = SPECPDL_INDEX ();
11539 FOR_EACH_FRAME (tail, other_frame)
11541 struct frame *tf = XFRAME (other_frame);
11543 if (tf != f
11544 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11545 && !FRAME_MINIBUF_ONLY_P (tf)
11546 && !EQ (other_frame, tip_frame)
11547 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11548 break;
11551 /* Set global variable indicating that multiple frames exist. */
11552 multiple_frames = CONSP (tail);
11554 /* Switch to the buffer of selected window of the frame. Set up
11555 mode_line_target so that display_mode_element will output into
11556 mode_line_noprop_buf; then display the title. */
11557 record_unwind_protect (unwind_format_mode_line,
11558 format_mode_line_unwind_data
11559 (f, current_buffer, selected_window, 0));
11561 Fselect_window (f->selected_window, Qt);
11562 set_buffer_internal_1
11563 (XBUFFER (XWINDOW (f->selected_window)->contents));
11564 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11566 mode_line_target = MODE_LINE_TITLE;
11567 title_start = MODE_LINE_NOPROP_LEN (0);
11568 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11569 NULL, DEFAULT_FACE_ID);
11570 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11571 len = MODE_LINE_NOPROP_LEN (title_start);
11572 title = mode_line_noprop_buf + title_start;
11573 unbind_to (count, Qnil);
11575 /* Set the title only if it's changed. This avoids consing in
11576 the common case where it hasn't. (If it turns out that we've
11577 already wasted too much time by walking through the list with
11578 display_mode_element, then we might need to optimize at a
11579 higher level than this.) */
11580 if (! STRINGP (f->name)
11581 || SBYTES (f->name) != len
11582 || memcmp (title, SDATA (f->name), len) != 0)
11583 x_implicitly_set_name (f, make_string (title, len), Qnil);
11587 #endif /* not HAVE_WINDOW_SYSTEM */
11590 /***********************************************************************
11591 Menu Bars
11592 ***********************************************************************/
11594 /* Non-zero if we will not redisplay all visible windows. */
11595 #define REDISPLAY_SOME_P() \
11596 ((windows_or_buffers_changed == 0 \
11597 || windows_or_buffers_changed == REDISPLAY_SOME) \
11598 && (update_mode_lines == 0 \
11599 || update_mode_lines == REDISPLAY_SOME))
11601 /* Prepare for redisplay by updating menu-bar item lists when
11602 appropriate. This can call eval. */
11604 static void
11605 prepare_menu_bars (void)
11607 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11608 bool some_windows = REDISPLAY_SOME_P ();
11609 struct gcpro gcpro1, gcpro2;
11610 Lisp_Object tooltip_frame;
11612 #ifdef HAVE_WINDOW_SYSTEM
11613 tooltip_frame = tip_frame;
11614 #else
11615 tooltip_frame = Qnil;
11616 #endif
11618 if (FUNCTIONP (Vpre_redisplay_function))
11620 Lisp_Object windows = all_windows ? Qt : Qnil;
11621 if (all_windows && some_windows)
11623 Lisp_Object ws = window_list ();
11624 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11626 Lisp_Object this = XCAR (ws);
11627 struct window *w = XWINDOW (this);
11628 if (w->redisplay
11629 || XFRAME (w->frame)->redisplay
11630 || XBUFFER (w->contents)->text->redisplay)
11632 windows = Fcons (this, windows);
11636 safe__call1 (true, Vpre_redisplay_function, windows);
11639 /* Update all frame titles based on their buffer names, etc. We do
11640 this before the menu bars so that the buffer-menu will show the
11641 up-to-date frame titles. */
11642 #ifdef HAVE_WINDOW_SYSTEM
11643 if (all_windows)
11645 Lisp_Object tail, frame;
11647 FOR_EACH_FRAME (tail, frame)
11649 struct frame *f = XFRAME (frame);
11650 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11651 if (some_windows
11652 && !f->redisplay
11653 && !w->redisplay
11654 && !XBUFFER (w->contents)->text->redisplay)
11655 continue;
11657 if (!EQ (frame, tooltip_frame)
11658 && (FRAME_ICONIFIED_P (f)
11659 || FRAME_VISIBLE_P (f) == 1
11660 /* Exclude TTY frames that are obscured because they
11661 are not the top frame on their console. This is
11662 because x_consider_frame_title actually switches
11663 to the frame, which for TTY frames means it is
11664 marked as garbaged, and will be completely
11665 redrawn on the next redisplay cycle. This causes
11666 TTY frames to be completely redrawn, when there
11667 are more than one of them, even though nothing
11668 should be changed on display. */
11669 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11670 x_consider_frame_title (frame);
11673 #endif /* HAVE_WINDOW_SYSTEM */
11675 /* Update the menu bar item lists, if appropriate. This has to be
11676 done before any actual redisplay or generation of display lines. */
11678 if (all_windows)
11680 Lisp_Object tail, frame;
11681 ptrdiff_t count = SPECPDL_INDEX ();
11682 /* 1 means that update_menu_bar has run its hooks
11683 so any further calls to update_menu_bar shouldn't do so again. */
11684 int menu_bar_hooks_run = 0;
11686 record_unwind_save_match_data ();
11688 FOR_EACH_FRAME (tail, frame)
11690 struct frame *f = XFRAME (frame);
11691 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11693 /* Ignore tooltip frame. */
11694 if (EQ (frame, tooltip_frame))
11695 continue;
11697 if (some_windows
11698 && !f->redisplay
11699 && !w->redisplay
11700 && !XBUFFER (w->contents)->text->redisplay)
11701 continue;
11703 /* If a window on this frame changed size, report that to
11704 the user and clear the size-change flag. */
11705 if (FRAME_WINDOW_SIZES_CHANGED (f))
11707 Lisp_Object functions;
11709 /* Clear flag first in case we get an error below. */
11710 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11711 functions = Vwindow_size_change_functions;
11712 GCPRO2 (tail, functions);
11714 while (CONSP (functions))
11716 if (!EQ (XCAR (functions), Qt))
11717 call1 (XCAR (functions), frame);
11718 functions = XCDR (functions);
11720 UNGCPRO;
11723 GCPRO1 (tail);
11724 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11725 #ifdef HAVE_WINDOW_SYSTEM
11726 update_tool_bar (f, 0);
11727 #endif
11728 #ifdef HAVE_NS
11729 if (windows_or_buffers_changed
11730 && FRAME_NS_P (f))
11731 ns_set_doc_edited
11732 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11733 #endif
11734 UNGCPRO;
11737 unbind_to (count, Qnil);
11739 else
11741 struct frame *sf = SELECTED_FRAME ();
11742 update_menu_bar (sf, 1, 0);
11743 #ifdef HAVE_WINDOW_SYSTEM
11744 update_tool_bar (sf, 1);
11745 #endif
11750 /* Update the menu bar item list for frame F. This has to be done
11751 before we start to fill in any display lines, because it can call
11752 eval.
11754 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11756 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11757 already ran the menu bar hooks for this redisplay, so there
11758 is no need to run them again. The return value is the
11759 updated value of this flag, to pass to the next call. */
11761 static int
11762 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11764 Lisp_Object window;
11765 register struct window *w;
11767 /* If called recursively during a menu update, do nothing. This can
11768 happen when, for instance, an activate-menubar-hook causes a
11769 redisplay. */
11770 if (inhibit_menubar_update)
11771 return hooks_run;
11773 window = FRAME_SELECTED_WINDOW (f);
11774 w = XWINDOW (window);
11776 if (FRAME_WINDOW_P (f)
11778 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11779 || defined (HAVE_NS) || defined (USE_GTK)
11780 FRAME_EXTERNAL_MENU_BAR (f)
11781 #else
11782 FRAME_MENU_BAR_LINES (f) > 0
11783 #endif
11784 : FRAME_MENU_BAR_LINES (f) > 0)
11786 /* If the user has switched buffers or windows, we need to
11787 recompute to reflect the new bindings. But we'll
11788 recompute when update_mode_lines is set too; that means
11789 that people can use force-mode-line-update to request
11790 that the menu bar be recomputed. The adverse effect on
11791 the rest of the redisplay algorithm is about the same as
11792 windows_or_buffers_changed anyway. */
11793 if (windows_or_buffers_changed
11794 /* This used to test w->update_mode_line, but we believe
11795 there is no need to recompute the menu in that case. */
11796 || update_mode_lines
11797 || window_buffer_changed (w))
11799 struct buffer *prev = current_buffer;
11800 ptrdiff_t count = SPECPDL_INDEX ();
11802 specbind (Qinhibit_menubar_update, Qt);
11804 set_buffer_internal_1 (XBUFFER (w->contents));
11805 if (save_match_data)
11806 record_unwind_save_match_data ();
11807 if (NILP (Voverriding_local_map_menu_flag))
11809 specbind (Qoverriding_terminal_local_map, Qnil);
11810 specbind (Qoverriding_local_map, Qnil);
11813 if (!hooks_run)
11815 /* Run the Lucid hook. */
11816 safe_run_hooks (Qactivate_menubar_hook);
11818 /* If it has changed current-menubar from previous value,
11819 really recompute the menu-bar from the value. */
11820 if (! NILP (Vlucid_menu_bar_dirty_flag))
11821 call0 (Qrecompute_lucid_menubar);
11823 safe_run_hooks (Qmenu_bar_update_hook);
11825 hooks_run = 1;
11828 XSETFRAME (Vmenu_updating_frame, f);
11829 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11831 /* Redisplay the menu bar in case we changed it. */
11832 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11833 || defined (HAVE_NS) || defined (USE_GTK)
11834 if (FRAME_WINDOW_P (f))
11836 #if defined (HAVE_NS)
11837 /* All frames on Mac OS share the same menubar. So only
11838 the selected frame should be allowed to set it. */
11839 if (f == SELECTED_FRAME ())
11840 #endif
11841 set_frame_menubar (f, 0, 0);
11843 else
11844 /* On a terminal screen, the menu bar is an ordinary screen
11845 line, and this makes it get updated. */
11846 w->update_mode_line = 1;
11847 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11848 /* In the non-toolkit version, the menu bar is an ordinary screen
11849 line, and this makes it get updated. */
11850 w->update_mode_line = 1;
11851 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11853 unbind_to (count, Qnil);
11854 set_buffer_internal_1 (prev);
11858 return hooks_run;
11861 /***********************************************************************
11862 Tool-bars
11863 ***********************************************************************/
11865 #ifdef HAVE_WINDOW_SYSTEM
11867 /* Select `frame' temporarily without running all the code in
11868 do_switch_frame.
11869 FIXME: Maybe do_switch_frame should be trimmed down similarly
11870 when `norecord' is set. */
11871 static void
11872 fast_set_selected_frame (Lisp_Object frame)
11874 if (!EQ (selected_frame, frame))
11876 selected_frame = frame;
11877 selected_window = XFRAME (frame)->selected_window;
11881 /* Update the tool-bar item list for frame F. This has to be done
11882 before we start to fill in any display lines. Called from
11883 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11884 and restore it here. */
11886 static void
11887 update_tool_bar (struct frame *f, int save_match_data)
11889 #if defined (USE_GTK) || defined (HAVE_NS)
11890 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11891 #else
11892 int do_update = (WINDOWP (f->tool_bar_window)
11893 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
11894 #endif
11896 if (do_update)
11898 Lisp_Object window;
11899 struct window *w;
11901 window = FRAME_SELECTED_WINDOW (f);
11902 w = XWINDOW (window);
11904 /* If the user has switched buffers or windows, we need to
11905 recompute to reflect the new bindings. But we'll
11906 recompute when update_mode_lines is set too; that means
11907 that people can use force-mode-line-update to request
11908 that the menu bar be recomputed. The adverse effect on
11909 the rest of the redisplay algorithm is about the same as
11910 windows_or_buffers_changed anyway. */
11911 if (windows_or_buffers_changed
11912 || w->update_mode_line
11913 || update_mode_lines
11914 || window_buffer_changed (w))
11916 struct buffer *prev = current_buffer;
11917 ptrdiff_t count = SPECPDL_INDEX ();
11918 Lisp_Object frame, new_tool_bar;
11919 int new_n_tool_bar;
11920 struct gcpro gcpro1;
11922 /* Set current_buffer to the buffer of the selected
11923 window of the frame, so that we get the right local
11924 keymaps. */
11925 set_buffer_internal_1 (XBUFFER (w->contents));
11927 /* Save match data, if we must. */
11928 if (save_match_data)
11929 record_unwind_save_match_data ();
11931 /* Make sure that we don't accidentally use bogus keymaps. */
11932 if (NILP (Voverriding_local_map_menu_flag))
11934 specbind (Qoverriding_terminal_local_map, Qnil);
11935 specbind (Qoverriding_local_map, Qnil);
11938 GCPRO1 (new_tool_bar);
11940 /* We must temporarily set the selected frame to this frame
11941 before calling tool_bar_items, because the calculation of
11942 the tool-bar keymap uses the selected frame (see
11943 `tool-bar-make-keymap' in tool-bar.el). */
11944 eassert (EQ (selected_window,
11945 /* Since we only explicitly preserve selected_frame,
11946 check that selected_window would be redundant. */
11947 XFRAME (selected_frame)->selected_window));
11948 record_unwind_protect (fast_set_selected_frame, selected_frame);
11949 XSETFRAME (frame, f);
11950 fast_set_selected_frame (frame);
11952 /* Build desired tool-bar items from keymaps. */
11953 new_tool_bar
11954 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11955 &new_n_tool_bar);
11957 /* Redisplay the tool-bar if we changed it. */
11958 if (new_n_tool_bar != f->n_tool_bar_items
11959 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11961 /* Redisplay that happens asynchronously due to an expose event
11962 may access f->tool_bar_items. Make sure we update both
11963 variables within BLOCK_INPUT so no such event interrupts. */
11964 block_input ();
11965 fset_tool_bar_items (f, new_tool_bar);
11966 f->n_tool_bar_items = new_n_tool_bar;
11967 w->update_mode_line = 1;
11968 unblock_input ();
11971 UNGCPRO;
11973 unbind_to (count, Qnil);
11974 set_buffer_internal_1 (prev);
11979 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
11981 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11982 F's desired tool-bar contents. F->tool_bar_items must have
11983 been set up previously by calling prepare_menu_bars. */
11985 static void
11986 build_desired_tool_bar_string (struct frame *f)
11988 int i, size, size_needed;
11989 struct gcpro gcpro1, gcpro2, gcpro3;
11990 Lisp_Object image, plist, props;
11992 image = plist = props = Qnil;
11993 GCPRO3 (image, plist, props);
11995 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11996 Otherwise, make a new string. */
11998 /* The size of the string we might be able to reuse. */
11999 size = (STRINGP (f->desired_tool_bar_string)
12000 ? SCHARS (f->desired_tool_bar_string)
12001 : 0);
12003 /* We need one space in the string for each image. */
12004 size_needed = f->n_tool_bar_items;
12006 /* Reuse f->desired_tool_bar_string, if possible. */
12007 if (size < size_needed || NILP (f->desired_tool_bar_string))
12008 fset_desired_tool_bar_string
12009 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12010 else
12012 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
12013 Fremove_text_properties (make_number (0), make_number (size),
12014 props, f->desired_tool_bar_string);
12017 /* Put a `display' property on the string for the images to display,
12018 put a `menu_item' property on tool-bar items with a value that
12019 is the index of the item in F's tool-bar item vector. */
12020 for (i = 0; i < f->n_tool_bar_items; ++i)
12022 #define PROP(IDX) \
12023 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12025 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12026 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12027 int hmargin, vmargin, relief, idx, end;
12029 /* If image is a vector, choose the image according to the
12030 button state. */
12031 image = PROP (TOOL_BAR_ITEM_IMAGES);
12032 if (VECTORP (image))
12034 if (enabled_p)
12035 idx = (selected_p
12036 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12037 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12038 else
12039 idx = (selected_p
12040 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12041 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12043 eassert (ASIZE (image) >= idx);
12044 image = AREF (image, idx);
12046 else
12047 idx = -1;
12049 /* Ignore invalid image specifications. */
12050 if (!valid_image_p (image))
12051 continue;
12053 /* Display the tool-bar button pressed, or depressed. */
12054 plist = Fcopy_sequence (XCDR (image));
12056 /* Compute margin and relief to draw. */
12057 relief = (tool_bar_button_relief >= 0
12058 ? tool_bar_button_relief
12059 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12060 hmargin = vmargin = relief;
12062 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12063 INT_MAX - max (hmargin, vmargin)))
12065 hmargin += XFASTINT (Vtool_bar_button_margin);
12066 vmargin += XFASTINT (Vtool_bar_button_margin);
12068 else if (CONSP (Vtool_bar_button_margin))
12070 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12071 INT_MAX - hmargin))
12072 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12074 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12075 INT_MAX - vmargin))
12076 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12079 if (auto_raise_tool_bar_buttons_p)
12081 /* Add a `:relief' property to the image spec if the item is
12082 selected. */
12083 if (selected_p)
12085 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12086 hmargin -= relief;
12087 vmargin -= relief;
12090 else
12092 /* If image is selected, display it pressed, i.e. with a
12093 negative relief. If it's not selected, display it with a
12094 raised relief. */
12095 plist = Fplist_put (plist, QCrelief,
12096 (selected_p
12097 ? make_number (-relief)
12098 : make_number (relief)));
12099 hmargin -= relief;
12100 vmargin -= relief;
12103 /* Put a margin around the image. */
12104 if (hmargin || vmargin)
12106 if (hmargin == vmargin)
12107 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12108 else
12109 plist = Fplist_put (plist, QCmargin,
12110 Fcons (make_number (hmargin),
12111 make_number (vmargin)));
12114 /* If button is not enabled, and we don't have special images
12115 for the disabled state, make the image appear disabled by
12116 applying an appropriate algorithm to it. */
12117 if (!enabled_p && idx < 0)
12118 plist = Fplist_put (plist, QCconversion, Qdisabled);
12120 /* Put a `display' text property on the string for the image to
12121 display. Put a `menu-item' property on the string that gives
12122 the start of this item's properties in the tool-bar items
12123 vector. */
12124 image = Fcons (Qimage, plist);
12125 props = list4 (Qdisplay, image,
12126 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
12128 /* Let the last image hide all remaining spaces in the tool bar
12129 string. The string can be longer than needed when we reuse a
12130 previous string. */
12131 if (i + 1 == f->n_tool_bar_items)
12132 end = SCHARS (f->desired_tool_bar_string);
12133 else
12134 end = i + 1;
12135 Fadd_text_properties (make_number (i), make_number (end),
12136 props, f->desired_tool_bar_string);
12137 #undef PROP
12140 UNGCPRO;
12144 /* Display one line of the tool-bar of frame IT->f.
12146 HEIGHT specifies the desired height of the tool-bar line.
12147 If the actual height of the glyph row is less than HEIGHT, the
12148 row's height is increased to HEIGHT, and the icons are centered
12149 vertically in the new height.
12151 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12152 count a final empty row in case the tool-bar width exactly matches
12153 the window width.
12156 static void
12157 display_tool_bar_line (struct it *it, int height)
12159 struct glyph_row *row = it->glyph_row;
12160 int max_x = it->last_visible_x;
12161 struct glyph *last;
12163 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12164 clear_glyph_row (row);
12165 row->enabled_p = true;
12166 row->y = it->current_y;
12168 /* Note that this isn't made use of if the face hasn't a box,
12169 so there's no need to check the face here. */
12170 it->start_of_box_run_p = 1;
12172 while (it->current_x < max_x)
12174 int x, n_glyphs_before, i, nglyphs;
12175 struct it it_before;
12177 /* Get the next display element. */
12178 if (!get_next_display_element (it))
12180 /* Don't count empty row if we are counting needed tool-bar lines. */
12181 if (height < 0 && !it->hpos)
12182 return;
12183 break;
12186 /* Produce glyphs. */
12187 n_glyphs_before = row->used[TEXT_AREA];
12188 it_before = *it;
12190 PRODUCE_GLYPHS (it);
12192 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12193 i = 0;
12194 x = it_before.current_x;
12195 while (i < nglyphs)
12197 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12199 if (x + glyph->pixel_width > max_x)
12201 /* Glyph doesn't fit on line. Backtrack. */
12202 row->used[TEXT_AREA] = n_glyphs_before;
12203 *it = it_before;
12204 /* If this is the only glyph on this line, it will never fit on the
12205 tool-bar, so skip it. But ensure there is at least one glyph,
12206 so we don't accidentally disable the tool-bar. */
12207 if (n_glyphs_before == 0
12208 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12209 break;
12210 goto out;
12213 ++it->hpos;
12214 x += glyph->pixel_width;
12215 ++i;
12218 /* Stop at line end. */
12219 if (ITERATOR_AT_END_OF_LINE_P (it))
12220 break;
12222 set_iterator_to_next (it, 1);
12225 out:;
12227 row->displays_text_p = row->used[TEXT_AREA] != 0;
12229 /* Use default face for the border below the tool bar.
12231 FIXME: When auto-resize-tool-bars is grow-only, there is
12232 no additional border below the possibly empty tool-bar lines.
12233 So to make the extra empty lines look "normal", we have to
12234 use the tool-bar face for the border too. */
12235 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12236 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12237 it->face_id = DEFAULT_FACE_ID;
12239 extend_face_to_end_of_line (it);
12240 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12241 last->right_box_line_p = 1;
12242 if (last == row->glyphs[TEXT_AREA])
12243 last->left_box_line_p = 1;
12245 /* Make line the desired height and center it vertically. */
12246 if ((height -= it->max_ascent + it->max_descent) > 0)
12248 /* Don't add more than one line height. */
12249 height %= FRAME_LINE_HEIGHT (it->f);
12250 it->max_ascent += height / 2;
12251 it->max_descent += (height + 1) / 2;
12254 compute_line_metrics (it);
12256 /* If line is empty, make it occupy the rest of the tool-bar. */
12257 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12259 row->height = row->phys_height = it->last_visible_y - row->y;
12260 row->visible_height = row->height;
12261 row->ascent = row->phys_ascent = 0;
12262 row->extra_line_spacing = 0;
12265 row->full_width_p = 1;
12266 row->continued_p = 0;
12267 row->truncated_on_left_p = 0;
12268 row->truncated_on_right_p = 0;
12270 it->current_x = it->hpos = 0;
12271 it->current_y += row->height;
12272 ++it->vpos;
12273 ++it->glyph_row;
12277 /* Value is the number of pixels needed to make all tool-bar items of
12278 frame F visible. The actual number of glyph rows needed is
12279 returned in *N_ROWS if non-NULL. */
12280 static int
12281 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12283 struct window *w = XWINDOW (f->tool_bar_window);
12284 struct it it;
12285 /* tool_bar_height is called from redisplay_tool_bar after building
12286 the desired matrix, so use (unused) mode-line row as temporary row to
12287 avoid destroying the first tool-bar row. */
12288 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12290 /* Initialize an iterator for iteration over
12291 F->desired_tool_bar_string in the tool-bar window of frame F. */
12292 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12293 temp_row->reversed_p = false;
12294 it.first_visible_x = 0;
12295 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12296 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12297 it.paragraph_embedding = L2R;
12299 while (!ITERATOR_AT_END_P (&it))
12301 clear_glyph_row (temp_row);
12302 it.glyph_row = temp_row;
12303 display_tool_bar_line (&it, -1);
12305 clear_glyph_row (temp_row);
12307 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12308 if (n_rows)
12309 *n_rows = it.vpos > 0 ? it.vpos : -1;
12311 if (pixelwise)
12312 return it.current_y;
12313 else
12314 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12317 #endif /* !USE_GTK && !HAVE_NS */
12319 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12320 0, 2, 0,
12321 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12322 If FRAME is nil or omitted, use the selected frame. Optional argument
12323 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12324 (Lisp_Object frame, Lisp_Object pixelwise)
12326 int height = 0;
12328 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12329 struct frame *f = decode_any_frame (frame);
12331 if (WINDOWP (f->tool_bar_window)
12332 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12334 update_tool_bar (f, 1);
12335 if (f->n_tool_bar_items)
12337 build_desired_tool_bar_string (f);
12338 height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
12341 #endif
12343 return make_number (height);
12347 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
12348 height should be changed. */
12349 static int
12350 redisplay_tool_bar (struct frame *f)
12352 #if defined (USE_GTK) || defined (HAVE_NS)
12354 if (FRAME_EXTERNAL_TOOL_BAR (f))
12355 update_frame_tool_bar (f);
12356 return 0;
12358 #else /* !USE_GTK && !HAVE_NS */
12360 struct window *w;
12361 struct it it;
12362 struct glyph_row *row;
12364 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12365 do anything. This means you must start with tool-bar-lines
12366 non-zero to get the auto-sizing effect. Or in other words, you
12367 can turn off tool-bars by specifying tool-bar-lines zero. */
12368 if (!WINDOWP (f->tool_bar_window)
12369 || (w = XWINDOW (f->tool_bar_window),
12370 WINDOW_TOTAL_LINES (w) == 0))
12371 return 0;
12373 /* Set up an iterator for the tool-bar window. */
12374 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12375 it.first_visible_x = 0;
12376 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12377 row = it.glyph_row;
12378 row->reversed_p = false;
12380 /* Build a string that represents the contents of the tool-bar. */
12381 build_desired_tool_bar_string (f);
12382 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12383 /* FIXME: This should be controlled by a user option. But it
12384 doesn't make sense to have an R2L tool bar if the menu bar cannot
12385 be drawn also R2L, and making the menu bar R2L is tricky due
12386 toolkit-specific code that implements it. If an R2L tool bar is
12387 ever supported, display_tool_bar_line should also be augmented to
12388 call unproduce_glyphs like display_line and display_string
12389 do. */
12390 it.paragraph_embedding = L2R;
12392 if (f->n_tool_bar_rows == 0)
12394 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
12396 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12398 x_change_tool_bar_height (f, new_height);
12399 /* Always do that now. */
12400 clear_glyph_matrix (w->desired_matrix);
12401 f->fonts_changed = 1;
12402 return 1;
12406 /* Display as many lines as needed to display all tool-bar items. */
12408 if (f->n_tool_bar_rows > 0)
12410 int border, rows, height, extra;
12412 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12413 border = XINT (Vtool_bar_border);
12414 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12415 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12416 else if (EQ (Vtool_bar_border, Qborder_width))
12417 border = f->border_width;
12418 else
12419 border = 0;
12420 if (border < 0)
12421 border = 0;
12423 rows = f->n_tool_bar_rows;
12424 height = max (1, (it.last_visible_y - border) / rows);
12425 extra = it.last_visible_y - border - height * rows;
12427 while (it.current_y < it.last_visible_y)
12429 int h = 0;
12430 if (extra > 0 && rows-- > 0)
12432 h = (extra + rows - 1) / rows;
12433 extra -= h;
12435 display_tool_bar_line (&it, height + h);
12438 else
12440 while (it.current_y < it.last_visible_y)
12441 display_tool_bar_line (&it, 0);
12444 /* It doesn't make much sense to try scrolling in the tool-bar
12445 window, so don't do it. */
12446 w->desired_matrix->no_scrolling_p = 1;
12447 w->must_be_updated_p = 1;
12449 if (!NILP (Vauto_resize_tool_bars))
12451 int change_height_p = 0;
12453 /* If we couldn't display everything, change the tool-bar's
12454 height if there is room for more. */
12455 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12456 change_height_p = 1;
12458 /* We subtract 1 because display_tool_bar_line advances the
12459 glyph_row pointer before returning to its caller. We want to
12460 examine the last glyph row produced by
12461 display_tool_bar_line. */
12462 row = it.glyph_row - 1;
12464 /* If there are blank lines at the end, except for a partially
12465 visible blank line at the end that is smaller than
12466 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12467 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12468 && row->height >= FRAME_LINE_HEIGHT (f))
12469 change_height_p = 1;
12471 /* If row displays tool-bar items, but is partially visible,
12472 change the tool-bar's height. */
12473 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12474 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12475 change_height_p = 1;
12477 /* Resize windows as needed by changing the `tool-bar-lines'
12478 frame parameter. */
12479 if (change_height_p)
12481 int nrows;
12482 int new_height = tool_bar_height (f, &nrows, 1);
12484 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12485 && !f->minimize_tool_bar_window_p)
12486 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12487 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12488 f->minimize_tool_bar_window_p = 0;
12490 if (change_height_p)
12492 x_change_tool_bar_height (f, new_height);
12493 clear_glyph_matrix (w->desired_matrix);
12494 f->n_tool_bar_rows = nrows;
12495 f->fonts_changed = 1;
12497 return 1;
12502 f->minimize_tool_bar_window_p = 0;
12503 return 0;
12505 #endif /* USE_GTK || HAVE_NS */
12508 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12510 /* Get information about the tool-bar item which is displayed in GLYPH
12511 on frame F. Return in *PROP_IDX the index where tool-bar item
12512 properties start in F->tool_bar_items. Value is zero if
12513 GLYPH doesn't display a tool-bar item. */
12515 static int
12516 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12518 Lisp_Object prop;
12519 int success_p;
12520 int charpos;
12522 /* This function can be called asynchronously, which means we must
12523 exclude any possibility that Fget_text_property signals an
12524 error. */
12525 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12526 charpos = max (0, charpos);
12528 /* Get the text property `menu-item' at pos. The value of that
12529 property is the start index of this item's properties in
12530 F->tool_bar_items. */
12531 prop = Fget_text_property (make_number (charpos),
12532 Qmenu_item, f->current_tool_bar_string);
12533 if (INTEGERP (prop))
12535 *prop_idx = XINT (prop);
12536 success_p = 1;
12538 else
12539 success_p = 0;
12541 return success_p;
12545 /* Get information about the tool-bar item at position X/Y on frame F.
12546 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12547 the current matrix of the tool-bar window of F, or NULL if not
12548 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12549 item in F->tool_bar_items. Value is
12551 -1 if X/Y is not on a tool-bar item
12552 0 if X/Y is on the same item that was highlighted before.
12553 1 otherwise. */
12555 static int
12556 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12557 int *hpos, int *vpos, int *prop_idx)
12559 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12560 struct window *w = XWINDOW (f->tool_bar_window);
12561 int area;
12563 /* Find the glyph under X/Y. */
12564 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12565 if (*glyph == NULL)
12566 return -1;
12568 /* Get the start of this tool-bar item's properties in
12569 f->tool_bar_items. */
12570 if (!tool_bar_item_info (f, *glyph, prop_idx))
12571 return -1;
12573 /* Is mouse on the highlighted item? */
12574 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12575 && *vpos >= hlinfo->mouse_face_beg_row
12576 && *vpos <= hlinfo->mouse_face_end_row
12577 && (*vpos > hlinfo->mouse_face_beg_row
12578 || *hpos >= hlinfo->mouse_face_beg_col)
12579 && (*vpos < hlinfo->mouse_face_end_row
12580 || *hpos < hlinfo->mouse_face_end_col
12581 || hlinfo->mouse_face_past_end))
12582 return 0;
12584 return 1;
12588 /* EXPORT:
12589 Handle mouse button event on the tool-bar of frame F, at
12590 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12591 0 for button release. MODIFIERS is event modifiers for button
12592 release. */
12594 void
12595 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12596 int modifiers)
12598 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12599 struct window *w = XWINDOW (f->tool_bar_window);
12600 int hpos, vpos, prop_idx;
12601 struct glyph *glyph;
12602 Lisp_Object enabled_p;
12603 int ts;
12605 /* If not on the highlighted tool-bar item, and mouse-highlight is
12606 non-nil, return. This is so we generate the tool-bar button
12607 click only when the mouse button is released on the same item as
12608 where it was pressed. However, when mouse-highlight is disabled,
12609 generate the click when the button is released regardless of the
12610 highlight, since tool-bar items are not highlighted in that
12611 case. */
12612 frame_to_window_pixel_xy (w, &x, &y);
12613 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12614 if (ts == -1
12615 || (ts != 0 && !NILP (Vmouse_highlight)))
12616 return;
12618 /* When mouse-highlight is off, generate the click for the item
12619 where the button was pressed, disregarding where it was
12620 released. */
12621 if (NILP (Vmouse_highlight) && !down_p)
12622 prop_idx = f->last_tool_bar_item;
12624 /* If item is disabled, do nothing. */
12625 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12626 if (NILP (enabled_p))
12627 return;
12629 if (down_p)
12631 /* Show item in pressed state. */
12632 if (!NILP (Vmouse_highlight))
12633 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12634 f->last_tool_bar_item = prop_idx;
12636 else
12638 Lisp_Object key, frame;
12639 struct input_event event;
12640 EVENT_INIT (event);
12642 /* Show item in released state. */
12643 if (!NILP (Vmouse_highlight))
12644 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12646 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12648 XSETFRAME (frame, f);
12649 event.kind = TOOL_BAR_EVENT;
12650 event.frame_or_window = frame;
12651 event.arg = frame;
12652 kbd_buffer_store_event (&event);
12654 event.kind = TOOL_BAR_EVENT;
12655 event.frame_or_window = frame;
12656 event.arg = key;
12657 event.modifiers = modifiers;
12658 kbd_buffer_store_event (&event);
12659 f->last_tool_bar_item = -1;
12664 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12665 tool-bar window-relative coordinates X/Y. Called from
12666 note_mouse_highlight. */
12668 static void
12669 note_tool_bar_highlight (struct frame *f, int x, int y)
12671 Lisp_Object window = f->tool_bar_window;
12672 struct window *w = XWINDOW (window);
12673 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
12674 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12675 int hpos, vpos;
12676 struct glyph *glyph;
12677 struct glyph_row *row;
12678 int i;
12679 Lisp_Object enabled_p;
12680 int prop_idx;
12681 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12682 int mouse_down_p, rc;
12684 /* Function note_mouse_highlight is called with negative X/Y
12685 values when mouse moves outside of the frame. */
12686 if (x <= 0 || y <= 0)
12688 clear_mouse_face (hlinfo);
12689 return;
12692 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12693 if (rc < 0)
12695 /* Not on tool-bar item. */
12696 clear_mouse_face (hlinfo);
12697 return;
12699 else if (rc == 0)
12700 /* On same tool-bar item as before. */
12701 goto set_help_echo;
12703 clear_mouse_face (hlinfo);
12705 /* Mouse is down, but on different tool-bar item? */
12706 mouse_down_p = (x_mouse_grabbed (dpyinfo)
12707 && f == dpyinfo->last_mouse_frame);
12709 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
12710 return;
12712 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12714 /* If tool-bar item is not enabled, don't highlight it. */
12715 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12716 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
12718 /* Compute the x-position of the glyph. In front and past the
12719 image is a space. We include this in the highlighted area. */
12720 row = MATRIX_ROW (w->current_matrix, vpos);
12721 for (i = x = 0; i < hpos; ++i)
12722 x += row->glyphs[TEXT_AREA][i].pixel_width;
12724 /* Record this as the current active region. */
12725 hlinfo->mouse_face_beg_col = hpos;
12726 hlinfo->mouse_face_beg_row = vpos;
12727 hlinfo->mouse_face_beg_x = x;
12728 hlinfo->mouse_face_past_end = 0;
12730 hlinfo->mouse_face_end_col = hpos + 1;
12731 hlinfo->mouse_face_end_row = vpos;
12732 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12733 hlinfo->mouse_face_window = window;
12734 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12736 /* Display it as active. */
12737 show_mouse_face (hlinfo, draw);
12740 set_help_echo:
12742 /* Set help_echo_string to a help string to display for this tool-bar item.
12743 XTread_socket does the rest. */
12744 help_echo_object = help_echo_window = Qnil;
12745 help_echo_pos = -1;
12746 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12747 if (NILP (help_echo_string))
12748 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12751 #endif /* !USE_GTK && !HAVE_NS */
12753 #endif /* HAVE_WINDOW_SYSTEM */
12757 /************************************************************************
12758 Horizontal scrolling
12759 ************************************************************************/
12761 static int hscroll_window_tree (Lisp_Object);
12762 static int hscroll_windows (Lisp_Object);
12764 /* For all leaf windows in the window tree rooted at WINDOW, set their
12765 hscroll value so that PT is (i) visible in the window, and (ii) so
12766 that it is not within a certain margin at the window's left and
12767 right border. Value is non-zero if any window's hscroll has been
12768 changed. */
12770 static int
12771 hscroll_window_tree (Lisp_Object window)
12773 int hscrolled_p = 0;
12774 int hscroll_relative_p = FLOATP (Vhscroll_step);
12775 int hscroll_step_abs = 0;
12776 double hscroll_step_rel = 0;
12778 if (hscroll_relative_p)
12780 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12781 if (hscroll_step_rel < 0)
12783 hscroll_relative_p = 0;
12784 hscroll_step_abs = 0;
12787 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12789 hscroll_step_abs = XINT (Vhscroll_step);
12790 if (hscroll_step_abs < 0)
12791 hscroll_step_abs = 0;
12793 else
12794 hscroll_step_abs = 0;
12796 while (WINDOWP (window))
12798 struct window *w = XWINDOW (window);
12800 if (WINDOWP (w->contents))
12801 hscrolled_p |= hscroll_window_tree (w->contents);
12802 else if (w->cursor.vpos >= 0)
12804 int h_margin;
12805 int text_area_width;
12806 struct glyph_row *cursor_row;
12807 struct glyph_row *bottom_row;
12808 int row_r2l_p;
12810 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
12811 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
12812 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12813 else
12814 cursor_row = bottom_row - 1;
12816 if (!cursor_row->enabled_p)
12818 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12819 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
12820 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12821 else
12822 cursor_row = bottom_row - 1;
12824 row_r2l_p = cursor_row->reversed_p;
12826 text_area_width = window_box_width (w, TEXT_AREA);
12828 /* Scroll when cursor is inside this scroll margin. */
12829 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12831 /* If the position of this window's point has explicitly
12832 changed, no more suspend auto hscrolling. */
12833 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12834 w->suspend_auto_hscroll = 0;
12836 /* Remember window point. */
12837 Fset_marker (w->old_pointm,
12838 ((w == XWINDOW (selected_window))
12839 ? make_number (BUF_PT (XBUFFER (w->contents)))
12840 : Fmarker_position (w->pointm)),
12841 w->contents);
12843 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12844 && w->suspend_auto_hscroll == 0
12845 /* In some pathological cases, like restoring a window
12846 configuration into a frame that is much smaller than
12847 the one from which the configuration was saved, we
12848 get glyph rows whose start and end have zero buffer
12849 positions, which we cannot handle below. Just skip
12850 such windows. */
12851 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
12852 /* For left-to-right rows, hscroll when cursor is either
12853 (i) inside the right hscroll margin, or (ii) if it is
12854 inside the left margin and the window is already
12855 hscrolled. */
12856 && ((!row_r2l_p
12857 && ((w->hscroll && w->cursor.x <= h_margin)
12858 || (cursor_row->enabled_p
12859 && cursor_row->truncated_on_right_p
12860 && (w->cursor.x >= text_area_width - h_margin))))
12861 /* For right-to-left rows, the logic is similar,
12862 except that rules for scrolling to left and right
12863 are reversed. E.g., if cursor.x <= h_margin, we
12864 need to hscroll "to the right" unconditionally,
12865 and that will scroll the screen to the left so as
12866 to reveal the next portion of the row. */
12867 || (row_r2l_p
12868 && ((cursor_row->enabled_p
12869 /* FIXME: It is confusing to set the
12870 truncated_on_right_p flag when R2L rows
12871 are actually truncated on the left. */
12872 && cursor_row->truncated_on_right_p
12873 && w->cursor.x <= h_margin)
12874 || (w->hscroll
12875 && (w->cursor.x >= text_area_width - h_margin))))))
12877 struct it it;
12878 ptrdiff_t hscroll;
12879 struct buffer *saved_current_buffer;
12880 ptrdiff_t pt;
12881 int wanted_x;
12883 /* Find point in a display of infinite width. */
12884 saved_current_buffer = current_buffer;
12885 current_buffer = XBUFFER (w->contents);
12887 if (w == XWINDOW (selected_window))
12888 pt = PT;
12889 else
12890 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
12892 /* Move iterator to pt starting at cursor_row->start in
12893 a line with infinite width. */
12894 init_to_row_start (&it, w, cursor_row);
12895 it.last_visible_x = INFINITY;
12896 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12897 current_buffer = saved_current_buffer;
12899 /* Position cursor in window. */
12900 if (!hscroll_relative_p && hscroll_step_abs == 0)
12901 hscroll = max (0, (it.current_x
12902 - (ITERATOR_AT_END_OF_LINE_P (&it)
12903 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12904 : (text_area_width / 2))))
12905 / FRAME_COLUMN_WIDTH (it.f);
12906 else if ((!row_r2l_p
12907 && w->cursor.x >= text_area_width - h_margin)
12908 || (row_r2l_p && w->cursor.x <= h_margin))
12910 if (hscroll_relative_p)
12911 wanted_x = text_area_width * (1 - hscroll_step_rel)
12912 - h_margin;
12913 else
12914 wanted_x = text_area_width
12915 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12916 - h_margin;
12917 hscroll
12918 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12920 else
12922 if (hscroll_relative_p)
12923 wanted_x = text_area_width * hscroll_step_rel
12924 + h_margin;
12925 else
12926 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12927 + h_margin;
12928 hscroll
12929 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12931 hscroll = max (hscroll, w->min_hscroll);
12933 /* Don't prevent redisplay optimizations if hscroll
12934 hasn't changed, as it will unnecessarily slow down
12935 redisplay. */
12936 if (w->hscroll != hscroll)
12938 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12939 w->hscroll = hscroll;
12940 hscrolled_p = 1;
12945 window = w->next;
12948 /* Value is non-zero if hscroll of any leaf window has been changed. */
12949 return hscrolled_p;
12953 /* Set hscroll so that cursor is visible and not inside horizontal
12954 scroll margins for all windows in the tree rooted at WINDOW. See
12955 also hscroll_window_tree above. Value is non-zero if any window's
12956 hscroll has been changed. If it has, desired matrices on the frame
12957 of WINDOW are cleared. */
12959 static int
12960 hscroll_windows (Lisp_Object window)
12962 int hscrolled_p = hscroll_window_tree (window);
12963 if (hscrolled_p)
12964 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12965 return hscrolled_p;
12970 /************************************************************************
12971 Redisplay
12972 ************************************************************************/
12974 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12975 to a non-zero value. This is sometimes handy to have in a debugger
12976 session. */
12978 #ifdef GLYPH_DEBUG
12980 /* First and last unchanged row for try_window_id. */
12982 static int debug_first_unchanged_at_end_vpos;
12983 static int debug_last_unchanged_at_beg_vpos;
12985 /* Delta vpos and y. */
12987 static int debug_dvpos, debug_dy;
12989 /* Delta in characters and bytes for try_window_id. */
12991 static ptrdiff_t debug_delta, debug_delta_bytes;
12993 /* Values of window_end_pos and window_end_vpos at the end of
12994 try_window_id. */
12996 static ptrdiff_t debug_end_vpos;
12998 /* Append a string to W->desired_matrix->method. FMT is a printf
12999 format string. If trace_redisplay_p is true also printf the
13000 resulting string to stderr. */
13002 static void debug_method_add (struct window *, char const *, ...)
13003 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13005 static void
13006 debug_method_add (struct window *w, char const *fmt, ...)
13008 void *ptr = w;
13009 char *method = w->desired_matrix->method;
13010 int len = strlen (method);
13011 int size = sizeof w->desired_matrix->method;
13012 int remaining = size - len - 1;
13013 va_list ap;
13015 if (len && remaining)
13017 method[len] = '|';
13018 --remaining, ++len;
13021 va_start (ap, fmt);
13022 vsnprintf (method + len, remaining + 1, fmt, ap);
13023 va_end (ap);
13025 if (trace_redisplay_p)
13026 fprintf (stderr, "%p (%s): %s\n",
13027 ptr,
13028 ((BUFFERP (w->contents)
13029 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13030 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13031 : "no buffer"),
13032 method + len);
13035 #endif /* GLYPH_DEBUG */
13038 /* Value is non-zero if all changes in window W, which displays
13039 current_buffer, are in the text between START and END. START is a
13040 buffer position, END is given as a distance from Z. Used in
13041 redisplay_internal for display optimization. */
13043 static int
13044 text_outside_line_unchanged_p (struct window *w,
13045 ptrdiff_t start, ptrdiff_t end)
13047 int unchanged_p = 1;
13049 /* If text or overlays have changed, see where. */
13050 if (window_outdated (w))
13052 /* Gap in the line? */
13053 if (GPT < start || Z - GPT < end)
13054 unchanged_p = 0;
13056 /* Changes start in front of the line, or end after it? */
13057 if (unchanged_p
13058 && (BEG_UNCHANGED < start - 1
13059 || END_UNCHANGED < end))
13060 unchanged_p = 0;
13062 /* If selective display, can't optimize if changes start at the
13063 beginning of the line. */
13064 if (unchanged_p
13065 && INTEGERP (BVAR (current_buffer, selective_display))
13066 && XINT (BVAR (current_buffer, selective_display)) > 0
13067 && (BEG_UNCHANGED < start || GPT <= start))
13068 unchanged_p = 0;
13070 /* If there are overlays at the start or end of the line, these
13071 may have overlay strings with newlines in them. A change at
13072 START, for instance, may actually concern the display of such
13073 overlay strings as well, and they are displayed on different
13074 lines. So, quickly rule out this case. (For the future, it
13075 might be desirable to implement something more telling than
13076 just BEG/END_UNCHANGED.) */
13077 if (unchanged_p)
13079 if (BEG + BEG_UNCHANGED == start
13080 && overlay_touches_p (start))
13081 unchanged_p = 0;
13082 if (END_UNCHANGED == end
13083 && overlay_touches_p (Z - end))
13084 unchanged_p = 0;
13087 /* Under bidi reordering, adding or deleting a character in the
13088 beginning of a paragraph, before the first strong directional
13089 character, can change the base direction of the paragraph (unless
13090 the buffer specifies a fixed paragraph direction), which will
13091 require to redisplay the whole paragraph. It might be worthwhile
13092 to find the paragraph limits and widen the range of redisplayed
13093 lines to that, but for now just give up this optimization. */
13094 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13095 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13096 unchanged_p = 0;
13099 return unchanged_p;
13103 /* Do a frame update, taking possible shortcuts into account. This is
13104 the main external entry point for redisplay.
13106 If the last redisplay displayed an echo area message and that message
13107 is no longer requested, we clear the echo area or bring back the
13108 mini-buffer if that is in use. */
13110 void
13111 redisplay (void)
13113 redisplay_internal ();
13117 static Lisp_Object
13118 overlay_arrow_string_or_property (Lisp_Object var)
13120 Lisp_Object val;
13122 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13123 return val;
13125 return Voverlay_arrow_string;
13128 /* Return 1 if there are any overlay-arrows in current_buffer. */
13129 static int
13130 overlay_arrow_in_current_buffer_p (void)
13132 Lisp_Object vlist;
13134 for (vlist = Voverlay_arrow_variable_list;
13135 CONSP (vlist);
13136 vlist = XCDR (vlist))
13138 Lisp_Object var = XCAR (vlist);
13139 Lisp_Object val;
13141 if (!SYMBOLP (var))
13142 continue;
13143 val = find_symbol_value (var);
13144 if (MARKERP (val)
13145 && current_buffer == XMARKER (val)->buffer)
13146 return 1;
13148 return 0;
13152 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
13153 has changed. */
13155 static int
13156 overlay_arrows_changed_p (void)
13158 Lisp_Object vlist;
13160 for (vlist = Voverlay_arrow_variable_list;
13161 CONSP (vlist);
13162 vlist = XCDR (vlist))
13164 Lisp_Object var = XCAR (vlist);
13165 Lisp_Object val, pstr;
13167 if (!SYMBOLP (var))
13168 continue;
13169 val = find_symbol_value (var);
13170 if (!MARKERP (val))
13171 continue;
13172 if (! EQ (COERCE_MARKER (val),
13173 Fget (var, Qlast_arrow_position))
13174 || ! (pstr = overlay_arrow_string_or_property (var),
13175 EQ (pstr, Fget (var, Qlast_arrow_string))))
13176 return 1;
13178 return 0;
13181 /* Mark overlay arrows to be updated on next redisplay. */
13183 static void
13184 update_overlay_arrows (int up_to_date)
13186 Lisp_Object vlist;
13188 for (vlist = Voverlay_arrow_variable_list;
13189 CONSP (vlist);
13190 vlist = XCDR (vlist))
13192 Lisp_Object var = XCAR (vlist);
13194 if (!SYMBOLP (var))
13195 continue;
13197 if (up_to_date > 0)
13199 Lisp_Object val = find_symbol_value (var);
13200 Fput (var, Qlast_arrow_position,
13201 COERCE_MARKER (val));
13202 Fput (var, Qlast_arrow_string,
13203 overlay_arrow_string_or_property (var));
13205 else if (up_to_date < 0
13206 || !NILP (Fget (var, Qlast_arrow_position)))
13208 Fput (var, Qlast_arrow_position, Qt);
13209 Fput (var, Qlast_arrow_string, Qt);
13215 /* Return overlay arrow string to display at row.
13216 Return integer (bitmap number) for arrow bitmap in left fringe.
13217 Return nil if no overlay arrow. */
13219 static Lisp_Object
13220 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13222 Lisp_Object vlist;
13224 for (vlist = Voverlay_arrow_variable_list;
13225 CONSP (vlist);
13226 vlist = XCDR (vlist))
13228 Lisp_Object var = XCAR (vlist);
13229 Lisp_Object val;
13231 if (!SYMBOLP (var))
13232 continue;
13234 val = find_symbol_value (var);
13236 if (MARKERP (val)
13237 && current_buffer == XMARKER (val)->buffer
13238 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13240 if (FRAME_WINDOW_P (it->f)
13241 /* FIXME: if ROW->reversed_p is set, this should test
13242 the right fringe, not the left one. */
13243 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13245 #ifdef HAVE_WINDOW_SYSTEM
13246 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13248 int fringe_bitmap;
13249 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
13250 return make_number (fringe_bitmap);
13252 #endif
13253 return make_number (-1); /* Use default arrow bitmap. */
13255 return overlay_arrow_string_or_property (var);
13259 return Qnil;
13262 /* Return 1 if point moved out of or into a composition. Otherwise
13263 return 0. PREV_BUF and PREV_PT are the last point buffer and
13264 position. BUF and PT are the current point buffer and position. */
13266 static int
13267 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13268 struct buffer *buf, ptrdiff_t pt)
13270 ptrdiff_t start, end;
13271 Lisp_Object prop;
13272 Lisp_Object buffer;
13274 XSETBUFFER (buffer, buf);
13275 /* Check a composition at the last point if point moved within the
13276 same buffer. */
13277 if (prev_buf == buf)
13279 if (prev_pt == pt)
13280 /* Point didn't move. */
13281 return 0;
13283 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13284 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13285 && composition_valid_p (start, end, prop)
13286 && start < prev_pt && end > prev_pt)
13287 /* The last point was within the composition. Return 1 iff
13288 point moved out of the composition. */
13289 return (pt <= start || pt >= end);
13292 /* Check a composition at the current point. */
13293 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13294 && find_composition (pt, -1, &start, &end, &prop, buffer)
13295 && composition_valid_p (start, end, prop)
13296 && start < pt && end > pt);
13299 /* Reconsider the clip changes of buffer which is displayed in W. */
13301 static void
13302 reconsider_clip_changes (struct window *w)
13304 struct buffer *b = XBUFFER (w->contents);
13306 if (b->clip_changed
13307 && w->window_end_valid
13308 && w->current_matrix->buffer == b
13309 && w->current_matrix->zv == BUF_ZV (b)
13310 && w->current_matrix->begv == BUF_BEGV (b))
13311 b->clip_changed = 0;
13313 /* If display wasn't paused, and W is not a tool bar window, see if
13314 point has been moved into or out of a composition. In that case,
13315 we set b->clip_changed to 1 to force updating the screen. If
13316 b->clip_changed has already been set to 1, we can skip this
13317 check. */
13318 if (!b->clip_changed && w->window_end_valid)
13320 ptrdiff_t pt = (w == XWINDOW (selected_window)
13321 ? PT : marker_position (w->pointm));
13323 if ((w->current_matrix->buffer != b || pt != w->last_point)
13324 && check_point_in_composition (w->current_matrix->buffer,
13325 w->last_point, b, pt))
13326 b->clip_changed = 1;
13330 static void
13331 propagate_buffer_redisplay (void)
13332 { /* Resetting b->text->redisplay is problematic!
13333 We can't just reset it in the case that some window that displays
13334 it has not been redisplayed; and such a window can stay
13335 unredisplayed for a long time if it's currently invisible.
13336 But we do want to reset it at the end of redisplay otherwise
13337 its displayed windows will keep being redisplayed over and over
13338 again.
13339 So we copy all b->text->redisplay flags up to their windows here,
13340 such that mark_window_display_accurate can safely reset
13341 b->text->redisplay. */
13342 Lisp_Object ws = window_list ();
13343 for (; CONSP (ws); ws = XCDR (ws))
13345 struct window *thisw = XWINDOW (XCAR (ws));
13346 struct buffer *thisb = XBUFFER (thisw->contents);
13347 if (thisb->text->redisplay)
13348 thisw->redisplay = true;
13352 #define STOP_POLLING \
13353 do { if (! polling_stopped_here) stop_polling (); \
13354 polling_stopped_here = 1; } while (0)
13356 #define RESUME_POLLING \
13357 do { if (polling_stopped_here) start_polling (); \
13358 polling_stopped_here = 0; } while (0)
13361 /* Perhaps in the future avoid recentering windows if it
13362 is not necessary; currently that causes some problems. */
13364 static void
13365 redisplay_internal (void)
13367 struct window *w = XWINDOW (selected_window);
13368 struct window *sw;
13369 struct frame *fr;
13370 int pending;
13371 bool must_finish = 0, match_p;
13372 struct text_pos tlbufpos, tlendpos;
13373 int number_of_visible_frames;
13374 ptrdiff_t count;
13375 struct frame *sf;
13376 int polling_stopped_here = 0;
13377 Lisp_Object tail, frame;
13379 /* True means redisplay has to consider all windows on all
13380 frames. False, only selected_window is considered. */
13381 bool consider_all_windows_p;
13383 /* True means redisplay has to redisplay the miniwindow. */
13384 bool update_miniwindow_p = false;
13386 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13388 /* No redisplay if running in batch mode or frame is not yet fully
13389 initialized, or redisplay is explicitly turned off by setting
13390 Vinhibit_redisplay. */
13391 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13392 || !NILP (Vinhibit_redisplay))
13393 return;
13395 /* Don't examine these until after testing Vinhibit_redisplay.
13396 When Emacs is shutting down, perhaps because its connection to
13397 X has dropped, we should not look at them at all. */
13398 fr = XFRAME (w->frame);
13399 sf = SELECTED_FRAME ();
13401 if (!fr->glyphs_initialized_p)
13402 return;
13404 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13405 if (popup_activated ())
13406 return;
13407 #endif
13409 /* I don't think this happens but let's be paranoid. */
13410 if (redisplaying_p)
13411 return;
13413 /* Record a function that clears redisplaying_p
13414 when we leave this function. */
13415 count = SPECPDL_INDEX ();
13416 record_unwind_protect_void (unwind_redisplay);
13417 redisplaying_p = 1;
13418 specbind (Qinhibit_free_realized_faces, Qnil);
13420 /* Record this function, so it appears on the profiler's backtraces. */
13421 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
13423 FOR_EACH_FRAME (tail, frame)
13424 XFRAME (frame)->already_hscrolled_p = 0;
13426 retry:
13427 /* Remember the currently selected window. */
13428 sw = w;
13430 pending = 0;
13431 last_escape_glyph_frame = NULL;
13432 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13433 last_glyphless_glyph_frame = NULL;
13434 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13436 /* If face_change_count is non-zero, init_iterator will free all
13437 realized faces, which includes the faces referenced from current
13438 matrices. So, we can't reuse current matrices in this case. */
13439 if (face_change_count)
13440 windows_or_buffers_changed = 47;
13442 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13443 && FRAME_TTY (sf)->previous_frame != sf)
13445 /* Since frames on a single ASCII terminal share the same
13446 display area, displaying a different frame means redisplay
13447 the whole thing. */
13448 SET_FRAME_GARBAGED (sf);
13449 #ifndef DOS_NT
13450 set_tty_color_mode (FRAME_TTY (sf), sf);
13451 #endif
13452 FRAME_TTY (sf)->previous_frame = sf;
13455 /* Set the visible flags for all frames. Do this before checking for
13456 resized or garbaged frames; they want to know if their frames are
13457 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13458 number_of_visible_frames = 0;
13460 FOR_EACH_FRAME (tail, frame)
13462 struct frame *f = XFRAME (frame);
13464 if (FRAME_VISIBLE_P (f))
13466 ++number_of_visible_frames;
13467 /* Adjust matrices for visible frames only. */
13468 if (f->fonts_changed)
13470 adjust_frame_glyphs (f);
13471 f->fonts_changed = 0;
13473 /* If cursor type has been changed on the frame
13474 other than selected, consider all frames. */
13475 if (f != sf && f->cursor_type_changed)
13476 update_mode_lines = 31;
13478 clear_desired_matrices (f);
13481 /* Notice any pending interrupt request to change frame size. */
13482 do_pending_window_change (1);
13484 /* do_pending_window_change could change the selected_window due to
13485 frame resizing which makes the selected window too small. */
13486 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13487 sw = w;
13489 /* Clear frames marked as garbaged. */
13490 clear_garbaged_frames ();
13492 /* Build menubar and tool-bar items. */
13493 if (NILP (Vmemory_full))
13494 prepare_menu_bars ();
13496 reconsider_clip_changes (w);
13498 /* In most cases selected window displays current buffer. */
13499 match_p = XBUFFER (w->contents) == current_buffer;
13500 if (match_p)
13502 /* Detect case that we need to write or remove a star in the mode line. */
13503 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13504 w->update_mode_line = 1;
13506 if (mode_line_update_needed (w))
13507 w->update_mode_line = 1;
13510 /* Normally the message* functions will have already displayed and
13511 updated the echo area, but the frame may have been trashed, or
13512 the update may have been preempted, so display the echo area
13513 again here. Checking message_cleared_p captures the case that
13514 the echo area should be cleared. */
13515 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13516 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13517 || (message_cleared_p
13518 && minibuf_level == 0
13519 /* If the mini-window is currently selected, this means the
13520 echo-area doesn't show through. */
13521 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13523 int window_height_changed_p = echo_area_display (0);
13525 if (message_cleared_p)
13526 update_miniwindow_p = true;
13528 must_finish = 1;
13530 /* If we don't display the current message, don't clear the
13531 message_cleared_p flag, because, if we did, we wouldn't clear
13532 the echo area in the next redisplay which doesn't preserve
13533 the echo area. */
13534 if (!display_last_displayed_message_p)
13535 message_cleared_p = 0;
13537 if (window_height_changed_p)
13539 windows_or_buffers_changed = 50;
13541 /* If window configuration was changed, frames may have been
13542 marked garbaged. Clear them or we will experience
13543 surprises wrt scrolling. */
13544 clear_garbaged_frames ();
13547 else if (EQ (selected_window, minibuf_window)
13548 && (current_buffer->clip_changed || window_outdated (w))
13549 && resize_mini_window (w, 0))
13551 /* Resized active mini-window to fit the size of what it is
13552 showing if its contents might have changed. */
13553 must_finish = 1;
13555 /* If window configuration was changed, frames may have been
13556 marked garbaged. Clear them or we will experience
13557 surprises wrt scrolling. */
13558 clear_garbaged_frames ();
13561 if (windows_or_buffers_changed && !update_mode_lines)
13562 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13563 only the windows's contents needs to be refreshed, or whether the
13564 mode-lines also need a refresh. */
13565 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13566 ? REDISPLAY_SOME : 32);
13568 /* If specs for an arrow have changed, do thorough redisplay
13569 to ensure we remove any arrow that should no longer exist. */
13570 if (overlay_arrows_changed_p ())
13571 /* Apparently, this is the only case where we update other windows,
13572 without updating other mode-lines. */
13573 windows_or_buffers_changed = 49;
13575 consider_all_windows_p = (update_mode_lines
13576 || windows_or_buffers_changed);
13578 #define AINC(a,i) \
13579 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13580 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13582 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13583 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13585 /* Optimize the case that only the line containing the cursor in the
13586 selected window has changed. Variables starting with this_ are
13587 set in display_line and record information about the line
13588 containing the cursor. */
13589 tlbufpos = this_line_start_pos;
13590 tlendpos = this_line_end_pos;
13591 if (!consider_all_windows_p
13592 && CHARPOS (tlbufpos) > 0
13593 && !w->update_mode_line
13594 && !current_buffer->clip_changed
13595 && !current_buffer->prevent_redisplay_optimizations_p
13596 && FRAME_VISIBLE_P (XFRAME (w->frame))
13597 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13598 && !XFRAME (w->frame)->cursor_type_changed
13599 /* Make sure recorded data applies to current buffer, etc. */
13600 && this_line_buffer == current_buffer
13601 && match_p
13602 && !w->force_start
13603 && !w->optional_new_start
13604 /* Point must be on the line that we have info recorded about. */
13605 && PT >= CHARPOS (tlbufpos)
13606 && PT <= Z - CHARPOS (tlendpos)
13607 /* All text outside that line, including its final newline,
13608 must be unchanged. */
13609 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13610 CHARPOS (tlendpos)))
13612 if (CHARPOS (tlbufpos) > BEGV
13613 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13614 && (CHARPOS (tlbufpos) == ZV
13615 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13616 /* Former continuation line has disappeared by becoming empty. */
13617 goto cancel;
13618 else if (window_outdated (w) || MINI_WINDOW_P (w))
13620 /* We have to handle the case of continuation around a
13621 wide-column character (see the comment in indent.c around
13622 line 1340).
13624 For instance, in the following case:
13626 -------- Insert --------
13627 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13628 J_I_ ==> J_I_ `^^' are cursors.
13629 ^^ ^^
13630 -------- --------
13632 As we have to redraw the line above, we cannot use this
13633 optimization. */
13635 struct it it;
13636 int line_height_before = this_line_pixel_height;
13638 /* Note that start_display will handle the case that the
13639 line starting at tlbufpos is a continuation line. */
13640 start_display (&it, w, tlbufpos);
13642 /* Implementation note: It this still necessary? */
13643 if (it.current_x != this_line_start_x)
13644 goto cancel;
13646 TRACE ((stderr, "trying display optimization 1\n"));
13647 w->cursor.vpos = -1;
13648 overlay_arrow_seen = 0;
13649 it.vpos = this_line_vpos;
13650 it.current_y = this_line_y;
13651 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13652 display_line (&it);
13654 /* If line contains point, is not continued,
13655 and ends at same distance from eob as before, we win. */
13656 if (w->cursor.vpos >= 0
13657 /* Line is not continued, otherwise this_line_start_pos
13658 would have been set to 0 in display_line. */
13659 && CHARPOS (this_line_start_pos)
13660 /* Line ends as before. */
13661 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13662 /* Line has same height as before. Otherwise other lines
13663 would have to be shifted up or down. */
13664 && this_line_pixel_height == line_height_before)
13666 /* If this is not the window's last line, we must adjust
13667 the charstarts of the lines below. */
13668 if (it.current_y < it.last_visible_y)
13670 struct glyph_row *row
13671 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13672 ptrdiff_t delta, delta_bytes;
13674 /* We used to distinguish between two cases here,
13675 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13676 when the line ends in a newline or the end of the
13677 buffer's accessible portion. But both cases did
13678 the same, so they were collapsed. */
13679 delta = (Z
13680 - CHARPOS (tlendpos)
13681 - MATRIX_ROW_START_CHARPOS (row));
13682 delta_bytes = (Z_BYTE
13683 - BYTEPOS (tlendpos)
13684 - MATRIX_ROW_START_BYTEPOS (row));
13686 increment_matrix_positions (w->current_matrix,
13687 this_line_vpos + 1,
13688 w->current_matrix->nrows,
13689 delta, delta_bytes);
13692 /* If this row displays text now but previously didn't,
13693 or vice versa, w->window_end_vpos may have to be
13694 adjusted. */
13695 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13697 if (w->window_end_vpos < this_line_vpos)
13698 w->window_end_vpos = this_line_vpos;
13700 else if (w->window_end_vpos == this_line_vpos
13701 && this_line_vpos > 0)
13702 w->window_end_vpos = this_line_vpos - 1;
13703 w->window_end_valid = 0;
13705 /* Update hint: No need to try to scroll in update_window. */
13706 w->desired_matrix->no_scrolling_p = 1;
13708 #ifdef GLYPH_DEBUG
13709 *w->desired_matrix->method = 0;
13710 debug_method_add (w, "optimization 1");
13711 #endif
13712 #ifdef HAVE_WINDOW_SYSTEM
13713 update_window_fringes (w, 0);
13714 #endif
13715 goto update;
13717 else
13718 goto cancel;
13720 else if (/* Cursor position hasn't changed. */
13721 PT == w->last_point
13722 /* Make sure the cursor was last displayed
13723 in this window. Otherwise we have to reposition it. */
13725 /* PXW: Must be converted to pixels, probably. */
13726 && 0 <= w->cursor.vpos
13727 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13729 if (!must_finish)
13731 do_pending_window_change (1);
13732 /* If selected_window changed, redisplay again. */
13733 if (WINDOWP (selected_window)
13734 && (w = XWINDOW (selected_window)) != sw)
13735 goto retry;
13737 /* We used to always goto end_of_redisplay here, but this
13738 isn't enough if we have a blinking cursor. */
13739 if (w->cursor_off_p == w->last_cursor_off_p)
13740 goto end_of_redisplay;
13742 goto update;
13744 /* If highlighting the region, or if the cursor is in the echo area,
13745 then we can't just move the cursor. */
13746 else if (NILP (Vshow_trailing_whitespace)
13747 && !cursor_in_echo_area)
13749 struct it it;
13750 struct glyph_row *row;
13752 /* Skip from tlbufpos to PT and see where it is. Note that
13753 PT may be in invisible text. If so, we will end at the
13754 next visible position. */
13755 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13756 NULL, DEFAULT_FACE_ID);
13757 it.current_x = this_line_start_x;
13758 it.current_y = this_line_y;
13759 it.vpos = this_line_vpos;
13761 /* The call to move_it_to stops in front of PT, but
13762 moves over before-strings. */
13763 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13765 if (it.vpos == this_line_vpos
13766 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13767 row->enabled_p))
13769 eassert (this_line_vpos == it.vpos);
13770 eassert (this_line_y == it.current_y);
13771 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13772 #ifdef GLYPH_DEBUG
13773 *w->desired_matrix->method = 0;
13774 debug_method_add (w, "optimization 3");
13775 #endif
13776 goto update;
13778 else
13779 goto cancel;
13782 cancel:
13783 /* Text changed drastically or point moved off of line. */
13784 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
13787 CHARPOS (this_line_start_pos) = 0;
13788 ++clear_face_cache_count;
13789 #ifdef HAVE_WINDOW_SYSTEM
13790 ++clear_image_cache_count;
13791 #endif
13793 /* Build desired matrices, and update the display. If
13794 consider_all_windows_p is non-zero, do it for all windows on all
13795 frames. Otherwise do it for selected_window, only. */
13797 if (consider_all_windows_p)
13799 FOR_EACH_FRAME (tail, frame)
13800 XFRAME (frame)->updated_p = 0;
13802 propagate_buffer_redisplay ();
13804 FOR_EACH_FRAME (tail, frame)
13806 struct frame *f = XFRAME (frame);
13808 /* We don't have to do anything for unselected terminal
13809 frames. */
13810 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13811 && !EQ (FRAME_TTY (f)->top_frame, frame))
13812 continue;
13814 retry_frame:
13816 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13818 bool gcscrollbars
13819 /* Only GC scrollbars when we redisplay the whole frame. */
13820 = f->redisplay || !REDISPLAY_SOME_P ();
13821 /* Mark all the scroll bars to be removed; we'll redeem
13822 the ones we want when we redisplay their windows. */
13823 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13824 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13826 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13827 redisplay_windows (FRAME_ROOT_WINDOW (f));
13828 /* Remember that the invisible frames need to be redisplayed next
13829 time they're visible. */
13830 else if (!REDISPLAY_SOME_P ())
13831 f->redisplay = true;
13833 /* The X error handler may have deleted that frame. */
13834 if (!FRAME_LIVE_P (f))
13835 continue;
13837 /* Any scroll bars which redisplay_windows should have
13838 nuked should now go away. */
13839 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13840 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13842 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13844 /* If fonts changed on visible frame, display again. */
13845 if (f->fonts_changed)
13847 adjust_frame_glyphs (f);
13848 f->fonts_changed = 0;
13849 goto retry_frame;
13852 /* See if we have to hscroll. */
13853 if (!f->already_hscrolled_p)
13855 f->already_hscrolled_p = 1;
13856 if (hscroll_windows (f->root_window))
13857 goto retry_frame;
13860 /* Prevent various kinds of signals during display
13861 update. stdio is not robust about handling
13862 signals, which can cause an apparent I/O error. */
13863 if (interrupt_input)
13864 unrequest_sigio ();
13865 STOP_POLLING;
13867 pending |= update_frame (f, 0, 0);
13868 f->cursor_type_changed = 0;
13869 f->updated_p = 1;
13874 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13876 if (!pending)
13878 /* Do the mark_window_display_accurate after all windows have
13879 been redisplayed because this call resets flags in buffers
13880 which are needed for proper redisplay. */
13881 FOR_EACH_FRAME (tail, frame)
13883 struct frame *f = XFRAME (frame);
13884 if (f->updated_p)
13886 f->redisplay = false;
13887 mark_window_display_accurate (f->root_window, 1);
13888 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13889 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13894 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13896 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13897 struct frame *mini_frame;
13899 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13900 /* Use list_of_error, not Qerror, so that
13901 we catch only errors and don't run the debugger. */
13902 internal_condition_case_1 (redisplay_window_1, selected_window,
13903 list_of_error,
13904 redisplay_window_error);
13905 if (update_miniwindow_p)
13906 internal_condition_case_1 (redisplay_window_1, mini_window,
13907 list_of_error,
13908 redisplay_window_error);
13910 /* Compare desired and current matrices, perform output. */
13912 update:
13913 /* If fonts changed, display again. */
13914 if (sf->fonts_changed)
13915 goto retry;
13917 /* Prevent various kinds of signals during display update.
13918 stdio is not robust about handling signals,
13919 which can cause an apparent I/O error. */
13920 if (interrupt_input)
13921 unrequest_sigio ();
13922 STOP_POLLING;
13924 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13926 if (hscroll_windows (selected_window))
13927 goto retry;
13929 XWINDOW (selected_window)->must_be_updated_p = true;
13930 pending = update_frame (sf, 0, 0);
13931 sf->cursor_type_changed = 0;
13934 /* We may have called echo_area_display at the top of this
13935 function. If the echo area is on another frame, that may
13936 have put text on a frame other than the selected one, so the
13937 above call to update_frame would not have caught it. Catch
13938 it here. */
13939 mini_window = FRAME_MINIBUF_WINDOW (sf);
13940 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13942 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13944 XWINDOW (mini_window)->must_be_updated_p = true;
13945 pending |= update_frame (mini_frame, 0, 0);
13946 mini_frame->cursor_type_changed = 0;
13947 if (!pending && hscroll_windows (mini_window))
13948 goto retry;
13952 /* If display was paused because of pending input, make sure we do a
13953 thorough update the next time. */
13954 if (pending)
13956 /* Prevent the optimization at the beginning of
13957 redisplay_internal that tries a single-line update of the
13958 line containing the cursor in the selected window. */
13959 CHARPOS (this_line_start_pos) = 0;
13961 /* Let the overlay arrow be updated the next time. */
13962 update_overlay_arrows (0);
13964 /* If we pause after scrolling, some rows in the current
13965 matrices of some windows are not valid. */
13966 if (!WINDOW_FULL_WIDTH_P (w)
13967 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13968 update_mode_lines = 36;
13970 else
13972 if (!consider_all_windows_p)
13974 /* This has already been done above if
13975 consider_all_windows_p is set. */
13976 if (XBUFFER (w->contents)->text->redisplay
13977 && buffer_window_count (XBUFFER (w->contents)) > 1)
13978 /* This can happen if b->text->redisplay was set during
13979 jit-lock. */
13980 propagate_buffer_redisplay ();
13981 mark_window_display_accurate_1 (w, 1);
13983 /* Say overlay arrows are up to date. */
13984 update_overlay_arrows (1);
13986 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13987 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13990 update_mode_lines = 0;
13991 windows_or_buffers_changed = 0;
13994 /* Start SIGIO interrupts coming again. Having them off during the
13995 code above makes it less likely one will discard output, but not
13996 impossible, since there might be stuff in the system buffer here.
13997 But it is much hairier to try to do anything about that. */
13998 if (interrupt_input)
13999 request_sigio ();
14000 RESUME_POLLING;
14002 /* If a frame has become visible which was not before, redisplay
14003 again, so that we display it. Expose events for such a frame
14004 (which it gets when becoming visible) don't call the parts of
14005 redisplay constructing glyphs, so simply exposing a frame won't
14006 display anything in this case. So, we have to display these
14007 frames here explicitly. */
14008 if (!pending)
14010 int new_count = 0;
14012 FOR_EACH_FRAME (tail, frame)
14014 if (XFRAME (frame)->visible)
14015 new_count++;
14018 if (new_count != number_of_visible_frames)
14019 windows_or_buffers_changed = 52;
14022 /* Change frame size now if a change is pending. */
14023 do_pending_window_change (1);
14025 /* If we just did a pending size change, or have additional
14026 visible frames, or selected_window changed, redisplay again. */
14027 if ((windows_or_buffers_changed && !pending)
14028 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14029 goto retry;
14031 /* Clear the face and image caches.
14033 We used to do this only if consider_all_windows_p. But the cache
14034 needs to be cleared if a timer creates images in the current
14035 buffer (e.g. the test case in Bug#6230). */
14037 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14039 clear_face_cache (0);
14040 clear_face_cache_count = 0;
14043 #ifdef HAVE_WINDOW_SYSTEM
14044 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14046 clear_image_caches (Qnil);
14047 clear_image_cache_count = 0;
14049 #endif /* HAVE_WINDOW_SYSTEM */
14051 end_of_redisplay:
14052 if (interrupt_input && interrupts_deferred)
14053 request_sigio ();
14055 unbind_to (count, Qnil);
14056 RESUME_POLLING;
14060 /* Redisplay, but leave alone any recent echo area message unless
14061 another message has been requested in its place.
14063 This is useful in situations where you need to redisplay but no
14064 user action has occurred, making it inappropriate for the message
14065 area to be cleared. See tracking_off and
14066 wait_reading_process_output for examples of these situations.
14068 FROM_WHERE is an integer saying from where this function was
14069 called. This is useful for debugging. */
14071 void
14072 redisplay_preserve_echo_area (int from_where)
14074 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14076 if (!NILP (echo_area_buffer[1]))
14078 /* We have a previously displayed message, but no current
14079 message. Redisplay the previous message. */
14080 display_last_displayed_message_p = 1;
14081 redisplay_internal ();
14082 display_last_displayed_message_p = 0;
14084 else
14085 redisplay_internal ();
14087 flush_frame (SELECTED_FRAME ());
14091 /* Function registered with record_unwind_protect in redisplay_internal. */
14093 static void
14094 unwind_redisplay (void)
14096 redisplaying_p = 0;
14100 /* Mark the display of leaf window W as accurate or inaccurate.
14101 If ACCURATE_P is non-zero mark display of W as accurate. If
14102 ACCURATE_P is zero, arrange for W to be redisplayed the next
14103 time redisplay_internal is called. */
14105 static void
14106 mark_window_display_accurate_1 (struct window *w, int accurate_p)
14108 struct buffer *b = XBUFFER (w->contents);
14110 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14111 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14112 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14114 if (accurate_p)
14116 b->clip_changed = false;
14117 b->prevent_redisplay_optimizations_p = false;
14118 eassert (buffer_window_count (b) > 0);
14119 /* Resetting b->text->redisplay is problematic!
14120 In order to make it safer to do it here, redisplay_internal must
14121 have copied all b->text->redisplay to their respective windows. */
14122 b->text->redisplay = false;
14124 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14125 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14126 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14127 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14129 w->current_matrix->buffer = b;
14130 w->current_matrix->begv = BUF_BEGV (b);
14131 w->current_matrix->zv = BUF_ZV (b);
14133 w->last_cursor_vpos = w->cursor.vpos;
14134 w->last_cursor_off_p = w->cursor_off_p;
14136 if (w == XWINDOW (selected_window))
14137 w->last_point = BUF_PT (b);
14138 else
14139 w->last_point = marker_position (w->pointm);
14141 w->window_end_valid = true;
14142 w->update_mode_line = false;
14145 w->redisplay = !accurate_p;
14149 /* Mark the display of windows in the window tree rooted at WINDOW as
14150 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
14151 windows as accurate. If ACCURATE_P is zero, arrange for windows to
14152 be redisplayed the next time redisplay_internal is called. */
14154 void
14155 mark_window_display_accurate (Lisp_Object window, int accurate_p)
14157 struct window *w;
14159 for (; !NILP (window); window = w->next)
14161 w = XWINDOW (window);
14162 if (WINDOWP (w->contents))
14163 mark_window_display_accurate (w->contents, accurate_p);
14164 else
14165 mark_window_display_accurate_1 (w, accurate_p);
14168 if (accurate_p)
14169 update_overlay_arrows (1);
14170 else
14171 /* Force a thorough redisplay the next time by setting
14172 last_arrow_position and last_arrow_string to t, which is
14173 unequal to any useful value of Voverlay_arrow_... */
14174 update_overlay_arrows (-1);
14178 /* Return value in display table DP (Lisp_Char_Table *) for character
14179 C. Since a display table doesn't have any parent, we don't have to
14180 follow parent. Do not call this function directly but use the
14181 macro DISP_CHAR_VECTOR. */
14183 Lisp_Object
14184 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14186 Lisp_Object val;
14188 if (ASCII_CHAR_P (c))
14190 val = dp->ascii;
14191 if (SUB_CHAR_TABLE_P (val))
14192 val = XSUB_CHAR_TABLE (val)->contents[c];
14194 else
14196 Lisp_Object table;
14198 XSETCHAR_TABLE (table, dp);
14199 val = char_table_ref (table, c);
14201 if (NILP (val))
14202 val = dp->defalt;
14203 return val;
14208 /***********************************************************************
14209 Window Redisplay
14210 ***********************************************************************/
14212 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14214 static void
14215 redisplay_windows (Lisp_Object window)
14217 while (!NILP (window))
14219 struct window *w = XWINDOW (window);
14221 if (WINDOWP (w->contents))
14222 redisplay_windows (w->contents);
14223 else if (BUFFERP (w->contents))
14225 displayed_buffer = XBUFFER (w->contents);
14226 /* Use list_of_error, not Qerror, so that
14227 we catch only errors and don't run the debugger. */
14228 internal_condition_case_1 (redisplay_window_0, window,
14229 list_of_error,
14230 redisplay_window_error);
14233 window = w->next;
14237 static Lisp_Object
14238 redisplay_window_error (Lisp_Object ignore)
14240 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14241 return Qnil;
14244 static Lisp_Object
14245 redisplay_window_0 (Lisp_Object window)
14247 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14248 redisplay_window (window, false);
14249 return Qnil;
14252 static Lisp_Object
14253 redisplay_window_1 (Lisp_Object window)
14255 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14256 redisplay_window (window, true);
14257 return Qnil;
14261 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14262 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14263 which positions recorded in ROW differ from current buffer
14264 positions.
14266 Return 0 if cursor is not on this row, 1 otherwise. */
14268 static int
14269 set_cursor_from_row (struct window *w, struct glyph_row *row,
14270 struct glyph_matrix *matrix,
14271 ptrdiff_t delta, ptrdiff_t delta_bytes,
14272 int dy, int dvpos)
14274 struct glyph *glyph = row->glyphs[TEXT_AREA];
14275 struct glyph *end = glyph + row->used[TEXT_AREA];
14276 struct glyph *cursor = NULL;
14277 /* The last known character position in row. */
14278 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14279 int x = row->x;
14280 ptrdiff_t pt_old = PT - delta;
14281 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14282 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14283 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14284 /* A glyph beyond the edge of TEXT_AREA which we should never
14285 touch. */
14286 struct glyph *glyphs_end = end;
14287 /* Non-zero means we've found a match for cursor position, but that
14288 glyph has the avoid_cursor_p flag set. */
14289 int match_with_avoid_cursor = 0;
14290 /* Non-zero means we've seen at least one glyph that came from a
14291 display string. */
14292 int string_seen = 0;
14293 /* Largest and smallest buffer positions seen so far during scan of
14294 glyph row. */
14295 ptrdiff_t bpos_max = pos_before;
14296 ptrdiff_t bpos_min = pos_after;
14297 /* Last buffer position covered by an overlay string with an integer
14298 `cursor' property. */
14299 ptrdiff_t bpos_covered = 0;
14300 /* Non-zero means the display string on which to display the cursor
14301 comes from a text property, not from an overlay. */
14302 int string_from_text_prop = 0;
14304 /* Don't even try doing anything if called for a mode-line or
14305 header-line row, since the rest of the code isn't prepared to
14306 deal with such calamities. */
14307 eassert (!row->mode_line_p);
14308 if (row->mode_line_p)
14309 return 0;
14311 /* Skip over glyphs not having an object at the start and the end of
14312 the row. These are special glyphs like truncation marks on
14313 terminal frames. */
14314 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14316 if (!row->reversed_p)
14318 while (glyph < end
14319 && INTEGERP (glyph->object)
14320 && glyph->charpos < 0)
14322 x += glyph->pixel_width;
14323 ++glyph;
14325 while (end > glyph
14326 && INTEGERP ((end - 1)->object)
14327 /* CHARPOS is zero for blanks and stretch glyphs
14328 inserted by extend_face_to_end_of_line. */
14329 && (end - 1)->charpos <= 0)
14330 --end;
14331 glyph_before = glyph - 1;
14332 glyph_after = end;
14334 else
14336 struct glyph *g;
14338 /* If the glyph row is reversed, we need to process it from back
14339 to front, so swap the edge pointers. */
14340 glyphs_end = end = glyph - 1;
14341 glyph += row->used[TEXT_AREA] - 1;
14343 while (glyph > end + 1
14344 && INTEGERP (glyph->object)
14345 && glyph->charpos < 0)
14347 --glyph;
14348 x -= glyph->pixel_width;
14350 if (INTEGERP (glyph->object) && glyph->charpos < 0)
14351 --glyph;
14352 /* By default, in reversed rows we put the cursor on the
14353 rightmost (first in the reading order) glyph. */
14354 for (g = end + 1; g < glyph; g++)
14355 x += g->pixel_width;
14356 while (end < glyph
14357 && INTEGERP ((end + 1)->object)
14358 && (end + 1)->charpos <= 0)
14359 ++end;
14360 glyph_before = glyph + 1;
14361 glyph_after = end;
14364 else if (row->reversed_p)
14366 /* In R2L rows that don't display text, put the cursor on the
14367 rightmost glyph. Case in point: an empty last line that is
14368 part of an R2L paragraph. */
14369 cursor = end - 1;
14370 /* Avoid placing the cursor on the last glyph of the row, where
14371 on terminal frames we hold the vertical border between
14372 adjacent windows. */
14373 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14374 && !WINDOW_RIGHTMOST_P (w)
14375 && cursor == row->glyphs[LAST_AREA] - 1)
14376 cursor--;
14377 x = -1; /* will be computed below, at label compute_x */
14380 /* Step 1: Try to find the glyph whose character position
14381 corresponds to point. If that's not possible, find 2 glyphs
14382 whose character positions are the closest to point, one before
14383 point, the other after it. */
14384 if (!row->reversed_p)
14385 while (/* not marched to end of glyph row */
14386 glyph < end
14387 /* glyph was not inserted by redisplay for internal purposes */
14388 && !INTEGERP (glyph->object))
14390 if (BUFFERP (glyph->object))
14392 ptrdiff_t dpos = glyph->charpos - pt_old;
14394 if (glyph->charpos > bpos_max)
14395 bpos_max = glyph->charpos;
14396 if (glyph->charpos < bpos_min)
14397 bpos_min = glyph->charpos;
14398 if (!glyph->avoid_cursor_p)
14400 /* If we hit point, we've found the glyph on which to
14401 display the cursor. */
14402 if (dpos == 0)
14404 match_with_avoid_cursor = 0;
14405 break;
14407 /* See if we've found a better approximation to
14408 POS_BEFORE or to POS_AFTER. */
14409 if (0 > dpos && dpos > pos_before - pt_old)
14411 pos_before = glyph->charpos;
14412 glyph_before = glyph;
14414 else if (0 < dpos && dpos < pos_after - pt_old)
14416 pos_after = glyph->charpos;
14417 glyph_after = glyph;
14420 else if (dpos == 0)
14421 match_with_avoid_cursor = 1;
14423 else if (STRINGP (glyph->object))
14425 Lisp_Object chprop;
14426 ptrdiff_t glyph_pos = glyph->charpos;
14428 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14429 glyph->object);
14430 if (!NILP (chprop))
14432 /* If the string came from a `display' text property,
14433 look up the buffer position of that property and
14434 use that position to update bpos_max, as if we
14435 actually saw such a position in one of the row's
14436 glyphs. This helps with supporting integer values
14437 of `cursor' property on the display string in
14438 situations where most or all of the row's buffer
14439 text is completely covered by display properties,
14440 so that no glyph with valid buffer positions is
14441 ever seen in the row. */
14442 ptrdiff_t prop_pos =
14443 string_buffer_position_lim (glyph->object, pos_before,
14444 pos_after, 0);
14446 if (prop_pos >= pos_before)
14447 bpos_max = prop_pos;
14449 if (INTEGERP (chprop))
14451 bpos_covered = bpos_max + XINT (chprop);
14452 /* If the `cursor' property covers buffer positions up
14453 to and including point, we should display cursor on
14454 this glyph. Note that, if a `cursor' property on one
14455 of the string's characters has an integer value, we
14456 will break out of the loop below _before_ we get to
14457 the position match above. IOW, integer values of
14458 the `cursor' property override the "exact match for
14459 point" strategy of positioning the cursor. */
14460 /* Implementation note: bpos_max == pt_old when, e.g.,
14461 we are in an empty line, where bpos_max is set to
14462 MATRIX_ROW_START_CHARPOS, see above. */
14463 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14465 cursor = glyph;
14466 break;
14470 string_seen = 1;
14472 x += glyph->pixel_width;
14473 ++glyph;
14475 else if (glyph > end) /* row is reversed */
14476 while (!INTEGERP (glyph->object))
14478 if (BUFFERP (glyph->object))
14480 ptrdiff_t dpos = glyph->charpos - pt_old;
14482 if (glyph->charpos > bpos_max)
14483 bpos_max = glyph->charpos;
14484 if (glyph->charpos < bpos_min)
14485 bpos_min = glyph->charpos;
14486 if (!glyph->avoid_cursor_p)
14488 if (dpos == 0)
14490 match_with_avoid_cursor = 0;
14491 break;
14493 if (0 > dpos && dpos > pos_before - pt_old)
14495 pos_before = glyph->charpos;
14496 glyph_before = glyph;
14498 else if (0 < dpos && dpos < pos_after - pt_old)
14500 pos_after = glyph->charpos;
14501 glyph_after = glyph;
14504 else if (dpos == 0)
14505 match_with_avoid_cursor = 1;
14507 else if (STRINGP (glyph->object))
14509 Lisp_Object chprop;
14510 ptrdiff_t glyph_pos = glyph->charpos;
14512 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14513 glyph->object);
14514 if (!NILP (chprop))
14516 ptrdiff_t prop_pos =
14517 string_buffer_position_lim (glyph->object, pos_before,
14518 pos_after, 0);
14520 if (prop_pos >= pos_before)
14521 bpos_max = prop_pos;
14523 if (INTEGERP (chprop))
14525 bpos_covered = bpos_max + XINT (chprop);
14526 /* If the `cursor' property covers buffer positions up
14527 to and including point, we should display cursor on
14528 this glyph. */
14529 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14531 cursor = glyph;
14532 break;
14535 string_seen = 1;
14537 --glyph;
14538 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14540 x--; /* can't use any pixel_width */
14541 break;
14543 x -= glyph->pixel_width;
14546 /* Step 2: If we didn't find an exact match for point, we need to
14547 look for a proper place to put the cursor among glyphs between
14548 GLYPH_BEFORE and GLYPH_AFTER. */
14549 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14550 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14551 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
14553 /* An empty line has a single glyph whose OBJECT is zero and
14554 whose CHARPOS is the position of a newline on that line.
14555 Note that on a TTY, there are more glyphs after that, which
14556 were produced by extend_face_to_end_of_line, but their
14557 CHARPOS is zero or negative. */
14558 int empty_line_p =
14559 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14560 && INTEGERP (glyph->object) && glyph->charpos > 0
14561 /* On a TTY, continued and truncated rows also have a glyph at
14562 their end whose OBJECT is zero and whose CHARPOS is
14563 positive (the continuation and truncation glyphs), but such
14564 rows are obviously not "empty". */
14565 && !(row->continued_p || row->truncated_on_right_p);
14567 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14569 ptrdiff_t ellipsis_pos;
14571 /* Scan back over the ellipsis glyphs. */
14572 if (!row->reversed_p)
14574 ellipsis_pos = (glyph - 1)->charpos;
14575 while (glyph > row->glyphs[TEXT_AREA]
14576 && (glyph - 1)->charpos == ellipsis_pos)
14577 glyph--, x -= glyph->pixel_width;
14578 /* That loop always goes one position too far, including
14579 the glyph before the ellipsis. So scan forward over
14580 that one. */
14581 x += glyph->pixel_width;
14582 glyph++;
14584 else /* row is reversed */
14586 ellipsis_pos = (glyph + 1)->charpos;
14587 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14588 && (glyph + 1)->charpos == ellipsis_pos)
14589 glyph++, x += glyph->pixel_width;
14590 x -= glyph->pixel_width;
14591 glyph--;
14594 else if (match_with_avoid_cursor)
14596 cursor = glyph_after;
14597 x = -1;
14599 else if (string_seen)
14601 int incr = row->reversed_p ? -1 : +1;
14603 /* Need to find the glyph that came out of a string which is
14604 present at point. That glyph is somewhere between
14605 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14606 positioned between POS_BEFORE and POS_AFTER in the
14607 buffer. */
14608 struct glyph *start, *stop;
14609 ptrdiff_t pos = pos_before;
14611 x = -1;
14613 /* If the row ends in a newline from a display string,
14614 reordering could have moved the glyphs belonging to the
14615 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14616 in this case we extend the search to the last glyph in
14617 the row that was not inserted by redisplay. */
14618 if (row->ends_in_newline_from_string_p)
14620 glyph_after = end;
14621 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14624 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14625 correspond to POS_BEFORE and POS_AFTER, respectively. We
14626 need START and STOP in the order that corresponds to the
14627 row's direction as given by its reversed_p flag. If the
14628 directionality of characters between POS_BEFORE and
14629 POS_AFTER is the opposite of the row's base direction,
14630 these characters will have been reordered for display,
14631 and we need to reverse START and STOP. */
14632 if (!row->reversed_p)
14634 start = min (glyph_before, glyph_after);
14635 stop = max (glyph_before, glyph_after);
14637 else
14639 start = max (glyph_before, glyph_after);
14640 stop = min (glyph_before, glyph_after);
14642 for (glyph = start + incr;
14643 row->reversed_p ? glyph > stop : glyph < stop; )
14646 /* Any glyphs that come from the buffer are here because
14647 of bidi reordering. Skip them, and only pay
14648 attention to glyphs that came from some string. */
14649 if (STRINGP (glyph->object))
14651 Lisp_Object str;
14652 ptrdiff_t tem;
14653 /* If the display property covers the newline, we
14654 need to search for it one position farther. */
14655 ptrdiff_t lim = pos_after
14656 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14658 string_from_text_prop = 0;
14659 str = glyph->object;
14660 tem = string_buffer_position_lim (str, pos, lim, 0);
14661 if (tem == 0 /* from overlay */
14662 || pos <= tem)
14664 /* If the string from which this glyph came is
14665 found in the buffer at point, or at position
14666 that is closer to point than pos_after, then
14667 we've found the glyph we've been looking for.
14668 If it comes from an overlay (tem == 0), and
14669 it has the `cursor' property on one of its
14670 glyphs, record that glyph as a candidate for
14671 displaying the cursor. (As in the
14672 unidirectional version, we will display the
14673 cursor on the last candidate we find.) */
14674 if (tem == 0
14675 || tem == pt_old
14676 || (tem - pt_old > 0 && tem < pos_after))
14678 /* The glyphs from this string could have
14679 been reordered. Find the one with the
14680 smallest string position. Or there could
14681 be a character in the string with the
14682 `cursor' property, which means display
14683 cursor on that character's glyph. */
14684 ptrdiff_t strpos = glyph->charpos;
14686 if (tem)
14688 cursor = glyph;
14689 string_from_text_prop = 1;
14691 for ( ;
14692 (row->reversed_p ? glyph > stop : glyph < stop)
14693 && EQ (glyph->object, str);
14694 glyph += incr)
14696 Lisp_Object cprop;
14697 ptrdiff_t gpos = glyph->charpos;
14699 cprop = Fget_char_property (make_number (gpos),
14700 Qcursor,
14701 glyph->object);
14702 if (!NILP (cprop))
14704 cursor = glyph;
14705 break;
14707 if (tem && glyph->charpos < strpos)
14709 strpos = glyph->charpos;
14710 cursor = glyph;
14714 if (tem == pt_old
14715 || (tem - pt_old > 0 && tem < pos_after))
14716 goto compute_x;
14718 if (tem)
14719 pos = tem + 1; /* don't find previous instances */
14721 /* This string is not what we want; skip all of the
14722 glyphs that came from it. */
14723 while ((row->reversed_p ? glyph > stop : glyph < stop)
14724 && EQ (glyph->object, str))
14725 glyph += incr;
14727 else
14728 glyph += incr;
14731 /* If we reached the end of the line, and END was from a string,
14732 the cursor is not on this line. */
14733 if (cursor == NULL
14734 && (row->reversed_p ? glyph <= end : glyph >= end)
14735 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14736 && STRINGP (end->object)
14737 && row->continued_p)
14738 return 0;
14740 /* A truncated row may not include PT among its character positions.
14741 Setting the cursor inside the scroll margin will trigger
14742 recalculation of hscroll in hscroll_window_tree. But if a
14743 display string covers point, defer to the string-handling
14744 code below to figure this out. */
14745 else if (row->truncated_on_left_p && pt_old < bpos_min)
14747 cursor = glyph_before;
14748 x = -1;
14750 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14751 /* Zero-width characters produce no glyphs. */
14752 || (!empty_line_p
14753 && (row->reversed_p
14754 ? glyph_after > glyphs_end
14755 : glyph_after < glyphs_end)))
14757 cursor = glyph_after;
14758 x = -1;
14762 compute_x:
14763 if (cursor != NULL)
14764 glyph = cursor;
14765 else if (glyph == glyphs_end
14766 && pos_before == pos_after
14767 && STRINGP ((row->reversed_p
14768 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14769 : row->glyphs[TEXT_AREA])->object))
14771 /* If all the glyphs of this row came from strings, put the
14772 cursor on the first glyph of the row. This avoids having the
14773 cursor outside of the text area in this very rare and hard
14774 use case. */
14775 glyph =
14776 row->reversed_p
14777 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14778 : row->glyphs[TEXT_AREA];
14780 if (x < 0)
14782 struct glyph *g;
14784 /* Need to compute x that corresponds to GLYPH. */
14785 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14787 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14788 emacs_abort ();
14789 x += g->pixel_width;
14793 /* ROW could be part of a continued line, which, under bidi
14794 reordering, might have other rows whose start and end charpos
14795 occlude point. Only set w->cursor if we found a better
14796 approximation to the cursor position than we have from previously
14797 examined candidate rows belonging to the same continued line. */
14798 if (/* We already have a candidate row. */
14799 w->cursor.vpos >= 0
14800 /* That candidate is not the row we are processing. */
14801 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14802 /* Make sure cursor.vpos specifies a row whose start and end
14803 charpos occlude point, and it is valid candidate for being a
14804 cursor-row. This is because some callers of this function
14805 leave cursor.vpos at the row where the cursor was displayed
14806 during the last redisplay cycle. */
14807 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14808 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14809 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14811 struct glyph *g1
14812 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14814 /* Don't consider glyphs that are outside TEXT_AREA. */
14815 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14816 return 0;
14817 /* Keep the candidate whose buffer position is the closest to
14818 point or has the `cursor' property. */
14819 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14820 w->cursor.hpos >= 0
14821 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14822 && ((BUFFERP (g1->object)
14823 && (g1->charpos == pt_old /* An exact match always wins. */
14824 || (BUFFERP (glyph->object)
14825 && eabs (g1->charpos - pt_old)
14826 < eabs (glyph->charpos - pt_old))))
14827 /* Previous candidate is a glyph from a string that has
14828 a non-nil `cursor' property. */
14829 || (STRINGP (g1->object)
14830 && (!NILP (Fget_char_property (make_number (g1->charpos),
14831 Qcursor, g1->object))
14832 /* Previous candidate is from the same display
14833 string as this one, and the display string
14834 came from a text property. */
14835 || (EQ (g1->object, glyph->object)
14836 && string_from_text_prop)
14837 /* this candidate is from newline and its
14838 position is not an exact match */
14839 || (INTEGERP (glyph->object)
14840 && glyph->charpos != pt_old)))))
14841 return 0;
14842 /* If this candidate gives an exact match, use that. */
14843 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14844 /* If this candidate is a glyph created for the
14845 terminating newline of a line, and point is on that
14846 newline, it wins because it's an exact match. */
14847 || (!row->continued_p
14848 && INTEGERP (glyph->object)
14849 && glyph->charpos == 0
14850 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14851 /* Otherwise, keep the candidate that comes from a row
14852 spanning less buffer positions. This may win when one or
14853 both candidate positions are on glyphs that came from
14854 display strings, for which we cannot compare buffer
14855 positions. */
14856 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14857 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14858 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14859 return 0;
14861 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14862 w->cursor.x = x;
14863 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14864 w->cursor.y = row->y + dy;
14866 if (w == XWINDOW (selected_window))
14868 if (!row->continued_p
14869 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14870 && row->x == 0)
14872 this_line_buffer = XBUFFER (w->contents);
14874 CHARPOS (this_line_start_pos)
14875 = MATRIX_ROW_START_CHARPOS (row) + delta;
14876 BYTEPOS (this_line_start_pos)
14877 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14879 CHARPOS (this_line_end_pos)
14880 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14881 BYTEPOS (this_line_end_pos)
14882 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14884 this_line_y = w->cursor.y;
14885 this_line_pixel_height = row->height;
14886 this_line_vpos = w->cursor.vpos;
14887 this_line_start_x = row->x;
14889 else
14890 CHARPOS (this_line_start_pos) = 0;
14893 return 1;
14897 /* Run window scroll functions, if any, for WINDOW with new window
14898 start STARTP. Sets the window start of WINDOW to that position.
14900 We assume that the window's buffer is really current. */
14902 static struct text_pos
14903 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14905 struct window *w = XWINDOW (window);
14906 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14908 eassert (current_buffer == XBUFFER (w->contents));
14910 if (!NILP (Vwindow_scroll_functions))
14912 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14913 make_number (CHARPOS (startp)));
14914 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14915 /* In case the hook functions switch buffers. */
14916 set_buffer_internal (XBUFFER (w->contents));
14919 return startp;
14923 /* Make sure the line containing the cursor is fully visible.
14924 A value of 1 means there is nothing to be done.
14925 (Either the line is fully visible, or it cannot be made so,
14926 or we cannot tell.)
14928 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14929 is higher than window.
14931 A value of 0 means the caller should do scrolling
14932 as if point had gone off the screen. */
14934 static int
14935 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14937 struct glyph_matrix *matrix;
14938 struct glyph_row *row;
14939 int window_height;
14941 if (!make_cursor_line_fully_visible_p)
14942 return 1;
14944 /* It's not always possible to find the cursor, e.g, when a window
14945 is full of overlay strings. Don't do anything in that case. */
14946 if (w->cursor.vpos < 0)
14947 return 1;
14949 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14950 row = MATRIX_ROW (matrix, w->cursor.vpos);
14952 /* If the cursor row is not partially visible, there's nothing to do. */
14953 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14954 return 1;
14956 /* If the row the cursor is in is taller than the window's height,
14957 it's not clear what to do, so do nothing. */
14958 window_height = window_box_height (w);
14959 if (row->height >= window_height)
14961 if (!force_p || MINI_WINDOW_P (w)
14962 || w->vscroll || w->cursor.vpos == 0)
14963 return 1;
14965 return 0;
14969 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14970 non-zero means only WINDOW is redisplayed in redisplay_internal.
14971 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14972 in redisplay_window to bring a partially visible line into view in
14973 the case that only the cursor has moved.
14975 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14976 last screen line's vertical height extends past the end of the screen.
14978 Value is
14980 1 if scrolling succeeded
14982 0 if scrolling didn't find point.
14984 -1 if new fonts have been loaded so that we must interrupt
14985 redisplay, adjust glyph matrices, and try again. */
14987 enum
14989 SCROLLING_SUCCESS,
14990 SCROLLING_FAILED,
14991 SCROLLING_NEED_LARGER_MATRICES
14994 /* If scroll-conservatively is more than this, never recenter.
14996 If you change this, don't forget to update the doc string of
14997 `scroll-conservatively' and the Emacs manual. */
14998 #define SCROLL_LIMIT 100
15000 static int
15001 try_scrolling (Lisp_Object window, int just_this_one_p,
15002 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15003 int temp_scroll_step, int last_line_misfit)
15005 struct window *w = XWINDOW (window);
15006 struct frame *f = XFRAME (w->frame);
15007 struct text_pos pos, startp;
15008 struct it it;
15009 int this_scroll_margin, scroll_max, rc, height;
15010 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
15011 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
15012 Lisp_Object aggressive;
15013 /* We will never try scrolling more than this number of lines. */
15014 int scroll_limit = SCROLL_LIMIT;
15015 int frame_line_height = default_line_pixel_height (w);
15016 int window_total_lines
15017 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15019 #ifdef GLYPH_DEBUG
15020 debug_method_add (w, "try_scrolling");
15021 #endif
15023 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15025 /* Compute scroll margin height in pixels. We scroll when point is
15026 within this distance from the top or bottom of the window. */
15027 if (scroll_margin > 0)
15028 this_scroll_margin = min (scroll_margin, window_total_lines / 4)
15029 * frame_line_height;
15030 else
15031 this_scroll_margin = 0;
15033 /* Force arg_scroll_conservatively to have a reasonable value, to
15034 avoid scrolling too far away with slow move_it_* functions. Note
15035 that the user can supply scroll-conservatively equal to
15036 `most-positive-fixnum', which can be larger than INT_MAX. */
15037 if (arg_scroll_conservatively > scroll_limit)
15039 arg_scroll_conservatively = scroll_limit + 1;
15040 scroll_max = scroll_limit * frame_line_height;
15042 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15043 /* Compute how much we should try to scroll maximally to bring
15044 point into view. */
15045 scroll_max = (max (scroll_step,
15046 max (arg_scroll_conservatively, temp_scroll_step))
15047 * frame_line_height);
15048 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15049 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15050 /* We're trying to scroll because of aggressive scrolling but no
15051 scroll_step is set. Choose an arbitrary one. */
15052 scroll_max = 10 * frame_line_height;
15053 else
15054 scroll_max = 0;
15056 too_near_end:
15058 /* Decide whether to scroll down. */
15059 if (PT > CHARPOS (startp))
15061 int scroll_margin_y;
15063 /* Compute the pixel ypos of the scroll margin, then move IT to
15064 either that ypos or PT, whichever comes first. */
15065 start_display (&it, w, startp);
15066 scroll_margin_y = it.last_visible_y - this_scroll_margin
15067 - frame_line_height * extra_scroll_margin_lines;
15068 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15069 (MOVE_TO_POS | MOVE_TO_Y));
15071 if (PT > CHARPOS (it.current.pos))
15073 int y0 = line_bottom_y (&it);
15074 /* Compute how many pixels below window bottom to stop searching
15075 for PT. This avoids costly search for PT that is far away if
15076 the user limited scrolling by a small number of lines, but
15077 always finds PT if scroll_conservatively is set to a large
15078 number, such as most-positive-fixnum. */
15079 int slack = max (scroll_max, 10 * frame_line_height);
15080 int y_to_move = it.last_visible_y + slack;
15082 /* Compute the distance from the scroll margin to PT or to
15083 the scroll limit, whichever comes first. This should
15084 include the height of the cursor line, to make that line
15085 fully visible. */
15086 move_it_to (&it, PT, -1, y_to_move,
15087 -1, MOVE_TO_POS | MOVE_TO_Y);
15088 dy = line_bottom_y (&it) - y0;
15090 if (dy > scroll_max)
15091 return SCROLLING_FAILED;
15093 if (dy > 0)
15094 scroll_down_p = 1;
15098 if (scroll_down_p)
15100 /* Point is in or below the bottom scroll margin, so move the
15101 window start down. If scrolling conservatively, move it just
15102 enough down to make point visible. If scroll_step is set,
15103 move it down by scroll_step. */
15104 if (arg_scroll_conservatively)
15105 amount_to_scroll
15106 = min (max (dy, frame_line_height),
15107 frame_line_height * arg_scroll_conservatively);
15108 else if (scroll_step || temp_scroll_step)
15109 amount_to_scroll = scroll_max;
15110 else
15112 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15113 height = WINDOW_BOX_TEXT_HEIGHT (w);
15114 if (NUMBERP (aggressive))
15116 double float_amount = XFLOATINT (aggressive) * height;
15117 int aggressive_scroll = float_amount;
15118 if (aggressive_scroll == 0 && float_amount > 0)
15119 aggressive_scroll = 1;
15120 /* Don't let point enter the scroll margin near top of
15121 the window. This could happen if the value of
15122 scroll_up_aggressively is too large and there are
15123 non-zero margins, because scroll_up_aggressively
15124 means put point that fraction of window height
15125 _from_the_bottom_margin_. */
15126 if (aggressive_scroll + 2*this_scroll_margin > height)
15127 aggressive_scroll = height - 2*this_scroll_margin;
15128 amount_to_scroll = dy + aggressive_scroll;
15132 if (amount_to_scroll <= 0)
15133 return SCROLLING_FAILED;
15135 start_display (&it, w, startp);
15136 if (arg_scroll_conservatively <= scroll_limit)
15137 move_it_vertically (&it, amount_to_scroll);
15138 else
15140 /* Extra precision for users who set scroll-conservatively
15141 to a large number: make sure the amount we scroll
15142 the window start is never less than amount_to_scroll,
15143 which was computed as distance from window bottom to
15144 point. This matters when lines at window top and lines
15145 below window bottom have different height. */
15146 struct it it1;
15147 void *it1data = NULL;
15148 /* We use a temporary it1 because line_bottom_y can modify
15149 its argument, if it moves one line down; see there. */
15150 int start_y;
15152 SAVE_IT (it1, it, it1data);
15153 start_y = line_bottom_y (&it1);
15154 do {
15155 RESTORE_IT (&it, &it, it1data);
15156 move_it_by_lines (&it, 1);
15157 SAVE_IT (it1, it, it1data);
15158 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
15161 /* If STARTP is unchanged, move it down another screen line. */
15162 if (CHARPOS (it.current.pos) == CHARPOS (startp))
15163 move_it_by_lines (&it, 1);
15164 startp = it.current.pos;
15166 else
15168 struct text_pos scroll_margin_pos = startp;
15169 int y_offset = 0;
15171 /* See if point is inside the scroll margin at the top of the
15172 window. */
15173 if (this_scroll_margin)
15175 int y_start;
15177 start_display (&it, w, startp);
15178 y_start = it.current_y;
15179 move_it_vertically (&it, this_scroll_margin);
15180 scroll_margin_pos = it.current.pos;
15181 /* If we didn't move enough before hitting ZV, request
15182 additional amount of scroll, to move point out of the
15183 scroll margin. */
15184 if (IT_CHARPOS (it) == ZV
15185 && it.current_y - y_start < this_scroll_margin)
15186 y_offset = this_scroll_margin - (it.current_y - y_start);
15189 if (PT < CHARPOS (scroll_margin_pos))
15191 /* Point is in the scroll margin at the top of the window or
15192 above what is displayed in the window. */
15193 int y0, y_to_move;
15195 /* Compute the vertical distance from PT to the scroll
15196 margin position. Move as far as scroll_max allows, or
15197 one screenful, or 10 screen lines, whichever is largest.
15198 Give up if distance is greater than scroll_max or if we
15199 didn't reach the scroll margin position. */
15200 SET_TEXT_POS (pos, PT, PT_BYTE);
15201 start_display (&it, w, pos);
15202 y0 = it.current_y;
15203 y_to_move = max (it.last_visible_y,
15204 max (scroll_max, 10 * frame_line_height));
15205 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15206 y_to_move, -1,
15207 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15208 dy = it.current_y - y0;
15209 if (dy > scroll_max
15210 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15211 return SCROLLING_FAILED;
15213 /* Additional scroll for when ZV was too close to point. */
15214 dy += y_offset;
15216 /* Compute new window start. */
15217 start_display (&it, w, startp);
15219 if (arg_scroll_conservatively)
15220 amount_to_scroll = max (dy, frame_line_height *
15221 max (scroll_step, temp_scroll_step));
15222 else if (scroll_step || temp_scroll_step)
15223 amount_to_scroll = scroll_max;
15224 else
15226 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15227 height = WINDOW_BOX_TEXT_HEIGHT (w);
15228 if (NUMBERP (aggressive))
15230 double float_amount = XFLOATINT (aggressive) * height;
15231 int aggressive_scroll = float_amount;
15232 if (aggressive_scroll == 0 && float_amount > 0)
15233 aggressive_scroll = 1;
15234 /* Don't let point enter the scroll margin near
15235 bottom of the window, if the value of
15236 scroll_down_aggressively happens to be too
15237 large. */
15238 if (aggressive_scroll + 2*this_scroll_margin > height)
15239 aggressive_scroll = height - 2*this_scroll_margin;
15240 amount_to_scroll = dy + aggressive_scroll;
15244 if (amount_to_scroll <= 0)
15245 return SCROLLING_FAILED;
15247 move_it_vertically_backward (&it, amount_to_scroll);
15248 startp = it.current.pos;
15252 /* Run window scroll functions. */
15253 startp = run_window_scroll_functions (window, startp);
15255 /* Display the window. Give up if new fonts are loaded, or if point
15256 doesn't appear. */
15257 if (!try_window (window, startp, 0))
15258 rc = SCROLLING_NEED_LARGER_MATRICES;
15259 else if (w->cursor.vpos < 0)
15261 clear_glyph_matrix (w->desired_matrix);
15262 rc = SCROLLING_FAILED;
15264 else
15266 /* Maybe forget recorded base line for line number display. */
15267 if (!just_this_one_p
15268 || current_buffer->clip_changed
15269 || BEG_UNCHANGED < CHARPOS (startp))
15270 w->base_line_number = 0;
15272 /* If cursor ends up on a partially visible line,
15273 treat that as being off the bottom of the screen. */
15274 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
15275 /* It's possible that the cursor is on the first line of the
15276 buffer, which is partially obscured due to a vscroll
15277 (Bug#7537). In that case, avoid looping forever. */
15278 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15280 clear_glyph_matrix (w->desired_matrix);
15281 ++extra_scroll_margin_lines;
15282 goto too_near_end;
15284 rc = SCROLLING_SUCCESS;
15287 return rc;
15291 /* Compute a suitable window start for window W if display of W starts
15292 on a continuation line. Value is non-zero if a new window start
15293 was computed.
15295 The new window start will be computed, based on W's width, starting
15296 from the start of the continued line. It is the start of the
15297 screen line with the minimum distance from the old start W->start. */
15299 static int
15300 compute_window_start_on_continuation_line (struct window *w)
15302 struct text_pos pos, start_pos;
15303 int window_start_changed_p = 0;
15305 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15307 /* If window start is on a continuation line... Window start may be
15308 < BEGV in case there's invisible text at the start of the
15309 buffer (M-x rmail, for example). */
15310 if (CHARPOS (start_pos) > BEGV
15311 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15313 struct it it;
15314 struct glyph_row *row;
15316 /* Handle the case that the window start is out of range. */
15317 if (CHARPOS (start_pos) < BEGV)
15318 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15319 else if (CHARPOS (start_pos) > ZV)
15320 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15322 /* Find the start of the continued line. This should be fast
15323 because find_newline is fast (newline cache). */
15324 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
15325 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15326 row, DEFAULT_FACE_ID);
15327 reseat_at_previous_visible_line_start (&it);
15329 /* If the line start is "too far" away from the window start,
15330 say it takes too much time to compute a new window start. */
15331 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15332 /* PXW: Do we need upper bounds here? */
15333 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
15335 int min_distance, distance;
15337 /* Move forward by display lines to find the new window
15338 start. If window width was enlarged, the new start can
15339 be expected to be > the old start. If window width was
15340 decreased, the new window start will be < the old start.
15341 So, we're looking for the display line start with the
15342 minimum distance from the old window start. */
15343 pos = it.current.pos;
15344 min_distance = INFINITY;
15345 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15346 distance < min_distance)
15348 min_distance = distance;
15349 pos = it.current.pos;
15350 if (it.line_wrap == WORD_WRAP)
15352 /* Under WORD_WRAP, move_it_by_lines is likely to
15353 overshoot and stop not at the first, but the
15354 second character from the left margin. So in
15355 that case, we need a more tight control on the X
15356 coordinate of the iterator than move_it_by_lines
15357 promises in its contract. The method is to first
15358 go to the last (rightmost) visible character of a
15359 line, then move to the leftmost character on the
15360 next line in a separate call. */
15361 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15362 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15363 move_it_to (&it, ZV, 0,
15364 it.current_y + it.max_ascent + it.max_descent, -1,
15365 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15367 else
15368 move_it_by_lines (&it, 1);
15371 /* Set the window start there. */
15372 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15373 window_start_changed_p = 1;
15377 return window_start_changed_p;
15381 /* Try cursor movement in case text has not changed in window WINDOW,
15382 with window start STARTP. Value is
15384 CURSOR_MOVEMENT_SUCCESS if successful
15386 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15388 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15389 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15390 we want to scroll as if scroll-step were set to 1. See the code.
15392 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15393 which case we have to abort this redisplay, and adjust matrices
15394 first. */
15396 enum
15398 CURSOR_MOVEMENT_SUCCESS,
15399 CURSOR_MOVEMENT_CANNOT_BE_USED,
15400 CURSOR_MOVEMENT_MUST_SCROLL,
15401 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15404 static int
15405 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15407 struct window *w = XWINDOW (window);
15408 struct frame *f = XFRAME (w->frame);
15409 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15411 #ifdef GLYPH_DEBUG
15412 if (inhibit_try_cursor_movement)
15413 return rc;
15414 #endif
15416 /* Previously, there was a check for Lisp integer in the
15417 if-statement below. Now, this field is converted to
15418 ptrdiff_t, thus zero means invalid position in a buffer. */
15419 eassert (w->last_point > 0);
15420 /* Likewise there was a check whether window_end_vpos is nil or larger
15421 than the window. Now window_end_vpos is int and so never nil, but
15422 let's leave eassert to check whether it fits in the window. */
15423 eassert (w->window_end_vpos < w->current_matrix->nrows);
15425 /* Handle case where text has not changed, only point, and it has
15426 not moved off the frame. */
15427 if (/* Point may be in this window. */
15428 PT >= CHARPOS (startp)
15429 /* Selective display hasn't changed. */
15430 && !current_buffer->clip_changed
15431 /* Function force-mode-line-update is used to force a thorough
15432 redisplay. It sets either windows_or_buffers_changed or
15433 update_mode_lines. So don't take a shortcut here for these
15434 cases. */
15435 && !update_mode_lines
15436 && !windows_or_buffers_changed
15437 && !f->cursor_type_changed
15438 && NILP (Vshow_trailing_whitespace)
15439 /* This code is not used for mini-buffer for the sake of the case
15440 of redisplaying to replace an echo area message; since in
15441 that case the mini-buffer contents per se are usually
15442 unchanged. This code is of no real use in the mini-buffer
15443 since the handling of this_line_start_pos, etc., in redisplay
15444 handles the same cases. */
15445 && !EQ (window, minibuf_window)
15446 && (FRAME_WINDOW_P (f)
15447 || !overlay_arrow_in_current_buffer_p ()))
15449 int this_scroll_margin, top_scroll_margin;
15450 struct glyph_row *row = NULL;
15451 int frame_line_height = default_line_pixel_height (w);
15452 int window_total_lines
15453 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
15455 #ifdef GLYPH_DEBUG
15456 debug_method_add (w, "cursor movement");
15457 #endif
15459 /* Scroll if point within this distance from the top or bottom
15460 of the window. This is a pixel value. */
15461 if (scroll_margin > 0)
15463 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
15464 this_scroll_margin *= frame_line_height;
15466 else
15467 this_scroll_margin = 0;
15469 top_scroll_margin = this_scroll_margin;
15470 if (WINDOW_WANTS_HEADER_LINE_P (w))
15471 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15473 /* Start with the row the cursor was displayed during the last
15474 not paused redisplay. Give up if that row is not valid. */
15475 if (w->last_cursor_vpos < 0
15476 || w->last_cursor_vpos >= w->current_matrix->nrows)
15477 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15478 else
15480 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15481 if (row->mode_line_p)
15482 ++row;
15483 if (!row->enabled_p)
15484 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15487 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15489 int scroll_p = 0, must_scroll = 0;
15490 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15492 if (PT > w->last_point)
15494 /* Point has moved forward. */
15495 while (MATRIX_ROW_END_CHARPOS (row) < PT
15496 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15498 eassert (row->enabled_p);
15499 ++row;
15502 /* If the end position of a row equals the start
15503 position of the next row, and PT is at that position,
15504 we would rather display cursor in the next line. */
15505 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15506 && MATRIX_ROW_END_CHARPOS (row) == PT
15507 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
15508 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15509 && !cursor_row_p (row))
15510 ++row;
15512 /* If within the scroll margin, scroll. Note that
15513 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15514 the next line would be drawn, and that
15515 this_scroll_margin can be zero. */
15516 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15517 || PT > MATRIX_ROW_END_CHARPOS (row)
15518 /* Line is completely visible last line in window
15519 and PT is to be set in the next line. */
15520 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15521 && PT == MATRIX_ROW_END_CHARPOS (row)
15522 && !row->ends_at_zv_p
15523 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15524 scroll_p = 1;
15526 else if (PT < w->last_point)
15528 /* Cursor has to be moved backward. Note that PT >=
15529 CHARPOS (startp) because of the outer if-statement. */
15530 while (!row->mode_line_p
15531 && (MATRIX_ROW_START_CHARPOS (row) > PT
15532 || (MATRIX_ROW_START_CHARPOS (row) == PT
15533 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15534 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15535 row > w->current_matrix->rows
15536 && (row-1)->ends_in_newline_from_string_p))))
15537 && (row->y > top_scroll_margin
15538 || CHARPOS (startp) == BEGV))
15540 eassert (row->enabled_p);
15541 --row;
15544 /* Consider the following case: Window starts at BEGV,
15545 there is invisible, intangible text at BEGV, so that
15546 display starts at some point START > BEGV. It can
15547 happen that we are called with PT somewhere between
15548 BEGV and START. Try to handle that case. */
15549 if (row < w->current_matrix->rows
15550 || row->mode_line_p)
15552 row = w->current_matrix->rows;
15553 if (row->mode_line_p)
15554 ++row;
15557 /* Due to newlines in overlay strings, we may have to
15558 skip forward over overlay strings. */
15559 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15560 && MATRIX_ROW_END_CHARPOS (row) == PT
15561 && !cursor_row_p (row))
15562 ++row;
15564 /* If within the scroll margin, scroll. */
15565 if (row->y < top_scroll_margin
15566 && CHARPOS (startp) != BEGV)
15567 scroll_p = 1;
15569 else
15571 /* Cursor did not move. So don't scroll even if cursor line
15572 is partially visible, as it was so before. */
15573 rc = CURSOR_MOVEMENT_SUCCESS;
15576 if (PT < MATRIX_ROW_START_CHARPOS (row)
15577 || PT > MATRIX_ROW_END_CHARPOS (row))
15579 /* if PT is not in the glyph row, give up. */
15580 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15581 must_scroll = 1;
15583 else if (rc != CURSOR_MOVEMENT_SUCCESS
15584 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15586 struct glyph_row *row1;
15588 /* If rows are bidi-reordered and point moved, back up
15589 until we find a row that does not belong to a
15590 continuation line. This is because we must consider
15591 all rows of a continued line as candidates for the
15592 new cursor positioning, since row start and end
15593 positions change non-linearly with vertical position
15594 in such rows. */
15595 /* FIXME: Revisit this when glyph ``spilling'' in
15596 continuation lines' rows is implemented for
15597 bidi-reordered rows. */
15598 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15599 MATRIX_ROW_CONTINUATION_LINE_P (row);
15600 --row)
15602 /* If we hit the beginning of the displayed portion
15603 without finding the first row of a continued
15604 line, give up. */
15605 if (row <= row1)
15607 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15608 break;
15610 eassert (row->enabled_p);
15613 if (must_scroll)
15615 else if (rc != CURSOR_MOVEMENT_SUCCESS
15616 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15617 /* Make sure this isn't a header line by any chance, since
15618 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15619 && !row->mode_line_p
15620 && make_cursor_line_fully_visible_p)
15622 if (PT == MATRIX_ROW_END_CHARPOS (row)
15623 && !row->ends_at_zv_p
15624 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15625 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15626 else if (row->height > window_box_height (w))
15628 /* If we end up in a partially visible line, let's
15629 make it fully visible, except when it's taller
15630 than the window, in which case we can't do much
15631 about it. */
15632 *scroll_step = 1;
15633 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15635 else
15637 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15638 if (!cursor_row_fully_visible_p (w, 0, 1))
15639 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15640 else
15641 rc = CURSOR_MOVEMENT_SUCCESS;
15644 else if (scroll_p)
15645 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15646 else if (rc != CURSOR_MOVEMENT_SUCCESS
15647 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15649 /* With bidi-reordered rows, there could be more than
15650 one candidate row whose start and end positions
15651 occlude point. We need to let set_cursor_from_row
15652 find the best candidate. */
15653 /* FIXME: Revisit this when glyph ``spilling'' in
15654 continuation lines' rows is implemented for
15655 bidi-reordered rows. */
15656 int rv = 0;
15660 int at_zv_p = 0, exact_match_p = 0;
15662 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15663 && PT <= MATRIX_ROW_END_CHARPOS (row)
15664 && cursor_row_p (row))
15665 rv |= set_cursor_from_row (w, row, w->current_matrix,
15666 0, 0, 0, 0);
15667 /* As soon as we've found the exact match for point,
15668 or the first suitable row whose ends_at_zv_p flag
15669 is set, we are done. */
15670 if (rv)
15672 at_zv_p = MATRIX_ROW (w->current_matrix,
15673 w->cursor.vpos)->ends_at_zv_p;
15674 if (!at_zv_p
15675 && w->cursor.hpos >= 0
15676 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15677 w->cursor.vpos))
15679 struct glyph_row *candidate =
15680 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15681 struct glyph *g =
15682 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15683 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15685 exact_match_p =
15686 (BUFFERP (g->object) && g->charpos == PT)
15687 || (INTEGERP (g->object)
15688 && (g->charpos == PT
15689 || (g->charpos == 0 && endpos - 1 == PT)));
15691 if (at_zv_p || exact_match_p)
15693 rc = CURSOR_MOVEMENT_SUCCESS;
15694 break;
15697 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15698 break;
15699 ++row;
15701 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15702 || row->continued_p)
15703 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15704 || (MATRIX_ROW_START_CHARPOS (row) == PT
15705 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15706 /* If we didn't find any candidate rows, or exited the
15707 loop before all the candidates were examined, signal
15708 to the caller that this method failed. */
15709 if (rc != CURSOR_MOVEMENT_SUCCESS
15710 && !(rv
15711 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15712 && !row->continued_p))
15713 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15714 else if (rv)
15715 rc = CURSOR_MOVEMENT_SUCCESS;
15717 else
15721 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15723 rc = CURSOR_MOVEMENT_SUCCESS;
15724 break;
15726 ++row;
15728 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15729 && MATRIX_ROW_START_CHARPOS (row) == PT
15730 && cursor_row_p (row));
15735 return rc;
15739 void
15740 set_vertical_scroll_bar (struct window *w)
15742 ptrdiff_t start, end, whole;
15744 /* Calculate the start and end positions for the current window.
15745 At some point, it would be nice to choose between scrollbars
15746 which reflect the whole buffer size, with special markers
15747 indicating narrowing, and scrollbars which reflect only the
15748 visible region.
15750 Note that mini-buffers sometimes aren't displaying any text. */
15751 if (!MINI_WINDOW_P (w)
15752 || (w == XWINDOW (minibuf_window)
15753 && NILP (echo_area_buffer[0])))
15755 struct buffer *buf = XBUFFER (w->contents);
15756 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15757 start = marker_position (w->start) - BUF_BEGV (buf);
15758 /* I don't think this is guaranteed to be right. For the
15759 moment, we'll pretend it is. */
15760 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15762 if (end < start)
15763 end = start;
15764 if (whole < (end - start))
15765 whole = end - start;
15767 else
15768 start = end = whole = 0;
15770 /* Indicate what this scroll bar ought to be displaying now. */
15771 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15772 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15773 (w, end - start, whole, start);
15777 void
15778 set_horizontal_scroll_bar (struct window *w)
15780 int start, end, whole, portion;
15782 if (!MINI_WINDOW_P (w)
15783 || (w == XWINDOW (minibuf_window)
15784 && NILP (echo_area_buffer[0])))
15786 struct buffer *b = XBUFFER (w->contents);
15787 struct buffer *old_buffer = NULL;
15788 struct it it;
15789 struct text_pos startp;
15791 if (b != current_buffer)
15793 old_buffer = current_buffer;
15794 set_buffer_internal (b);
15797 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15798 start_display (&it, w, startp);
15799 it.last_visible_x = INT_MAX;
15800 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
15801 MOVE_TO_X | MOVE_TO_Y);
15802 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
15803 window_box_height (w), -1,
15804 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
15806 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
15807 end = start + window_box_width (w, TEXT_AREA);
15808 portion = end - start;
15809 /* After enlarging a horizontally scrolled window such that it
15810 gets at least as wide as the text it contains, make sure that
15811 the thumb doesn't fill the entire scroll bar so we can still
15812 drag it back to see the entire text. */
15813 whole = max (whole, end);
15815 if (it.bidi_p)
15817 Lisp_Object pdir;
15819 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
15820 if (EQ (pdir, Qright_to_left))
15822 start = whole - end;
15823 end = start + portion;
15827 if (old_buffer)
15828 set_buffer_internal (old_buffer);
15830 else
15831 start = end = whole = portion = 0;
15833 w->hscroll_whole = whole;
15835 /* Indicate what this scroll bar ought to be displaying now. */
15836 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15837 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15838 (w, portion, whole, start);
15842 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15843 selected_window is redisplayed.
15845 We can return without actually redisplaying the window if fonts has been
15846 changed on window's frame. In that case, redisplay_internal will retry.
15848 As one of the important parts of redisplaying a window, we need to
15849 decide whether the previous window-start position (stored in the
15850 window's w->start marker position) is still valid, and if it isn't,
15851 recompute it. Some details about that:
15853 . The previous window-start could be in a continuation line, in
15854 which case we need to recompute it when the window width
15855 changes. See compute_window_start_on_continuation_line and its
15856 call below.
15858 . The text that changed since last redisplay could include the
15859 previous window-start position. In that case, we try to salvage
15860 what we can from the current glyph matrix by calling
15861 try_scrolling, which see.
15863 . Some Emacs command could force us to use a specific window-start
15864 position by setting the window's force_start flag, or gently
15865 propose doing that by setting the window's optional_new_start
15866 flag. In these cases, we try using the specified start point if
15867 that succeeds (i.e. the window desired matrix is successfully
15868 recomputed, and point location is within the window). In case
15869 of optional_new_start, we first check if the specified start
15870 position is feasible, i.e. if it will allow point to be
15871 displayed in the window. If using the specified start point
15872 fails, e.g., if new fonts are needed to be loaded, we abort the
15873 redisplay cycle and leave it up to the next cycle to figure out
15874 things.
15876 . Note that the window's force_start flag is sometimes set by
15877 redisplay itself, when it decides that the previous window start
15878 point is fine and should be kept. Search for "goto force_start"
15879 below to see the details. Like the values of window-start
15880 specified outside of redisplay, these internally-deduced values
15881 are tested for feasibility, and ignored if found to be
15882 unfeasible.
15884 . Note that the function try_window, used to completely redisplay
15885 a window, accepts the window's start point as its argument.
15886 This is used several times in the redisplay code to control
15887 where the window start will be, according to user options such
15888 as scroll-conservatively, and also to ensure the screen line
15889 showing point will be fully (as opposed to partially) visible on
15890 display. */
15892 static void
15893 redisplay_window (Lisp_Object window, bool just_this_one_p)
15895 struct window *w = XWINDOW (window);
15896 struct frame *f = XFRAME (w->frame);
15897 struct buffer *buffer = XBUFFER (w->contents);
15898 struct buffer *old = current_buffer;
15899 struct text_pos lpoint, opoint, startp;
15900 int update_mode_line;
15901 int tem;
15902 struct it it;
15903 /* Record it now because it's overwritten. */
15904 bool current_matrix_up_to_date_p = false;
15905 bool used_current_matrix_p = false;
15906 /* This is less strict than current_matrix_up_to_date_p.
15907 It indicates that the buffer contents and narrowing are unchanged. */
15908 bool buffer_unchanged_p = false;
15909 int temp_scroll_step = 0;
15910 ptrdiff_t count = SPECPDL_INDEX ();
15911 int rc;
15912 int centering_position = -1;
15913 int last_line_misfit = 0;
15914 ptrdiff_t beg_unchanged, end_unchanged;
15915 int frame_line_height;
15917 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15918 opoint = lpoint;
15920 #ifdef GLYPH_DEBUG
15921 *w->desired_matrix->method = 0;
15922 #endif
15924 if (!just_this_one_p
15925 && REDISPLAY_SOME_P ()
15926 && !w->redisplay
15927 && !f->redisplay
15928 && !buffer->text->redisplay
15929 && BUF_PT (buffer) == w->last_point)
15930 return;
15932 /* Make sure that both W's markers are valid. */
15933 eassert (XMARKER (w->start)->buffer == buffer);
15934 eassert (XMARKER (w->pointm)->buffer == buffer);
15936 /* We come here again if we need to run window-text-change-functions
15937 below. */
15938 restart:
15939 reconsider_clip_changes (w);
15940 frame_line_height = default_line_pixel_height (w);
15942 /* Has the mode line to be updated? */
15943 update_mode_line = (w->update_mode_line
15944 || update_mode_lines
15945 || buffer->clip_changed
15946 || buffer->prevent_redisplay_optimizations_p);
15948 if (!just_this_one_p)
15949 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
15950 cleverly elsewhere. */
15951 w->must_be_updated_p = true;
15953 if (MINI_WINDOW_P (w))
15955 if (w == XWINDOW (echo_area_window)
15956 && !NILP (echo_area_buffer[0]))
15958 if (update_mode_line)
15959 /* We may have to update a tty frame's menu bar or a
15960 tool-bar. Example `M-x C-h C-h C-g'. */
15961 goto finish_menu_bars;
15962 else
15963 /* We've already displayed the echo area glyphs in this window. */
15964 goto finish_scroll_bars;
15966 else if ((w != XWINDOW (minibuf_window)
15967 || minibuf_level == 0)
15968 /* When buffer is nonempty, redisplay window normally. */
15969 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15970 /* Quail displays non-mini buffers in minibuffer window.
15971 In that case, redisplay the window normally. */
15972 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15974 /* W is a mini-buffer window, but it's not active, so clear
15975 it. */
15976 int yb = window_text_bottom_y (w);
15977 struct glyph_row *row;
15978 int y;
15980 for (y = 0, row = w->desired_matrix->rows;
15981 y < yb;
15982 y += row->height, ++row)
15983 blank_row (w, row, y);
15984 goto finish_scroll_bars;
15987 clear_glyph_matrix (w->desired_matrix);
15990 /* Otherwise set up data on this window; select its buffer and point
15991 value. */
15992 /* Really select the buffer, for the sake of buffer-local
15993 variables. */
15994 set_buffer_internal_1 (XBUFFER (w->contents));
15996 current_matrix_up_to_date_p
15997 = (w->window_end_valid
15998 && !current_buffer->clip_changed
15999 && !current_buffer->prevent_redisplay_optimizations_p
16000 && !window_outdated (w));
16002 /* Run the window-text-change-functions
16003 if it is possible that the text on the screen has changed
16004 (either due to modification of the text, or any other reason). */
16005 if (!current_matrix_up_to_date_p
16006 && !NILP (Vwindow_text_change_functions))
16008 safe_run_hooks (Qwindow_text_change_functions);
16009 goto restart;
16012 beg_unchanged = BEG_UNCHANGED;
16013 end_unchanged = END_UNCHANGED;
16015 SET_TEXT_POS (opoint, PT, PT_BYTE);
16017 specbind (Qinhibit_point_motion_hooks, Qt);
16019 buffer_unchanged_p
16020 = (w->window_end_valid
16021 && !current_buffer->clip_changed
16022 && !window_outdated (w));
16024 /* When windows_or_buffers_changed is non-zero, we can't rely
16025 on the window end being valid, so set it to zero there. */
16026 if (windows_or_buffers_changed)
16028 /* If window starts on a continuation line, maybe adjust the
16029 window start in case the window's width changed. */
16030 if (XMARKER (w->start)->buffer == current_buffer)
16031 compute_window_start_on_continuation_line (w);
16033 w->window_end_valid = false;
16034 /* If so, we also can't rely on current matrix
16035 and should not fool try_cursor_movement below. */
16036 current_matrix_up_to_date_p = false;
16039 /* Some sanity checks. */
16040 CHECK_WINDOW_END (w);
16041 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16042 emacs_abort ();
16043 if (BYTEPOS (opoint) < CHARPOS (opoint))
16044 emacs_abort ();
16046 if (mode_line_update_needed (w))
16047 update_mode_line = 1;
16049 /* Point refers normally to the selected window. For any other
16050 window, set up appropriate value. */
16051 if (!EQ (window, selected_window))
16053 ptrdiff_t new_pt = marker_position (w->pointm);
16054 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16056 if (new_pt < BEGV)
16058 new_pt = BEGV;
16059 new_pt_byte = BEGV_BYTE;
16060 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16062 else if (new_pt > (ZV - 1))
16064 new_pt = ZV;
16065 new_pt_byte = ZV_BYTE;
16066 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16069 /* We don't use SET_PT so that the point-motion hooks don't run. */
16070 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16073 /* If any of the character widths specified in the display table
16074 have changed, invalidate the width run cache. It's true that
16075 this may be a bit late to catch such changes, but the rest of
16076 redisplay goes (non-fatally) haywire when the display table is
16077 changed, so why should we worry about doing any better? */
16078 if (current_buffer->width_run_cache
16079 || (current_buffer->base_buffer
16080 && current_buffer->base_buffer->width_run_cache))
16082 struct Lisp_Char_Table *disptab = buffer_display_table ();
16084 if (! disptab_matches_widthtab
16085 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16087 struct buffer *buf = current_buffer;
16089 if (buf->base_buffer)
16090 buf = buf->base_buffer;
16091 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16092 recompute_width_table (current_buffer, disptab);
16096 /* If window-start is screwed up, choose a new one. */
16097 if (XMARKER (w->start)->buffer != current_buffer)
16098 goto recenter;
16100 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16102 /* If someone specified a new starting point but did not insist,
16103 check whether it can be used. */
16104 if (w->optional_new_start
16105 && CHARPOS (startp) >= BEGV
16106 && CHARPOS (startp) <= ZV)
16108 w->optional_new_start = 0;
16109 start_display (&it, w, startp);
16110 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16111 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16112 if (IT_CHARPOS (it) == PT)
16113 w->force_start = 1;
16114 /* IT may overshoot PT if text at PT is invisible. */
16115 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
16116 w->force_start = 1;
16119 force_start:
16121 /* Handle case where place to start displaying has been specified,
16122 unless the specified location is outside the accessible range. */
16123 if (w->force_start || window_frozen_p (w))
16125 /* We set this later on if we have to adjust point. */
16126 int new_vpos = -1;
16128 w->force_start = 0;
16129 w->vscroll = 0;
16130 w->window_end_valid = 0;
16132 /* Forget any recorded base line for line number display. */
16133 if (!buffer_unchanged_p)
16134 w->base_line_number = 0;
16136 /* Redisplay the mode line. Select the buffer properly for that.
16137 Also, run the hook window-scroll-functions
16138 because we have scrolled. */
16139 /* Note, we do this after clearing force_start because
16140 if there's an error, it is better to forget about force_start
16141 than to get into an infinite loop calling the hook functions
16142 and having them get more errors. */
16143 if (!update_mode_line
16144 || ! NILP (Vwindow_scroll_functions))
16146 update_mode_line = 1;
16147 w->update_mode_line = 1;
16148 startp = run_window_scroll_functions (window, startp);
16151 if (CHARPOS (startp) < BEGV)
16152 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16153 else if (CHARPOS (startp) > ZV)
16154 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16156 /* Redisplay, then check if cursor has been set during the
16157 redisplay. Give up if new fonts were loaded. */
16158 /* We used to issue a CHECK_MARGINS argument to try_window here,
16159 but this causes scrolling to fail when point begins inside
16160 the scroll margin (bug#148) -- cyd */
16161 if (!try_window (window, startp, 0))
16163 w->force_start = 1;
16164 clear_glyph_matrix (w->desired_matrix);
16165 goto need_larger_matrices;
16168 if (w->cursor.vpos < 0 && !window_frozen_p (w))
16170 /* If point does not appear, try to move point so it does
16171 appear. The desired matrix has been built above, so we
16172 can use it here. */
16173 new_vpos = window_box_height (w) / 2;
16176 if (!cursor_row_fully_visible_p (w, 0, 0))
16178 /* Point does appear, but on a line partly visible at end of window.
16179 Move it back to a fully-visible line. */
16180 new_vpos = window_box_height (w);
16181 /* But if window_box_height suggests a Y coordinate that is
16182 not less than we already have, that line will clearly not
16183 be fully visible, so give up and scroll the display.
16184 This can happen when the default face uses a font whose
16185 dimensions are different from the frame's default
16186 font. */
16187 if (new_vpos >= w->cursor.y)
16189 w->cursor.vpos = -1;
16190 clear_glyph_matrix (w->desired_matrix);
16191 goto try_to_scroll;
16194 else if (w->cursor.vpos >= 0)
16196 /* Some people insist on not letting point enter the scroll
16197 margin, even though this part handles windows that didn't
16198 scroll at all. */
16199 int window_total_lines
16200 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16201 int margin = min (scroll_margin, window_total_lines / 4);
16202 int pixel_margin = margin * frame_line_height;
16203 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
16205 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16206 below, which finds the row to move point to, advances by
16207 the Y coordinate of the _next_ row, see the definition of
16208 MATRIX_ROW_BOTTOM_Y. */
16209 if (w->cursor.vpos < margin + header_line)
16211 w->cursor.vpos = -1;
16212 clear_glyph_matrix (w->desired_matrix);
16213 goto try_to_scroll;
16215 else
16217 int window_height = window_box_height (w);
16219 if (header_line)
16220 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16221 if (w->cursor.y >= window_height - pixel_margin)
16223 w->cursor.vpos = -1;
16224 clear_glyph_matrix (w->desired_matrix);
16225 goto try_to_scroll;
16230 /* If we need to move point for either of the above reasons,
16231 now actually do it. */
16232 if (new_vpos >= 0)
16234 struct glyph_row *row;
16236 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16237 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16238 ++row;
16240 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16241 MATRIX_ROW_START_BYTEPOS (row));
16243 if (w != XWINDOW (selected_window))
16244 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16245 else if (current_buffer == old)
16246 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16248 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16250 /* If we are highlighting the region, then we just changed
16251 the region, so redisplay to show it. */
16252 /* FIXME: We need to (re)run pre-redisplay-function! */
16253 /* if (markpos_of_region () >= 0)
16255 clear_glyph_matrix (w->desired_matrix);
16256 if (!try_window (window, startp, 0))
16257 goto need_larger_matrices;
16262 #ifdef GLYPH_DEBUG
16263 debug_method_add (w, "forced window start");
16264 #endif
16265 goto done;
16268 /* Handle case where text has not changed, only point, and it has
16269 not moved off the frame, and we are not retrying after hscroll.
16270 (current_matrix_up_to_date_p is nonzero when retrying.) */
16271 if (current_matrix_up_to_date_p
16272 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16273 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16275 switch (rc)
16277 case CURSOR_MOVEMENT_SUCCESS:
16278 used_current_matrix_p = 1;
16279 goto done;
16281 case CURSOR_MOVEMENT_MUST_SCROLL:
16282 goto try_to_scroll;
16284 default:
16285 emacs_abort ();
16288 /* If current starting point was originally the beginning of a line
16289 but no longer is, find a new starting point. */
16290 else if (w->start_at_line_beg
16291 && !(CHARPOS (startp) <= BEGV
16292 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16294 #ifdef GLYPH_DEBUG
16295 debug_method_add (w, "recenter 1");
16296 #endif
16297 goto recenter;
16300 /* Try scrolling with try_window_id. Value is > 0 if update has
16301 been done, it is -1 if we know that the same window start will
16302 not work. It is 0 if unsuccessful for some other reason. */
16303 else if ((tem = try_window_id (w)) != 0)
16305 #ifdef GLYPH_DEBUG
16306 debug_method_add (w, "try_window_id %d", tem);
16307 #endif
16309 if (f->fonts_changed)
16310 goto need_larger_matrices;
16311 if (tem > 0)
16312 goto done;
16314 /* Otherwise try_window_id has returned -1 which means that we
16315 don't want the alternative below this comment to execute. */
16317 else if (CHARPOS (startp) >= BEGV
16318 && CHARPOS (startp) <= ZV
16319 && PT >= CHARPOS (startp)
16320 && (CHARPOS (startp) < ZV
16321 /* Avoid starting at end of buffer. */
16322 || CHARPOS (startp) == BEGV
16323 || !window_outdated (w)))
16325 int d1, d2, d3, d4, d5, d6;
16327 /* If first window line is a continuation line, and window start
16328 is inside the modified region, but the first change is before
16329 current window start, we must select a new window start.
16331 However, if this is the result of a down-mouse event (e.g. by
16332 extending the mouse-drag-overlay), we don't want to select a
16333 new window start, since that would change the position under
16334 the mouse, resulting in an unwanted mouse-movement rather
16335 than a simple mouse-click. */
16336 if (!w->start_at_line_beg
16337 && NILP (do_mouse_tracking)
16338 && CHARPOS (startp) > BEGV
16339 && CHARPOS (startp) > BEG + beg_unchanged
16340 && CHARPOS (startp) <= Z - end_unchanged
16341 /* Even if w->start_at_line_beg is nil, a new window may
16342 start at a line_beg, since that's how set_buffer_window
16343 sets it. So, we need to check the return value of
16344 compute_window_start_on_continuation_line. (See also
16345 bug#197). */
16346 && XMARKER (w->start)->buffer == current_buffer
16347 && compute_window_start_on_continuation_line (w)
16348 /* It doesn't make sense to force the window start like we
16349 do at label force_start if it is already known that point
16350 will not be visible in the resulting window, because
16351 doing so will move point from its correct position
16352 instead of scrolling the window to bring point into view.
16353 See bug#9324. */
16354 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
16356 w->force_start = 1;
16357 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16358 goto force_start;
16361 #ifdef GLYPH_DEBUG
16362 debug_method_add (w, "same window start");
16363 #endif
16365 /* Try to redisplay starting at same place as before.
16366 If point has not moved off frame, accept the results. */
16367 if (!current_matrix_up_to_date_p
16368 /* Don't use try_window_reusing_current_matrix in this case
16369 because a window scroll function can have changed the
16370 buffer. */
16371 || !NILP (Vwindow_scroll_functions)
16372 || MINI_WINDOW_P (w)
16373 || !(used_current_matrix_p
16374 = try_window_reusing_current_matrix (w)))
16376 IF_DEBUG (debug_method_add (w, "1"));
16377 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
16378 /* -1 means we need to scroll.
16379 0 means we need new matrices, but fonts_changed
16380 is set in that case, so we will detect it below. */
16381 goto try_to_scroll;
16384 if (f->fonts_changed)
16385 goto need_larger_matrices;
16387 if (w->cursor.vpos >= 0)
16389 if (!just_this_one_p
16390 || current_buffer->clip_changed
16391 || BEG_UNCHANGED < CHARPOS (startp))
16392 /* Forget any recorded base line for line number display. */
16393 w->base_line_number = 0;
16395 if (!cursor_row_fully_visible_p (w, 1, 0))
16397 clear_glyph_matrix (w->desired_matrix);
16398 last_line_misfit = 1;
16400 /* Drop through and scroll. */
16401 else
16402 goto done;
16404 else
16405 clear_glyph_matrix (w->desired_matrix);
16408 try_to_scroll:
16410 /* Redisplay the mode line. Select the buffer properly for that. */
16411 if (!update_mode_line)
16413 update_mode_line = 1;
16414 w->update_mode_line = 1;
16417 /* Try to scroll by specified few lines. */
16418 if ((scroll_conservatively
16419 || emacs_scroll_step
16420 || temp_scroll_step
16421 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
16422 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
16423 && CHARPOS (startp) >= BEGV
16424 && CHARPOS (startp) <= ZV)
16426 /* The function returns -1 if new fonts were loaded, 1 if
16427 successful, 0 if not successful. */
16428 int ss = try_scrolling (window, just_this_one_p,
16429 scroll_conservatively,
16430 emacs_scroll_step,
16431 temp_scroll_step, last_line_misfit);
16432 switch (ss)
16434 case SCROLLING_SUCCESS:
16435 goto done;
16437 case SCROLLING_NEED_LARGER_MATRICES:
16438 goto need_larger_matrices;
16440 case SCROLLING_FAILED:
16441 break;
16443 default:
16444 emacs_abort ();
16448 /* Finally, just choose a place to start which positions point
16449 according to user preferences. */
16451 recenter:
16453 #ifdef GLYPH_DEBUG
16454 debug_method_add (w, "recenter");
16455 #endif
16457 /* Forget any previously recorded base line for line number display. */
16458 if (!buffer_unchanged_p)
16459 w->base_line_number = 0;
16461 /* Determine the window start relative to point. */
16462 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16463 it.current_y = it.last_visible_y;
16464 if (centering_position < 0)
16466 int window_total_lines
16467 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16468 int margin =
16469 scroll_margin > 0
16470 ? min (scroll_margin, window_total_lines / 4)
16471 : 0;
16472 ptrdiff_t margin_pos = CHARPOS (startp);
16473 Lisp_Object aggressive;
16474 int scrolling_up;
16476 /* If there is a scroll margin at the top of the window, find
16477 its character position. */
16478 if (margin
16479 /* Cannot call start_display if startp is not in the
16480 accessible region of the buffer. This can happen when we
16481 have just switched to a different buffer and/or changed
16482 its restriction. In that case, startp is initialized to
16483 the character position 1 (BEGV) because we did not yet
16484 have chance to display the buffer even once. */
16485 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
16487 struct it it1;
16488 void *it1data = NULL;
16490 SAVE_IT (it1, it, it1data);
16491 start_display (&it1, w, startp);
16492 move_it_vertically (&it1, margin * frame_line_height);
16493 margin_pos = IT_CHARPOS (it1);
16494 RESTORE_IT (&it, &it, it1data);
16496 scrolling_up = PT > margin_pos;
16497 aggressive =
16498 scrolling_up
16499 ? BVAR (current_buffer, scroll_up_aggressively)
16500 : BVAR (current_buffer, scroll_down_aggressively);
16502 if (!MINI_WINDOW_P (w)
16503 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16505 int pt_offset = 0;
16507 /* Setting scroll-conservatively overrides
16508 scroll-*-aggressively. */
16509 if (!scroll_conservatively && NUMBERP (aggressive))
16511 double float_amount = XFLOATINT (aggressive);
16513 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16514 if (pt_offset == 0 && float_amount > 0)
16515 pt_offset = 1;
16516 if (pt_offset && margin > 0)
16517 margin -= 1;
16519 /* Compute how much to move the window start backward from
16520 point so that point will be displayed where the user
16521 wants it. */
16522 if (scrolling_up)
16524 centering_position = it.last_visible_y;
16525 if (pt_offset)
16526 centering_position -= pt_offset;
16527 centering_position -=
16528 frame_line_height * (1 + margin + (last_line_misfit != 0))
16529 + WINDOW_HEADER_LINE_HEIGHT (w);
16530 /* Don't let point enter the scroll margin near top of
16531 the window. */
16532 if (centering_position < margin * frame_line_height)
16533 centering_position = margin * frame_line_height;
16535 else
16536 centering_position = margin * frame_line_height + pt_offset;
16538 else
16539 /* Set the window start half the height of the window backward
16540 from point. */
16541 centering_position = window_box_height (w) / 2;
16543 move_it_vertically_backward (&it, centering_position);
16545 eassert (IT_CHARPOS (it) >= BEGV);
16547 /* The function move_it_vertically_backward may move over more
16548 than the specified y-distance. If it->w is small, e.g. a
16549 mini-buffer window, we may end up in front of the window's
16550 display area. Start displaying at the start of the line
16551 containing PT in this case. */
16552 if (it.current_y <= 0)
16554 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16555 move_it_vertically_backward (&it, 0);
16556 it.current_y = 0;
16559 it.current_x = it.hpos = 0;
16561 /* Set the window start position here explicitly, to avoid an
16562 infinite loop in case the functions in window-scroll-functions
16563 get errors. */
16564 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16566 /* Run scroll hooks. */
16567 startp = run_window_scroll_functions (window, it.current.pos);
16569 /* Redisplay the window. */
16570 if (!current_matrix_up_to_date_p
16571 || windows_or_buffers_changed
16572 || f->cursor_type_changed
16573 /* Don't use try_window_reusing_current_matrix in this case
16574 because it can have changed the buffer. */
16575 || !NILP (Vwindow_scroll_functions)
16576 || !just_this_one_p
16577 || MINI_WINDOW_P (w)
16578 || !(used_current_matrix_p
16579 = try_window_reusing_current_matrix (w)))
16580 try_window (window, startp, 0);
16582 /* If new fonts have been loaded (due to fontsets), give up. We
16583 have to start a new redisplay since we need to re-adjust glyph
16584 matrices. */
16585 if (f->fonts_changed)
16586 goto need_larger_matrices;
16588 /* If cursor did not appear assume that the middle of the window is
16589 in the first line of the window. Do it again with the next line.
16590 (Imagine a window of height 100, displaying two lines of height
16591 60. Moving back 50 from it->last_visible_y will end in the first
16592 line.) */
16593 if (w->cursor.vpos < 0)
16595 if (w->window_end_valid && PT >= Z - w->window_end_pos)
16597 clear_glyph_matrix (w->desired_matrix);
16598 move_it_by_lines (&it, 1);
16599 try_window (window, it.current.pos, 0);
16601 else if (PT < IT_CHARPOS (it))
16603 clear_glyph_matrix (w->desired_matrix);
16604 move_it_by_lines (&it, -1);
16605 try_window (window, it.current.pos, 0);
16607 else
16609 /* Not much we can do about it. */
16613 /* Consider the following case: Window starts at BEGV, there is
16614 invisible, intangible text at BEGV, so that display starts at
16615 some point START > BEGV. It can happen that we are called with
16616 PT somewhere between BEGV and START. Try to handle that case,
16617 and similar ones. */
16618 if (w->cursor.vpos < 0)
16620 /* First, try locating the proper glyph row for PT. */
16621 struct glyph_row *row =
16622 row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0);
16624 /* Sometimes point is at the beginning of invisible text that is
16625 before the 1st character displayed in the row. In that case,
16626 row_containing_pos fails to find the row, because no glyphs
16627 with appropriate buffer positions are present in the row.
16628 Therefore, we next try to find the row which shows the 1st
16629 position after the invisible text. */
16630 if (!row)
16632 Lisp_Object val =
16633 get_char_property_and_overlay (make_number (PT), Qinvisible,
16634 Qnil, NULL);
16636 if (TEXT_PROP_MEANS_INVISIBLE (val))
16638 ptrdiff_t alt_pos;
16639 Lisp_Object invis_end =
16640 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16641 Qnil, Qnil);
16643 if (NATNUMP (invis_end))
16644 alt_pos = XFASTINT (invis_end);
16645 else
16646 alt_pos = ZV;
16647 row = row_containing_pos (w, alt_pos, w->current_matrix->rows,
16648 NULL, 0);
16651 /* Finally, fall back on the first row of the window after the
16652 header line (if any). This is slightly better than not
16653 displaying the cursor at all. */
16654 if (!row)
16656 row = w->current_matrix->rows;
16657 if (row->mode_line_p)
16658 ++row;
16660 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16663 if (!cursor_row_fully_visible_p (w, 0, 0))
16665 /* If vscroll is enabled, disable it and try again. */
16666 if (w->vscroll)
16668 w->vscroll = 0;
16669 clear_glyph_matrix (w->desired_matrix);
16670 goto recenter;
16673 /* Users who set scroll-conservatively to a large number want
16674 point just above/below the scroll margin. If we ended up
16675 with point's row partially visible, move the window start to
16676 make that row fully visible and out of the margin. */
16677 if (scroll_conservatively > SCROLL_LIMIT)
16679 int window_total_lines
16680 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
16681 int margin =
16682 scroll_margin > 0
16683 ? min (scroll_margin, window_total_lines / 4)
16684 : 0;
16685 int move_down = w->cursor.vpos >= window_total_lines / 2;
16687 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16688 clear_glyph_matrix (w->desired_matrix);
16689 if (1 == try_window (window, it.current.pos,
16690 TRY_WINDOW_CHECK_MARGINS))
16691 goto done;
16694 /* If centering point failed to make the whole line visible,
16695 put point at the top instead. That has to make the whole line
16696 visible, if it can be done. */
16697 if (centering_position == 0)
16698 goto done;
16700 clear_glyph_matrix (w->desired_matrix);
16701 centering_position = 0;
16702 goto recenter;
16705 done:
16707 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16708 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16709 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16711 /* Display the mode line, if we must. */
16712 if ((update_mode_line
16713 /* If window not full width, must redo its mode line
16714 if (a) the window to its side is being redone and
16715 (b) we do a frame-based redisplay. This is a consequence
16716 of how inverted lines are drawn in frame-based redisplay. */
16717 || (!just_this_one_p
16718 && !FRAME_WINDOW_P (f)
16719 && !WINDOW_FULL_WIDTH_P (w))
16720 /* Line number to display. */
16721 || w->base_line_pos > 0
16722 /* Column number is displayed and different from the one displayed. */
16723 || (w->column_number_displayed != -1
16724 && (w->column_number_displayed != current_column ())))
16725 /* This means that the window has a mode line. */
16726 && (WINDOW_WANTS_MODELINE_P (w)
16727 || WINDOW_WANTS_HEADER_LINE_P (w)))
16730 display_mode_lines (w);
16732 /* If mode line height has changed, arrange for a thorough
16733 immediate redisplay using the correct mode line height. */
16734 if (WINDOW_WANTS_MODELINE_P (w)
16735 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16737 f->fonts_changed = 1;
16738 w->mode_line_height = -1;
16739 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16740 = DESIRED_MODE_LINE_HEIGHT (w);
16743 /* If header line height has changed, arrange for a thorough
16744 immediate redisplay using the correct header line height. */
16745 if (WINDOW_WANTS_HEADER_LINE_P (w)
16746 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16748 f->fonts_changed = 1;
16749 w->header_line_height = -1;
16750 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16751 = DESIRED_HEADER_LINE_HEIGHT (w);
16754 if (f->fonts_changed)
16755 goto need_larger_matrices;
16758 if (!line_number_displayed && w->base_line_pos != -1)
16760 w->base_line_pos = 0;
16761 w->base_line_number = 0;
16764 finish_menu_bars:
16766 /* When we reach a frame's selected window, redo the frame's menu bar. */
16767 if (update_mode_line
16768 && EQ (FRAME_SELECTED_WINDOW (f), window))
16770 int redisplay_menu_p = 0;
16772 if (FRAME_WINDOW_P (f))
16774 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16775 || defined (HAVE_NS) || defined (USE_GTK)
16776 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16777 #else
16778 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16779 #endif
16781 else
16782 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16784 if (redisplay_menu_p)
16785 display_menu_bar (w);
16787 #ifdef HAVE_WINDOW_SYSTEM
16788 if (FRAME_WINDOW_P (f))
16790 #if defined (USE_GTK) || defined (HAVE_NS)
16791 if (FRAME_EXTERNAL_TOOL_BAR (f))
16792 redisplay_tool_bar (f);
16793 #else
16794 if (WINDOWP (f->tool_bar_window)
16795 && (FRAME_TOOL_BAR_LINES (f) > 0
16796 || !NILP (Vauto_resize_tool_bars))
16797 && redisplay_tool_bar (f))
16798 ignore_mouse_drag_p = 1;
16799 #endif
16801 #endif
16804 #ifdef HAVE_WINDOW_SYSTEM
16805 if (FRAME_WINDOW_P (f)
16806 && update_window_fringes (w, (just_this_one_p
16807 || (!used_current_matrix_p && !overlay_arrow_seen)
16808 || w->pseudo_window_p)))
16810 update_begin (f);
16811 block_input ();
16812 if (draw_window_fringes (w, 1))
16814 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
16815 x_draw_right_divider (w);
16816 else
16817 x_draw_vertical_border (w);
16819 unblock_input ();
16820 update_end (f);
16823 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
16824 x_draw_bottom_divider (w);
16825 #endif /* HAVE_WINDOW_SYSTEM */
16827 /* We go to this label, with fonts_changed set, if it is
16828 necessary to try again using larger glyph matrices.
16829 We have to redeem the scroll bar even in this case,
16830 because the loop in redisplay_internal expects that. */
16831 need_larger_matrices:
16833 finish_scroll_bars:
16835 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16837 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16838 /* Set the thumb's position and size. */
16839 set_vertical_scroll_bar (w);
16841 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16842 /* Set the thumb's position and size. */
16843 set_horizontal_scroll_bar (w);
16845 /* Note that we actually used the scroll bar attached to this
16846 window, so it shouldn't be deleted at the end of redisplay. */
16847 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16848 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16851 /* Restore current_buffer and value of point in it. The window
16852 update may have changed the buffer, so first make sure `opoint'
16853 is still valid (Bug#6177). */
16854 if (CHARPOS (opoint) < BEGV)
16855 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16856 else if (CHARPOS (opoint) > ZV)
16857 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16858 else
16859 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16861 set_buffer_internal_1 (old);
16862 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16863 shorter. This can be caused by log truncation in *Messages*. */
16864 if (CHARPOS (lpoint) <= ZV)
16865 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16867 unbind_to (count, Qnil);
16871 /* Build the complete desired matrix of WINDOW with a window start
16872 buffer position POS.
16874 Value is 1 if successful. It is zero if fonts were loaded during
16875 redisplay which makes re-adjusting glyph matrices necessary, and -1
16876 if point would appear in the scroll margins.
16877 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16878 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16879 set in FLAGS.) */
16882 try_window (Lisp_Object window, struct text_pos pos, int flags)
16884 struct window *w = XWINDOW (window);
16885 struct it it;
16886 struct glyph_row *last_text_row = NULL;
16887 struct frame *f = XFRAME (w->frame);
16888 int frame_line_height = default_line_pixel_height (w);
16890 /* Make POS the new window start. */
16891 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16893 /* Mark cursor position as unknown. No overlay arrow seen. */
16894 w->cursor.vpos = -1;
16895 overlay_arrow_seen = 0;
16897 /* Initialize iterator and info to start at POS. */
16898 start_display (&it, w, pos);
16899 it.glyph_row->reversed_p = false;
16901 /* Display all lines of W. */
16902 while (it.current_y < it.last_visible_y)
16904 if (display_line (&it))
16905 last_text_row = it.glyph_row - 1;
16906 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16907 return 0;
16910 /* Don't let the cursor end in the scroll margins. */
16911 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16912 && !MINI_WINDOW_P (w))
16914 int this_scroll_margin;
16915 int window_total_lines
16916 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
16918 if (scroll_margin > 0)
16920 this_scroll_margin = min (scroll_margin, window_total_lines / 4);
16921 this_scroll_margin *= frame_line_height;
16923 else
16924 this_scroll_margin = 0;
16926 if ((w->cursor.y >= 0 /* not vscrolled */
16927 && w->cursor.y < this_scroll_margin
16928 && CHARPOS (pos) > BEGV
16929 && IT_CHARPOS (it) < ZV)
16930 /* rms: considering make_cursor_line_fully_visible_p here
16931 seems to give wrong results. We don't want to recenter
16932 when the last line is partly visible, we want to allow
16933 that case to be handled in the usual way. */
16934 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16936 w->cursor.vpos = -1;
16937 clear_glyph_matrix (w->desired_matrix);
16938 return -1;
16942 /* If bottom moved off end of frame, change mode line percentage. */
16943 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16944 w->update_mode_line = 1;
16946 /* Set window_end_pos to the offset of the last character displayed
16947 on the window from the end of current_buffer. Set
16948 window_end_vpos to its row number. */
16949 if (last_text_row)
16951 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16952 adjust_window_ends (w, last_text_row, 0);
16953 eassert
16954 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16955 w->window_end_vpos)));
16957 else
16959 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16960 w->window_end_pos = Z - ZV;
16961 w->window_end_vpos = 0;
16964 /* But that is not valid info until redisplay finishes. */
16965 w->window_end_valid = 0;
16966 return 1;
16971 /************************************************************************
16972 Window redisplay reusing current matrix when buffer has not changed
16973 ************************************************************************/
16975 /* Try redisplay of window W showing an unchanged buffer with a
16976 different window start than the last time it was displayed by
16977 reusing its current matrix. Value is non-zero if successful.
16978 W->start is the new window start. */
16980 static int
16981 try_window_reusing_current_matrix (struct window *w)
16983 struct frame *f = XFRAME (w->frame);
16984 struct glyph_row *bottom_row;
16985 struct it it;
16986 struct run run;
16987 struct text_pos start, new_start;
16988 int nrows_scrolled, i;
16989 struct glyph_row *last_text_row;
16990 struct glyph_row *last_reused_text_row;
16991 struct glyph_row *start_row;
16992 int start_vpos, min_y, max_y;
16994 #ifdef GLYPH_DEBUG
16995 if (inhibit_try_window_reusing)
16996 return 0;
16997 #endif
16999 if (/* This function doesn't handle terminal frames. */
17000 !FRAME_WINDOW_P (f)
17001 /* Don't try to reuse the display if windows have been split
17002 or such. */
17003 || windows_or_buffers_changed
17004 || f->cursor_type_changed)
17005 return 0;
17007 /* Can't do this if showing trailing whitespace. */
17008 if (!NILP (Vshow_trailing_whitespace))
17009 return 0;
17011 /* If top-line visibility has changed, give up. */
17012 if (WINDOW_WANTS_HEADER_LINE_P (w)
17013 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17014 return 0;
17016 /* Give up if old or new display is scrolled vertically. We could
17017 make this function handle this, but right now it doesn't. */
17018 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17019 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17020 return 0;
17022 /* The variable new_start now holds the new window start. The old
17023 start `start' can be determined from the current matrix. */
17024 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17025 start = start_row->minpos;
17026 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17028 /* Clear the desired matrix for the display below. */
17029 clear_glyph_matrix (w->desired_matrix);
17031 if (CHARPOS (new_start) <= CHARPOS (start))
17033 /* Don't use this method if the display starts with an ellipsis
17034 displayed for invisible text. It's not easy to handle that case
17035 below, and it's certainly not worth the effort since this is
17036 not a frequent case. */
17037 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17038 return 0;
17040 IF_DEBUG (debug_method_add (w, "twu1"));
17042 /* Display up to a row that can be reused. The variable
17043 last_text_row is set to the last row displayed that displays
17044 text. Note that it.vpos == 0 if or if not there is a
17045 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17046 start_display (&it, w, new_start);
17047 w->cursor.vpos = -1;
17048 last_text_row = last_reused_text_row = NULL;
17050 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17052 /* If we have reached into the characters in the START row,
17053 that means the line boundaries have changed. So we
17054 can't start copying with the row START. Maybe it will
17055 work to start copying with the following row. */
17056 while (IT_CHARPOS (it) > CHARPOS (start))
17058 /* Advance to the next row as the "start". */
17059 start_row++;
17060 start = start_row->minpos;
17061 /* If there are no more rows to try, or just one, give up. */
17062 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17063 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17064 || CHARPOS (start) == ZV)
17066 clear_glyph_matrix (w->desired_matrix);
17067 return 0;
17070 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17072 /* If we have reached alignment, we can copy the rest of the
17073 rows. */
17074 if (IT_CHARPOS (it) == CHARPOS (start)
17075 /* Don't accept "alignment" inside a display vector,
17076 since start_row could have started in the middle of
17077 that same display vector (thus their character
17078 positions match), and we have no way of telling if
17079 that is the case. */
17080 && it.current.dpvec_index < 0)
17081 break;
17083 it.glyph_row->reversed_p = false;
17084 if (display_line (&it))
17085 last_text_row = it.glyph_row - 1;
17089 /* A value of current_y < last_visible_y means that we stopped
17090 at the previous window start, which in turn means that we
17091 have at least one reusable row. */
17092 if (it.current_y < it.last_visible_y)
17094 struct glyph_row *row;
17096 /* IT.vpos always starts from 0; it counts text lines. */
17097 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17099 /* Find PT if not already found in the lines displayed. */
17100 if (w->cursor.vpos < 0)
17102 int dy = it.current_y - start_row->y;
17104 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17105 row = row_containing_pos (w, PT, row, NULL, dy);
17106 if (row)
17107 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17108 dy, nrows_scrolled);
17109 else
17111 clear_glyph_matrix (w->desired_matrix);
17112 return 0;
17116 /* Scroll the display. Do it before the current matrix is
17117 changed. The problem here is that update has not yet
17118 run, i.e. part of the current matrix is not up to date.
17119 scroll_run_hook will clear the cursor, and use the
17120 current matrix to get the height of the row the cursor is
17121 in. */
17122 run.current_y = start_row->y;
17123 run.desired_y = it.current_y;
17124 run.height = it.last_visible_y - it.current_y;
17126 if (run.height > 0 && run.current_y != run.desired_y)
17128 update_begin (f);
17129 FRAME_RIF (f)->update_window_begin_hook (w);
17130 FRAME_RIF (f)->clear_window_mouse_face (w);
17131 FRAME_RIF (f)->scroll_run_hook (w, &run);
17132 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17133 update_end (f);
17136 /* Shift current matrix down by nrows_scrolled lines. */
17137 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17138 rotate_matrix (w->current_matrix,
17139 start_vpos,
17140 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17141 nrows_scrolled);
17143 /* Disable lines that must be updated. */
17144 for (i = 0; i < nrows_scrolled; ++i)
17145 (start_row + i)->enabled_p = false;
17147 /* Re-compute Y positions. */
17148 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17149 max_y = it.last_visible_y;
17150 for (row = start_row + nrows_scrolled;
17151 row < bottom_row;
17152 ++row)
17154 row->y = it.current_y;
17155 row->visible_height = row->height;
17157 if (row->y < min_y)
17158 row->visible_height -= min_y - row->y;
17159 if (row->y + row->height > max_y)
17160 row->visible_height -= row->y + row->height - max_y;
17161 if (row->fringe_bitmap_periodic_p)
17162 row->redraw_fringe_bitmaps_p = 1;
17164 it.current_y += row->height;
17166 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17167 last_reused_text_row = row;
17168 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17169 break;
17172 /* Disable lines in the current matrix which are now
17173 below the window. */
17174 for (++row; row < bottom_row; ++row)
17175 row->enabled_p = row->mode_line_p = 0;
17178 /* Update window_end_pos etc.; last_reused_text_row is the last
17179 reused row from the current matrix containing text, if any.
17180 The value of last_text_row is the last displayed line
17181 containing text. */
17182 if (last_reused_text_row)
17183 adjust_window_ends (w, last_reused_text_row, 1);
17184 else if (last_text_row)
17185 adjust_window_ends (w, last_text_row, 0);
17186 else
17188 /* This window must be completely empty. */
17189 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17190 w->window_end_pos = Z - ZV;
17191 w->window_end_vpos = 0;
17193 w->window_end_valid = 0;
17195 /* Update hint: don't try scrolling again in update_window. */
17196 w->desired_matrix->no_scrolling_p = 1;
17198 #ifdef GLYPH_DEBUG
17199 debug_method_add (w, "try_window_reusing_current_matrix 1");
17200 #endif
17201 return 1;
17203 else if (CHARPOS (new_start) > CHARPOS (start))
17205 struct glyph_row *pt_row, *row;
17206 struct glyph_row *first_reusable_row;
17207 struct glyph_row *first_row_to_display;
17208 int dy;
17209 int yb = window_text_bottom_y (w);
17211 /* Find the row starting at new_start, if there is one. Don't
17212 reuse a partially visible line at the end. */
17213 first_reusable_row = start_row;
17214 while (first_reusable_row->enabled_p
17215 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17216 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17217 < CHARPOS (new_start)))
17218 ++first_reusable_row;
17220 /* Give up if there is no row to reuse. */
17221 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17222 || !first_reusable_row->enabled_p
17223 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17224 != CHARPOS (new_start)))
17225 return 0;
17227 /* We can reuse fully visible rows beginning with
17228 first_reusable_row to the end of the window. Set
17229 first_row_to_display to the first row that cannot be reused.
17230 Set pt_row to the row containing point, if there is any. */
17231 pt_row = NULL;
17232 for (first_row_to_display = first_reusable_row;
17233 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17234 ++first_row_to_display)
17236 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17237 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17238 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17239 && first_row_to_display->ends_at_zv_p
17240 && pt_row == NULL)))
17241 pt_row = first_row_to_display;
17244 /* Start displaying at the start of first_row_to_display. */
17245 eassert (first_row_to_display->y < yb);
17246 init_to_row_start (&it, w, first_row_to_display);
17248 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17249 - start_vpos);
17250 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17251 - nrows_scrolled);
17252 it.current_y = (first_row_to_display->y - first_reusable_row->y
17253 + WINDOW_HEADER_LINE_HEIGHT (w));
17255 /* Display lines beginning with first_row_to_display in the
17256 desired matrix. Set last_text_row to the last row displayed
17257 that displays text. */
17258 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
17259 if (pt_row == NULL)
17260 w->cursor.vpos = -1;
17261 last_text_row = NULL;
17262 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17263 if (display_line (&it))
17264 last_text_row = it.glyph_row - 1;
17266 /* If point is in a reused row, adjust y and vpos of the cursor
17267 position. */
17268 if (pt_row)
17270 w->cursor.vpos -= nrows_scrolled;
17271 w->cursor.y -= first_reusable_row->y - start_row->y;
17274 /* Give up if point isn't in a row displayed or reused. (This
17275 also handles the case where w->cursor.vpos < nrows_scrolled
17276 after the calls to display_line, which can happen with scroll
17277 margins. See bug#1295.) */
17278 if (w->cursor.vpos < 0)
17280 clear_glyph_matrix (w->desired_matrix);
17281 return 0;
17284 /* Scroll the display. */
17285 run.current_y = first_reusable_row->y;
17286 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
17287 run.height = it.last_visible_y - run.current_y;
17288 dy = run.current_y - run.desired_y;
17290 if (run.height)
17292 update_begin (f);
17293 FRAME_RIF (f)->update_window_begin_hook (w);
17294 FRAME_RIF (f)->clear_window_mouse_face (w);
17295 FRAME_RIF (f)->scroll_run_hook (w, &run);
17296 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17297 update_end (f);
17300 /* Adjust Y positions of reused rows. */
17301 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17302 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17303 max_y = it.last_visible_y;
17304 for (row = first_reusable_row; row < first_row_to_display; ++row)
17306 row->y -= dy;
17307 row->visible_height = row->height;
17308 if (row->y < min_y)
17309 row->visible_height -= min_y - row->y;
17310 if (row->y + row->height > max_y)
17311 row->visible_height -= row->y + row->height - max_y;
17312 if (row->fringe_bitmap_periodic_p)
17313 row->redraw_fringe_bitmaps_p = 1;
17316 /* Scroll the current matrix. */
17317 eassert (nrows_scrolled > 0);
17318 rotate_matrix (w->current_matrix,
17319 start_vpos,
17320 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17321 -nrows_scrolled);
17323 /* Disable rows not reused. */
17324 for (row -= nrows_scrolled; row < bottom_row; ++row)
17325 row->enabled_p = false;
17327 /* Point may have moved to a different line, so we cannot assume that
17328 the previous cursor position is valid; locate the correct row. */
17329 if (pt_row)
17331 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
17332 row < bottom_row
17333 && PT >= MATRIX_ROW_END_CHARPOS (row)
17334 && !row->ends_at_zv_p;
17335 row++)
17337 w->cursor.vpos++;
17338 w->cursor.y = row->y;
17340 if (row < bottom_row)
17342 /* Can't simply scan the row for point with
17343 bidi-reordered glyph rows. Let set_cursor_from_row
17344 figure out where to put the cursor, and if it fails,
17345 give up. */
17346 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
17348 if (!set_cursor_from_row (w, row, w->current_matrix,
17349 0, 0, 0, 0))
17351 clear_glyph_matrix (w->desired_matrix);
17352 return 0;
17355 else
17357 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
17358 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17360 for (; glyph < end
17361 && (!BUFFERP (glyph->object)
17362 || glyph->charpos < PT);
17363 glyph++)
17365 w->cursor.hpos++;
17366 w->cursor.x += glyph->pixel_width;
17372 /* Adjust window end. A null value of last_text_row means that
17373 the window end is in reused rows which in turn means that
17374 only its vpos can have changed. */
17375 if (last_text_row)
17376 adjust_window_ends (w, last_text_row, 0);
17377 else
17378 w->window_end_vpos -= nrows_scrolled;
17380 w->window_end_valid = 0;
17381 w->desired_matrix->no_scrolling_p = 1;
17383 #ifdef GLYPH_DEBUG
17384 debug_method_add (w, "try_window_reusing_current_matrix 2");
17385 #endif
17386 return 1;
17389 return 0;
17394 /************************************************************************
17395 Window redisplay reusing current matrix when buffer has changed
17396 ************************************************************************/
17398 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
17399 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
17400 ptrdiff_t *, ptrdiff_t *);
17401 static struct glyph_row *
17402 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
17403 struct glyph_row *);
17406 /* Return the last row in MATRIX displaying text. If row START is
17407 non-null, start searching with that row. IT gives the dimensions
17408 of the display. Value is null if matrix is empty; otherwise it is
17409 a pointer to the row found. */
17411 static struct glyph_row *
17412 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
17413 struct glyph_row *start)
17415 struct glyph_row *row, *row_found;
17417 /* Set row_found to the last row in IT->w's current matrix
17418 displaying text. The loop looks funny but think of partially
17419 visible lines. */
17420 row_found = NULL;
17421 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
17422 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17424 eassert (row->enabled_p);
17425 row_found = row;
17426 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
17427 break;
17428 ++row;
17431 return row_found;
17435 /* Return the last row in the current matrix of W that is not affected
17436 by changes at the start of current_buffer that occurred since W's
17437 current matrix was built. Value is null if no such row exists.
17439 BEG_UNCHANGED us the number of characters unchanged at the start of
17440 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
17441 first changed character in current_buffer. Characters at positions <
17442 BEG + BEG_UNCHANGED are at the same buffer positions as they were
17443 when the current matrix was built. */
17445 static struct glyph_row *
17446 find_last_unchanged_at_beg_row (struct window *w)
17448 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
17449 struct glyph_row *row;
17450 struct glyph_row *row_found = NULL;
17451 int yb = window_text_bottom_y (w);
17453 /* Find the last row displaying unchanged text. */
17454 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17455 MATRIX_ROW_DISPLAYS_TEXT_P (row)
17456 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
17457 ++row)
17459 if (/* If row ends before first_changed_pos, it is unchanged,
17460 except in some case. */
17461 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
17462 /* When row ends in ZV and we write at ZV it is not
17463 unchanged. */
17464 && !row->ends_at_zv_p
17465 /* When first_changed_pos is the end of a continued line,
17466 row is not unchanged because it may be no longer
17467 continued. */
17468 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
17469 && (row->continued_p
17470 || row->exact_window_width_line_p))
17471 /* If ROW->end is beyond ZV, then ROW->end is outdated and
17472 needs to be recomputed, so don't consider this row as
17473 unchanged. This happens when the last line was
17474 bidi-reordered and was killed immediately before this
17475 redisplay cycle. In that case, ROW->end stores the
17476 buffer position of the first visual-order character of
17477 the killed text, which is now beyond ZV. */
17478 && CHARPOS (row->end.pos) <= ZV)
17479 row_found = row;
17481 /* Stop if last visible row. */
17482 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
17483 break;
17486 return row_found;
17490 /* Find the first glyph row in the current matrix of W that is not
17491 affected by changes at the end of current_buffer since the
17492 time W's current matrix was built.
17494 Return in *DELTA the number of chars by which buffer positions in
17495 unchanged text at the end of current_buffer must be adjusted.
17497 Return in *DELTA_BYTES the corresponding number of bytes.
17499 Value is null if no such row exists, i.e. all rows are affected by
17500 changes. */
17502 static struct glyph_row *
17503 find_first_unchanged_at_end_row (struct window *w,
17504 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
17506 struct glyph_row *row;
17507 struct glyph_row *row_found = NULL;
17509 *delta = *delta_bytes = 0;
17511 /* Display must not have been paused, otherwise the current matrix
17512 is not up to date. */
17513 eassert (w->window_end_valid);
17515 /* A value of window_end_pos >= END_UNCHANGED means that the window
17516 end is in the range of changed text. If so, there is no
17517 unchanged row at the end of W's current matrix. */
17518 if (w->window_end_pos >= END_UNCHANGED)
17519 return NULL;
17521 /* Set row to the last row in W's current matrix displaying text. */
17522 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17524 /* If matrix is entirely empty, no unchanged row exists. */
17525 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17527 /* The value of row is the last glyph row in the matrix having a
17528 meaningful buffer position in it. The end position of row
17529 corresponds to window_end_pos. This allows us to translate
17530 buffer positions in the current matrix to current buffer
17531 positions for characters not in changed text. */
17532 ptrdiff_t Z_old =
17533 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17534 ptrdiff_t Z_BYTE_old =
17535 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17536 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17537 struct glyph_row *first_text_row
17538 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17540 *delta = Z - Z_old;
17541 *delta_bytes = Z_BYTE - Z_BYTE_old;
17543 /* Set last_unchanged_pos to the buffer position of the last
17544 character in the buffer that has not been changed. Z is the
17545 index + 1 of the last character in current_buffer, i.e. by
17546 subtracting END_UNCHANGED we get the index of the last
17547 unchanged character, and we have to add BEG to get its buffer
17548 position. */
17549 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17550 last_unchanged_pos_old = last_unchanged_pos - *delta;
17552 /* Search backward from ROW for a row displaying a line that
17553 starts at a minimum position >= last_unchanged_pos_old. */
17554 for (; row > first_text_row; --row)
17556 /* This used to abort, but it can happen.
17557 It is ok to just stop the search instead here. KFS. */
17558 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17559 break;
17561 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17562 row_found = row;
17566 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17568 return row_found;
17572 /* Make sure that glyph rows in the current matrix of window W
17573 reference the same glyph memory as corresponding rows in the
17574 frame's frame matrix. This function is called after scrolling W's
17575 current matrix on a terminal frame in try_window_id and
17576 try_window_reusing_current_matrix. */
17578 static void
17579 sync_frame_with_window_matrix_rows (struct window *w)
17581 struct frame *f = XFRAME (w->frame);
17582 struct glyph_row *window_row, *window_row_end, *frame_row;
17584 /* Preconditions: W must be a leaf window and full-width. Its frame
17585 must have a frame matrix. */
17586 eassert (BUFFERP (w->contents));
17587 eassert (WINDOW_FULL_WIDTH_P (w));
17588 eassert (!FRAME_WINDOW_P (f));
17590 /* If W is a full-width window, glyph pointers in W's current matrix
17591 have, by definition, to be the same as glyph pointers in the
17592 corresponding frame matrix. Note that frame matrices have no
17593 marginal areas (see build_frame_matrix). */
17594 window_row = w->current_matrix->rows;
17595 window_row_end = window_row + w->current_matrix->nrows;
17596 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17597 while (window_row < window_row_end)
17599 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17600 struct glyph *end = window_row->glyphs[LAST_AREA];
17602 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17603 frame_row->glyphs[TEXT_AREA] = start;
17604 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17605 frame_row->glyphs[LAST_AREA] = end;
17607 /* Disable frame rows whose corresponding window rows have
17608 been disabled in try_window_id. */
17609 if (!window_row->enabled_p)
17610 frame_row->enabled_p = false;
17612 ++window_row, ++frame_row;
17617 /* Find the glyph row in window W containing CHARPOS. Consider all
17618 rows between START and END (not inclusive). END null means search
17619 all rows to the end of the display area of W. Value is the row
17620 containing CHARPOS or null. */
17622 struct glyph_row *
17623 row_containing_pos (struct window *w, ptrdiff_t charpos,
17624 struct glyph_row *start, struct glyph_row *end, int dy)
17626 struct glyph_row *row = start;
17627 struct glyph_row *best_row = NULL;
17628 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
17629 int last_y;
17631 /* If we happen to start on a header-line, skip that. */
17632 if (row->mode_line_p)
17633 ++row;
17635 if ((end && row >= end) || !row->enabled_p)
17636 return NULL;
17638 last_y = window_text_bottom_y (w) - dy;
17640 while (1)
17642 /* Give up if we have gone too far. */
17643 if (end && row >= end)
17644 return NULL;
17645 /* This formerly returned if they were equal.
17646 I think that both quantities are of a "last plus one" type;
17647 if so, when they are equal, the row is within the screen. -- rms. */
17648 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17649 return NULL;
17651 /* If it is in this row, return this row. */
17652 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17653 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17654 /* The end position of a row equals the start
17655 position of the next row. If CHARPOS is there, we
17656 would rather consider it displayed in the next
17657 line, except when this line ends in ZV. */
17658 && !row_for_charpos_p (row, charpos)))
17659 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17661 struct glyph *g;
17663 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17664 || (!best_row && !row->continued_p))
17665 return row;
17666 /* In bidi-reordered rows, there could be several rows whose
17667 edges surround CHARPOS, all of these rows belonging to
17668 the same continued line. We need to find the row which
17669 fits CHARPOS the best. */
17670 for (g = row->glyphs[TEXT_AREA];
17671 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17672 g++)
17674 if (!STRINGP (g->object))
17676 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17678 mindif = eabs (g->charpos - charpos);
17679 best_row = row;
17680 /* Exact match always wins. */
17681 if (mindif == 0)
17682 return best_row;
17687 else if (best_row && !row->continued_p)
17688 return best_row;
17689 ++row;
17694 /* Try to redisplay window W by reusing its existing display. W's
17695 current matrix must be up to date when this function is called,
17696 i.e. window_end_valid must be nonzero.
17698 Value is
17700 >= 1 if successful, i.e. display has been updated
17701 specifically:
17702 1 means the changes were in front of a newline that precedes
17703 the window start, and the whole current matrix was reused
17704 2 means the changes were after the last position displayed
17705 in the window, and the whole current matrix was reused
17706 3 means portions of the current matrix were reused, while
17707 some of the screen lines were redrawn
17708 -1 if redisplay with same window start is known not to succeed
17709 0 if otherwise unsuccessful
17711 The following steps are performed:
17713 1. Find the last row in the current matrix of W that is not
17714 affected by changes at the start of current_buffer. If no such row
17715 is found, give up.
17717 2. Find the first row in W's current matrix that is not affected by
17718 changes at the end of current_buffer. Maybe there is no such row.
17720 3. Display lines beginning with the row + 1 found in step 1 to the
17721 row found in step 2 or, if step 2 didn't find a row, to the end of
17722 the window.
17724 4. If cursor is not known to appear on the window, give up.
17726 5. If display stopped at the row found in step 2, scroll the
17727 display and current matrix as needed.
17729 6. Maybe display some lines at the end of W, if we must. This can
17730 happen under various circumstances, like a partially visible line
17731 becoming fully visible, or because newly displayed lines are displayed
17732 in smaller font sizes.
17734 7. Update W's window end information. */
17736 static int
17737 try_window_id (struct window *w)
17739 struct frame *f = XFRAME (w->frame);
17740 struct glyph_matrix *current_matrix = w->current_matrix;
17741 struct glyph_matrix *desired_matrix = w->desired_matrix;
17742 struct glyph_row *last_unchanged_at_beg_row;
17743 struct glyph_row *first_unchanged_at_end_row;
17744 struct glyph_row *row;
17745 struct glyph_row *bottom_row;
17746 int bottom_vpos;
17747 struct it it;
17748 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17749 int dvpos, dy;
17750 struct text_pos start_pos;
17751 struct run run;
17752 int first_unchanged_at_end_vpos = 0;
17753 struct glyph_row *last_text_row, *last_text_row_at_end;
17754 struct text_pos start;
17755 ptrdiff_t first_changed_charpos, last_changed_charpos;
17757 #ifdef GLYPH_DEBUG
17758 if (inhibit_try_window_id)
17759 return 0;
17760 #endif
17762 /* This is handy for debugging. */
17763 #if 0
17764 #define GIVE_UP(X) \
17765 do { \
17766 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17767 return 0; \
17768 } while (0)
17769 #else
17770 #define GIVE_UP(X) return 0
17771 #endif
17773 SET_TEXT_POS_FROM_MARKER (start, w->start);
17775 /* Don't use this for mini-windows because these can show
17776 messages and mini-buffers, and we don't handle that here. */
17777 if (MINI_WINDOW_P (w))
17778 GIVE_UP (1);
17780 /* This flag is used to prevent redisplay optimizations. */
17781 if (windows_or_buffers_changed || f->cursor_type_changed)
17782 GIVE_UP (2);
17784 /* This function's optimizations cannot be used if overlays have
17785 changed in the buffer displayed by the window, so give up if they
17786 have. */
17787 if (w->last_overlay_modified != OVERLAY_MODIFF)
17788 GIVE_UP (21);
17790 /* Verify that narrowing has not changed.
17791 Also verify that we were not told to prevent redisplay optimizations.
17792 It would be nice to further
17793 reduce the number of cases where this prevents try_window_id. */
17794 if (current_buffer->clip_changed
17795 || current_buffer->prevent_redisplay_optimizations_p)
17796 GIVE_UP (3);
17798 /* Window must either use window-based redisplay or be full width. */
17799 if (!FRAME_WINDOW_P (f)
17800 && (!FRAME_LINE_INS_DEL_OK (f)
17801 || !WINDOW_FULL_WIDTH_P (w)))
17802 GIVE_UP (4);
17804 /* Give up if point is known NOT to appear in W. */
17805 if (PT < CHARPOS (start))
17806 GIVE_UP (5);
17808 /* Another way to prevent redisplay optimizations. */
17809 if (w->last_modified == 0)
17810 GIVE_UP (6);
17812 /* Verify that window is not hscrolled. */
17813 if (w->hscroll != 0)
17814 GIVE_UP (7);
17816 /* Verify that display wasn't paused. */
17817 if (!w->window_end_valid)
17818 GIVE_UP (8);
17820 /* Likewise if highlighting trailing whitespace. */
17821 if (!NILP (Vshow_trailing_whitespace))
17822 GIVE_UP (11);
17824 /* Can't use this if overlay arrow position and/or string have
17825 changed. */
17826 if (overlay_arrows_changed_p ())
17827 GIVE_UP (12);
17829 /* When word-wrap is on, adding a space to the first word of a
17830 wrapped line can change the wrap position, altering the line
17831 above it. It might be worthwhile to handle this more
17832 intelligently, but for now just redisplay from scratch. */
17833 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17834 GIVE_UP (21);
17836 /* Under bidi reordering, adding or deleting a character in the
17837 beginning of a paragraph, before the first strong directional
17838 character, can change the base direction of the paragraph (unless
17839 the buffer specifies a fixed paragraph direction), which will
17840 require to redisplay the whole paragraph. It might be worthwhile
17841 to find the paragraph limits and widen the range of redisplayed
17842 lines to that, but for now just give up this optimization and
17843 redisplay from scratch. */
17844 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17845 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17846 GIVE_UP (22);
17848 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17849 only if buffer has really changed. The reason is that the gap is
17850 initially at Z for freshly visited files. The code below would
17851 set end_unchanged to 0 in that case. */
17852 if (MODIFF > SAVE_MODIFF
17853 /* This seems to happen sometimes after saving a buffer. */
17854 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17856 if (GPT - BEG < BEG_UNCHANGED)
17857 BEG_UNCHANGED = GPT - BEG;
17858 if (Z - GPT < END_UNCHANGED)
17859 END_UNCHANGED = Z - GPT;
17862 /* The position of the first and last character that has been changed. */
17863 first_changed_charpos = BEG + BEG_UNCHANGED;
17864 last_changed_charpos = Z - END_UNCHANGED;
17866 /* If window starts after a line end, and the last change is in
17867 front of that newline, then changes don't affect the display.
17868 This case happens with stealth-fontification. Note that although
17869 the display is unchanged, glyph positions in the matrix have to
17870 be adjusted, of course. */
17871 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17872 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17873 && ((last_changed_charpos < CHARPOS (start)
17874 && CHARPOS (start) == BEGV)
17875 || (last_changed_charpos < CHARPOS (start) - 1
17876 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17878 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17879 struct glyph_row *r0;
17881 /* Compute how many chars/bytes have been added to or removed
17882 from the buffer. */
17883 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17884 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17885 Z_delta = Z - Z_old;
17886 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17888 /* Give up if PT is not in the window. Note that it already has
17889 been checked at the start of try_window_id that PT is not in
17890 front of the window start. */
17891 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17892 GIVE_UP (13);
17894 /* If window start is unchanged, we can reuse the whole matrix
17895 as is, after adjusting glyph positions. No need to compute
17896 the window end again, since its offset from Z hasn't changed. */
17897 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17898 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17899 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17900 /* PT must not be in a partially visible line. */
17901 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17902 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17904 /* Adjust positions in the glyph matrix. */
17905 if (Z_delta || Z_delta_bytes)
17907 struct glyph_row *r1
17908 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17909 increment_matrix_positions (w->current_matrix,
17910 MATRIX_ROW_VPOS (r0, current_matrix),
17911 MATRIX_ROW_VPOS (r1, current_matrix),
17912 Z_delta, Z_delta_bytes);
17915 /* Set the cursor. */
17916 row = row_containing_pos (w, PT, r0, NULL, 0);
17917 if (row)
17918 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17919 return 1;
17923 /* Handle the case that changes are all below what is displayed in
17924 the window, and that PT is in the window. This shortcut cannot
17925 be taken if ZV is visible in the window, and text has been added
17926 there that is visible in the window. */
17927 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17928 /* ZV is not visible in the window, or there are no
17929 changes at ZV, actually. */
17930 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17931 || first_changed_charpos == last_changed_charpos))
17933 struct glyph_row *r0;
17935 /* Give up if PT is not in the window. Note that it already has
17936 been checked at the start of try_window_id that PT is not in
17937 front of the window start. */
17938 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17939 GIVE_UP (14);
17941 /* If window start is unchanged, we can reuse the whole matrix
17942 as is, without changing glyph positions since no text has
17943 been added/removed in front of the window end. */
17944 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17945 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17946 /* PT must not be in a partially visible line. */
17947 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17948 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17950 /* We have to compute the window end anew since text
17951 could have been added/removed after it. */
17952 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17953 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17955 /* Set the cursor. */
17956 row = row_containing_pos (w, PT, r0, NULL, 0);
17957 if (row)
17958 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17959 return 2;
17963 /* Give up if window start is in the changed area.
17965 The condition used to read
17967 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17969 but why that was tested escapes me at the moment. */
17970 if (CHARPOS (start) >= first_changed_charpos
17971 && CHARPOS (start) <= last_changed_charpos)
17972 GIVE_UP (15);
17974 /* Check that window start agrees with the start of the first glyph
17975 row in its current matrix. Check this after we know the window
17976 start is not in changed text, otherwise positions would not be
17977 comparable. */
17978 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17979 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17980 GIVE_UP (16);
17982 /* Give up if the window ends in strings. Overlay strings
17983 at the end are difficult to handle, so don't try. */
17984 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17985 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17986 GIVE_UP (20);
17988 /* Compute the position at which we have to start displaying new
17989 lines. Some of the lines at the top of the window might be
17990 reusable because they are not displaying changed text. Find the
17991 last row in W's current matrix not affected by changes at the
17992 start of current_buffer. Value is null if changes start in the
17993 first line of window. */
17994 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17995 if (last_unchanged_at_beg_row)
17997 /* Avoid starting to display in the middle of a character, a TAB
17998 for instance. This is easier than to set up the iterator
17999 exactly, and it's not a frequent case, so the additional
18000 effort wouldn't really pay off. */
18001 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18002 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18003 && last_unchanged_at_beg_row > w->current_matrix->rows)
18004 --last_unchanged_at_beg_row;
18006 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18007 GIVE_UP (17);
18009 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
18010 GIVE_UP (18);
18011 start_pos = it.current.pos;
18013 /* Start displaying new lines in the desired matrix at the same
18014 vpos we would use in the current matrix, i.e. below
18015 last_unchanged_at_beg_row. */
18016 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18017 current_matrix);
18018 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18019 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18021 eassert (it.hpos == 0 && it.current_x == 0);
18023 else
18025 /* There are no reusable lines at the start of the window.
18026 Start displaying in the first text line. */
18027 start_display (&it, w, start);
18028 it.vpos = it.first_vpos;
18029 start_pos = it.current.pos;
18032 /* Find the first row that is not affected by changes at the end of
18033 the buffer. Value will be null if there is no unchanged row, in
18034 which case we must redisplay to the end of the window. delta
18035 will be set to the value by which buffer positions beginning with
18036 first_unchanged_at_end_row have to be adjusted due to text
18037 changes. */
18038 first_unchanged_at_end_row
18039 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18040 IF_DEBUG (debug_delta = delta);
18041 IF_DEBUG (debug_delta_bytes = delta_bytes);
18043 /* Set stop_pos to the buffer position up to which we will have to
18044 display new lines. If first_unchanged_at_end_row != NULL, this
18045 is the buffer position of the start of the line displayed in that
18046 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18047 that we don't stop at a buffer position. */
18048 stop_pos = 0;
18049 if (first_unchanged_at_end_row)
18051 eassert (last_unchanged_at_beg_row == NULL
18052 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18054 /* If this is a continuation line, move forward to the next one
18055 that isn't. Changes in lines above affect this line.
18056 Caution: this may move first_unchanged_at_end_row to a row
18057 not displaying text. */
18058 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18059 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18060 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18061 < it.last_visible_y))
18062 ++first_unchanged_at_end_row;
18064 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18065 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18066 >= it.last_visible_y))
18067 first_unchanged_at_end_row = NULL;
18068 else
18070 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18071 + delta);
18072 first_unchanged_at_end_vpos
18073 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18074 eassert (stop_pos >= Z - END_UNCHANGED);
18077 else if (last_unchanged_at_beg_row == NULL)
18078 GIVE_UP (19);
18081 #ifdef GLYPH_DEBUG
18083 /* Either there is no unchanged row at the end, or the one we have
18084 now displays text. This is a necessary condition for the window
18085 end pos calculation at the end of this function. */
18086 eassert (first_unchanged_at_end_row == NULL
18087 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18089 debug_last_unchanged_at_beg_vpos
18090 = (last_unchanged_at_beg_row
18091 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18092 : -1);
18093 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18095 #endif /* GLYPH_DEBUG */
18098 /* Display new lines. Set last_text_row to the last new line
18099 displayed which has text on it, i.e. might end up as being the
18100 line where the window_end_vpos is. */
18101 w->cursor.vpos = -1;
18102 last_text_row = NULL;
18103 overlay_arrow_seen = 0;
18104 if (it.current_y < it.last_visible_y
18105 && !f->fonts_changed
18106 && (first_unchanged_at_end_row == NULL
18107 || IT_CHARPOS (it) < stop_pos))
18108 it.glyph_row->reversed_p = false;
18109 while (it.current_y < it.last_visible_y
18110 && !f->fonts_changed
18111 && (first_unchanged_at_end_row == NULL
18112 || IT_CHARPOS (it) < stop_pos))
18114 if (display_line (&it))
18115 last_text_row = it.glyph_row - 1;
18118 if (f->fonts_changed)
18119 return -1;
18122 /* Compute differences in buffer positions, y-positions etc. for
18123 lines reused at the bottom of the window. Compute what we can
18124 scroll. */
18125 if (first_unchanged_at_end_row
18126 /* No lines reused because we displayed everything up to the
18127 bottom of the window. */
18128 && it.current_y < it.last_visible_y)
18130 dvpos = (it.vpos
18131 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18132 current_matrix));
18133 dy = it.current_y - first_unchanged_at_end_row->y;
18134 run.current_y = first_unchanged_at_end_row->y;
18135 run.desired_y = run.current_y + dy;
18136 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18138 else
18140 delta = delta_bytes = dvpos = dy
18141 = run.current_y = run.desired_y = run.height = 0;
18142 first_unchanged_at_end_row = NULL;
18144 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18147 /* Find the cursor if not already found. We have to decide whether
18148 PT will appear on this window (it sometimes doesn't, but this is
18149 not a very frequent case.) This decision has to be made before
18150 the current matrix is altered. A value of cursor.vpos < 0 means
18151 that PT is either in one of the lines beginning at
18152 first_unchanged_at_end_row or below the window. Don't care for
18153 lines that might be displayed later at the window end; as
18154 mentioned, this is not a frequent case. */
18155 if (w->cursor.vpos < 0)
18157 /* Cursor in unchanged rows at the top? */
18158 if (PT < CHARPOS (start_pos)
18159 && last_unchanged_at_beg_row)
18161 row = row_containing_pos (w, PT,
18162 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18163 last_unchanged_at_beg_row + 1, 0);
18164 if (row)
18165 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18168 /* Start from first_unchanged_at_end_row looking for PT. */
18169 else if (first_unchanged_at_end_row)
18171 row = row_containing_pos (w, PT - delta,
18172 first_unchanged_at_end_row, NULL, 0);
18173 if (row)
18174 set_cursor_from_row (w, row, w->current_matrix, delta,
18175 delta_bytes, dy, dvpos);
18178 /* Give up if cursor was not found. */
18179 if (w->cursor.vpos < 0)
18181 clear_glyph_matrix (w->desired_matrix);
18182 return -1;
18186 /* Don't let the cursor end in the scroll margins. */
18188 int this_scroll_margin, cursor_height;
18189 int frame_line_height = default_line_pixel_height (w);
18190 int window_total_lines
18191 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
18193 this_scroll_margin =
18194 max (0, min (scroll_margin, window_total_lines / 4));
18195 this_scroll_margin *= frame_line_height;
18196 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18198 if ((w->cursor.y < this_scroll_margin
18199 && CHARPOS (start) > BEGV)
18200 /* Old redisplay didn't take scroll margin into account at the bottom,
18201 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18202 || (w->cursor.y + (make_cursor_line_fully_visible_p
18203 ? cursor_height + this_scroll_margin
18204 : 1)) > it.last_visible_y)
18206 w->cursor.vpos = -1;
18207 clear_glyph_matrix (w->desired_matrix);
18208 return -1;
18212 /* Scroll the display. Do it before changing the current matrix so
18213 that xterm.c doesn't get confused about where the cursor glyph is
18214 found. */
18215 if (dy && run.height)
18217 update_begin (f);
18219 if (FRAME_WINDOW_P (f))
18221 FRAME_RIF (f)->update_window_begin_hook (w);
18222 FRAME_RIF (f)->clear_window_mouse_face (w);
18223 FRAME_RIF (f)->scroll_run_hook (w, &run);
18224 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
18226 else
18228 /* Terminal frame. In this case, dvpos gives the number of
18229 lines to scroll by; dvpos < 0 means scroll up. */
18230 int from_vpos
18231 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18232 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18233 int end = (WINDOW_TOP_EDGE_LINE (w)
18234 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
18235 + window_internal_height (w));
18237 #if defined (HAVE_GPM) || defined (MSDOS)
18238 x_clear_window_mouse_face (w);
18239 #endif
18240 /* Perform the operation on the screen. */
18241 if (dvpos > 0)
18243 /* Scroll last_unchanged_at_beg_row to the end of the
18244 window down dvpos lines. */
18245 set_terminal_window (f, end);
18247 /* On dumb terminals delete dvpos lines at the end
18248 before inserting dvpos empty lines. */
18249 if (!FRAME_SCROLL_REGION_OK (f))
18250 ins_del_lines (f, end - dvpos, -dvpos);
18252 /* Insert dvpos empty lines in front of
18253 last_unchanged_at_beg_row. */
18254 ins_del_lines (f, from, dvpos);
18256 else if (dvpos < 0)
18258 /* Scroll up last_unchanged_at_beg_vpos to the end of
18259 the window to last_unchanged_at_beg_vpos - |dvpos|. */
18260 set_terminal_window (f, end);
18262 /* Delete dvpos lines in front of
18263 last_unchanged_at_beg_vpos. ins_del_lines will set
18264 the cursor to the given vpos and emit |dvpos| delete
18265 line sequences. */
18266 ins_del_lines (f, from + dvpos, dvpos);
18268 /* On a dumb terminal insert dvpos empty lines at the
18269 end. */
18270 if (!FRAME_SCROLL_REGION_OK (f))
18271 ins_del_lines (f, end + dvpos, -dvpos);
18274 set_terminal_window (f, 0);
18277 update_end (f);
18280 /* Shift reused rows of the current matrix to the right position.
18281 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
18282 text. */
18283 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18284 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
18285 if (dvpos < 0)
18287 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
18288 bottom_vpos, dvpos);
18289 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
18290 bottom_vpos);
18292 else if (dvpos > 0)
18294 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
18295 bottom_vpos, dvpos);
18296 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
18297 first_unchanged_at_end_vpos + dvpos);
18300 /* For frame-based redisplay, make sure that current frame and window
18301 matrix are in sync with respect to glyph memory. */
18302 if (!FRAME_WINDOW_P (f))
18303 sync_frame_with_window_matrix_rows (w);
18305 /* Adjust buffer positions in reused rows. */
18306 if (delta || delta_bytes)
18307 increment_matrix_positions (current_matrix,
18308 first_unchanged_at_end_vpos + dvpos,
18309 bottom_vpos, delta, delta_bytes);
18311 /* Adjust Y positions. */
18312 if (dy)
18313 shift_glyph_matrix (w, current_matrix,
18314 first_unchanged_at_end_vpos + dvpos,
18315 bottom_vpos, dy);
18317 if (first_unchanged_at_end_row)
18319 first_unchanged_at_end_row += dvpos;
18320 if (first_unchanged_at_end_row->y >= it.last_visible_y
18321 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
18322 first_unchanged_at_end_row = NULL;
18325 /* If scrolling up, there may be some lines to display at the end of
18326 the window. */
18327 last_text_row_at_end = NULL;
18328 if (dy < 0)
18330 /* Scrolling up can leave for example a partially visible line
18331 at the end of the window to be redisplayed. */
18332 /* Set last_row to the glyph row in the current matrix where the
18333 window end line is found. It has been moved up or down in
18334 the matrix by dvpos. */
18335 int last_vpos = w->window_end_vpos + dvpos;
18336 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
18338 /* If last_row is the window end line, it should display text. */
18339 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
18341 /* If window end line was partially visible before, begin
18342 displaying at that line. Otherwise begin displaying with the
18343 line following it. */
18344 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
18346 init_to_row_start (&it, w, last_row);
18347 it.vpos = last_vpos;
18348 it.current_y = last_row->y;
18350 else
18352 init_to_row_end (&it, w, last_row);
18353 it.vpos = 1 + last_vpos;
18354 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
18355 ++last_row;
18358 /* We may start in a continuation line. If so, we have to
18359 get the right continuation_lines_width and current_x. */
18360 it.continuation_lines_width = last_row->continuation_lines_width;
18361 it.hpos = it.current_x = 0;
18363 /* Display the rest of the lines at the window end. */
18364 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18365 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18367 /* Is it always sure that the display agrees with lines in
18368 the current matrix? I don't think so, so we mark rows
18369 displayed invalid in the current matrix by setting their
18370 enabled_p flag to zero. */
18371 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18372 if (display_line (&it))
18373 last_text_row_at_end = it.glyph_row - 1;
18377 /* Update window_end_pos and window_end_vpos. */
18378 if (first_unchanged_at_end_row && !last_text_row_at_end)
18380 /* Window end line if one of the preserved rows from the current
18381 matrix. Set row to the last row displaying text in current
18382 matrix starting at first_unchanged_at_end_row, after
18383 scrolling. */
18384 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18385 row = find_last_row_displaying_text (w->current_matrix, &it,
18386 first_unchanged_at_end_row);
18387 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
18388 adjust_window_ends (w, row, 1);
18389 eassert (w->window_end_bytepos >= 0);
18390 IF_DEBUG (debug_method_add (w, "A"));
18392 else if (last_text_row_at_end)
18394 adjust_window_ends (w, last_text_row_at_end, 0);
18395 eassert (w->window_end_bytepos >= 0);
18396 IF_DEBUG (debug_method_add (w, "B"));
18398 else if (last_text_row)
18400 /* We have displayed either to the end of the window or at the
18401 end of the window, i.e. the last row with text is to be found
18402 in the desired matrix. */
18403 adjust_window_ends (w, last_text_row, 0);
18404 eassert (w->window_end_bytepos >= 0);
18406 else if (first_unchanged_at_end_row == NULL
18407 && last_text_row == NULL
18408 && last_text_row_at_end == NULL)
18410 /* Displayed to end of window, but no line containing text was
18411 displayed. Lines were deleted at the end of the window. */
18412 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
18413 int vpos = w->window_end_vpos;
18414 struct glyph_row *current_row = current_matrix->rows + vpos;
18415 struct glyph_row *desired_row = desired_matrix->rows + vpos;
18417 for (row = NULL;
18418 row == NULL && vpos >= first_vpos;
18419 --vpos, --current_row, --desired_row)
18421 if (desired_row->enabled_p)
18423 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
18424 row = desired_row;
18426 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
18427 row = current_row;
18430 eassert (row != NULL);
18431 w->window_end_vpos = vpos + 1;
18432 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18433 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18434 eassert (w->window_end_bytepos >= 0);
18435 IF_DEBUG (debug_method_add (w, "C"));
18437 else
18438 emacs_abort ();
18440 IF_DEBUG ((debug_end_pos = w->window_end_pos,
18441 debug_end_vpos = w->window_end_vpos));
18443 /* Record that display has not been completed. */
18444 w->window_end_valid = 0;
18445 w->desired_matrix->no_scrolling_p = 1;
18446 return 3;
18448 #undef GIVE_UP
18453 /***********************************************************************
18454 More debugging support
18455 ***********************************************************************/
18457 #ifdef GLYPH_DEBUG
18459 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
18460 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
18461 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
18464 /* Dump the contents of glyph matrix MATRIX on stderr.
18466 GLYPHS 0 means don't show glyph contents.
18467 GLYPHS 1 means show glyphs in short form
18468 GLYPHS > 1 means show glyphs in long form. */
18470 void
18471 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
18473 int i;
18474 for (i = 0; i < matrix->nrows; ++i)
18475 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
18479 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
18480 the glyph row and area where the glyph comes from. */
18482 void
18483 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
18485 if (glyph->type == CHAR_GLYPH
18486 || glyph->type == GLYPHLESS_GLYPH)
18488 fprintf (stderr,
18489 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18490 glyph - row->glyphs[TEXT_AREA],
18491 (glyph->type == CHAR_GLYPH
18492 ? 'C'
18493 : 'G'),
18494 glyph->charpos,
18495 (BUFFERP (glyph->object)
18496 ? 'B'
18497 : (STRINGP (glyph->object)
18498 ? 'S'
18499 : (INTEGERP (glyph->object)
18500 ? '0'
18501 : '-'))),
18502 glyph->pixel_width,
18503 glyph->u.ch,
18504 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18505 ? glyph->u.ch
18506 : '.'),
18507 glyph->face_id,
18508 glyph->left_box_line_p,
18509 glyph->right_box_line_p);
18511 else if (glyph->type == STRETCH_GLYPH)
18513 fprintf (stderr,
18514 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18515 glyph - row->glyphs[TEXT_AREA],
18516 'S',
18517 glyph->charpos,
18518 (BUFFERP (glyph->object)
18519 ? 'B'
18520 : (STRINGP (glyph->object)
18521 ? 'S'
18522 : (INTEGERP (glyph->object)
18523 ? '0'
18524 : '-'))),
18525 glyph->pixel_width,
18527 ' ',
18528 glyph->face_id,
18529 glyph->left_box_line_p,
18530 glyph->right_box_line_p);
18532 else if (glyph->type == IMAGE_GLYPH)
18534 fprintf (stderr,
18535 " %5"pD"d %c %9"pI"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
18536 glyph - row->glyphs[TEXT_AREA],
18537 'I',
18538 glyph->charpos,
18539 (BUFFERP (glyph->object)
18540 ? 'B'
18541 : (STRINGP (glyph->object)
18542 ? 'S'
18543 : (INTEGERP (glyph->object)
18544 ? '0'
18545 : '-'))),
18546 glyph->pixel_width,
18547 glyph->u.img_id,
18548 '.',
18549 glyph->face_id,
18550 glyph->left_box_line_p,
18551 glyph->right_box_line_p);
18553 else if (glyph->type == COMPOSITE_GLYPH)
18555 fprintf (stderr,
18556 " %5"pD"d %c %9"pI"d %c %3d 0x%06x",
18557 glyph - row->glyphs[TEXT_AREA],
18558 '+',
18559 glyph->charpos,
18560 (BUFFERP (glyph->object)
18561 ? 'B'
18562 : (STRINGP (glyph->object)
18563 ? 'S'
18564 : (INTEGERP (glyph->object)
18565 ? '0'
18566 : '-'))),
18567 glyph->pixel_width,
18568 glyph->u.cmp.id);
18569 if (glyph->u.cmp.automatic)
18570 fprintf (stderr,
18571 "[%d-%d]",
18572 glyph->slice.cmp.from, glyph->slice.cmp.to);
18573 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18574 glyph->face_id,
18575 glyph->left_box_line_p,
18576 glyph->right_box_line_p);
18581 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
18582 GLYPHS 0 means don't show glyph contents.
18583 GLYPHS 1 means show glyphs in short form
18584 GLYPHS > 1 means show glyphs in long form. */
18586 void
18587 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18589 if (glyphs != 1)
18591 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18592 fprintf (stderr, "==============================================================================\n");
18594 fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18595 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18596 vpos,
18597 MATRIX_ROW_START_CHARPOS (row),
18598 MATRIX_ROW_END_CHARPOS (row),
18599 row->used[TEXT_AREA],
18600 row->contains_overlapping_glyphs_p,
18601 row->enabled_p,
18602 row->truncated_on_left_p,
18603 row->truncated_on_right_p,
18604 row->continued_p,
18605 MATRIX_ROW_CONTINUATION_LINE_P (row),
18606 MATRIX_ROW_DISPLAYS_TEXT_P (row),
18607 row->ends_at_zv_p,
18608 row->fill_line_p,
18609 row->ends_in_middle_of_char_p,
18610 row->starts_in_middle_of_char_p,
18611 row->mouse_face_p,
18612 row->x,
18613 row->y,
18614 row->pixel_width,
18615 row->height,
18616 row->visible_height,
18617 row->ascent,
18618 row->phys_ascent);
18619 /* The next 3 lines should align to "Start" in the header. */
18620 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
18621 row->end.overlay_string_index,
18622 row->continuation_lines_width);
18623 fprintf (stderr, " %9"pI"d %9"pI"d\n",
18624 CHARPOS (row->start.string_pos),
18625 CHARPOS (row->end.string_pos));
18626 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
18627 row->end.dpvec_index);
18630 if (glyphs > 1)
18632 int area;
18634 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18636 struct glyph *glyph = row->glyphs[area];
18637 struct glyph *glyph_end = glyph + row->used[area];
18639 /* Glyph for a line end in text. */
18640 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18641 ++glyph_end;
18643 if (glyph < glyph_end)
18644 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
18646 for (; glyph < glyph_end; ++glyph)
18647 dump_glyph (row, glyph, area);
18650 else if (glyphs == 1)
18652 int area;
18654 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18656 char *s = alloca (row->used[area] + 4);
18657 int i;
18659 for (i = 0; i < row->used[area]; ++i)
18661 struct glyph *glyph = row->glyphs[area] + i;
18662 if (i == row->used[area] - 1
18663 && area == TEXT_AREA
18664 && INTEGERP (glyph->object)
18665 && glyph->type == CHAR_GLYPH
18666 && glyph->u.ch == ' ')
18668 strcpy (&s[i], "[\\n]");
18669 i += 4;
18671 else if (glyph->type == CHAR_GLYPH
18672 && glyph->u.ch < 0x80
18673 && glyph->u.ch >= ' ')
18674 s[i] = glyph->u.ch;
18675 else
18676 s[i] = '.';
18679 s[i] = '\0';
18680 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18686 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18687 Sdump_glyph_matrix, 0, 1, "p",
18688 doc: /* Dump the current matrix of the selected window to stderr.
18689 Shows contents of glyph row structures. With non-nil
18690 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18691 glyphs in short form, otherwise show glyphs in long form. */)
18692 (Lisp_Object glyphs)
18694 struct window *w = XWINDOW (selected_window);
18695 struct buffer *buffer = XBUFFER (w->contents);
18697 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18698 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18699 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18700 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18701 fprintf (stderr, "=============================================\n");
18702 dump_glyph_matrix (w->current_matrix,
18703 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18704 return Qnil;
18708 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18709 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18710 (void)
18712 struct frame *f = XFRAME (selected_frame);
18713 dump_glyph_matrix (f->current_matrix, 1);
18714 return Qnil;
18718 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18719 doc: /* Dump glyph row ROW to stderr.
18720 GLYPH 0 means don't dump glyphs.
18721 GLYPH 1 means dump glyphs in short form.
18722 GLYPH > 1 or omitted means dump glyphs in long form. */)
18723 (Lisp_Object row, Lisp_Object glyphs)
18725 struct glyph_matrix *matrix;
18726 EMACS_INT vpos;
18728 CHECK_NUMBER (row);
18729 matrix = XWINDOW (selected_window)->current_matrix;
18730 vpos = XINT (row);
18731 if (vpos >= 0 && vpos < matrix->nrows)
18732 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18733 vpos,
18734 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18735 return Qnil;
18739 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18740 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18741 GLYPH 0 means don't dump glyphs.
18742 GLYPH 1 means dump glyphs in short form.
18743 GLYPH > 1 or omitted means dump glyphs in long form.
18745 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
18746 do nothing. */)
18747 (Lisp_Object row, Lisp_Object glyphs)
18749 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
18750 struct frame *sf = SELECTED_FRAME ();
18751 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18752 EMACS_INT vpos;
18754 CHECK_NUMBER (row);
18755 vpos = XINT (row);
18756 if (vpos >= 0 && vpos < m->nrows)
18757 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18758 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18759 #endif
18760 return Qnil;
18764 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18765 doc: /* Toggle tracing of redisplay.
18766 With ARG, turn tracing on if and only if ARG is positive. */)
18767 (Lisp_Object arg)
18769 if (NILP (arg))
18770 trace_redisplay_p = !trace_redisplay_p;
18771 else
18773 arg = Fprefix_numeric_value (arg);
18774 trace_redisplay_p = XINT (arg) > 0;
18777 return Qnil;
18781 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18782 doc: /* Like `format', but print result to stderr.
18783 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18784 (ptrdiff_t nargs, Lisp_Object *args)
18786 Lisp_Object s = Fformat (nargs, args);
18787 fprintf (stderr, "%s", SDATA (s));
18788 return Qnil;
18791 #endif /* GLYPH_DEBUG */
18795 /***********************************************************************
18796 Building Desired Matrix Rows
18797 ***********************************************************************/
18799 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18800 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18802 static struct glyph_row *
18803 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18805 struct frame *f = XFRAME (WINDOW_FRAME (w));
18806 struct buffer *buffer = XBUFFER (w->contents);
18807 struct buffer *old = current_buffer;
18808 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18809 int arrow_len = SCHARS (overlay_arrow_string);
18810 const unsigned char *arrow_end = arrow_string + arrow_len;
18811 const unsigned char *p;
18812 struct it it;
18813 bool multibyte_p;
18814 int n_glyphs_before;
18816 set_buffer_temp (buffer);
18817 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18818 scratch_glyph_row.reversed_p = false;
18819 it.glyph_row->used[TEXT_AREA] = 0;
18820 SET_TEXT_POS (it.position, 0, 0);
18822 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18823 p = arrow_string;
18824 while (p < arrow_end)
18826 Lisp_Object face, ilisp;
18828 /* Get the next character. */
18829 if (multibyte_p)
18830 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18831 else
18833 it.c = it.char_to_display = *p, it.len = 1;
18834 if (! ASCII_CHAR_P (it.c))
18835 it.char_to_display = BYTE8_TO_CHAR (it.c);
18837 p += it.len;
18839 /* Get its face. */
18840 ilisp = make_number (p - arrow_string);
18841 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18842 it.face_id = compute_char_face (f, it.char_to_display, face);
18844 /* Compute its width, get its glyphs. */
18845 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18846 SET_TEXT_POS (it.position, -1, -1);
18847 PRODUCE_GLYPHS (&it);
18849 /* If this character doesn't fit any more in the line, we have
18850 to remove some glyphs. */
18851 if (it.current_x > it.last_visible_x)
18853 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18854 break;
18858 set_buffer_temp (old);
18859 return it.glyph_row;
18863 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18864 glyphs to insert is determined by produce_special_glyphs. */
18866 static void
18867 insert_left_trunc_glyphs (struct it *it)
18869 struct it truncate_it;
18870 struct glyph *from, *end, *to, *toend;
18872 eassert (!FRAME_WINDOW_P (it->f)
18873 || (!it->glyph_row->reversed_p
18874 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18875 || (it->glyph_row->reversed_p
18876 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18878 /* Get the truncation glyphs. */
18879 truncate_it = *it;
18880 truncate_it.current_x = 0;
18881 truncate_it.face_id = DEFAULT_FACE_ID;
18882 truncate_it.glyph_row = &scratch_glyph_row;
18883 truncate_it.area = TEXT_AREA;
18884 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18885 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18886 truncate_it.object = make_number (0);
18887 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18889 /* Overwrite glyphs from IT with truncation glyphs. */
18890 if (!it->glyph_row->reversed_p)
18892 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18894 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18895 end = from + tused;
18896 to = it->glyph_row->glyphs[TEXT_AREA];
18897 toend = to + it->glyph_row->used[TEXT_AREA];
18898 if (FRAME_WINDOW_P (it->f))
18900 /* On GUI frames, when variable-size fonts are displayed,
18901 the truncation glyphs may need more pixels than the row's
18902 glyphs they overwrite. We overwrite more glyphs to free
18903 enough screen real estate, and enlarge the stretch glyph
18904 on the right (see display_line), if there is one, to
18905 preserve the screen position of the truncation glyphs on
18906 the right. */
18907 int w = 0;
18908 struct glyph *g = to;
18909 short used;
18911 /* The first glyph could be partially visible, in which case
18912 it->glyph_row->x will be negative. But we want the left
18913 truncation glyphs to be aligned at the left margin of the
18914 window, so we override the x coordinate at which the row
18915 will begin. */
18916 it->glyph_row->x = 0;
18917 while (g < toend && w < it->truncation_pixel_width)
18919 w += g->pixel_width;
18920 ++g;
18922 if (g - to - tused > 0)
18924 memmove (to + tused, g, (toend - g) * sizeof(*g));
18925 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18927 used = it->glyph_row->used[TEXT_AREA];
18928 if (it->glyph_row->truncated_on_right_p
18929 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18930 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18931 == STRETCH_GLYPH)
18933 int extra = w - it->truncation_pixel_width;
18935 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18939 while (from < end)
18940 *to++ = *from++;
18942 /* There may be padding glyphs left over. Overwrite them too. */
18943 if (!FRAME_WINDOW_P (it->f))
18945 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18947 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18948 while (from < end)
18949 *to++ = *from++;
18953 if (to > toend)
18954 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18956 else
18958 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18960 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18961 that back to front. */
18962 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18963 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18964 toend = it->glyph_row->glyphs[TEXT_AREA];
18965 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18966 if (FRAME_WINDOW_P (it->f))
18968 int w = 0;
18969 struct glyph *g = to;
18971 while (g >= toend && w < it->truncation_pixel_width)
18973 w += g->pixel_width;
18974 --g;
18976 if (to - g - tused > 0)
18977 to = g + tused;
18978 if (it->glyph_row->truncated_on_right_p
18979 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18980 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18982 int extra = w - it->truncation_pixel_width;
18984 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18988 while (from >= end && to >= toend)
18989 *to-- = *from--;
18990 if (!FRAME_WINDOW_P (it->f))
18992 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18994 from =
18995 truncate_it.glyph_row->glyphs[TEXT_AREA]
18996 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18997 while (from >= end && to >= toend)
18998 *to-- = *from--;
19001 if (from >= end)
19003 /* Need to free some room before prepending additional
19004 glyphs. */
19005 int move_by = from - end + 1;
19006 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19007 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19009 for ( ; g >= g0; g--)
19010 g[move_by] = *g;
19011 while (from >= end)
19012 *to-- = *from--;
19013 it->glyph_row->used[TEXT_AREA] += move_by;
19018 /* Compute the hash code for ROW. */
19019 unsigned
19020 row_hash (struct glyph_row *row)
19022 int area, k;
19023 unsigned hashval = 0;
19025 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19026 for (k = 0; k < row->used[area]; ++k)
19027 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19028 + row->glyphs[area][k].u.val
19029 + row->glyphs[area][k].face_id
19030 + row->glyphs[area][k].padding_p
19031 + (row->glyphs[area][k].type << 2));
19033 return hashval;
19036 /* Compute the pixel height and width of IT->glyph_row.
19038 Most of the time, ascent and height of a display line will be equal
19039 to the max_ascent and max_height values of the display iterator
19040 structure. This is not the case if
19042 1. We hit ZV without displaying anything. In this case, max_ascent
19043 and max_height will be zero.
19045 2. We have some glyphs that don't contribute to the line height.
19046 (The glyph row flag contributes_to_line_height_p is for future
19047 pixmap extensions).
19049 The first case is easily covered by using default values because in
19050 these cases, the line height does not really matter, except that it
19051 must not be zero. */
19053 static void
19054 compute_line_metrics (struct it *it)
19056 struct glyph_row *row = it->glyph_row;
19058 if (FRAME_WINDOW_P (it->f))
19060 int i, min_y, max_y;
19062 /* The line may consist of one space only, that was added to
19063 place the cursor on it. If so, the row's height hasn't been
19064 computed yet. */
19065 if (row->height == 0)
19067 if (it->max_ascent + it->max_descent == 0)
19068 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19069 row->ascent = it->max_ascent;
19070 row->height = it->max_ascent + it->max_descent;
19071 row->phys_ascent = it->max_phys_ascent;
19072 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19073 row->extra_line_spacing = it->max_extra_line_spacing;
19076 /* Compute the width of this line. */
19077 row->pixel_width = row->x;
19078 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19079 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19081 eassert (row->pixel_width >= 0);
19082 eassert (row->ascent >= 0 && row->height > 0);
19084 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19085 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19087 /* If first line's physical ascent is larger than its logical
19088 ascent, use the physical ascent, and make the row taller.
19089 This makes accented characters fully visible. */
19090 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19091 && row->phys_ascent > row->ascent)
19093 row->height += row->phys_ascent - row->ascent;
19094 row->ascent = row->phys_ascent;
19097 /* Compute how much of the line is visible. */
19098 row->visible_height = row->height;
19100 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19101 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19103 if (row->y < min_y)
19104 row->visible_height -= min_y - row->y;
19105 if (row->y + row->height > max_y)
19106 row->visible_height -= row->y + row->height - max_y;
19108 else
19110 row->pixel_width = row->used[TEXT_AREA];
19111 if (row->continued_p)
19112 row->pixel_width -= it->continuation_pixel_width;
19113 else if (row->truncated_on_right_p)
19114 row->pixel_width -= it->truncation_pixel_width;
19115 row->ascent = row->phys_ascent = 0;
19116 row->height = row->phys_height = row->visible_height = 1;
19117 row->extra_line_spacing = 0;
19120 /* Compute a hash code for this row. */
19121 row->hash = row_hash (row);
19123 it->max_ascent = it->max_descent = 0;
19124 it->max_phys_ascent = it->max_phys_descent = 0;
19128 /* Append one space to the glyph row of iterator IT if doing a
19129 window-based redisplay. The space has the same face as
19130 IT->face_id. Value is non-zero if a space was added.
19132 This function is called to make sure that there is always one glyph
19133 at the end of a glyph row that the cursor can be set on under
19134 window-systems. (If there weren't such a glyph we would not know
19135 how wide and tall a box cursor should be displayed).
19137 At the same time this space let's a nicely handle clearing to the
19138 end of the line if the row ends in italic text. */
19140 static int
19141 append_space_for_newline (struct it *it, int default_face_p)
19143 if (FRAME_WINDOW_P (it->f))
19145 int n = it->glyph_row->used[TEXT_AREA];
19147 if (it->glyph_row->glyphs[TEXT_AREA] + n
19148 < it->glyph_row->glyphs[1 + TEXT_AREA])
19150 /* Save some values that must not be changed.
19151 Must save IT->c and IT->len because otherwise
19152 ITERATOR_AT_END_P wouldn't work anymore after
19153 append_space_for_newline has been called. */
19154 enum display_element_type saved_what = it->what;
19155 int saved_c = it->c, saved_len = it->len;
19156 int saved_char_to_display = it->char_to_display;
19157 int saved_x = it->current_x;
19158 int saved_face_id = it->face_id;
19159 int saved_box_end = it->end_of_box_run_p;
19160 struct text_pos saved_pos;
19161 Lisp_Object saved_object;
19162 struct face *face;
19164 saved_object = it->object;
19165 saved_pos = it->position;
19167 it->what = IT_CHARACTER;
19168 memset (&it->position, 0, sizeof it->position);
19169 it->object = make_number (0);
19170 it->c = it->char_to_display = ' ';
19171 it->len = 1;
19173 /* If the default face was remapped, be sure to use the
19174 remapped face for the appended newline. */
19175 if (default_face_p)
19176 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19177 else if (it->face_before_selective_p)
19178 it->face_id = it->saved_face_id;
19179 face = FACE_FROM_ID (it->f, it->face_id);
19180 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19181 /* In R2L rows, we will prepend a stretch glyph that will
19182 have the end_of_box_run_p flag set for it, so there's no
19183 need for the appended newline glyph to have that flag
19184 set. */
19185 if (it->glyph_row->reversed_p
19186 /* But if the appended newline glyph goes all the way to
19187 the end of the row, there will be no stretch glyph,
19188 so leave the box flag set. */
19189 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
19190 it->end_of_box_run_p = 0;
19192 PRODUCE_GLYPHS (it);
19194 it->override_ascent = -1;
19195 it->constrain_row_ascent_descent_p = 0;
19196 it->current_x = saved_x;
19197 it->object = saved_object;
19198 it->position = saved_pos;
19199 it->what = saved_what;
19200 it->face_id = saved_face_id;
19201 it->len = saved_len;
19202 it->c = saved_c;
19203 it->char_to_display = saved_char_to_display;
19204 it->end_of_box_run_p = saved_box_end;
19205 return 1;
19209 return 0;
19213 /* Extend the face of the last glyph in the text area of IT->glyph_row
19214 to the end of the display line. Called from display_line. If the
19215 glyph row is empty, add a space glyph to it so that we know the
19216 face to draw. Set the glyph row flag fill_line_p. If the glyph
19217 row is R2L, prepend a stretch glyph to cover the empty space to the
19218 left of the leftmost glyph. */
19220 static void
19221 extend_face_to_end_of_line (struct it *it)
19223 struct face *face, *default_face;
19224 struct frame *f = it->f;
19226 /* If line is already filled, do nothing. Non window-system frames
19227 get a grace of one more ``pixel'' because their characters are
19228 1-``pixel'' wide, so they hit the equality too early. This grace
19229 is needed only for R2L rows that are not continued, to produce
19230 one extra blank where we could display the cursor. */
19231 if ((it->current_x >= it->last_visible_x
19232 + (!FRAME_WINDOW_P (f)
19233 && it->glyph_row->reversed_p
19234 && !it->glyph_row->continued_p))
19235 /* If the window has display margins, we will need to extend
19236 their face even if the text area is filled. */
19237 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19238 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
19239 return;
19241 /* The default face, possibly remapped. */
19242 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
19244 /* Face extension extends the background and box of IT->face_id
19245 to the end of the line. If the background equals the background
19246 of the frame, we don't have to do anything. */
19247 if (it->face_before_selective_p)
19248 face = FACE_FROM_ID (f, it->saved_face_id);
19249 else
19250 face = FACE_FROM_ID (f, it->face_id);
19252 if (FRAME_WINDOW_P (f)
19253 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
19254 && face->box == FACE_NO_BOX
19255 && face->background == FRAME_BACKGROUND_PIXEL (f)
19256 #ifdef HAVE_WINDOW_SYSTEM
19257 && !face->stipple
19258 #endif
19259 && !it->glyph_row->reversed_p)
19260 return;
19262 /* Set the glyph row flag indicating that the face of the last glyph
19263 in the text area has to be drawn to the end of the text area. */
19264 it->glyph_row->fill_line_p = 1;
19266 /* If current character of IT is not ASCII, make sure we have the
19267 ASCII face. This will be automatically undone the next time
19268 get_next_display_element returns a multibyte character. Note
19269 that the character will always be single byte in unibyte
19270 text. */
19271 if (!ASCII_CHAR_P (it->c))
19273 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
19276 if (FRAME_WINDOW_P (f))
19278 /* If the row is empty, add a space with the current face of IT,
19279 so that we know which face to draw. */
19280 if (it->glyph_row->used[TEXT_AREA] == 0)
19282 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
19283 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
19284 it->glyph_row->used[TEXT_AREA] = 1;
19286 /* Mode line and the header line don't have margins, and
19287 likewise the frame's tool-bar window, if there is any. */
19288 if (!(it->glyph_row->mode_line_p
19289 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19290 || (WINDOWP (f->tool_bar_window)
19291 && it->w == XWINDOW (f->tool_bar_window))
19292 #endif
19295 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19296 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
19298 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
19299 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
19300 default_face->id;
19301 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
19303 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19304 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
19306 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
19307 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
19308 default_face->id;
19309 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
19312 #ifdef HAVE_WINDOW_SYSTEM
19313 if (it->glyph_row->reversed_p)
19315 /* Prepend a stretch glyph to the row, such that the
19316 rightmost glyph will be drawn flushed all the way to the
19317 right margin of the window. The stretch glyph that will
19318 occupy the empty space, if any, to the left of the
19319 glyphs. */
19320 struct font *font = face->font ? face->font : FRAME_FONT (f);
19321 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
19322 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
19323 struct glyph *g;
19324 int row_width, stretch_ascent, stretch_width;
19325 struct text_pos saved_pos;
19326 int saved_face_id, saved_avoid_cursor, saved_box_start;
19328 for (row_width = 0, g = row_start; g < row_end; g++)
19329 row_width += g->pixel_width;
19330 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
19331 if (stretch_width > 0)
19333 stretch_ascent =
19334 (((it->ascent + it->descent)
19335 * FONT_BASE (font)) / FONT_HEIGHT (font));
19336 saved_pos = it->position;
19337 memset (&it->position, 0, sizeof it->position);
19338 saved_avoid_cursor = it->avoid_cursor_p;
19339 it->avoid_cursor_p = 1;
19340 saved_face_id = it->face_id;
19341 saved_box_start = it->start_of_box_run_p;
19342 /* The last row's stretch glyph should get the default
19343 face, to avoid painting the rest of the window with
19344 the region face, if the region ends at ZV. */
19345 if (it->glyph_row->ends_at_zv_p)
19346 it->face_id = default_face->id;
19347 else
19348 it->face_id = face->id;
19349 it->start_of_box_run_p = 0;
19350 append_stretch_glyph (it, make_number (0), stretch_width,
19351 it->ascent + it->descent, stretch_ascent);
19352 it->position = saved_pos;
19353 it->avoid_cursor_p = saved_avoid_cursor;
19354 it->face_id = saved_face_id;
19355 it->start_of_box_run_p = saved_box_start;
19357 /* If stretch_width comes out negative, it means that the
19358 last glyph is only partially visible. In R2L rows, we
19359 want the leftmost glyph to be partially visible, so we
19360 need to give the row the corresponding left offset. */
19361 if (stretch_width < 0)
19362 it->glyph_row->x = stretch_width;
19364 #endif /* HAVE_WINDOW_SYSTEM */
19366 else
19368 /* Save some values that must not be changed. */
19369 int saved_x = it->current_x;
19370 struct text_pos saved_pos;
19371 Lisp_Object saved_object;
19372 enum display_element_type saved_what = it->what;
19373 int saved_face_id = it->face_id;
19375 saved_object = it->object;
19376 saved_pos = it->position;
19378 it->what = IT_CHARACTER;
19379 memset (&it->position, 0, sizeof it->position);
19380 it->object = make_number (0);
19381 it->c = it->char_to_display = ' ';
19382 it->len = 1;
19384 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
19385 && (it->glyph_row->used[LEFT_MARGIN_AREA]
19386 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19387 && !it->glyph_row->mode_line_p
19388 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19390 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
19391 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
19393 for (it->current_x = 0; g < e; g++)
19394 it->current_x += g->pixel_width;
19396 it->area = LEFT_MARGIN_AREA;
19397 it->face_id = default_face->id;
19398 while (it->glyph_row->used[LEFT_MARGIN_AREA]
19399 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
19401 PRODUCE_GLYPHS (it);
19402 /* term.c:produce_glyphs advances it->current_x only for
19403 TEXT_AREA. */
19404 it->current_x += it->pixel_width;
19407 it->current_x = saved_x;
19408 it->area = TEXT_AREA;
19411 /* The last row's blank glyphs should get the default face, to
19412 avoid painting the rest of the window with the region face,
19413 if the region ends at ZV. */
19414 if (it->glyph_row->ends_at_zv_p)
19415 it->face_id = default_face->id;
19416 else
19417 it->face_id = face->id;
19418 PRODUCE_GLYPHS (it);
19420 while (it->current_x <= it->last_visible_x)
19421 PRODUCE_GLYPHS (it);
19423 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
19424 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
19425 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19426 && !it->glyph_row->mode_line_p
19427 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
19429 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
19430 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
19432 for ( ; g < e; g++)
19433 it->current_x += g->pixel_width;
19435 it->area = RIGHT_MARGIN_AREA;
19436 it->face_id = default_face->id;
19437 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
19438 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
19440 PRODUCE_GLYPHS (it);
19441 it->current_x += it->pixel_width;
19444 it->area = TEXT_AREA;
19447 /* Don't count these blanks really. It would let us insert a left
19448 truncation glyph below and make us set the cursor on them, maybe. */
19449 it->current_x = saved_x;
19450 it->object = saved_object;
19451 it->position = saved_pos;
19452 it->what = saved_what;
19453 it->face_id = saved_face_id;
19458 /* Value is non-zero if text starting at CHARPOS in current_buffer is
19459 trailing whitespace. */
19461 static int
19462 trailing_whitespace_p (ptrdiff_t charpos)
19464 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
19465 int c = 0;
19467 while (bytepos < ZV_BYTE
19468 && (c = FETCH_CHAR (bytepos),
19469 c == ' ' || c == '\t'))
19470 ++bytepos;
19472 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
19474 if (bytepos != PT_BYTE)
19475 return 1;
19477 return 0;
19481 /* Highlight trailing whitespace, if any, in ROW. */
19483 static void
19484 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
19486 int used = row->used[TEXT_AREA];
19488 if (used)
19490 struct glyph *start = row->glyphs[TEXT_AREA];
19491 struct glyph *glyph = start + used - 1;
19493 if (row->reversed_p)
19495 /* Right-to-left rows need to be processed in the opposite
19496 direction, so swap the edge pointers. */
19497 glyph = start;
19498 start = row->glyphs[TEXT_AREA] + used - 1;
19501 /* Skip over glyphs inserted to display the cursor at the
19502 end of a line, for extending the face of the last glyph
19503 to the end of the line on terminals, and for truncation
19504 and continuation glyphs. */
19505 if (!row->reversed_p)
19507 while (glyph >= start
19508 && glyph->type == CHAR_GLYPH
19509 && INTEGERP (glyph->object))
19510 --glyph;
19512 else
19514 while (glyph <= start
19515 && glyph->type == CHAR_GLYPH
19516 && INTEGERP (glyph->object))
19517 ++glyph;
19520 /* If last glyph is a space or stretch, and it's trailing
19521 whitespace, set the face of all trailing whitespace glyphs in
19522 IT->glyph_row to `trailing-whitespace'. */
19523 if ((row->reversed_p ? glyph <= start : glyph >= start)
19524 && BUFFERP (glyph->object)
19525 && (glyph->type == STRETCH_GLYPH
19526 || (glyph->type == CHAR_GLYPH
19527 && glyph->u.ch == ' '))
19528 && trailing_whitespace_p (glyph->charpos))
19530 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
19531 if (face_id < 0)
19532 return;
19534 if (!row->reversed_p)
19536 while (glyph >= start
19537 && BUFFERP (glyph->object)
19538 && (glyph->type == STRETCH_GLYPH
19539 || (glyph->type == CHAR_GLYPH
19540 && glyph->u.ch == ' ')))
19541 (glyph--)->face_id = face_id;
19543 else
19545 while (glyph <= start
19546 && BUFFERP (glyph->object)
19547 && (glyph->type == STRETCH_GLYPH
19548 || (glyph->type == CHAR_GLYPH
19549 && glyph->u.ch == ' ')))
19550 (glyph++)->face_id = face_id;
19557 /* Value is non-zero if glyph row ROW should be
19558 considered to hold the buffer position CHARPOS. */
19560 static int
19561 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
19563 int result = 1;
19565 if (charpos == CHARPOS (row->end.pos)
19566 || charpos == MATRIX_ROW_END_CHARPOS (row))
19568 /* Suppose the row ends on a string.
19569 Unless the row is continued, that means it ends on a newline
19570 in the string. If it's anything other than a display string
19571 (e.g., a before-string from an overlay), we don't want the
19572 cursor there. (This heuristic seems to give the optimal
19573 behavior for the various types of multi-line strings.)
19574 One exception: if the string has `cursor' property on one of
19575 its characters, we _do_ want the cursor there. */
19576 if (CHARPOS (row->end.string_pos) >= 0)
19578 if (row->continued_p)
19579 result = 1;
19580 else
19582 /* Check for `display' property. */
19583 struct glyph *beg = row->glyphs[TEXT_AREA];
19584 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
19585 struct glyph *glyph;
19587 result = 0;
19588 for (glyph = end; glyph >= beg; --glyph)
19589 if (STRINGP (glyph->object))
19591 Lisp_Object prop
19592 = Fget_char_property (make_number (charpos),
19593 Qdisplay, Qnil);
19594 result =
19595 (!NILP (prop)
19596 && display_prop_string_p (prop, glyph->object));
19597 /* If there's a `cursor' property on one of the
19598 string's characters, this row is a cursor row,
19599 even though this is not a display string. */
19600 if (!result)
19602 Lisp_Object s = glyph->object;
19604 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
19606 ptrdiff_t gpos = glyph->charpos;
19608 if (!NILP (Fget_char_property (make_number (gpos),
19609 Qcursor, s)))
19611 result = 1;
19612 break;
19616 break;
19620 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
19622 /* If the row ends in middle of a real character,
19623 and the line is continued, we want the cursor here.
19624 That's because CHARPOS (ROW->end.pos) would equal
19625 PT if PT is before the character. */
19626 if (!row->ends_in_ellipsis_p)
19627 result = row->continued_p;
19628 else
19629 /* If the row ends in an ellipsis, then
19630 CHARPOS (ROW->end.pos) will equal point after the
19631 invisible text. We want that position to be displayed
19632 after the ellipsis. */
19633 result = 0;
19635 /* If the row ends at ZV, display the cursor at the end of that
19636 row instead of at the start of the row below. */
19637 else if (row->ends_at_zv_p)
19638 result = 1;
19639 else
19640 result = 0;
19643 return result;
19646 /* Value is non-zero if glyph row ROW should be
19647 used to hold the cursor. */
19649 static int
19650 cursor_row_p (struct glyph_row *row)
19652 return row_for_charpos_p (row, PT);
19657 /* Push the property PROP so that it will be rendered at the current
19658 position in IT. Return 1 if PROP was successfully pushed, 0
19659 otherwise. Called from handle_line_prefix to handle the
19660 `line-prefix' and `wrap-prefix' properties. */
19662 static int
19663 push_prefix_prop (struct it *it, Lisp_Object prop)
19665 struct text_pos pos =
19666 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
19668 eassert (it->method == GET_FROM_BUFFER
19669 || it->method == GET_FROM_DISPLAY_VECTOR
19670 || it->method == GET_FROM_STRING);
19672 /* We need to save the current buffer/string position, so it will be
19673 restored by pop_it, because iterate_out_of_display_property
19674 depends on that being set correctly, but some situations leave
19675 it->position not yet set when this function is called. */
19676 push_it (it, &pos);
19678 if (STRINGP (prop))
19680 if (SCHARS (prop) == 0)
19682 pop_it (it);
19683 return 0;
19686 it->string = prop;
19687 it->string_from_prefix_prop_p = 1;
19688 it->multibyte_p = STRING_MULTIBYTE (it->string);
19689 it->current.overlay_string_index = -1;
19690 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19691 it->end_charpos = it->string_nchars = SCHARS (it->string);
19692 it->method = GET_FROM_STRING;
19693 it->stop_charpos = 0;
19694 it->prev_stop = 0;
19695 it->base_level_stop = 0;
19697 /* Force paragraph direction to be that of the parent
19698 buffer/string. */
19699 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19700 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19701 else
19702 it->paragraph_embedding = L2R;
19704 /* Set up the bidi iterator for this display string. */
19705 if (it->bidi_p)
19707 it->bidi_it.string.lstring = it->string;
19708 it->bidi_it.string.s = NULL;
19709 it->bidi_it.string.schars = it->end_charpos;
19710 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19711 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19712 it->bidi_it.string.unibyte = !it->multibyte_p;
19713 it->bidi_it.w = it->w;
19714 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19717 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19719 it->method = GET_FROM_STRETCH;
19720 it->object = prop;
19722 #ifdef HAVE_WINDOW_SYSTEM
19723 else if (IMAGEP (prop))
19725 it->what = IT_IMAGE;
19726 it->image_id = lookup_image (it->f, prop);
19727 it->method = GET_FROM_IMAGE;
19729 #endif /* HAVE_WINDOW_SYSTEM */
19730 else
19732 pop_it (it); /* bogus display property, give up */
19733 return 0;
19736 return 1;
19739 /* Return the character-property PROP at the current position in IT. */
19741 static Lisp_Object
19742 get_it_property (struct it *it, Lisp_Object prop)
19744 Lisp_Object position, object = it->object;
19746 if (STRINGP (object))
19747 position = make_number (IT_STRING_CHARPOS (*it));
19748 else if (BUFFERP (object))
19750 position = make_number (IT_CHARPOS (*it));
19751 object = it->window;
19753 else
19754 return Qnil;
19756 return Fget_char_property (position, prop, object);
19759 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19761 static void
19762 handle_line_prefix (struct it *it)
19764 Lisp_Object prefix;
19766 if (it->continuation_lines_width > 0)
19768 prefix = get_it_property (it, Qwrap_prefix);
19769 if (NILP (prefix))
19770 prefix = Vwrap_prefix;
19772 else
19774 prefix = get_it_property (it, Qline_prefix);
19775 if (NILP (prefix))
19776 prefix = Vline_prefix;
19778 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19780 /* If the prefix is wider than the window, and we try to wrap
19781 it, it would acquire its own wrap prefix, and so on till the
19782 iterator stack overflows. So, don't wrap the prefix. */
19783 it->line_wrap = TRUNCATE;
19784 it->avoid_cursor_p = 1;
19790 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19791 only for R2L lines from display_line and display_string, when they
19792 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19793 the line/string needs to be continued on the next glyph row. */
19794 static void
19795 unproduce_glyphs (struct it *it, int n)
19797 struct glyph *glyph, *end;
19799 eassert (it->glyph_row);
19800 eassert (it->glyph_row->reversed_p);
19801 eassert (it->area == TEXT_AREA);
19802 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19804 if (n > it->glyph_row->used[TEXT_AREA])
19805 n = it->glyph_row->used[TEXT_AREA];
19806 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19807 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19808 for ( ; glyph < end; glyph++)
19809 glyph[-n] = *glyph;
19812 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19813 and ROW->maxpos. */
19814 static void
19815 find_row_edges (struct it *it, struct glyph_row *row,
19816 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19817 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19819 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19820 lines' rows is implemented for bidi-reordered rows. */
19822 /* ROW->minpos is the value of min_pos, the minimal buffer position
19823 we have in ROW, or ROW->start.pos if that is smaller. */
19824 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19825 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19826 else
19827 /* We didn't find buffer positions smaller than ROW->start, or
19828 didn't find _any_ valid buffer positions in any of the glyphs,
19829 so we must trust the iterator's computed positions. */
19830 row->minpos = row->start.pos;
19831 if (max_pos <= 0)
19833 max_pos = CHARPOS (it->current.pos);
19834 max_bpos = BYTEPOS (it->current.pos);
19837 /* Here are the various use-cases for ending the row, and the
19838 corresponding values for ROW->maxpos:
19840 Line ends in a newline from buffer eol_pos + 1
19841 Line is continued from buffer max_pos + 1
19842 Line is truncated on right it->current.pos
19843 Line ends in a newline from string max_pos + 1(*)
19844 (*) + 1 only when line ends in a forward scan
19845 Line is continued from string max_pos
19846 Line is continued from display vector max_pos
19847 Line is entirely from a string min_pos == max_pos
19848 Line is entirely from a display vector min_pos == max_pos
19849 Line that ends at ZV ZV
19851 If you discover other use-cases, please add them here as
19852 appropriate. */
19853 if (row->ends_at_zv_p)
19854 row->maxpos = it->current.pos;
19855 else if (row->used[TEXT_AREA])
19857 int seen_this_string = 0;
19858 struct glyph_row *r1 = row - 1;
19860 /* Did we see the same display string on the previous row? */
19861 if (STRINGP (it->object)
19862 /* this is not the first row */
19863 && row > it->w->desired_matrix->rows
19864 /* previous row is not the header line */
19865 && !r1->mode_line_p
19866 /* previous row also ends in a newline from a string */
19867 && r1->ends_in_newline_from_string_p)
19869 struct glyph *start, *end;
19871 /* Search for the last glyph of the previous row that came
19872 from buffer or string. Depending on whether the row is
19873 L2R or R2L, we need to process it front to back or the
19874 other way round. */
19875 if (!r1->reversed_p)
19877 start = r1->glyphs[TEXT_AREA];
19878 end = start + r1->used[TEXT_AREA];
19879 /* Glyphs inserted by redisplay have an integer (zero)
19880 as their object. */
19881 while (end > start
19882 && INTEGERP ((end - 1)->object)
19883 && (end - 1)->charpos <= 0)
19884 --end;
19885 if (end > start)
19887 if (EQ ((end - 1)->object, it->object))
19888 seen_this_string = 1;
19890 else
19891 /* If all the glyphs of the previous row were inserted
19892 by redisplay, it means the previous row was
19893 produced from a single newline, which is only
19894 possible if that newline came from the same string
19895 as the one which produced this ROW. */
19896 seen_this_string = 1;
19898 else
19900 end = r1->glyphs[TEXT_AREA] - 1;
19901 start = end + r1->used[TEXT_AREA];
19902 while (end < start
19903 && INTEGERP ((end + 1)->object)
19904 && (end + 1)->charpos <= 0)
19905 ++end;
19906 if (end < start)
19908 if (EQ ((end + 1)->object, it->object))
19909 seen_this_string = 1;
19911 else
19912 seen_this_string = 1;
19915 /* Take note of each display string that covers a newline only
19916 once, the first time we see it. This is for when a display
19917 string includes more than one newline in it. */
19918 if (row->ends_in_newline_from_string_p && !seen_this_string)
19920 /* If we were scanning the buffer forward when we displayed
19921 the string, we want to account for at least one buffer
19922 position that belongs to this row (position covered by
19923 the display string), so that cursor positioning will
19924 consider this row as a candidate when point is at the end
19925 of the visual line represented by this row. This is not
19926 required when scanning back, because max_pos will already
19927 have a much larger value. */
19928 if (CHARPOS (row->end.pos) > max_pos)
19929 INC_BOTH (max_pos, max_bpos);
19930 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19932 else if (CHARPOS (it->eol_pos) > 0)
19933 SET_TEXT_POS (row->maxpos,
19934 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19935 else if (row->continued_p)
19937 /* If max_pos is different from IT's current position, it
19938 means IT->method does not belong to the display element
19939 at max_pos. However, it also means that the display
19940 element at max_pos was displayed in its entirety on this
19941 line, which is equivalent to saying that the next line
19942 starts at the next buffer position. */
19943 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19944 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19945 else
19947 INC_BOTH (max_pos, max_bpos);
19948 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19951 else if (row->truncated_on_right_p)
19952 /* display_line already called reseat_at_next_visible_line_start,
19953 which puts the iterator at the beginning of the next line, in
19954 the logical order. */
19955 row->maxpos = it->current.pos;
19956 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19957 /* A line that is entirely from a string/image/stretch... */
19958 row->maxpos = row->minpos;
19959 else
19960 emacs_abort ();
19962 else
19963 row->maxpos = it->current.pos;
19966 /* Construct the glyph row IT->glyph_row in the desired matrix of
19967 IT->w from text at the current position of IT. See dispextern.h
19968 for an overview of struct it. Value is non-zero if
19969 IT->glyph_row displays text, as opposed to a line displaying ZV
19970 only. */
19972 static int
19973 display_line (struct it *it)
19975 struct glyph_row *row = it->glyph_row;
19976 Lisp_Object overlay_arrow_string;
19977 struct it wrap_it;
19978 void *wrap_data = NULL;
19979 int may_wrap = 0, wrap_x IF_LINT (= 0);
19980 int wrap_row_used = -1;
19981 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19982 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19983 int wrap_row_extra_line_spacing IF_LINT (= 0);
19984 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19985 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19986 int cvpos;
19987 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19988 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19989 bool pending_handle_line_prefix = false;
19991 /* We always start displaying at hpos zero even if hscrolled. */
19992 eassert (it->hpos == 0 && it->current_x == 0);
19994 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19995 >= it->w->desired_matrix->nrows)
19997 it->w->nrows_scale_factor++;
19998 it->f->fonts_changed = 1;
19999 return 0;
20002 /* Clear the result glyph row and enable it. */
20003 prepare_desired_row (it->w, row, false);
20005 row->y = it->current_y;
20006 row->start = it->start;
20007 row->continuation_lines_width = it->continuation_lines_width;
20008 row->displays_text_p = 1;
20009 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
20010 it->starts_in_middle_of_char_p = 0;
20012 /* Arrange the overlays nicely for our purposes. Usually, we call
20013 display_line on only one line at a time, in which case this
20014 can't really hurt too much, or we call it on lines which appear
20015 one after another in the buffer, in which case all calls to
20016 recenter_overlay_lists but the first will be pretty cheap. */
20017 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20019 /* Move over display elements that are not visible because we are
20020 hscrolled. This may stop at an x-position < IT->first_visible_x
20021 if the first glyph is partially visible or if we hit a line end. */
20022 if (it->current_x < it->first_visible_x)
20024 enum move_it_result move_result;
20026 this_line_min_pos = row->start.pos;
20027 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
20028 MOVE_TO_POS | MOVE_TO_X);
20029 /* If we are under a large hscroll, move_it_in_display_line_to
20030 could hit the end of the line without reaching
20031 it->first_visible_x. Pretend that we did reach it. This is
20032 especially important on a TTY, where we will call
20033 extend_face_to_end_of_line, which needs to know how many
20034 blank glyphs to produce. */
20035 if (it->current_x < it->first_visible_x
20036 && (move_result == MOVE_NEWLINE_OR_CR
20037 || move_result == MOVE_POS_MATCH_OR_ZV))
20038 it->current_x = it->first_visible_x;
20040 /* Record the smallest positions seen while we moved over
20041 display elements that are not visible. This is needed by
20042 redisplay_internal for optimizing the case where the cursor
20043 stays inside the same line. The rest of this function only
20044 considers positions that are actually displayed, so
20045 RECORD_MAX_MIN_POS will not otherwise record positions that
20046 are hscrolled to the left of the left edge of the window. */
20047 min_pos = CHARPOS (this_line_min_pos);
20048 min_bpos = BYTEPOS (this_line_min_pos);
20050 else if (it->area == TEXT_AREA)
20052 /* We only do this when not calling move_it_in_display_line_to
20053 above, because that function calls itself handle_line_prefix. */
20054 handle_line_prefix (it);
20056 else
20058 /* Line-prefix and wrap-prefix are always displayed in the text
20059 area. But if this is the first call to display_line after
20060 init_iterator, the iterator might have been set up to write
20061 into a marginal area, e.g. if the line begins with some
20062 display property that writes to the margins. So we need to
20063 wait with the call to handle_line_prefix until whatever
20064 writes to the margin has done its job. */
20065 pending_handle_line_prefix = true;
20068 /* Get the initial row height. This is either the height of the
20069 text hscrolled, if there is any, or zero. */
20070 row->ascent = it->max_ascent;
20071 row->height = it->max_ascent + it->max_descent;
20072 row->phys_ascent = it->max_phys_ascent;
20073 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20074 row->extra_line_spacing = it->max_extra_line_spacing;
20076 /* Utility macro to record max and min buffer positions seen until now. */
20077 #define RECORD_MAX_MIN_POS(IT) \
20078 do \
20080 int composition_p = !STRINGP ((IT)->string) \
20081 && ((IT)->what == IT_COMPOSITION); \
20082 ptrdiff_t current_pos = \
20083 composition_p ? (IT)->cmp_it.charpos \
20084 : IT_CHARPOS (*(IT)); \
20085 ptrdiff_t current_bpos = \
20086 composition_p ? CHAR_TO_BYTE (current_pos) \
20087 : IT_BYTEPOS (*(IT)); \
20088 if (current_pos < min_pos) \
20090 min_pos = current_pos; \
20091 min_bpos = current_bpos; \
20093 if (IT_CHARPOS (*it) > max_pos) \
20095 max_pos = IT_CHARPOS (*it); \
20096 max_bpos = IT_BYTEPOS (*it); \
20099 while (0)
20101 /* Loop generating characters. The loop is left with IT on the next
20102 character to display. */
20103 while (1)
20105 int n_glyphs_before, hpos_before, x_before;
20106 int x, nglyphs;
20107 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
20109 /* Retrieve the next thing to display. Value is zero if end of
20110 buffer reached. */
20111 if (!get_next_display_element (it))
20113 /* Maybe add a space at the end of this line that is used to
20114 display the cursor there under X. Set the charpos of the
20115 first glyph of blank lines not corresponding to any text
20116 to -1. */
20117 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20118 row->exact_window_width_line_p = 1;
20119 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
20120 || row->used[TEXT_AREA] == 0)
20122 row->glyphs[TEXT_AREA]->charpos = -1;
20123 row->displays_text_p = 0;
20125 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
20126 && (!MINI_WINDOW_P (it->w)
20127 || (minibuf_level && EQ (it->window, minibuf_window))))
20128 row->indicate_empty_line_p = 1;
20131 it->continuation_lines_width = 0;
20132 row->ends_at_zv_p = 1;
20133 /* A row that displays right-to-left text must always have
20134 its last face extended all the way to the end of line,
20135 even if this row ends in ZV, because we still write to
20136 the screen left to right. We also need to extend the
20137 last face if the default face is remapped to some
20138 different face, otherwise the functions that clear
20139 portions of the screen will clear with the default face's
20140 background color. */
20141 if (row->reversed_p
20142 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
20143 extend_face_to_end_of_line (it);
20144 break;
20147 /* Now, get the metrics of what we want to display. This also
20148 generates glyphs in `row' (which is IT->glyph_row). */
20149 n_glyphs_before = row->used[TEXT_AREA];
20150 x = it->current_x;
20152 /* Remember the line height so far in case the next element doesn't
20153 fit on the line. */
20154 if (it->line_wrap != TRUNCATE)
20156 ascent = it->max_ascent;
20157 descent = it->max_descent;
20158 phys_ascent = it->max_phys_ascent;
20159 phys_descent = it->max_phys_descent;
20161 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
20163 if (IT_DISPLAYING_WHITESPACE (it))
20164 may_wrap = 1;
20165 else if (may_wrap)
20167 SAVE_IT (wrap_it, *it, wrap_data);
20168 wrap_x = x;
20169 wrap_row_used = row->used[TEXT_AREA];
20170 wrap_row_ascent = row->ascent;
20171 wrap_row_height = row->height;
20172 wrap_row_phys_ascent = row->phys_ascent;
20173 wrap_row_phys_height = row->phys_height;
20174 wrap_row_extra_line_spacing = row->extra_line_spacing;
20175 wrap_row_min_pos = min_pos;
20176 wrap_row_min_bpos = min_bpos;
20177 wrap_row_max_pos = max_pos;
20178 wrap_row_max_bpos = max_bpos;
20179 may_wrap = 0;
20184 PRODUCE_GLYPHS (it);
20186 /* If this display element was in marginal areas, continue with
20187 the next one. */
20188 if (it->area != TEXT_AREA)
20190 row->ascent = max (row->ascent, it->max_ascent);
20191 row->height = max (row->height, it->max_ascent + it->max_descent);
20192 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20193 row->phys_height = max (row->phys_height,
20194 it->max_phys_ascent + it->max_phys_descent);
20195 row->extra_line_spacing = max (row->extra_line_spacing,
20196 it->max_extra_line_spacing);
20197 set_iterator_to_next (it, 1);
20198 /* If we didn't handle the line/wrap prefix above, and the
20199 call to set_iterator_to_next just switched to TEXT_AREA,
20200 process the prefix now. */
20201 if (it->area == TEXT_AREA && pending_handle_line_prefix)
20203 pending_handle_line_prefix = false;
20204 handle_line_prefix (it);
20206 continue;
20209 /* Does the display element fit on the line? If we truncate
20210 lines, we should draw past the right edge of the window. If
20211 we don't truncate, we want to stop so that we can display the
20212 continuation glyph before the right margin. If lines are
20213 continued, there are two possible strategies for characters
20214 resulting in more than 1 glyph (e.g. tabs): Display as many
20215 glyphs as possible in this line and leave the rest for the
20216 continuation line, or display the whole element in the next
20217 line. Original redisplay did the former, so we do it also. */
20218 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20219 hpos_before = it->hpos;
20220 x_before = x;
20222 if (/* Not a newline. */
20223 nglyphs > 0
20224 /* Glyphs produced fit entirely in the line. */
20225 && it->current_x < it->last_visible_x)
20227 it->hpos += nglyphs;
20228 row->ascent = max (row->ascent, it->max_ascent);
20229 row->height = max (row->height, it->max_ascent + it->max_descent);
20230 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20231 row->phys_height = max (row->phys_height,
20232 it->max_phys_ascent + it->max_phys_descent);
20233 row->extra_line_spacing = max (row->extra_line_spacing,
20234 it->max_extra_line_spacing);
20235 if (it->current_x - it->pixel_width < it->first_visible_x
20236 /* In R2L rows, we arrange in extend_face_to_end_of_line
20237 to add a right offset to the line, by a suitable
20238 change to the stretch glyph that is the leftmost
20239 glyph of the line. */
20240 && !row->reversed_p)
20241 row->x = x - it->first_visible_x;
20242 /* Record the maximum and minimum buffer positions seen so
20243 far in glyphs that will be displayed by this row. */
20244 if (it->bidi_p)
20245 RECORD_MAX_MIN_POS (it);
20247 else
20249 int i, new_x;
20250 struct glyph *glyph;
20252 for (i = 0; i < nglyphs; ++i, x = new_x)
20254 /* Identify the glyphs added by the last call to
20255 PRODUCE_GLYPHS. In R2L rows, they are prepended to
20256 the previous glyphs. */
20257 if (!row->reversed_p)
20258 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20259 else
20260 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
20261 new_x = x + glyph->pixel_width;
20263 if (/* Lines are continued. */
20264 it->line_wrap != TRUNCATE
20265 && (/* Glyph doesn't fit on the line. */
20266 new_x > it->last_visible_x
20267 /* Or it fits exactly on a window system frame. */
20268 || (new_x == it->last_visible_x
20269 && FRAME_WINDOW_P (it->f)
20270 && (row->reversed_p
20271 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20272 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
20274 /* End of a continued line. */
20276 if (it->hpos == 0
20277 || (new_x == it->last_visible_x
20278 && FRAME_WINDOW_P (it->f)
20279 && (row->reversed_p
20280 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20281 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
20283 /* Current glyph is the only one on the line or
20284 fits exactly on the line. We must continue
20285 the line because we can't draw the cursor
20286 after the glyph. */
20287 row->continued_p = 1;
20288 it->current_x = new_x;
20289 it->continuation_lines_width += new_x;
20290 ++it->hpos;
20291 if (i == nglyphs - 1)
20293 /* If line-wrap is on, check if a previous
20294 wrap point was found. */
20295 if (wrap_row_used > 0
20296 /* Even if there is a previous wrap
20297 point, continue the line here as
20298 usual, if (i) the previous character
20299 was a space or tab AND (ii) the
20300 current character is not. */
20301 && (!may_wrap
20302 || IT_DISPLAYING_WHITESPACE (it)))
20303 goto back_to_wrap;
20305 /* Record the maximum and minimum buffer
20306 positions seen so far in glyphs that will be
20307 displayed by this row. */
20308 if (it->bidi_p)
20309 RECORD_MAX_MIN_POS (it);
20310 set_iterator_to_next (it, 1);
20311 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20313 if (!get_next_display_element (it))
20315 row->exact_window_width_line_p = 1;
20316 it->continuation_lines_width = 0;
20317 row->continued_p = 0;
20318 row->ends_at_zv_p = 1;
20320 else if (ITERATOR_AT_END_OF_LINE_P (it))
20322 row->continued_p = 0;
20323 row->exact_window_width_line_p = 1;
20327 else if (it->bidi_p)
20328 RECORD_MAX_MIN_POS (it);
20329 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20330 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20331 extend_face_to_end_of_line (it);
20333 else if (CHAR_GLYPH_PADDING_P (*glyph)
20334 && !FRAME_WINDOW_P (it->f))
20336 /* A padding glyph that doesn't fit on this line.
20337 This means the whole character doesn't fit
20338 on the line. */
20339 if (row->reversed_p)
20340 unproduce_glyphs (it, row->used[TEXT_AREA]
20341 - n_glyphs_before);
20342 row->used[TEXT_AREA] = n_glyphs_before;
20344 /* Fill the rest of the row with continuation
20345 glyphs like in 20.x. */
20346 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
20347 < row->glyphs[1 + TEXT_AREA])
20348 produce_special_glyphs (it, IT_CONTINUATION);
20350 row->continued_p = 1;
20351 it->current_x = x_before;
20352 it->continuation_lines_width += x_before;
20354 /* Restore the height to what it was before the
20355 element not fitting on the line. */
20356 it->max_ascent = ascent;
20357 it->max_descent = descent;
20358 it->max_phys_ascent = phys_ascent;
20359 it->max_phys_descent = phys_descent;
20360 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20361 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20362 extend_face_to_end_of_line (it);
20364 else if (wrap_row_used > 0)
20366 back_to_wrap:
20367 if (row->reversed_p)
20368 unproduce_glyphs (it,
20369 row->used[TEXT_AREA] - wrap_row_used);
20370 RESTORE_IT (it, &wrap_it, wrap_data);
20371 it->continuation_lines_width += wrap_x;
20372 row->used[TEXT_AREA] = wrap_row_used;
20373 row->ascent = wrap_row_ascent;
20374 row->height = wrap_row_height;
20375 row->phys_ascent = wrap_row_phys_ascent;
20376 row->phys_height = wrap_row_phys_height;
20377 row->extra_line_spacing = wrap_row_extra_line_spacing;
20378 min_pos = wrap_row_min_pos;
20379 min_bpos = wrap_row_min_bpos;
20380 max_pos = wrap_row_max_pos;
20381 max_bpos = wrap_row_max_bpos;
20382 row->continued_p = 1;
20383 row->ends_at_zv_p = 0;
20384 row->exact_window_width_line_p = 0;
20385 it->continuation_lines_width += x;
20387 /* Make sure that a non-default face is extended
20388 up to the right margin of the window. */
20389 extend_face_to_end_of_line (it);
20391 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
20393 /* A TAB that extends past the right edge of the
20394 window. This produces a single glyph on
20395 window system frames. We leave the glyph in
20396 this row and let it fill the row, but don't
20397 consume the TAB. */
20398 if ((row->reversed_p
20399 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20400 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20401 produce_special_glyphs (it, IT_CONTINUATION);
20402 it->continuation_lines_width += it->last_visible_x;
20403 row->ends_in_middle_of_char_p = 1;
20404 row->continued_p = 1;
20405 glyph->pixel_width = it->last_visible_x - x;
20406 it->starts_in_middle_of_char_p = 1;
20407 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20408 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
20409 extend_face_to_end_of_line (it);
20411 else
20413 /* Something other than a TAB that draws past
20414 the right edge of the window. Restore
20415 positions to values before the element. */
20416 if (row->reversed_p)
20417 unproduce_glyphs (it, row->used[TEXT_AREA]
20418 - (n_glyphs_before + i));
20419 row->used[TEXT_AREA] = n_glyphs_before + i;
20421 /* Display continuation glyphs. */
20422 it->current_x = x_before;
20423 it->continuation_lines_width += x;
20424 if (!FRAME_WINDOW_P (it->f)
20425 || (row->reversed_p
20426 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20427 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20428 produce_special_glyphs (it, IT_CONTINUATION);
20429 row->continued_p = 1;
20431 extend_face_to_end_of_line (it);
20433 if (nglyphs > 1 && i > 0)
20435 row->ends_in_middle_of_char_p = 1;
20436 it->starts_in_middle_of_char_p = 1;
20439 /* Restore the height to what it was before the
20440 element not fitting on the line. */
20441 it->max_ascent = ascent;
20442 it->max_descent = descent;
20443 it->max_phys_ascent = phys_ascent;
20444 it->max_phys_descent = phys_descent;
20447 break;
20449 else if (new_x > it->first_visible_x)
20451 /* Increment number of glyphs actually displayed. */
20452 ++it->hpos;
20454 /* Record the maximum and minimum buffer positions
20455 seen so far in glyphs that will be displayed by
20456 this row. */
20457 if (it->bidi_p)
20458 RECORD_MAX_MIN_POS (it);
20460 if (x < it->first_visible_x && !row->reversed_p)
20461 /* Glyph is partially visible, i.e. row starts at
20462 negative X position. Don't do that in R2L
20463 rows, where we arrange to add a right offset to
20464 the line in extend_face_to_end_of_line, by a
20465 suitable change to the stretch glyph that is
20466 the leftmost glyph of the line. */
20467 row->x = x - it->first_visible_x;
20468 /* When the last glyph of an R2L row only fits
20469 partially on the line, we need to set row->x to a
20470 negative offset, so that the leftmost glyph is
20471 the one that is partially visible. */
20472 if (row->reversed_p && new_x > it->last_visible_x)
20473 row->x = it->last_visible_x - new_x;
20475 else
20477 /* Glyph is completely off the left margin of the
20478 window. This should not happen because of the
20479 move_it_in_display_line at the start of this
20480 function, unless the text display area of the
20481 window is empty. */
20482 eassert (it->first_visible_x <= it->last_visible_x);
20485 /* Even if this display element produced no glyphs at all,
20486 we want to record its position. */
20487 if (it->bidi_p && nglyphs == 0)
20488 RECORD_MAX_MIN_POS (it);
20490 row->ascent = max (row->ascent, it->max_ascent);
20491 row->height = max (row->height, it->max_ascent + it->max_descent);
20492 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20493 row->phys_height = max (row->phys_height,
20494 it->max_phys_ascent + it->max_phys_descent);
20495 row->extra_line_spacing = max (row->extra_line_spacing,
20496 it->max_extra_line_spacing);
20498 /* End of this display line if row is continued. */
20499 if (row->continued_p || row->ends_at_zv_p)
20500 break;
20503 at_end_of_line:
20504 /* Is this a line end? If yes, we're also done, after making
20505 sure that a non-default face is extended up to the right
20506 margin of the window. */
20507 if (ITERATOR_AT_END_OF_LINE_P (it))
20509 int used_before = row->used[TEXT_AREA];
20511 row->ends_in_newline_from_string_p = STRINGP (it->object);
20513 /* Add a space at the end of the line that is used to
20514 display the cursor there. */
20515 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20516 append_space_for_newline (it, 0);
20518 /* Extend the face to the end of the line. */
20519 extend_face_to_end_of_line (it);
20521 /* Make sure we have the position. */
20522 if (used_before == 0)
20523 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
20525 /* Record the position of the newline, for use in
20526 find_row_edges. */
20527 it->eol_pos = it->current.pos;
20529 /* Consume the line end. This skips over invisible lines. */
20530 set_iterator_to_next (it, 1);
20531 it->continuation_lines_width = 0;
20532 break;
20535 /* Proceed with next display element. Note that this skips
20536 over lines invisible because of selective display. */
20537 set_iterator_to_next (it, 1);
20539 /* If we truncate lines, we are done when the last displayed
20540 glyphs reach past the right margin of the window. */
20541 if (it->line_wrap == TRUNCATE
20542 && ((FRAME_WINDOW_P (it->f)
20543 /* Images are preprocessed in produce_image_glyph such
20544 that they are cropped at the right edge of the
20545 window, so an image glyph will always end exactly at
20546 last_visible_x, even if there's no right fringe. */
20547 && (WINDOW_RIGHT_FRINGE_WIDTH (it->w) || it->what == IT_IMAGE))
20548 ? (it->current_x >= it->last_visible_x)
20549 : (it->current_x > it->last_visible_x)))
20551 /* Maybe add truncation glyphs. */
20552 if (!FRAME_WINDOW_P (it->f)
20553 || (row->reversed_p
20554 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20555 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
20557 int i, n;
20559 if (!row->reversed_p)
20561 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
20562 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20563 break;
20565 else
20567 for (i = 0; i < row->used[TEXT_AREA]; i++)
20568 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
20569 break;
20570 /* Remove any padding glyphs at the front of ROW, to
20571 make room for the truncation glyphs we will be
20572 adding below. The loop below always inserts at
20573 least one truncation glyph, so also remove the
20574 last glyph added to ROW. */
20575 unproduce_glyphs (it, i + 1);
20576 /* Adjust i for the loop below. */
20577 i = row->used[TEXT_AREA] - (i + 1);
20580 /* produce_special_glyphs overwrites the last glyph, so
20581 we don't want that if we want to keep that last
20582 glyph, which means it's an image. */
20583 if (it->current_x > it->last_visible_x)
20585 it->current_x = x_before;
20586 if (!FRAME_WINDOW_P (it->f))
20588 for (n = row->used[TEXT_AREA]; i < n; ++i)
20590 row->used[TEXT_AREA] = i;
20591 produce_special_glyphs (it, IT_TRUNCATION);
20594 else
20596 row->used[TEXT_AREA] = i;
20597 produce_special_glyphs (it, IT_TRUNCATION);
20599 it->hpos = hpos_before;
20602 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
20604 /* Don't truncate if we can overflow newline into fringe. */
20605 if (!get_next_display_element (it))
20607 it->continuation_lines_width = 0;
20608 row->ends_at_zv_p = 1;
20609 row->exact_window_width_line_p = 1;
20610 break;
20612 if (ITERATOR_AT_END_OF_LINE_P (it))
20614 row->exact_window_width_line_p = 1;
20615 goto at_end_of_line;
20617 it->current_x = x_before;
20618 it->hpos = hpos_before;
20621 row->truncated_on_right_p = 1;
20622 it->continuation_lines_width = 0;
20623 reseat_at_next_visible_line_start (it, 0);
20624 if (IT_BYTEPOS (*it) <= BEG_BYTE)
20625 row->ends_at_zv_p = true;
20626 else
20627 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
20628 break;
20632 if (wrap_data)
20633 bidi_unshelve_cache (wrap_data, 1);
20635 /* If line is not empty and hscrolled, maybe insert truncation glyphs
20636 at the left window margin. */
20637 if (it->first_visible_x
20638 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
20640 if (!FRAME_WINDOW_P (it->f)
20641 || (((row->reversed_p
20642 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20643 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
20644 /* Don't let insert_left_trunc_glyphs overwrite the
20645 first glyph of the row if it is an image. */
20646 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
20647 insert_left_trunc_glyphs (it);
20648 row->truncated_on_left_p = 1;
20651 /* Remember the position at which this line ends.
20653 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
20654 cannot be before the call to find_row_edges below, since that is
20655 where these positions are determined. */
20656 row->end = it->current;
20657 if (!it->bidi_p)
20659 row->minpos = row->start.pos;
20660 row->maxpos = row->end.pos;
20662 else
20664 /* ROW->minpos and ROW->maxpos must be the smallest and
20665 `1 + the largest' buffer positions in ROW. But if ROW was
20666 bidi-reordered, these two positions can be anywhere in the
20667 row, so we must determine them now. */
20668 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
20671 /* If the start of this line is the overlay arrow-position, then
20672 mark this glyph row as the one containing the overlay arrow.
20673 This is clearly a mess with variable size fonts. It would be
20674 better to let it be displayed like cursors under X. */
20675 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
20676 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
20677 !NILP (overlay_arrow_string)))
20679 /* Overlay arrow in window redisplay is a fringe bitmap. */
20680 if (STRINGP (overlay_arrow_string))
20682 struct glyph_row *arrow_row
20683 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
20684 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
20685 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
20686 struct glyph *p = row->glyphs[TEXT_AREA];
20687 struct glyph *p2, *end;
20689 /* Copy the arrow glyphs. */
20690 while (glyph < arrow_end)
20691 *p++ = *glyph++;
20693 /* Throw away padding glyphs. */
20694 p2 = p;
20695 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
20696 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
20697 ++p2;
20698 if (p2 > p)
20700 while (p2 < end)
20701 *p++ = *p2++;
20702 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
20705 else
20707 eassert (INTEGERP (overlay_arrow_string));
20708 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
20710 overlay_arrow_seen = 1;
20713 /* Highlight trailing whitespace. */
20714 if (!NILP (Vshow_trailing_whitespace))
20715 highlight_trailing_whitespace (it->f, it->glyph_row);
20717 /* Compute pixel dimensions of this line. */
20718 compute_line_metrics (it);
20720 /* Implementation note: No changes in the glyphs of ROW or in their
20721 faces can be done past this point, because compute_line_metrics
20722 computes ROW's hash value and stores it within the glyph_row
20723 structure. */
20725 /* Record whether this row ends inside an ellipsis. */
20726 row->ends_in_ellipsis_p
20727 = (it->method == GET_FROM_DISPLAY_VECTOR
20728 && it->ellipsis_p);
20730 /* Save fringe bitmaps in this row. */
20731 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
20732 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
20733 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
20734 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
20736 it->left_user_fringe_bitmap = 0;
20737 it->left_user_fringe_face_id = 0;
20738 it->right_user_fringe_bitmap = 0;
20739 it->right_user_fringe_face_id = 0;
20741 /* Maybe set the cursor. */
20742 cvpos = it->w->cursor.vpos;
20743 if ((cvpos < 0
20744 /* In bidi-reordered rows, keep checking for proper cursor
20745 position even if one has been found already, because buffer
20746 positions in such rows change non-linearly with ROW->VPOS,
20747 when a line is continued. One exception: when we are at ZV,
20748 display cursor on the first suitable glyph row, since all
20749 the empty rows after that also have their position set to ZV. */
20750 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20751 lines' rows is implemented for bidi-reordered rows. */
20752 || (it->bidi_p
20753 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
20754 && PT >= MATRIX_ROW_START_CHARPOS (row)
20755 && PT <= MATRIX_ROW_END_CHARPOS (row)
20756 && cursor_row_p (row))
20757 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
20759 /* Prepare for the next line. This line starts horizontally at (X
20760 HPOS) = (0 0). Vertical positions are incremented. As a
20761 convenience for the caller, IT->glyph_row is set to the next
20762 row to be used. */
20763 it->current_x = it->hpos = 0;
20764 it->current_y += row->height;
20765 SET_TEXT_POS (it->eol_pos, 0, 0);
20766 ++it->vpos;
20767 ++it->glyph_row;
20768 /* The next row should by default use the same value of the
20769 reversed_p flag as this one. set_iterator_to_next decides when
20770 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20771 the flag accordingly. */
20772 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20773 it->glyph_row->reversed_p = row->reversed_p;
20774 it->start = row->end;
20775 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
20777 #undef RECORD_MAX_MIN_POS
20780 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20781 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20782 doc: /* Return paragraph direction at point in BUFFER.
20783 Value is either `left-to-right' or `right-to-left'.
20784 If BUFFER is omitted or nil, it defaults to the current buffer.
20786 Paragraph direction determines how the text in the paragraph is displayed.
20787 In left-to-right paragraphs, text begins at the left margin of the window
20788 and the reading direction is generally left to right. In right-to-left
20789 paragraphs, text begins at the right margin and is read from right to left.
20791 See also `bidi-paragraph-direction'. */)
20792 (Lisp_Object buffer)
20794 struct buffer *buf = current_buffer;
20795 struct buffer *old = buf;
20797 if (! NILP (buffer))
20799 CHECK_BUFFER (buffer);
20800 buf = XBUFFER (buffer);
20803 if (NILP (BVAR (buf, bidi_display_reordering))
20804 || NILP (BVAR (buf, enable_multibyte_characters))
20805 /* When we are loading loadup.el, the character property tables
20806 needed for bidi iteration are not yet available. */
20807 || !NILP (Vpurify_flag))
20808 return Qleft_to_right;
20809 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20810 return BVAR (buf, bidi_paragraph_direction);
20811 else
20813 /* Determine the direction from buffer text. We could try to
20814 use current_matrix if it is up to date, but this seems fast
20815 enough as it is. */
20816 struct bidi_it itb;
20817 ptrdiff_t pos = BUF_PT (buf);
20818 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20819 int c;
20820 void *itb_data = bidi_shelve_cache ();
20822 set_buffer_temp (buf);
20823 /* bidi_paragraph_init finds the base direction of the paragraph
20824 by searching forward from paragraph start. We need the base
20825 direction of the current or _previous_ paragraph, so we need
20826 to make sure we are within that paragraph. To that end, find
20827 the previous non-empty line. */
20828 if (pos >= ZV && pos > BEGV)
20829 DEC_BOTH (pos, bytepos);
20830 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20831 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20833 while ((c = FETCH_BYTE (bytepos)) == '\n'
20834 || c == ' ' || c == '\t' || c == '\f')
20836 if (bytepos <= BEGV_BYTE)
20837 break;
20838 bytepos--;
20839 pos--;
20841 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20842 bytepos--;
20844 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20845 itb.paragraph_dir = NEUTRAL_DIR;
20846 itb.string.s = NULL;
20847 itb.string.lstring = Qnil;
20848 itb.string.bufpos = 0;
20849 itb.string.from_disp_str = 0;
20850 itb.string.unibyte = 0;
20851 /* We have no window to use here for ignoring window-specific
20852 overlays. Using NULL for window pointer will cause
20853 compute_display_string_pos to use the current buffer. */
20854 itb.w = NULL;
20855 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20856 bidi_unshelve_cache (itb_data, 0);
20857 set_buffer_temp (old);
20858 switch (itb.paragraph_dir)
20860 case L2R:
20861 return Qleft_to_right;
20862 break;
20863 case R2L:
20864 return Qright_to_left;
20865 break;
20866 default:
20867 emacs_abort ();
20872 DEFUN ("move-point-visually", Fmove_point_visually,
20873 Smove_point_visually, 1, 1, 0,
20874 doc: /* Move point in the visual order in the specified DIRECTION.
20875 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
20876 left.
20878 Value is the new character position of point. */)
20879 (Lisp_Object direction)
20881 struct window *w = XWINDOW (selected_window);
20882 struct buffer *b = XBUFFER (w->contents);
20883 struct glyph_row *row;
20884 int dir;
20885 Lisp_Object paragraph_dir;
20887 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
20888 (!(ROW)->continued_p \
20889 && INTEGERP ((GLYPH)->object) \
20890 && (GLYPH)->type == CHAR_GLYPH \
20891 && (GLYPH)->u.ch == ' ' \
20892 && (GLYPH)->charpos >= 0 \
20893 && !(GLYPH)->avoid_cursor_p)
20895 CHECK_NUMBER (direction);
20896 dir = XINT (direction);
20897 if (dir > 0)
20898 dir = 1;
20899 else
20900 dir = -1;
20902 /* If current matrix is up-to-date, we can use the information
20903 recorded in the glyphs, at least as long as the goal is on the
20904 screen. */
20905 if (w->window_end_valid
20906 && !windows_or_buffers_changed
20907 && b
20908 && !b->clip_changed
20909 && !b->prevent_redisplay_optimizations_p
20910 && !window_outdated (w)
20911 /* We rely below on the cursor coordinates to be up to date, but
20912 we cannot trust them if some command moved point since the
20913 last complete redisplay. */
20914 && w->last_point == BUF_PT (b)
20915 && w->cursor.vpos >= 0
20916 && w->cursor.vpos < w->current_matrix->nrows
20917 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
20919 struct glyph *g = row->glyphs[TEXT_AREA];
20920 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
20921 struct glyph *gpt = g + w->cursor.hpos;
20923 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
20925 if (BUFFERP (g->object) && g->charpos != PT)
20927 SET_PT (g->charpos);
20928 w->cursor.vpos = -1;
20929 return make_number (PT);
20931 else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object))
20933 ptrdiff_t new_pos;
20935 if (BUFFERP (gpt->object))
20937 new_pos = PT;
20938 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20939 new_pos += (row->reversed_p ? -dir : dir);
20940 else
20941 new_pos -= (row->reversed_p ? -dir : dir);;
20943 else if (BUFFERP (g->object))
20944 new_pos = g->charpos;
20945 else
20946 break;
20947 SET_PT (new_pos);
20948 w->cursor.vpos = -1;
20949 return make_number (PT);
20951 else if (ROW_GLYPH_NEWLINE_P (row, g))
20953 /* Glyphs inserted at the end of a non-empty line for
20954 positioning the cursor have zero charpos, so we must
20955 deduce the value of point by other means. */
20956 if (g->charpos > 0)
20957 SET_PT (g->charpos);
20958 else if (row->ends_at_zv_p && PT != ZV)
20959 SET_PT (ZV);
20960 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
20961 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20962 else
20963 break;
20964 w->cursor.vpos = -1;
20965 return make_number (PT);
20968 if (g == e || INTEGERP (g->object))
20970 if (row->truncated_on_left_p || row->truncated_on_right_p)
20971 goto simulate_display;
20972 if (!row->reversed_p)
20973 row += dir;
20974 else
20975 row -= dir;
20976 if (row < MATRIX_FIRST_TEXT_ROW (w->current_matrix)
20977 || row > MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
20978 goto simulate_display;
20980 if (dir > 0)
20982 if (row->reversed_p && !row->continued_p)
20984 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
20985 w->cursor.vpos = -1;
20986 return make_number (PT);
20988 g = row->glyphs[TEXT_AREA];
20989 e = g + row->used[TEXT_AREA];
20990 for ( ; g < e; g++)
20992 if (BUFFERP (g->object)
20993 /* Empty lines have only one glyph, which stands
20994 for the newline, and whose charpos is the
20995 buffer position of the newline. */
20996 || ROW_GLYPH_NEWLINE_P (row, g)
20997 /* When the buffer ends in a newline, the line at
20998 EOB also has one glyph, but its charpos is -1. */
20999 || (row->ends_at_zv_p
21000 && !row->reversed_p
21001 && INTEGERP (g->object)
21002 && g->type == CHAR_GLYPH
21003 && g->u.ch == ' '))
21005 if (g->charpos > 0)
21006 SET_PT (g->charpos);
21007 else if (!row->reversed_p
21008 && row->ends_at_zv_p
21009 && PT != ZV)
21010 SET_PT (ZV);
21011 else
21012 continue;
21013 w->cursor.vpos = -1;
21014 return make_number (PT);
21018 else
21020 if (!row->reversed_p && !row->continued_p)
21022 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
21023 w->cursor.vpos = -1;
21024 return make_number (PT);
21026 e = row->glyphs[TEXT_AREA];
21027 g = e + row->used[TEXT_AREA] - 1;
21028 for ( ; g >= e; g--)
21030 if (BUFFERP (g->object)
21031 || (ROW_GLYPH_NEWLINE_P (row, g)
21032 && g->charpos > 0)
21033 /* Empty R2L lines on GUI frames have the buffer
21034 position of the newline stored in the stretch
21035 glyph. */
21036 || g->type == STRETCH_GLYPH
21037 || (row->ends_at_zv_p
21038 && row->reversed_p
21039 && INTEGERP (g->object)
21040 && g->type == CHAR_GLYPH
21041 && g->u.ch == ' '))
21043 if (g->charpos > 0)
21044 SET_PT (g->charpos);
21045 else if (row->reversed_p
21046 && row->ends_at_zv_p
21047 && PT != ZV)
21048 SET_PT (ZV);
21049 else
21050 continue;
21051 w->cursor.vpos = -1;
21052 return make_number (PT);
21059 simulate_display:
21061 /* If we wind up here, we failed to move by using the glyphs, so we
21062 need to simulate display instead. */
21064 if (b)
21065 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
21066 else
21067 paragraph_dir = Qleft_to_right;
21068 if (EQ (paragraph_dir, Qright_to_left))
21069 dir = -dir;
21070 if (PT <= BEGV && dir < 0)
21071 xsignal0 (Qbeginning_of_buffer);
21072 else if (PT >= ZV && dir > 0)
21073 xsignal0 (Qend_of_buffer);
21074 else
21076 struct text_pos pt;
21077 struct it it;
21078 int pt_x, target_x, pixel_width, pt_vpos;
21079 bool at_eol_p;
21080 bool overshoot_expected = false;
21081 bool target_is_eol_p = false;
21083 /* Setup the arena. */
21084 SET_TEXT_POS (pt, PT, PT_BYTE);
21085 start_display (&it, w, pt);
21087 if (it.cmp_it.id < 0
21088 && it.method == GET_FROM_STRING
21089 && it.area == TEXT_AREA
21090 && it.string_from_display_prop_p
21091 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
21092 overshoot_expected = true;
21094 /* Find the X coordinate of point. We start from the beginning
21095 of this or previous line to make sure we are before point in
21096 the logical order (since the move_it_* functions can only
21097 move forward). */
21098 reseat:
21099 reseat_at_previous_visible_line_start (&it);
21100 it.current_x = it.hpos = it.current_y = it.vpos = 0;
21101 if (IT_CHARPOS (it) != PT)
21103 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
21104 -1, -1, -1, MOVE_TO_POS);
21105 /* If we missed point because the character there is
21106 displayed out of a display vector that has more than one
21107 glyph, retry expecting overshoot. */
21108 if (it.method == GET_FROM_DISPLAY_VECTOR
21109 && it.current.dpvec_index > 0
21110 && !overshoot_expected)
21112 overshoot_expected = true;
21113 goto reseat;
21115 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
21116 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
21118 pt_x = it.current_x;
21119 pt_vpos = it.vpos;
21120 if (dir > 0 || overshoot_expected)
21122 struct glyph_row *row = it.glyph_row;
21124 /* When point is at beginning of line, we don't have
21125 information about the glyph there loaded into struct
21126 it. Calling get_next_display_element fixes that. */
21127 if (pt_x == 0)
21128 get_next_display_element (&it);
21129 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21130 it.glyph_row = NULL;
21131 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
21132 it.glyph_row = row;
21133 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
21134 it, lest it will become out of sync with it's buffer
21135 position. */
21136 it.current_x = pt_x;
21138 else
21139 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
21140 pixel_width = it.pixel_width;
21141 if (overshoot_expected && at_eol_p)
21142 pixel_width = 0;
21143 else if (pixel_width <= 0)
21144 pixel_width = 1;
21146 /* If there's a display string (or something similar) at point,
21147 we are actually at the glyph to the left of point, so we need
21148 to correct the X coordinate. */
21149 if (overshoot_expected)
21151 if (it.bidi_p)
21152 pt_x += pixel_width * it.bidi_it.scan_dir;
21153 else
21154 pt_x += pixel_width;
21157 /* Compute target X coordinate, either to the left or to the
21158 right of point. On TTY frames, all characters have the same
21159 pixel width of 1, so we can use that. On GUI frames we don't
21160 have an easy way of getting at the pixel width of the
21161 character to the left of point, so we use a different method
21162 of getting to that place. */
21163 if (dir > 0)
21164 target_x = pt_x + pixel_width;
21165 else
21166 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
21168 /* Target X coordinate could be one line above or below the line
21169 of point, in which case we need to adjust the target X
21170 coordinate. Also, if moving to the left, we need to begin at
21171 the left edge of the point's screen line. */
21172 if (dir < 0)
21174 if (pt_x > 0)
21176 start_display (&it, w, pt);
21177 reseat_at_previous_visible_line_start (&it);
21178 it.current_x = it.current_y = it.hpos = 0;
21179 if (pt_vpos != 0)
21180 move_it_by_lines (&it, pt_vpos);
21182 else
21184 move_it_by_lines (&it, -1);
21185 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
21186 target_is_eol_p = true;
21187 /* Under word-wrap, we don't know the x coordinate of
21188 the last character displayed on the previous line,
21189 which immediately precedes the wrap point. To find
21190 out its x coordinate, we try moving to the right
21191 margin of the window, which will stop at the wrap
21192 point, and then reset target_x to point at the
21193 character that precedes the wrap point. This is not
21194 needed on GUI frames, because (see below) there we
21195 move from the left margin one grapheme cluster at a
21196 time, and stop when we hit the wrap point. */
21197 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
21199 void *it_data = NULL;
21200 struct it it2;
21202 SAVE_IT (it2, it, it_data);
21203 move_it_in_display_line_to (&it, ZV, target_x,
21204 MOVE_TO_POS | MOVE_TO_X);
21205 /* If we arrived at target_x, that _is_ the last
21206 character on the previous line. */
21207 if (it.current_x != target_x)
21208 target_x = it.current_x - 1;
21209 RESTORE_IT (&it, &it2, it_data);
21213 else
21215 if (at_eol_p
21216 || (target_x >= it.last_visible_x
21217 && it.line_wrap != TRUNCATE))
21219 if (pt_x > 0)
21220 move_it_by_lines (&it, 0);
21221 move_it_by_lines (&it, 1);
21222 target_x = 0;
21226 /* Move to the target X coordinate. */
21227 #ifdef HAVE_WINDOW_SYSTEM
21228 /* On GUI frames, as we don't know the X coordinate of the
21229 character to the left of point, moving point to the left
21230 requires walking, one grapheme cluster at a time, until we
21231 find ourself at a place immediately to the left of the
21232 character at point. */
21233 if (FRAME_WINDOW_P (it.f) && dir < 0)
21235 struct text_pos new_pos;
21236 enum move_it_result rc = MOVE_X_REACHED;
21238 if (it.current_x == 0)
21239 get_next_display_element (&it);
21240 if (it.what == IT_COMPOSITION)
21242 new_pos.charpos = it.cmp_it.charpos;
21243 new_pos.bytepos = -1;
21245 else
21246 new_pos = it.current.pos;
21248 while (it.current_x + it.pixel_width <= target_x
21249 && (rc == MOVE_X_REACHED
21250 /* Under word-wrap, move_it_in_display_line_to
21251 stops at correct coordinates, but sometimes
21252 returns MOVE_POS_MATCH_OR_ZV. */
21253 || (it.line_wrap == WORD_WRAP
21254 && rc == MOVE_POS_MATCH_OR_ZV)))
21256 int new_x = it.current_x + it.pixel_width;
21258 /* For composed characters, we want the position of the
21259 first character in the grapheme cluster (usually, the
21260 composition's base character), whereas it.current
21261 might give us the position of the _last_ one, e.g. if
21262 the composition is rendered in reverse due to bidi
21263 reordering. */
21264 if (it.what == IT_COMPOSITION)
21266 new_pos.charpos = it.cmp_it.charpos;
21267 new_pos.bytepos = -1;
21269 else
21270 new_pos = it.current.pos;
21271 if (new_x == it.current_x)
21272 new_x++;
21273 rc = move_it_in_display_line_to (&it, ZV, new_x,
21274 MOVE_TO_POS | MOVE_TO_X);
21275 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
21276 break;
21278 /* The previous position we saw in the loop is the one we
21279 want. */
21280 if (new_pos.bytepos == -1)
21281 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
21282 it.current.pos = new_pos;
21284 else
21285 #endif
21286 if (it.current_x != target_x)
21287 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
21289 /* When lines are truncated, the above loop will stop at the
21290 window edge. But we want to get to the end of line, even if
21291 it is beyond the window edge; automatic hscroll will then
21292 scroll the window to show point as appropriate. */
21293 if (target_is_eol_p && it.line_wrap == TRUNCATE
21294 && get_next_display_element (&it))
21296 struct text_pos new_pos = it.current.pos;
21298 while (!ITERATOR_AT_END_OF_LINE_P (&it))
21300 set_iterator_to_next (&it, 0);
21301 if (it.method == GET_FROM_BUFFER)
21302 new_pos = it.current.pos;
21303 if (!get_next_display_element (&it))
21304 break;
21307 it.current.pos = new_pos;
21310 /* If we ended up in a display string that covers point, move to
21311 buffer position to the right in the visual order. */
21312 if (dir > 0)
21314 while (IT_CHARPOS (it) == PT)
21316 set_iterator_to_next (&it, 0);
21317 if (!get_next_display_element (&it))
21318 break;
21322 /* Move point to that position. */
21323 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
21326 return make_number (PT);
21328 #undef ROW_GLYPH_NEWLINE_P
21331 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
21332 Sbidi_resolved_levels, 0, 1, 0,
21333 doc: /* Return the resolved bidirectional levels of characters at VPOS.
21335 The resolved levels are produced by the Emacs bidi reordering engine
21336 that implements the UBA, the Unicode Bidirectional Algorithm. Please
21337 read the Unicode Standard Annex 9 (UAX#9) for background information
21338 about these levels.
21340 VPOS is the zero-based number of the current window's screen line
21341 for which to produce the resolved levels. If VPOS is nil or omitted,
21342 it defaults to the screen line of point. If the window displays a
21343 header line, VPOS of zero will report on the header line, and first
21344 line of text in the window will have VPOS of 1.
21346 Value is an array of resolved levels, indexed by glyph number.
21347 Glyphs are numbered from zero starting from the beginning of the
21348 screen line, i.e. the left edge of the window for left-to-right lines
21349 and from the right edge for right-to-left lines. The resolved levels
21350 are produced only for the window's text area; text in display margins
21351 is not included.
21353 If the selected window's display is not up-to-date, or if the specified
21354 screen line does not display text, this function returns nil. It is
21355 highly recommended to bind this function to some simple key, like F8,
21356 in order to avoid these problems.
21358 This function exists mainly for testing the correctness of the
21359 Emacs UBA implementation, in particular with the test suite. */)
21360 (Lisp_Object vpos)
21362 struct window *w = XWINDOW (selected_window);
21363 struct buffer *b = XBUFFER (w->contents);
21364 int nrow;
21365 struct glyph_row *row;
21367 if (NILP (vpos))
21369 int d1, d2, d3, d4, d5;
21371 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
21373 else
21375 CHECK_NUMBER_COERCE_MARKER (vpos);
21376 nrow = XINT (vpos);
21379 /* We require up-to-date glyph matrix for this window. */
21380 if (w->window_end_valid
21381 && !windows_or_buffers_changed
21382 && b
21383 && !b->clip_changed
21384 && !b->prevent_redisplay_optimizations_p
21385 && !window_outdated (w)
21386 && nrow >= 0
21387 && nrow < w->current_matrix->nrows
21388 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
21389 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
21391 struct glyph *g, *e, *g1;
21392 int nglyphs, i;
21393 Lisp_Object levels;
21395 if (!row->reversed_p) /* Left-to-right glyph row. */
21397 g = g1 = row->glyphs[TEXT_AREA];
21398 e = g + row->used[TEXT_AREA];
21400 /* Skip over glyphs at the start of the row that was
21401 generated by redisplay for its own needs. */
21402 while (g < e
21403 && INTEGERP (g->object)
21404 && g->charpos < 0)
21405 g++;
21406 g1 = g;
21408 /* Count the "interesting" glyphs in this row. */
21409 for (nglyphs = 0; g < e && !INTEGERP (g->object); g++)
21410 nglyphs++;
21412 /* Create and fill the array. */
21413 levels = make_uninit_vector (nglyphs);
21414 for (i = 0; g1 < g; i++, g1++)
21415 ASET (levels, i, make_number (g1->resolved_level));
21417 else /* Right-to-left glyph row. */
21419 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21420 e = row->glyphs[TEXT_AREA] - 1;
21421 while (g > e
21422 && INTEGERP (g->object)
21423 && g->charpos < 0)
21424 g--;
21425 g1 = g;
21426 for (nglyphs = 0; g > e && !INTEGERP (g->object); g--)
21427 nglyphs++;
21428 levels = make_uninit_vector (nglyphs);
21429 for (i = 0; g1 > g; i++, g1--)
21430 ASET (levels, i, make_number (g1->resolved_level));
21432 return levels;
21434 else
21435 return Qnil;
21440 /***********************************************************************
21441 Menu Bar
21442 ***********************************************************************/
21444 /* Redisplay the menu bar in the frame for window W.
21446 The menu bar of X frames that don't have X toolkit support is
21447 displayed in a special window W->frame->menu_bar_window.
21449 The menu bar of terminal frames is treated specially as far as
21450 glyph matrices are concerned. Menu bar lines are not part of
21451 windows, so the update is done directly on the frame matrix rows
21452 for the menu bar. */
21454 static void
21455 display_menu_bar (struct window *w)
21457 struct frame *f = XFRAME (WINDOW_FRAME (w));
21458 struct it it;
21459 Lisp_Object items;
21460 int i;
21462 /* Don't do all this for graphical frames. */
21463 #ifdef HAVE_NTGUI
21464 if (FRAME_W32_P (f))
21465 return;
21466 #endif
21467 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21468 if (FRAME_X_P (f))
21469 return;
21470 #endif
21472 #ifdef HAVE_NS
21473 if (FRAME_NS_P (f))
21474 return;
21475 #endif /* HAVE_NS */
21477 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
21478 eassert (!FRAME_WINDOW_P (f));
21479 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
21480 it.first_visible_x = 0;
21481 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21482 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
21483 if (FRAME_WINDOW_P (f))
21485 /* Menu bar lines are displayed in the desired matrix of the
21486 dummy window menu_bar_window. */
21487 struct window *menu_w;
21488 menu_w = XWINDOW (f->menu_bar_window);
21489 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
21490 MENU_FACE_ID);
21491 it.first_visible_x = 0;
21492 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
21494 else
21495 #endif /* not USE_X_TOOLKIT and not USE_GTK */
21497 /* This is a TTY frame, i.e. character hpos/vpos are used as
21498 pixel x/y. */
21499 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
21500 MENU_FACE_ID);
21501 it.first_visible_x = 0;
21502 it.last_visible_x = FRAME_COLS (f);
21505 /* FIXME: This should be controlled by a user option. See the
21506 comments in redisplay_tool_bar and display_mode_line about
21507 this. */
21508 it.paragraph_embedding = L2R;
21510 /* Clear all rows of the menu bar. */
21511 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
21513 struct glyph_row *row = it.glyph_row + i;
21514 clear_glyph_row (row);
21515 row->enabled_p = true;
21516 row->full_width_p = 1;
21517 row->reversed_p = false;
21520 /* Display all items of the menu bar. */
21521 items = FRAME_MENU_BAR_ITEMS (it.f);
21522 for (i = 0; i < ASIZE (items); i += 4)
21524 Lisp_Object string;
21526 /* Stop at nil string. */
21527 string = AREF (items, i + 1);
21528 if (NILP (string))
21529 break;
21531 /* Remember where item was displayed. */
21532 ASET (items, i + 3, make_number (it.hpos));
21534 /* Display the item, pad with one space. */
21535 if (it.current_x < it.last_visible_x)
21536 display_string (NULL, string, Qnil, 0, 0, &it,
21537 SCHARS (string) + 1, 0, 0, -1);
21540 /* Fill out the line with spaces. */
21541 if (it.current_x < it.last_visible_x)
21542 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
21544 /* Compute the total height of the lines. */
21545 compute_line_metrics (&it);
21548 /* Deep copy of a glyph row, including the glyphs. */
21549 static void
21550 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
21552 struct glyph *pointers[1 + LAST_AREA];
21553 int to_used = to->used[TEXT_AREA];
21555 /* Save glyph pointers of TO. */
21556 memcpy (pointers, to->glyphs, sizeof to->glyphs);
21558 /* Do a structure assignment. */
21559 *to = *from;
21561 /* Restore original glyph pointers of TO. */
21562 memcpy (to->glyphs, pointers, sizeof to->glyphs);
21564 /* Copy the glyphs. */
21565 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
21566 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
21568 /* If we filled only part of the TO row, fill the rest with
21569 space_glyph (which will display as empty space). */
21570 if (to_used > from->used[TEXT_AREA])
21571 fill_up_frame_row_with_spaces (to, to_used);
21574 /* Display one menu item on a TTY, by overwriting the glyphs in the
21575 frame F's desired glyph matrix with glyphs produced from the menu
21576 item text. Called from term.c to display TTY drop-down menus one
21577 item at a time.
21579 ITEM_TEXT is the menu item text as a C string.
21581 FACE_ID is the face ID to be used for this menu item. FACE_ID
21582 could specify one of 3 faces: a face for an enabled item, a face
21583 for a disabled item, or a face for a selected item.
21585 X and Y are coordinates of the first glyph in the frame's desired
21586 matrix to be overwritten by the menu item. Since this is a TTY, Y
21587 is the zero-based number of the glyph row and X is the zero-based
21588 glyph number in the row, starting from left, where to start
21589 displaying the item.
21591 SUBMENU non-zero means this menu item drops down a submenu, which
21592 should be indicated by displaying a proper visual cue after the
21593 item text. */
21595 void
21596 display_tty_menu_item (const char *item_text, int width, int face_id,
21597 int x, int y, int submenu)
21599 struct it it;
21600 struct frame *f = SELECTED_FRAME ();
21601 struct window *w = XWINDOW (f->selected_window);
21602 int saved_used, saved_truncated, saved_width, saved_reversed;
21603 struct glyph_row *row;
21604 size_t item_len = strlen (item_text);
21606 eassert (FRAME_TERMCAP_P (f));
21608 /* Don't write beyond the matrix's last row. This can happen for
21609 TTY screens that are not high enough to show the entire menu.
21610 (This is actually a bit of defensive programming, as
21611 tty_menu_display already limits the number of menu items to one
21612 less than the number of screen lines.) */
21613 if (y >= f->desired_matrix->nrows)
21614 return;
21616 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
21617 it.first_visible_x = 0;
21618 it.last_visible_x = FRAME_COLS (f) - 1;
21619 row = it.glyph_row;
21620 /* Start with the row contents from the current matrix. */
21621 deep_copy_glyph_row (row, f->current_matrix->rows + y);
21622 saved_width = row->full_width_p;
21623 row->full_width_p = 1;
21624 saved_reversed = row->reversed_p;
21625 row->reversed_p = 0;
21626 row->enabled_p = true;
21628 /* Arrange for the menu item glyphs to start at (X,Y) and have the
21629 desired face. */
21630 eassert (x < f->desired_matrix->matrix_w);
21631 it.current_x = it.hpos = x;
21632 it.current_y = it.vpos = y;
21633 saved_used = row->used[TEXT_AREA];
21634 saved_truncated = row->truncated_on_right_p;
21635 row->used[TEXT_AREA] = x;
21636 it.face_id = face_id;
21637 it.line_wrap = TRUNCATE;
21639 /* FIXME: This should be controlled by a user option. See the
21640 comments in redisplay_tool_bar and display_mode_line about this.
21641 Also, if paragraph_embedding could ever be R2L, changes will be
21642 needed to avoid shifting to the right the row characters in
21643 term.c:append_glyph. */
21644 it.paragraph_embedding = L2R;
21646 /* Pad with a space on the left. */
21647 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
21648 width--;
21649 /* Display the menu item, pad with spaces to WIDTH. */
21650 if (submenu)
21652 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21653 item_len, 0, FRAME_COLS (f) - 1, -1);
21654 width -= item_len;
21655 /* Indicate with " >" that there's a submenu. */
21656 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
21657 FRAME_COLS (f) - 1, -1);
21659 else
21660 display_string (item_text, Qnil, Qnil, 0, 0, &it,
21661 width, 0, FRAME_COLS (f) - 1, -1);
21663 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
21664 row->truncated_on_right_p = saved_truncated;
21665 row->hash = row_hash (row);
21666 row->full_width_p = saved_width;
21667 row->reversed_p = saved_reversed;
21670 /***********************************************************************
21671 Mode Line
21672 ***********************************************************************/
21674 /* Redisplay mode lines in the window tree whose root is WINDOW. If
21675 FORCE is non-zero, redisplay mode lines unconditionally.
21676 Otherwise, redisplay only mode lines that are garbaged. Value is
21677 the number of windows whose mode lines were redisplayed. */
21679 static int
21680 redisplay_mode_lines (Lisp_Object window, bool force)
21682 int nwindows = 0;
21684 while (!NILP (window))
21686 struct window *w = XWINDOW (window);
21688 if (WINDOWP (w->contents))
21689 nwindows += redisplay_mode_lines (w->contents, force);
21690 else if (force
21691 || FRAME_GARBAGED_P (XFRAME (w->frame))
21692 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
21694 struct text_pos lpoint;
21695 struct buffer *old = current_buffer;
21697 /* Set the window's buffer for the mode line display. */
21698 SET_TEXT_POS (lpoint, PT, PT_BYTE);
21699 set_buffer_internal_1 (XBUFFER (w->contents));
21701 /* Point refers normally to the selected window. For any
21702 other window, set up appropriate value. */
21703 if (!EQ (window, selected_window))
21705 struct text_pos pt;
21707 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
21708 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
21711 /* Display mode lines. */
21712 clear_glyph_matrix (w->desired_matrix);
21713 if (display_mode_lines (w))
21714 ++nwindows;
21716 /* Restore old settings. */
21717 set_buffer_internal_1 (old);
21718 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
21721 window = w->next;
21724 return nwindows;
21728 /* Display the mode and/or header line of window W. Value is the
21729 sum number of mode lines and header lines displayed. */
21731 static int
21732 display_mode_lines (struct window *w)
21734 Lisp_Object old_selected_window = selected_window;
21735 Lisp_Object old_selected_frame = selected_frame;
21736 Lisp_Object new_frame = w->frame;
21737 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
21738 int n = 0;
21740 selected_frame = new_frame;
21741 /* FIXME: If we were to allow the mode-line's computation changing the buffer
21742 or window's point, then we'd need select_window_1 here as well. */
21743 XSETWINDOW (selected_window, w);
21744 XFRAME (new_frame)->selected_window = selected_window;
21746 /* These will be set while the mode line specs are processed. */
21747 line_number_displayed = 0;
21748 w->column_number_displayed = -1;
21750 if (WINDOW_WANTS_MODELINE_P (w))
21752 struct window *sel_w = XWINDOW (old_selected_window);
21754 /* Select mode line face based on the real selected window. */
21755 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
21756 BVAR (current_buffer, mode_line_format));
21757 ++n;
21760 if (WINDOW_WANTS_HEADER_LINE_P (w))
21762 display_mode_line (w, HEADER_LINE_FACE_ID,
21763 BVAR (current_buffer, header_line_format));
21764 ++n;
21767 XFRAME (new_frame)->selected_window = old_frame_selected_window;
21768 selected_frame = old_selected_frame;
21769 selected_window = old_selected_window;
21770 if (n > 0)
21771 w->must_be_updated_p = true;
21772 return n;
21776 /* Display mode or header line of window W. FACE_ID specifies which
21777 line to display; it is either MODE_LINE_FACE_ID or
21778 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
21779 display. Value is the pixel height of the mode/header line
21780 displayed. */
21782 static int
21783 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
21785 struct it it;
21786 struct face *face;
21787 ptrdiff_t count = SPECPDL_INDEX ();
21789 init_iterator (&it, w, -1, -1, NULL, face_id);
21790 /* Don't extend on a previously drawn mode-line.
21791 This may happen if called from pos_visible_p. */
21792 it.glyph_row->enabled_p = false;
21793 prepare_desired_row (w, it.glyph_row, true);
21795 it.glyph_row->mode_line_p = 1;
21797 /* FIXME: This should be controlled by a user option. But
21798 supporting such an option is not trivial, since the mode line is
21799 made up of many separate strings. */
21800 it.paragraph_embedding = L2R;
21802 record_unwind_protect (unwind_format_mode_line,
21803 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
21805 mode_line_target = MODE_LINE_DISPLAY;
21807 /* Temporarily make frame's keyboard the current kboard so that
21808 kboard-local variables in the mode_line_format will get the right
21809 values. */
21810 push_kboard (FRAME_KBOARD (it.f));
21811 record_unwind_save_match_data ();
21812 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21813 pop_kboard ();
21815 unbind_to (count, Qnil);
21817 /* Fill up with spaces. */
21818 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
21820 compute_line_metrics (&it);
21821 it.glyph_row->full_width_p = 1;
21822 it.glyph_row->continued_p = 0;
21823 it.glyph_row->truncated_on_left_p = 0;
21824 it.glyph_row->truncated_on_right_p = 0;
21826 /* Make a 3D mode-line have a shadow at its right end. */
21827 face = FACE_FROM_ID (it.f, face_id);
21828 extend_face_to_end_of_line (&it);
21829 if (face->box != FACE_NO_BOX)
21831 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
21832 + it.glyph_row->used[TEXT_AREA] - 1);
21833 last->right_box_line_p = 1;
21836 return it.glyph_row->height;
21839 /* Move element ELT in LIST to the front of LIST.
21840 Return the updated list. */
21842 static Lisp_Object
21843 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
21845 register Lisp_Object tail, prev;
21846 register Lisp_Object tem;
21848 tail = list;
21849 prev = Qnil;
21850 while (CONSP (tail))
21852 tem = XCAR (tail);
21854 if (EQ (elt, tem))
21856 /* Splice out the link TAIL. */
21857 if (NILP (prev))
21858 list = XCDR (tail);
21859 else
21860 Fsetcdr (prev, XCDR (tail));
21862 /* Now make it the first. */
21863 Fsetcdr (tail, list);
21864 return tail;
21866 else
21867 prev = tail;
21868 tail = XCDR (tail);
21869 QUIT;
21872 /* Not found--return unchanged LIST. */
21873 return list;
21876 /* Contribute ELT to the mode line for window IT->w. How it
21877 translates into text depends on its data type.
21879 IT describes the display environment in which we display, as usual.
21881 DEPTH is the depth in recursion. It is used to prevent
21882 infinite recursion here.
21884 FIELD_WIDTH is the number of characters the display of ELT should
21885 occupy in the mode line, and PRECISION is the maximum number of
21886 characters to display from ELT's representation. See
21887 display_string for details.
21889 Returns the hpos of the end of the text generated by ELT.
21891 PROPS is a property list to add to any string we encounter.
21893 If RISKY is nonzero, remove (disregard) any properties in any string
21894 we encounter, and ignore :eval and :propertize.
21896 The global variable `mode_line_target' determines whether the
21897 output is passed to `store_mode_line_noprop',
21898 `store_mode_line_string', or `display_string'. */
21900 static int
21901 display_mode_element (struct it *it, int depth, int field_width, int precision,
21902 Lisp_Object elt, Lisp_Object props, int risky)
21904 int n = 0, field, prec;
21905 int literal = 0;
21907 tail_recurse:
21908 if (depth > 100)
21909 elt = build_string ("*too-deep*");
21911 depth++;
21913 switch (XTYPE (elt))
21915 case Lisp_String:
21917 /* A string: output it and check for %-constructs within it. */
21918 unsigned char c;
21919 ptrdiff_t offset = 0;
21921 if (SCHARS (elt) > 0
21922 && (!NILP (props) || risky))
21924 Lisp_Object oprops, aelt;
21925 oprops = Ftext_properties_at (make_number (0), elt);
21927 /* If the starting string's properties are not what
21928 we want, translate the string. Also, if the string
21929 is risky, do that anyway. */
21931 if (NILP (Fequal (props, oprops)) || risky)
21933 /* If the starting string has properties,
21934 merge the specified ones onto the existing ones. */
21935 if (! NILP (oprops) && !risky)
21937 Lisp_Object tem;
21939 oprops = Fcopy_sequence (oprops);
21940 tem = props;
21941 while (CONSP (tem))
21943 oprops = Fplist_put (oprops, XCAR (tem),
21944 XCAR (XCDR (tem)));
21945 tem = XCDR (XCDR (tem));
21947 props = oprops;
21950 aelt = Fassoc (elt, mode_line_proptrans_alist);
21951 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
21953 /* AELT is what we want. Move it to the front
21954 without consing. */
21955 elt = XCAR (aelt);
21956 mode_line_proptrans_alist
21957 = move_elt_to_front (aelt, mode_line_proptrans_alist);
21959 else
21961 Lisp_Object tem;
21963 /* If AELT has the wrong props, it is useless.
21964 so get rid of it. */
21965 if (! NILP (aelt))
21966 mode_line_proptrans_alist
21967 = Fdelq (aelt, mode_line_proptrans_alist);
21969 elt = Fcopy_sequence (elt);
21970 Fset_text_properties (make_number (0), Flength (elt),
21971 props, elt);
21972 /* Add this item to mode_line_proptrans_alist. */
21973 mode_line_proptrans_alist
21974 = Fcons (Fcons (elt, props),
21975 mode_line_proptrans_alist);
21976 /* Truncate mode_line_proptrans_alist
21977 to at most 50 elements. */
21978 tem = Fnthcdr (make_number (50),
21979 mode_line_proptrans_alist);
21980 if (! NILP (tem))
21981 XSETCDR (tem, Qnil);
21986 offset = 0;
21988 if (literal)
21990 prec = precision - n;
21991 switch (mode_line_target)
21993 case MODE_LINE_NOPROP:
21994 case MODE_LINE_TITLE:
21995 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
21996 break;
21997 case MODE_LINE_STRING:
21998 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
21999 break;
22000 case MODE_LINE_DISPLAY:
22001 n += display_string (NULL, elt, Qnil, 0, 0, it,
22002 0, prec, 0, STRING_MULTIBYTE (elt));
22003 break;
22006 break;
22009 /* Handle the non-literal case. */
22011 while ((precision <= 0 || n < precision)
22012 && SREF (elt, offset) != 0
22013 && (mode_line_target != MODE_LINE_DISPLAY
22014 || it->current_x < it->last_visible_x))
22016 ptrdiff_t last_offset = offset;
22018 /* Advance to end of string or next format specifier. */
22019 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
22022 if (offset - 1 != last_offset)
22024 ptrdiff_t nchars, nbytes;
22026 /* Output to end of string or up to '%'. Field width
22027 is length of string. Don't output more than
22028 PRECISION allows us. */
22029 offset--;
22031 prec = c_string_width (SDATA (elt) + last_offset,
22032 offset - last_offset, precision - n,
22033 &nchars, &nbytes);
22035 switch (mode_line_target)
22037 case MODE_LINE_NOPROP:
22038 case MODE_LINE_TITLE:
22039 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
22040 break;
22041 case MODE_LINE_STRING:
22043 ptrdiff_t bytepos = last_offset;
22044 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22045 ptrdiff_t endpos = (precision <= 0
22046 ? string_byte_to_char (elt, offset)
22047 : charpos + nchars);
22049 n += store_mode_line_string (NULL,
22050 Fsubstring (elt, make_number (charpos),
22051 make_number (endpos)),
22052 0, 0, 0, Qnil);
22054 break;
22055 case MODE_LINE_DISPLAY:
22057 ptrdiff_t bytepos = last_offset;
22058 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
22060 if (precision <= 0)
22061 nchars = string_byte_to_char (elt, offset) - charpos;
22062 n += display_string (NULL, elt, Qnil, 0, charpos,
22063 it, 0, nchars, 0,
22064 STRING_MULTIBYTE (elt));
22066 break;
22069 else /* c == '%' */
22071 ptrdiff_t percent_position = offset;
22073 /* Get the specified minimum width. Zero means
22074 don't pad. */
22075 field = 0;
22076 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
22077 field = field * 10 + c - '0';
22079 /* Don't pad beyond the total padding allowed. */
22080 if (field_width - n > 0 && field > field_width - n)
22081 field = field_width - n;
22083 /* Note that either PRECISION <= 0 or N < PRECISION. */
22084 prec = precision - n;
22086 if (c == 'M')
22087 n += display_mode_element (it, depth, field, prec,
22088 Vglobal_mode_string, props,
22089 risky);
22090 else if (c != 0)
22092 bool multibyte;
22093 ptrdiff_t bytepos, charpos;
22094 const char *spec;
22095 Lisp_Object string;
22097 bytepos = percent_position;
22098 charpos = (STRING_MULTIBYTE (elt)
22099 ? string_byte_to_char (elt, bytepos)
22100 : bytepos);
22101 spec = decode_mode_spec (it->w, c, field, &string);
22102 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
22104 switch (mode_line_target)
22106 case MODE_LINE_NOPROP:
22107 case MODE_LINE_TITLE:
22108 n += store_mode_line_noprop (spec, field, prec);
22109 break;
22110 case MODE_LINE_STRING:
22112 Lisp_Object tem = build_string (spec);
22113 props = Ftext_properties_at (make_number (charpos), elt);
22114 /* Should only keep face property in props */
22115 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
22117 break;
22118 case MODE_LINE_DISPLAY:
22120 int nglyphs_before, nwritten;
22122 nglyphs_before = it->glyph_row->used[TEXT_AREA];
22123 nwritten = display_string (spec, string, elt,
22124 charpos, 0, it,
22125 field, prec, 0,
22126 multibyte);
22128 /* Assign to the glyphs written above the
22129 string where the `%x' came from, position
22130 of the `%'. */
22131 if (nwritten > 0)
22133 struct glyph *glyph
22134 = (it->glyph_row->glyphs[TEXT_AREA]
22135 + nglyphs_before);
22136 int i;
22138 for (i = 0; i < nwritten; ++i)
22140 glyph[i].object = elt;
22141 glyph[i].charpos = charpos;
22144 n += nwritten;
22147 break;
22150 else /* c == 0 */
22151 break;
22155 break;
22157 case Lisp_Symbol:
22158 /* A symbol: process the value of the symbol recursively
22159 as if it appeared here directly. Avoid error if symbol void.
22160 Special case: if value of symbol is a string, output the string
22161 literally. */
22163 register Lisp_Object tem;
22165 /* If the variable is not marked as risky to set
22166 then its contents are risky to use. */
22167 if (NILP (Fget (elt, Qrisky_local_variable)))
22168 risky = 1;
22170 tem = Fboundp (elt);
22171 if (!NILP (tem))
22173 tem = Fsymbol_value (elt);
22174 /* If value is a string, output that string literally:
22175 don't check for % within it. */
22176 if (STRINGP (tem))
22177 literal = 1;
22179 if (!EQ (tem, elt))
22181 /* Give up right away for nil or t. */
22182 elt = tem;
22183 goto tail_recurse;
22187 break;
22189 case Lisp_Cons:
22191 register Lisp_Object car, tem;
22193 /* A cons cell: five distinct cases.
22194 If first element is :eval or :propertize, do something special.
22195 If first element is a string or a cons, process all the elements
22196 and effectively concatenate them.
22197 If first element is a negative number, truncate displaying cdr to
22198 at most that many characters. If positive, pad (with spaces)
22199 to at least that many characters.
22200 If first element is a symbol, process the cadr or caddr recursively
22201 according to whether the symbol's value is non-nil or nil. */
22202 car = XCAR (elt);
22203 if (EQ (car, QCeval))
22205 /* An element of the form (:eval FORM) means evaluate FORM
22206 and use the result as mode line elements. */
22208 if (risky)
22209 break;
22211 if (CONSP (XCDR (elt)))
22213 Lisp_Object spec;
22214 spec = safe__eval (true, XCAR (XCDR (elt)));
22215 n += display_mode_element (it, depth, field_width - n,
22216 precision - n, spec, props,
22217 risky);
22220 else if (EQ (car, QCpropertize))
22222 /* An element of the form (:propertize ELT PROPS...)
22223 means display ELT but applying properties PROPS. */
22225 if (risky)
22226 break;
22228 if (CONSP (XCDR (elt)))
22229 n += display_mode_element (it, depth, field_width - n,
22230 precision - n, XCAR (XCDR (elt)),
22231 XCDR (XCDR (elt)), risky);
22233 else if (SYMBOLP (car))
22235 tem = Fboundp (car);
22236 elt = XCDR (elt);
22237 if (!CONSP (elt))
22238 goto invalid;
22239 /* elt is now the cdr, and we know it is a cons cell.
22240 Use its car if CAR has a non-nil value. */
22241 if (!NILP (tem))
22243 tem = Fsymbol_value (car);
22244 if (!NILP (tem))
22246 elt = XCAR (elt);
22247 goto tail_recurse;
22250 /* Symbol's value is nil (or symbol is unbound)
22251 Get the cddr of the original list
22252 and if possible find the caddr and use that. */
22253 elt = XCDR (elt);
22254 if (NILP (elt))
22255 break;
22256 else if (!CONSP (elt))
22257 goto invalid;
22258 elt = XCAR (elt);
22259 goto tail_recurse;
22261 else if (INTEGERP (car))
22263 register int lim = XINT (car);
22264 elt = XCDR (elt);
22265 if (lim < 0)
22267 /* Negative int means reduce maximum width. */
22268 if (precision <= 0)
22269 precision = -lim;
22270 else
22271 precision = min (precision, -lim);
22273 else if (lim > 0)
22275 /* Padding specified. Don't let it be more than
22276 current maximum. */
22277 if (precision > 0)
22278 lim = min (precision, lim);
22280 /* If that's more padding than already wanted, queue it.
22281 But don't reduce padding already specified even if
22282 that is beyond the current truncation point. */
22283 field_width = max (lim, field_width);
22285 goto tail_recurse;
22287 else if (STRINGP (car) || CONSP (car))
22289 Lisp_Object halftail = elt;
22290 int len = 0;
22292 while (CONSP (elt)
22293 && (precision <= 0 || n < precision))
22295 n += display_mode_element (it, depth,
22296 /* Do padding only after the last
22297 element in the list. */
22298 (! CONSP (XCDR (elt))
22299 ? field_width - n
22300 : 0),
22301 precision - n, XCAR (elt),
22302 props, risky);
22303 elt = XCDR (elt);
22304 len++;
22305 if ((len & 1) == 0)
22306 halftail = XCDR (halftail);
22307 /* Check for cycle. */
22308 if (EQ (halftail, elt))
22309 break;
22313 break;
22315 default:
22316 invalid:
22317 elt = build_string ("*invalid*");
22318 goto tail_recurse;
22321 /* Pad to FIELD_WIDTH. */
22322 if (field_width > 0 && n < field_width)
22324 switch (mode_line_target)
22326 case MODE_LINE_NOPROP:
22327 case MODE_LINE_TITLE:
22328 n += store_mode_line_noprop ("", field_width - n, 0);
22329 break;
22330 case MODE_LINE_STRING:
22331 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
22332 break;
22333 case MODE_LINE_DISPLAY:
22334 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
22335 0, 0, 0);
22336 break;
22340 return n;
22343 /* Store a mode-line string element in mode_line_string_list.
22345 If STRING is non-null, display that C string. Otherwise, the Lisp
22346 string LISP_STRING is displayed.
22348 FIELD_WIDTH is the minimum number of output glyphs to produce.
22349 If STRING has fewer characters than FIELD_WIDTH, pad to the right
22350 with spaces. FIELD_WIDTH <= 0 means don't pad.
22352 PRECISION is the maximum number of characters to output from
22353 STRING. PRECISION <= 0 means don't truncate the string.
22355 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
22356 properties to the string.
22358 PROPS are the properties to add to the string.
22359 The mode_line_string_face face property is always added to the string.
22362 static int
22363 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
22364 int field_width, int precision, Lisp_Object props)
22366 ptrdiff_t len;
22367 int n = 0;
22369 if (string != NULL)
22371 len = strlen (string);
22372 if (precision > 0 && len > precision)
22373 len = precision;
22374 lisp_string = make_string (string, len);
22375 if (NILP (props))
22376 props = mode_line_string_face_prop;
22377 else if (!NILP (mode_line_string_face))
22379 Lisp_Object face = Fplist_get (props, Qface);
22380 props = Fcopy_sequence (props);
22381 if (NILP (face))
22382 face = mode_line_string_face;
22383 else
22384 face = list2 (face, mode_line_string_face);
22385 props = Fplist_put (props, Qface, face);
22387 Fadd_text_properties (make_number (0), make_number (len),
22388 props, lisp_string);
22390 else
22392 len = XFASTINT (Flength (lisp_string));
22393 if (precision > 0 && len > precision)
22395 len = precision;
22396 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
22397 precision = -1;
22399 if (!NILP (mode_line_string_face))
22401 Lisp_Object face;
22402 if (NILP (props))
22403 props = Ftext_properties_at (make_number (0), lisp_string);
22404 face = Fplist_get (props, Qface);
22405 if (NILP (face))
22406 face = mode_line_string_face;
22407 else
22408 face = list2 (face, mode_line_string_face);
22409 props = list2 (Qface, face);
22410 if (copy_string)
22411 lisp_string = Fcopy_sequence (lisp_string);
22413 if (!NILP (props))
22414 Fadd_text_properties (make_number (0), make_number (len),
22415 props, lisp_string);
22418 if (len > 0)
22420 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22421 n += len;
22424 if (field_width > len)
22426 field_width -= len;
22427 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
22428 if (!NILP (props))
22429 Fadd_text_properties (make_number (0), make_number (field_width),
22430 props, lisp_string);
22431 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
22432 n += field_width;
22435 return n;
22439 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
22440 1, 4, 0,
22441 doc: /* Format a string out of a mode line format specification.
22442 First arg FORMAT specifies the mode line format (see `mode-line-format'
22443 for details) to use.
22445 By default, the format is evaluated for the currently selected window.
22447 Optional second arg FACE specifies the face property to put on all
22448 characters for which no face is specified. The value nil means the
22449 default face. The value t means whatever face the window's mode line
22450 currently uses (either `mode-line' or `mode-line-inactive',
22451 depending on whether the window is the selected window or not).
22452 An integer value means the value string has no text
22453 properties.
22455 Optional third and fourth args WINDOW and BUFFER specify the window
22456 and buffer to use as the context for the formatting (defaults
22457 are the selected window and the WINDOW's buffer). */)
22458 (Lisp_Object format, Lisp_Object face,
22459 Lisp_Object window, Lisp_Object buffer)
22461 struct it it;
22462 int len;
22463 struct window *w;
22464 struct buffer *old_buffer = NULL;
22465 int face_id;
22466 int no_props = INTEGERP (face);
22467 ptrdiff_t count = SPECPDL_INDEX ();
22468 Lisp_Object str;
22469 int string_start = 0;
22471 w = decode_any_window (window);
22472 XSETWINDOW (window, w);
22474 if (NILP (buffer))
22475 buffer = w->contents;
22476 CHECK_BUFFER (buffer);
22478 /* Make formatting the modeline a non-op when noninteractive, otherwise
22479 there will be problems later caused by a partially initialized frame. */
22480 if (NILP (format) || noninteractive)
22481 return empty_unibyte_string;
22483 if (no_props)
22484 face = Qnil;
22486 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
22487 : EQ (face, Qt) ? (EQ (window, selected_window)
22488 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
22489 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
22490 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
22491 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
22492 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
22493 : DEFAULT_FACE_ID;
22495 old_buffer = current_buffer;
22497 /* Save things including mode_line_proptrans_alist,
22498 and set that to nil so that we don't alter the outer value. */
22499 record_unwind_protect (unwind_format_mode_line,
22500 format_mode_line_unwind_data
22501 (XFRAME (WINDOW_FRAME (w)),
22502 old_buffer, selected_window, 1));
22503 mode_line_proptrans_alist = Qnil;
22505 Fselect_window (window, Qt);
22506 set_buffer_internal_1 (XBUFFER (buffer));
22508 init_iterator (&it, w, -1, -1, NULL, face_id);
22510 if (no_props)
22512 mode_line_target = MODE_LINE_NOPROP;
22513 mode_line_string_face_prop = Qnil;
22514 mode_line_string_list = Qnil;
22515 string_start = MODE_LINE_NOPROP_LEN (0);
22517 else
22519 mode_line_target = MODE_LINE_STRING;
22520 mode_line_string_list = Qnil;
22521 mode_line_string_face = face;
22522 mode_line_string_face_prop
22523 = NILP (face) ? Qnil : list2 (Qface, face);
22526 push_kboard (FRAME_KBOARD (it.f));
22527 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
22528 pop_kboard ();
22530 if (no_props)
22532 len = MODE_LINE_NOPROP_LEN (string_start);
22533 str = make_string (mode_line_noprop_buf + string_start, len);
22535 else
22537 mode_line_string_list = Fnreverse (mode_line_string_list);
22538 str = Fmapconcat (intern ("identity"), mode_line_string_list,
22539 empty_unibyte_string);
22542 unbind_to (count, Qnil);
22543 return str;
22546 /* Write a null-terminated, right justified decimal representation of
22547 the positive integer D to BUF using a minimal field width WIDTH. */
22549 static void
22550 pint2str (register char *buf, register int width, register ptrdiff_t d)
22552 register char *p = buf;
22554 if (d <= 0)
22555 *p++ = '0';
22556 else
22558 while (d > 0)
22560 *p++ = d % 10 + '0';
22561 d /= 10;
22565 for (width -= (int) (p - buf); width > 0; --width)
22566 *p++ = ' ';
22567 *p-- = '\0';
22568 while (p > buf)
22570 d = *buf;
22571 *buf++ = *p;
22572 *p-- = d;
22576 /* Write a null-terminated, right justified decimal and "human
22577 readable" representation of the nonnegative integer D to BUF using
22578 a minimal field width WIDTH. D should be smaller than 999.5e24. */
22580 static const char power_letter[] =
22582 0, /* no letter */
22583 'k', /* kilo */
22584 'M', /* mega */
22585 'G', /* giga */
22586 'T', /* tera */
22587 'P', /* peta */
22588 'E', /* exa */
22589 'Z', /* zetta */
22590 'Y' /* yotta */
22593 static void
22594 pint2hrstr (char *buf, int width, ptrdiff_t d)
22596 /* We aim to represent the nonnegative integer D as
22597 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
22598 ptrdiff_t quotient = d;
22599 int remainder = 0;
22600 /* -1 means: do not use TENTHS. */
22601 int tenths = -1;
22602 int exponent = 0;
22604 /* Length of QUOTIENT.TENTHS as a string. */
22605 int length;
22607 char * psuffix;
22608 char * p;
22610 if (quotient >= 1000)
22612 /* Scale to the appropriate EXPONENT. */
22615 remainder = quotient % 1000;
22616 quotient /= 1000;
22617 exponent++;
22619 while (quotient >= 1000);
22621 /* Round to nearest and decide whether to use TENTHS or not. */
22622 if (quotient <= 9)
22624 tenths = remainder / 100;
22625 if (remainder % 100 >= 50)
22627 if (tenths < 9)
22628 tenths++;
22629 else
22631 quotient++;
22632 if (quotient == 10)
22633 tenths = -1;
22634 else
22635 tenths = 0;
22639 else
22640 if (remainder >= 500)
22642 if (quotient < 999)
22643 quotient++;
22644 else
22646 quotient = 1;
22647 exponent++;
22648 tenths = 0;
22653 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
22654 if (tenths == -1 && quotient <= 99)
22655 if (quotient <= 9)
22656 length = 1;
22657 else
22658 length = 2;
22659 else
22660 length = 3;
22661 p = psuffix = buf + max (width, length);
22663 /* Print EXPONENT. */
22664 *psuffix++ = power_letter[exponent];
22665 *psuffix = '\0';
22667 /* Print TENTHS. */
22668 if (tenths >= 0)
22670 *--p = '0' + tenths;
22671 *--p = '.';
22674 /* Print QUOTIENT. */
22677 int digit = quotient % 10;
22678 *--p = '0' + digit;
22680 while ((quotient /= 10) != 0);
22682 /* Print leading spaces. */
22683 while (buf < p)
22684 *--p = ' ';
22687 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
22688 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
22689 type of CODING_SYSTEM. Return updated pointer into BUF. */
22691 static unsigned char invalid_eol_type[] = "(*invalid*)";
22693 static char *
22694 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
22696 Lisp_Object val;
22697 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
22698 const unsigned char *eol_str;
22699 int eol_str_len;
22700 /* The EOL conversion we are using. */
22701 Lisp_Object eoltype;
22703 val = CODING_SYSTEM_SPEC (coding_system);
22704 eoltype = Qnil;
22706 if (!VECTORP (val)) /* Not yet decided. */
22708 *buf++ = multibyte ? '-' : ' ';
22709 if (eol_flag)
22710 eoltype = eol_mnemonic_undecided;
22711 /* Don't mention EOL conversion if it isn't decided. */
22713 else
22715 Lisp_Object attrs;
22716 Lisp_Object eolvalue;
22718 attrs = AREF (val, 0);
22719 eolvalue = AREF (val, 2);
22721 *buf++ = multibyte
22722 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
22723 : ' ';
22725 if (eol_flag)
22727 /* The EOL conversion that is normal on this system. */
22729 if (NILP (eolvalue)) /* Not yet decided. */
22730 eoltype = eol_mnemonic_undecided;
22731 else if (VECTORP (eolvalue)) /* Not yet decided. */
22732 eoltype = eol_mnemonic_undecided;
22733 else /* eolvalue is Qunix, Qdos, or Qmac. */
22734 eoltype = (EQ (eolvalue, Qunix)
22735 ? eol_mnemonic_unix
22736 : (EQ (eolvalue, Qdos) == 1
22737 ? eol_mnemonic_dos : eol_mnemonic_mac));
22741 if (eol_flag)
22743 /* Mention the EOL conversion if it is not the usual one. */
22744 if (STRINGP (eoltype))
22746 eol_str = SDATA (eoltype);
22747 eol_str_len = SBYTES (eoltype);
22749 else if (CHARACTERP (eoltype))
22751 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
22752 int c = XFASTINT (eoltype);
22753 eol_str_len = CHAR_STRING (c, tmp);
22754 eol_str = tmp;
22756 else
22758 eol_str = invalid_eol_type;
22759 eol_str_len = sizeof (invalid_eol_type) - 1;
22761 memcpy (buf, eol_str, eol_str_len);
22762 buf += eol_str_len;
22765 return buf;
22768 /* Return a string for the output of a mode line %-spec for window W,
22769 generated by character C. FIELD_WIDTH > 0 means pad the string
22770 returned with spaces to that value. Return a Lisp string in
22771 *STRING if the resulting string is taken from that Lisp string.
22773 Note we operate on the current buffer for most purposes. */
22775 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
22777 static const char *
22778 decode_mode_spec (struct window *w, register int c, int field_width,
22779 Lisp_Object *string)
22781 Lisp_Object obj;
22782 struct frame *f = XFRAME (WINDOW_FRAME (w));
22783 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
22784 /* We are going to use f->decode_mode_spec_buffer as the buffer to
22785 produce strings from numerical values, so limit preposterously
22786 large values of FIELD_WIDTH to avoid overrunning the buffer's
22787 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
22788 bytes plus the terminating null. */
22789 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
22790 struct buffer *b = current_buffer;
22792 obj = Qnil;
22793 *string = Qnil;
22795 switch (c)
22797 case '*':
22798 if (!NILP (BVAR (b, read_only)))
22799 return "%";
22800 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22801 return "*";
22802 return "-";
22804 case '+':
22805 /* This differs from %* only for a modified read-only buffer. */
22806 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22807 return "*";
22808 if (!NILP (BVAR (b, read_only)))
22809 return "%";
22810 return "-";
22812 case '&':
22813 /* This differs from %* in ignoring read-only-ness. */
22814 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
22815 return "*";
22816 return "-";
22818 case '%':
22819 return "%";
22821 case '[':
22823 int i;
22824 char *p;
22826 if (command_loop_level > 5)
22827 return "[[[... ";
22828 p = decode_mode_spec_buf;
22829 for (i = 0; i < command_loop_level; i++)
22830 *p++ = '[';
22831 *p = 0;
22832 return decode_mode_spec_buf;
22835 case ']':
22837 int i;
22838 char *p;
22840 if (command_loop_level > 5)
22841 return " ...]]]";
22842 p = decode_mode_spec_buf;
22843 for (i = 0; i < command_loop_level; i++)
22844 *p++ = ']';
22845 *p = 0;
22846 return decode_mode_spec_buf;
22849 case '-':
22851 register int i;
22853 /* Let lots_of_dashes be a string of infinite length. */
22854 if (mode_line_target == MODE_LINE_NOPROP
22855 || mode_line_target == MODE_LINE_STRING)
22856 return "--";
22857 if (field_width <= 0
22858 || field_width > sizeof (lots_of_dashes))
22860 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
22861 decode_mode_spec_buf[i] = '-';
22862 decode_mode_spec_buf[i] = '\0';
22863 return decode_mode_spec_buf;
22865 else
22866 return lots_of_dashes;
22869 case 'b':
22870 obj = BVAR (b, name);
22871 break;
22873 case 'c':
22874 /* %c and %l are ignored in `frame-title-format'.
22875 (In redisplay_internal, the frame title is drawn _before_ the
22876 windows are updated, so the stuff which depends on actual
22877 window contents (such as %l) may fail to render properly, or
22878 even crash emacs.) */
22879 if (mode_line_target == MODE_LINE_TITLE)
22880 return "";
22881 else
22883 ptrdiff_t col = current_column ();
22884 w->column_number_displayed = col;
22885 pint2str (decode_mode_spec_buf, width, col);
22886 return decode_mode_spec_buf;
22889 case 'e':
22890 #ifndef SYSTEM_MALLOC
22892 if (NILP (Vmemory_full))
22893 return "";
22894 else
22895 return "!MEM FULL! ";
22897 #else
22898 return "";
22899 #endif
22901 case 'F':
22902 /* %F displays the frame name. */
22903 if (!NILP (f->title))
22904 return SSDATA (f->title);
22905 if (f->explicit_name || ! FRAME_WINDOW_P (f))
22906 return SSDATA (f->name);
22907 return "Emacs";
22909 case 'f':
22910 obj = BVAR (b, filename);
22911 break;
22913 case 'i':
22915 ptrdiff_t size = ZV - BEGV;
22916 pint2str (decode_mode_spec_buf, width, size);
22917 return decode_mode_spec_buf;
22920 case 'I':
22922 ptrdiff_t size = ZV - BEGV;
22923 pint2hrstr (decode_mode_spec_buf, width, size);
22924 return decode_mode_spec_buf;
22927 case 'l':
22929 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
22930 ptrdiff_t topline, nlines, height;
22931 ptrdiff_t junk;
22933 /* %c and %l are ignored in `frame-title-format'. */
22934 if (mode_line_target == MODE_LINE_TITLE)
22935 return "";
22937 startpos = marker_position (w->start);
22938 startpos_byte = marker_byte_position (w->start);
22939 height = WINDOW_TOTAL_LINES (w);
22941 /* If we decided that this buffer isn't suitable for line numbers,
22942 don't forget that too fast. */
22943 if (w->base_line_pos == -1)
22944 goto no_value;
22946 /* If the buffer is very big, don't waste time. */
22947 if (INTEGERP (Vline_number_display_limit)
22948 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
22950 w->base_line_pos = 0;
22951 w->base_line_number = 0;
22952 goto no_value;
22955 if (w->base_line_number > 0
22956 && w->base_line_pos > 0
22957 && w->base_line_pos <= startpos)
22959 line = w->base_line_number;
22960 linepos = w->base_line_pos;
22961 linepos_byte = buf_charpos_to_bytepos (b, linepos);
22963 else
22965 line = 1;
22966 linepos = BUF_BEGV (b);
22967 linepos_byte = BUF_BEGV_BYTE (b);
22970 /* Count lines from base line to window start position. */
22971 nlines = display_count_lines (linepos_byte,
22972 startpos_byte,
22973 startpos, &junk);
22975 topline = nlines + line;
22977 /* Determine a new base line, if the old one is too close
22978 or too far away, or if we did not have one.
22979 "Too close" means it's plausible a scroll-down would
22980 go back past it. */
22981 if (startpos == BUF_BEGV (b))
22983 w->base_line_number = topline;
22984 w->base_line_pos = BUF_BEGV (b);
22986 else if (nlines < height + 25 || nlines > height * 3 + 50
22987 || linepos == BUF_BEGV (b))
22989 ptrdiff_t limit = BUF_BEGV (b);
22990 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
22991 ptrdiff_t position;
22992 ptrdiff_t distance =
22993 (height * 2 + 30) * line_number_display_limit_width;
22995 if (startpos - distance > limit)
22997 limit = startpos - distance;
22998 limit_byte = CHAR_TO_BYTE (limit);
23001 nlines = display_count_lines (startpos_byte,
23002 limit_byte,
23003 - (height * 2 + 30),
23004 &position);
23005 /* If we couldn't find the lines we wanted within
23006 line_number_display_limit_width chars per line,
23007 give up on line numbers for this window. */
23008 if (position == limit_byte && limit == startpos - distance)
23010 w->base_line_pos = -1;
23011 w->base_line_number = 0;
23012 goto no_value;
23015 w->base_line_number = topline - nlines;
23016 w->base_line_pos = BYTE_TO_CHAR (position);
23019 /* Now count lines from the start pos to point. */
23020 nlines = display_count_lines (startpos_byte,
23021 PT_BYTE, PT, &junk);
23023 /* Record that we did display the line number. */
23024 line_number_displayed = 1;
23026 /* Make the string to show. */
23027 pint2str (decode_mode_spec_buf, width, topline + nlines);
23028 return decode_mode_spec_buf;
23029 no_value:
23031 char *p = decode_mode_spec_buf;
23032 int pad = width - 2;
23033 while (pad-- > 0)
23034 *p++ = ' ';
23035 *p++ = '?';
23036 *p++ = '?';
23037 *p = '\0';
23038 return decode_mode_spec_buf;
23041 break;
23043 case 'm':
23044 obj = BVAR (b, mode_name);
23045 break;
23047 case 'n':
23048 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
23049 return " Narrow";
23050 break;
23052 case 'p':
23054 ptrdiff_t pos = marker_position (w->start);
23055 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23057 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
23059 if (pos <= BUF_BEGV (b))
23060 return "All";
23061 else
23062 return "Bottom";
23064 else if (pos <= BUF_BEGV (b))
23065 return "Top";
23066 else
23068 if (total > 1000000)
23069 /* Do it differently for a large value, to avoid overflow. */
23070 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23071 else
23072 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
23073 /* We can't normally display a 3-digit number,
23074 so get us a 2-digit number that is close. */
23075 if (total == 100)
23076 total = 99;
23077 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23078 return decode_mode_spec_buf;
23082 /* Display percentage of size above the bottom of the screen. */
23083 case 'P':
23085 ptrdiff_t toppos = marker_position (w->start);
23086 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
23087 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
23089 if (botpos >= BUF_ZV (b))
23091 if (toppos <= BUF_BEGV (b))
23092 return "All";
23093 else
23094 return "Bottom";
23096 else
23098 if (total > 1000000)
23099 /* Do it differently for a large value, to avoid overflow. */
23100 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23101 else
23102 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
23103 /* We can't normally display a 3-digit number,
23104 so get us a 2-digit number that is close. */
23105 if (total == 100)
23106 total = 99;
23107 if (toppos <= BUF_BEGV (b))
23108 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
23109 else
23110 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23111 return decode_mode_spec_buf;
23115 case 's':
23116 /* status of process */
23117 obj = Fget_buffer_process (Fcurrent_buffer ());
23118 if (NILP (obj))
23119 return "no process";
23120 #ifndef MSDOS
23121 obj = Fsymbol_name (Fprocess_status (obj));
23122 #endif
23123 break;
23125 case '@':
23127 ptrdiff_t count = inhibit_garbage_collection ();
23128 Lisp_Object curdir = BVAR (current_buffer, directory);
23129 Lisp_Object val = Qnil;
23131 if (STRINGP (curdir))
23132 val = call1 (intern ("file-remote-p"), curdir);
23134 unbind_to (count, Qnil);
23136 if (NILP (val))
23137 return "-";
23138 else
23139 return "@";
23142 case 'z':
23143 /* coding-system (not including end-of-line format) */
23144 case 'Z':
23145 /* coding-system (including end-of-line type) */
23147 int eol_flag = (c == 'Z');
23148 char *p = decode_mode_spec_buf;
23150 if (! FRAME_WINDOW_P (f))
23152 /* No need to mention EOL here--the terminal never needs
23153 to do EOL conversion. */
23154 p = decode_mode_spec_coding (CODING_ID_NAME
23155 (FRAME_KEYBOARD_CODING (f)->id),
23156 p, 0);
23157 p = decode_mode_spec_coding (CODING_ID_NAME
23158 (FRAME_TERMINAL_CODING (f)->id),
23159 p, 0);
23161 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
23162 p, eol_flag);
23164 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
23165 #ifdef subprocesses
23166 obj = Fget_buffer_process (Fcurrent_buffer ());
23167 if (PROCESSP (obj))
23169 p = decode_mode_spec_coding
23170 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
23171 p = decode_mode_spec_coding
23172 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
23174 #endif /* subprocesses */
23175 #endif /* 0 */
23176 *p = 0;
23177 return decode_mode_spec_buf;
23181 if (STRINGP (obj))
23183 *string = obj;
23184 return SSDATA (obj);
23186 else
23187 return "";
23191 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
23192 means count lines back from START_BYTE. But don't go beyond
23193 LIMIT_BYTE. Return the number of lines thus found (always
23194 nonnegative).
23196 Set *BYTE_POS_PTR to the byte position where we stopped. This is
23197 either the position COUNT lines after/before START_BYTE, if we
23198 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
23199 COUNT lines. */
23201 static ptrdiff_t
23202 display_count_lines (ptrdiff_t start_byte,
23203 ptrdiff_t limit_byte, ptrdiff_t count,
23204 ptrdiff_t *byte_pos_ptr)
23206 register unsigned char *cursor;
23207 unsigned char *base;
23209 register ptrdiff_t ceiling;
23210 register unsigned char *ceiling_addr;
23211 ptrdiff_t orig_count = count;
23213 /* If we are not in selective display mode,
23214 check only for newlines. */
23215 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
23216 && !INTEGERP (BVAR (current_buffer, selective_display)));
23218 if (count > 0)
23220 while (start_byte < limit_byte)
23222 ceiling = BUFFER_CEILING_OF (start_byte);
23223 ceiling = min (limit_byte - 1, ceiling);
23224 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
23225 base = (cursor = BYTE_POS_ADDR (start_byte));
23229 if (selective_display)
23231 while (*cursor != '\n' && *cursor != 015
23232 && ++cursor != ceiling_addr)
23233 continue;
23234 if (cursor == ceiling_addr)
23235 break;
23237 else
23239 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
23240 if (! cursor)
23241 break;
23244 cursor++;
23246 if (--count == 0)
23248 start_byte += cursor - base;
23249 *byte_pos_ptr = start_byte;
23250 return orig_count;
23253 while (cursor < ceiling_addr);
23255 start_byte += ceiling_addr - base;
23258 else
23260 while (start_byte > limit_byte)
23262 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
23263 ceiling = max (limit_byte, ceiling);
23264 ceiling_addr = BYTE_POS_ADDR (ceiling);
23265 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
23266 while (1)
23268 if (selective_display)
23270 while (--cursor >= ceiling_addr
23271 && *cursor != '\n' && *cursor != 015)
23272 continue;
23273 if (cursor < ceiling_addr)
23274 break;
23276 else
23278 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
23279 if (! cursor)
23280 break;
23283 if (++count == 0)
23285 start_byte += cursor - base + 1;
23286 *byte_pos_ptr = start_byte;
23287 /* When scanning backwards, we should
23288 not count the newline posterior to which we stop. */
23289 return - orig_count - 1;
23292 start_byte += ceiling_addr - base;
23296 *byte_pos_ptr = limit_byte;
23298 if (count < 0)
23299 return - orig_count + count;
23300 return orig_count - count;
23306 /***********************************************************************
23307 Displaying strings
23308 ***********************************************************************/
23310 /* Display a NUL-terminated string, starting with index START.
23312 If STRING is non-null, display that C string. Otherwise, the Lisp
23313 string LISP_STRING is displayed. There's a case that STRING is
23314 non-null and LISP_STRING is not nil. It means STRING is a string
23315 data of LISP_STRING. In that case, we display LISP_STRING while
23316 ignoring its text properties.
23318 If FACE_STRING is not nil, FACE_STRING_POS is a position in
23319 FACE_STRING. Display STRING or LISP_STRING with the face at
23320 FACE_STRING_POS in FACE_STRING:
23322 Display the string in the environment given by IT, but use the
23323 standard display table, temporarily.
23325 FIELD_WIDTH is the minimum number of output glyphs to produce.
23326 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23327 with spaces. If STRING has more characters, more than FIELD_WIDTH
23328 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
23330 PRECISION is the maximum number of characters to output from
23331 STRING. PRECISION < 0 means don't truncate the string.
23333 This is roughly equivalent to printf format specifiers:
23335 FIELD_WIDTH PRECISION PRINTF
23336 ----------------------------------------
23337 -1 -1 %s
23338 -1 10 %.10s
23339 10 -1 %10s
23340 20 10 %20.10s
23342 MULTIBYTE zero means do not display multibyte chars, > 0 means do
23343 display them, and < 0 means obey the current buffer's value of
23344 enable_multibyte_characters.
23346 Value is the number of columns displayed. */
23348 static int
23349 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
23350 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
23351 int field_width, int precision, int max_x, int multibyte)
23353 int hpos_at_start = it->hpos;
23354 int saved_face_id = it->face_id;
23355 struct glyph_row *row = it->glyph_row;
23356 ptrdiff_t it_charpos;
23358 /* Initialize the iterator IT for iteration over STRING beginning
23359 with index START. */
23360 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
23361 precision, field_width, multibyte);
23362 if (string && STRINGP (lisp_string))
23363 /* LISP_STRING is the one returned by decode_mode_spec. We should
23364 ignore its text properties. */
23365 it->stop_charpos = it->end_charpos;
23367 /* If displaying STRING, set up the face of the iterator from
23368 FACE_STRING, if that's given. */
23369 if (STRINGP (face_string))
23371 ptrdiff_t endptr;
23372 struct face *face;
23374 it->face_id
23375 = face_at_string_position (it->w, face_string, face_string_pos,
23376 0, &endptr, it->base_face_id, 0);
23377 face = FACE_FROM_ID (it->f, it->face_id);
23378 it->face_box_p = face->box != FACE_NO_BOX;
23381 /* Set max_x to the maximum allowed X position. Don't let it go
23382 beyond the right edge of the window. */
23383 if (max_x <= 0)
23384 max_x = it->last_visible_x;
23385 else
23386 max_x = min (max_x, it->last_visible_x);
23388 /* Skip over display elements that are not visible. because IT->w is
23389 hscrolled. */
23390 if (it->current_x < it->first_visible_x)
23391 move_it_in_display_line_to (it, 100000, it->first_visible_x,
23392 MOVE_TO_POS | MOVE_TO_X);
23394 row->ascent = it->max_ascent;
23395 row->height = it->max_ascent + it->max_descent;
23396 row->phys_ascent = it->max_phys_ascent;
23397 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
23398 row->extra_line_spacing = it->max_extra_line_spacing;
23400 if (STRINGP (it->string))
23401 it_charpos = IT_STRING_CHARPOS (*it);
23402 else
23403 it_charpos = IT_CHARPOS (*it);
23405 /* This condition is for the case that we are called with current_x
23406 past last_visible_x. */
23407 while (it->current_x < max_x)
23409 int x_before, x, n_glyphs_before, i, nglyphs;
23411 /* Get the next display element. */
23412 if (!get_next_display_element (it))
23413 break;
23415 /* Produce glyphs. */
23416 x_before = it->current_x;
23417 n_glyphs_before = row->used[TEXT_AREA];
23418 PRODUCE_GLYPHS (it);
23420 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
23421 i = 0;
23422 x = x_before;
23423 while (i < nglyphs)
23425 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
23427 if (it->line_wrap != TRUNCATE
23428 && x + glyph->pixel_width > max_x)
23430 /* End of continued line or max_x reached. */
23431 if (CHAR_GLYPH_PADDING_P (*glyph))
23433 /* A wide character is unbreakable. */
23434 if (row->reversed_p)
23435 unproduce_glyphs (it, row->used[TEXT_AREA]
23436 - n_glyphs_before);
23437 row->used[TEXT_AREA] = n_glyphs_before;
23438 it->current_x = x_before;
23440 else
23442 if (row->reversed_p)
23443 unproduce_glyphs (it, row->used[TEXT_AREA]
23444 - (n_glyphs_before + i));
23445 row->used[TEXT_AREA] = n_glyphs_before + i;
23446 it->current_x = x;
23448 break;
23450 else if (x + glyph->pixel_width >= it->first_visible_x)
23452 /* Glyph is at least partially visible. */
23453 ++it->hpos;
23454 if (x < it->first_visible_x)
23455 row->x = x - it->first_visible_x;
23457 else
23459 /* Glyph is off the left margin of the display area.
23460 Should not happen. */
23461 emacs_abort ();
23464 row->ascent = max (row->ascent, it->max_ascent);
23465 row->height = max (row->height, it->max_ascent + it->max_descent);
23466 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
23467 row->phys_height = max (row->phys_height,
23468 it->max_phys_ascent + it->max_phys_descent);
23469 row->extra_line_spacing = max (row->extra_line_spacing,
23470 it->max_extra_line_spacing);
23471 x += glyph->pixel_width;
23472 ++i;
23475 /* Stop if max_x reached. */
23476 if (i < nglyphs)
23477 break;
23479 /* Stop at line ends. */
23480 if (ITERATOR_AT_END_OF_LINE_P (it))
23482 it->continuation_lines_width = 0;
23483 break;
23486 set_iterator_to_next (it, 1);
23487 if (STRINGP (it->string))
23488 it_charpos = IT_STRING_CHARPOS (*it);
23489 else
23490 it_charpos = IT_CHARPOS (*it);
23492 /* Stop if truncating at the right edge. */
23493 if (it->line_wrap == TRUNCATE
23494 && it->current_x >= it->last_visible_x)
23496 /* Add truncation mark, but don't do it if the line is
23497 truncated at a padding space. */
23498 if (it_charpos < it->string_nchars)
23500 if (!FRAME_WINDOW_P (it->f))
23502 int ii, n;
23504 if (it->current_x > it->last_visible_x)
23506 if (!row->reversed_p)
23508 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
23509 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23510 break;
23512 else
23514 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
23515 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
23516 break;
23517 unproduce_glyphs (it, ii + 1);
23518 ii = row->used[TEXT_AREA] - (ii + 1);
23520 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
23522 row->used[TEXT_AREA] = ii;
23523 produce_special_glyphs (it, IT_TRUNCATION);
23526 produce_special_glyphs (it, IT_TRUNCATION);
23528 row->truncated_on_right_p = 1;
23530 break;
23534 /* Maybe insert a truncation at the left. */
23535 if (it->first_visible_x
23536 && it_charpos > 0)
23538 if (!FRAME_WINDOW_P (it->f)
23539 || (row->reversed_p
23540 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23541 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
23542 insert_left_trunc_glyphs (it);
23543 row->truncated_on_left_p = 1;
23546 it->face_id = saved_face_id;
23548 /* Value is number of columns displayed. */
23549 return it->hpos - hpos_at_start;
23554 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
23555 appears as an element of LIST or as the car of an element of LIST.
23556 If PROPVAL is a list, compare each element against LIST in that
23557 way, and return 1/2 if any element of PROPVAL is found in LIST.
23558 Otherwise return 0. This function cannot quit.
23559 The return value is 2 if the text is invisible but with an ellipsis
23560 and 1 if it's invisible and without an ellipsis. */
23563 invisible_p (register Lisp_Object propval, Lisp_Object list)
23565 register Lisp_Object tail, proptail;
23567 for (tail = list; CONSP (tail); tail = XCDR (tail))
23569 register Lisp_Object tem;
23570 tem = XCAR (tail);
23571 if (EQ (propval, tem))
23572 return 1;
23573 if (CONSP (tem) && EQ (propval, XCAR (tem)))
23574 return NILP (XCDR (tem)) ? 1 : 2;
23577 if (CONSP (propval))
23579 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
23581 Lisp_Object propelt;
23582 propelt = XCAR (proptail);
23583 for (tail = list; CONSP (tail); tail = XCDR (tail))
23585 register Lisp_Object tem;
23586 tem = XCAR (tail);
23587 if (EQ (propelt, tem))
23588 return 1;
23589 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
23590 return NILP (XCDR (tem)) ? 1 : 2;
23595 return 0;
23598 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
23599 doc: /* Non-nil if the property makes the text invisible.
23600 POS-OR-PROP can be a marker or number, in which case it is taken to be
23601 a position in the current buffer and the value of the `invisible' property
23602 is checked; or it can be some other value, which is then presumed to be the
23603 value of the `invisible' property of the text of interest.
23604 The non-nil value returned can be t for truly invisible text or something
23605 else if the text is replaced by an ellipsis. */)
23606 (Lisp_Object pos_or_prop)
23608 Lisp_Object prop
23609 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
23610 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
23611 : pos_or_prop);
23612 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
23613 return (invis == 0 ? Qnil
23614 : invis == 1 ? Qt
23615 : make_number (invis));
23618 /* Calculate a width or height in pixels from a specification using
23619 the following elements:
23621 SPEC ::=
23622 NUM - a (fractional) multiple of the default font width/height
23623 (NUM) - specifies exactly NUM pixels
23624 UNIT - a fixed number of pixels, see below.
23625 ELEMENT - size of a display element in pixels, see below.
23626 (NUM . SPEC) - equals NUM * SPEC
23627 (+ SPEC SPEC ...) - add pixel values
23628 (- SPEC SPEC ...) - subtract pixel values
23629 (- SPEC) - negate pixel value
23631 NUM ::=
23632 INT or FLOAT - a number constant
23633 SYMBOL - use symbol's (buffer local) variable binding.
23635 UNIT ::=
23636 in - pixels per inch *)
23637 mm - pixels per 1/1000 meter *)
23638 cm - pixels per 1/100 meter *)
23639 width - width of current font in pixels.
23640 height - height of current font in pixels.
23642 *) using the ratio(s) defined in display-pixels-per-inch.
23644 ELEMENT ::=
23646 left-fringe - left fringe width in pixels
23647 right-fringe - right fringe width in pixels
23649 left-margin - left margin width in pixels
23650 right-margin - right margin width in pixels
23652 scroll-bar - scroll-bar area width in pixels
23654 Examples:
23656 Pixels corresponding to 5 inches:
23657 (5 . in)
23659 Total width of non-text areas on left side of window (if scroll-bar is on left):
23660 '(space :width (+ left-fringe left-margin scroll-bar))
23662 Align to first text column (in header line):
23663 '(space :align-to 0)
23665 Align to middle of text area minus half the width of variable `my-image'
23666 containing a loaded image:
23667 '(space :align-to (0.5 . (- text my-image)))
23669 Width of left margin minus width of 1 character in the default font:
23670 '(space :width (- left-margin 1))
23672 Width of left margin minus width of 2 characters in the current font:
23673 '(space :width (- left-margin (2 . width)))
23675 Center 1 character over left-margin (in header line):
23676 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
23678 Different ways to express width of left fringe plus left margin minus one pixel:
23679 '(space :width (- (+ left-fringe left-margin) (1)))
23680 '(space :width (+ left-fringe left-margin (- (1))))
23681 '(space :width (+ left-fringe left-margin (-1)))
23685 static int
23686 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
23687 struct font *font, int width_p, int *align_to)
23689 double pixels;
23691 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
23692 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
23694 if (NILP (prop))
23695 return OK_PIXELS (0);
23697 eassert (FRAME_LIVE_P (it->f));
23699 if (SYMBOLP (prop))
23701 if (SCHARS (SYMBOL_NAME (prop)) == 2)
23703 char *unit = SSDATA (SYMBOL_NAME (prop));
23705 if (unit[0] == 'i' && unit[1] == 'n')
23706 pixels = 1.0;
23707 else if (unit[0] == 'm' && unit[1] == 'm')
23708 pixels = 25.4;
23709 else if (unit[0] == 'c' && unit[1] == 'm')
23710 pixels = 2.54;
23711 else
23712 pixels = 0;
23713 if (pixels > 0)
23715 double ppi = (width_p ? FRAME_RES_X (it->f)
23716 : FRAME_RES_Y (it->f));
23718 if (ppi > 0)
23719 return OK_PIXELS (ppi / pixels);
23720 return 0;
23724 #ifdef HAVE_WINDOW_SYSTEM
23725 if (EQ (prop, Qheight))
23726 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
23727 if (EQ (prop, Qwidth))
23728 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
23729 #else
23730 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
23731 return OK_PIXELS (1);
23732 #endif
23734 if (EQ (prop, Qtext))
23735 return OK_PIXELS (width_p
23736 ? window_box_width (it->w, TEXT_AREA)
23737 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
23739 if (align_to && *align_to < 0)
23741 *res = 0;
23742 if (EQ (prop, Qleft))
23743 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
23744 if (EQ (prop, Qright))
23745 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
23746 if (EQ (prop, Qcenter))
23747 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
23748 + window_box_width (it->w, TEXT_AREA) / 2);
23749 if (EQ (prop, Qleft_fringe))
23750 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23751 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
23752 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
23753 if (EQ (prop, Qright_fringe))
23754 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23755 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23756 : window_box_right_offset (it->w, TEXT_AREA));
23757 if (EQ (prop, Qleft_margin))
23758 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
23759 if (EQ (prop, Qright_margin))
23760 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
23761 if (EQ (prop, Qscroll_bar))
23762 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
23764 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
23765 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
23766 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
23767 : 0)));
23769 else
23771 if (EQ (prop, Qleft_fringe))
23772 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
23773 if (EQ (prop, Qright_fringe))
23774 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
23775 if (EQ (prop, Qleft_margin))
23776 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
23777 if (EQ (prop, Qright_margin))
23778 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
23779 if (EQ (prop, Qscroll_bar))
23780 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
23783 prop = buffer_local_value (prop, it->w->contents);
23784 if (EQ (prop, Qunbound))
23785 prop = Qnil;
23788 if (INTEGERP (prop) || FLOATP (prop))
23790 int base_unit = (width_p
23791 ? FRAME_COLUMN_WIDTH (it->f)
23792 : FRAME_LINE_HEIGHT (it->f));
23793 return OK_PIXELS (XFLOATINT (prop) * base_unit);
23796 if (CONSP (prop))
23798 Lisp_Object car = XCAR (prop);
23799 Lisp_Object cdr = XCDR (prop);
23801 if (SYMBOLP (car))
23803 #ifdef HAVE_WINDOW_SYSTEM
23804 if (FRAME_WINDOW_P (it->f)
23805 && valid_image_p (prop))
23807 ptrdiff_t id = lookup_image (it->f, prop);
23808 struct image *img = IMAGE_FROM_ID (it->f, id);
23810 return OK_PIXELS (width_p ? img->width : img->height);
23812 #endif
23813 if (EQ (car, Qplus) || EQ (car, Qminus))
23815 int first = 1;
23816 double px;
23818 pixels = 0;
23819 while (CONSP (cdr))
23821 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
23822 font, width_p, align_to))
23823 return 0;
23824 if (first)
23825 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
23826 else
23827 pixels += px;
23828 cdr = XCDR (cdr);
23830 if (EQ (car, Qminus))
23831 pixels = -pixels;
23832 return OK_PIXELS (pixels);
23835 car = buffer_local_value (car, it->w->contents);
23836 if (EQ (car, Qunbound))
23837 car = Qnil;
23840 if (INTEGERP (car) || FLOATP (car))
23842 double fact;
23843 pixels = XFLOATINT (car);
23844 if (NILP (cdr))
23845 return OK_PIXELS (pixels);
23846 if (calc_pixel_width_or_height (&fact, it, cdr,
23847 font, width_p, align_to))
23848 return OK_PIXELS (pixels * fact);
23849 return 0;
23852 return 0;
23855 return 0;
23859 /***********************************************************************
23860 Glyph Display
23861 ***********************************************************************/
23863 #ifdef HAVE_WINDOW_SYSTEM
23865 #ifdef GLYPH_DEBUG
23867 void
23868 dump_glyph_string (struct glyph_string *s)
23870 fprintf (stderr, "glyph string\n");
23871 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
23872 s->x, s->y, s->width, s->height);
23873 fprintf (stderr, " ybase = %d\n", s->ybase);
23874 fprintf (stderr, " hl = %d\n", s->hl);
23875 fprintf (stderr, " left overhang = %d, right = %d\n",
23876 s->left_overhang, s->right_overhang);
23877 fprintf (stderr, " nchars = %d\n", s->nchars);
23878 fprintf (stderr, " extends to end of line = %d\n",
23879 s->extends_to_end_of_line_p);
23880 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
23881 fprintf (stderr, " bg width = %d\n", s->background_width);
23884 #endif /* GLYPH_DEBUG */
23886 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
23887 of XChar2b structures for S; it can't be allocated in
23888 init_glyph_string because it must be allocated via `alloca'. W
23889 is the window on which S is drawn. ROW and AREA are the glyph row
23890 and area within the row from which S is constructed. START is the
23891 index of the first glyph structure covered by S. HL is a
23892 face-override for drawing S. */
23894 #ifdef HAVE_NTGUI
23895 #define OPTIONAL_HDC(hdc) HDC hdc,
23896 #define DECLARE_HDC(hdc) HDC hdc;
23897 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
23898 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
23899 #endif
23901 #ifndef OPTIONAL_HDC
23902 #define OPTIONAL_HDC(hdc)
23903 #define DECLARE_HDC(hdc)
23904 #define ALLOCATE_HDC(hdc, f)
23905 #define RELEASE_HDC(hdc, f)
23906 #endif
23908 static void
23909 init_glyph_string (struct glyph_string *s,
23910 OPTIONAL_HDC (hdc)
23911 XChar2b *char2b, struct window *w, struct glyph_row *row,
23912 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
23914 memset (s, 0, sizeof *s);
23915 s->w = w;
23916 s->f = XFRAME (w->frame);
23917 #ifdef HAVE_NTGUI
23918 s->hdc = hdc;
23919 #endif
23920 s->display = FRAME_X_DISPLAY (s->f);
23921 s->window = FRAME_X_WINDOW (s->f);
23922 s->char2b = char2b;
23923 s->hl = hl;
23924 s->row = row;
23925 s->area = area;
23926 s->first_glyph = row->glyphs[area] + start;
23927 s->height = row->height;
23928 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
23929 s->ybase = s->y + row->ascent;
23933 /* Append the list of glyph strings with head H and tail T to the list
23934 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
23936 static void
23937 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23938 struct glyph_string *h, struct glyph_string *t)
23940 if (h)
23942 if (*head)
23943 (*tail)->next = h;
23944 else
23945 *head = h;
23946 h->prev = *tail;
23947 *tail = t;
23952 /* Prepend the list of glyph strings with head H and tail T to the
23953 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
23954 result. */
23956 static void
23957 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
23958 struct glyph_string *h, struct glyph_string *t)
23960 if (h)
23962 if (*head)
23963 (*head)->prev = t;
23964 else
23965 *tail = t;
23966 t->next = *head;
23967 *head = h;
23972 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
23973 Set *HEAD and *TAIL to the resulting list. */
23975 static void
23976 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
23977 struct glyph_string *s)
23979 s->next = s->prev = NULL;
23980 append_glyph_string_lists (head, tail, s, s);
23984 /* Get face and two-byte form of character C in face FACE_ID on frame F.
23985 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
23986 make sure that X resources for the face returned are allocated.
23987 Value is a pointer to a realized face that is ready for display if
23988 DISPLAY_P is non-zero. */
23990 static struct face *
23991 get_char_face_and_encoding (struct frame *f, int c, int face_id,
23992 XChar2b *char2b, int display_p)
23994 struct face *face = FACE_FROM_ID (f, face_id);
23995 unsigned code = 0;
23997 if (face->font)
23999 code = face->font->driver->encode_char (face->font, c);
24001 if (code == FONT_INVALID_CODE)
24002 code = 0;
24004 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24006 /* Make sure X resources of the face are allocated. */
24007 #ifdef HAVE_X_WINDOWS
24008 if (display_p)
24009 #endif
24011 eassert (face != NULL);
24012 prepare_face_for_display (f, face);
24015 return face;
24019 /* Get face and two-byte form of character glyph GLYPH on frame F.
24020 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
24021 a pointer to a realized face that is ready for display. */
24023 static struct face *
24024 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
24025 XChar2b *char2b, int *two_byte_p)
24027 struct face *face;
24028 unsigned code = 0;
24030 eassert (glyph->type == CHAR_GLYPH);
24031 face = FACE_FROM_ID (f, glyph->face_id);
24033 /* Make sure X resources of the face are allocated. */
24034 eassert (face != NULL);
24035 prepare_face_for_display (f, face);
24037 if (two_byte_p)
24038 *two_byte_p = 0;
24040 if (face->font)
24042 if (CHAR_BYTE8_P (glyph->u.ch))
24043 code = CHAR_TO_BYTE8 (glyph->u.ch);
24044 else
24045 code = face->font->driver->encode_char (face->font, glyph->u.ch);
24047 if (code == FONT_INVALID_CODE)
24048 code = 0;
24051 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24052 return face;
24056 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
24057 Return 1 if FONT has a glyph for C, otherwise return 0. */
24059 static int
24060 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
24062 unsigned code;
24064 if (CHAR_BYTE8_P (c))
24065 code = CHAR_TO_BYTE8 (c);
24066 else
24067 code = font->driver->encode_char (font, c);
24069 if (code == FONT_INVALID_CODE)
24070 return 0;
24071 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
24072 return 1;
24076 /* Fill glyph string S with composition components specified by S->cmp.
24078 BASE_FACE is the base face of the composition.
24079 S->cmp_from is the index of the first component for S.
24081 OVERLAPS non-zero means S should draw the foreground only, and use
24082 its physical height for clipping. See also draw_glyphs.
24084 Value is the index of a component not in S. */
24086 static int
24087 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
24088 int overlaps)
24090 int i;
24091 /* For all glyphs of this composition, starting at the offset
24092 S->cmp_from, until we reach the end of the definition or encounter a
24093 glyph that requires the different face, add it to S. */
24094 struct face *face;
24096 eassert (s);
24098 s->for_overlaps = overlaps;
24099 s->face = NULL;
24100 s->font = NULL;
24101 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
24103 int c = COMPOSITION_GLYPH (s->cmp, i);
24105 /* TAB in a composition means display glyphs with padding space
24106 on the left or right. */
24107 if (c != '\t')
24109 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
24110 -1, Qnil);
24112 face = get_char_face_and_encoding (s->f, c, face_id,
24113 s->char2b + i, 1);
24114 if (face)
24116 if (! s->face)
24118 s->face = face;
24119 s->font = s->face->font;
24121 else if (s->face != face)
24122 break;
24125 ++s->nchars;
24127 s->cmp_to = i;
24129 if (s->face == NULL)
24131 s->face = base_face->ascii_face;
24132 s->font = s->face->font;
24135 /* All glyph strings for the same composition has the same width,
24136 i.e. the width set for the first component of the composition. */
24137 s->width = s->first_glyph->pixel_width;
24139 /* If the specified font could not be loaded, use the frame's
24140 default font, but record the fact that we couldn't load it in
24141 the glyph string so that we can draw rectangles for the
24142 characters of the glyph string. */
24143 if (s->font == NULL)
24145 s->font_not_found_p = 1;
24146 s->font = FRAME_FONT (s->f);
24149 /* Adjust base line for subscript/superscript text. */
24150 s->ybase += s->first_glyph->voffset;
24152 /* This glyph string must always be drawn with 16-bit functions. */
24153 s->two_byte_p = 1;
24155 return s->cmp_to;
24158 static int
24159 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
24160 int start, int end, int overlaps)
24162 struct glyph *glyph, *last;
24163 Lisp_Object lgstring;
24164 int i;
24166 s->for_overlaps = overlaps;
24167 glyph = s->row->glyphs[s->area] + start;
24168 last = s->row->glyphs[s->area] + end;
24169 s->cmp_id = glyph->u.cmp.id;
24170 s->cmp_from = glyph->slice.cmp.from;
24171 s->cmp_to = glyph->slice.cmp.to + 1;
24172 s->face = FACE_FROM_ID (s->f, face_id);
24173 lgstring = composition_gstring_from_id (s->cmp_id);
24174 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
24175 glyph++;
24176 while (glyph < last
24177 && glyph->u.cmp.automatic
24178 && glyph->u.cmp.id == s->cmp_id
24179 && s->cmp_to == glyph->slice.cmp.from)
24180 s->cmp_to = (glyph++)->slice.cmp.to + 1;
24182 for (i = s->cmp_from; i < s->cmp_to; i++)
24184 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
24185 unsigned code = LGLYPH_CODE (lglyph);
24187 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
24189 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
24190 return glyph - s->row->glyphs[s->area];
24194 /* Fill glyph string S from a sequence glyphs for glyphless characters.
24195 See the comment of fill_glyph_string for arguments.
24196 Value is the index of the first glyph not in S. */
24199 static int
24200 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
24201 int start, int end, int overlaps)
24203 struct glyph *glyph, *last;
24204 int voffset;
24206 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
24207 s->for_overlaps = overlaps;
24208 glyph = s->row->glyphs[s->area] + start;
24209 last = s->row->glyphs[s->area] + end;
24210 voffset = glyph->voffset;
24211 s->face = FACE_FROM_ID (s->f, face_id);
24212 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
24213 s->nchars = 1;
24214 s->width = glyph->pixel_width;
24215 glyph++;
24216 while (glyph < last
24217 && glyph->type == GLYPHLESS_GLYPH
24218 && glyph->voffset == voffset
24219 && glyph->face_id == face_id)
24221 s->nchars++;
24222 s->width += glyph->pixel_width;
24223 glyph++;
24225 s->ybase += voffset;
24226 return glyph - s->row->glyphs[s->area];
24230 /* Fill glyph string S from a sequence of character glyphs.
24232 FACE_ID is the face id of the string. START is the index of the
24233 first glyph to consider, END is the index of the last + 1.
24234 OVERLAPS non-zero means S should draw the foreground only, and use
24235 its physical height for clipping. See also draw_glyphs.
24237 Value is the index of the first glyph not in S. */
24239 static int
24240 fill_glyph_string (struct glyph_string *s, int face_id,
24241 int start, int end, int overlaps)
24243 struct glyph *glyph, *last;
24244 int voffset;
24245 int glyph_not_available_p;
24247 eassert (s->f == XFRAME (s->w->frame));
24248 eassert (s->nchars == 0);
24249 eassert (start >= 0 && end > start);
24251 s->for_overlaps = overlaps;
24252 glyph = s->row->glyphs[s->area] + start;
24253 last = s->row->glyphs[s->area] + end;
24254 voffset = glyph->voffset;
24255 s->padding_p = glyph->padding_p;
24256 glyph_not_available_p = glyph->glyph_not_available_p;
24258 while (glyph < last
24259 && glyph->type == CHAR_GLYPH
24260 && glyph->voffset == voffset
24261 /* Same face id implies same font, nowadays. */
24262 && glyph->face_id == face_id
24263 && glyph->glyph_not_available_p == glyph_not_available_p)
24265 int two_byte_p;
24267 s->face = get_glyph_face_and_encoding (s->f, glyph,
24268 s->char2b + s->nchars,
24269 &two_byte_p);
24270 s->two_byte_p = two_byte_p;
24271 ++s->nchars;
24272 eassert (s->nchars <= end - start);
24273 s->width += glyph->pixel_width;
24274 if (glyph++->padding_p != s->padding_p)
24275 break;
24278 s->font = s->face->font;
24280 /* If the specified font could not be loaded, use the frame's font,
24281 but record the fact that we couldn't load it in
24282 S->font_not_found_p so that we can draw rectangles for the
24283 characters of the glyph string. */
24284 if (s->font == NULL || glyph_not_available_p)
24286 s->font_not_found_p = 1;
24287 s->font = FRAME_FONT (s->f);
24290 /* Adjust base line for subscript/superscript text. */
24291 s->ybase += voffset;
24293 eassert (s->face && s->face->gc);
24294 return glyph - s->row->glyphs[s->area];
24298 /* Fill glyph string S from image glyph S->first_glyph. */
24300 static void
24301 fill_image_glyph_string (struct glyph_string *s)
24303 eassert (s->first_glyph->type == IMAGE_GLYPH);
24304 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
24305 eassert (s->img);
24306 s->slice = s->first_glyph->slice.img;
24307 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
24308 s->font = s->face->font;
24309 s->width = s->first_glyph->pixel_width;
24311 /* Adjust base line for subscript/superscript text. */
24312 s->ybase += s->first_glyph->voffset;
24316 /* Fill glyph string S from a sequence of stretch glyphs.
24318 START is the index of the first glyph to consider,
24319 END is the index of the last + 1.
24321 Value is the index of the first glyph not in S. */
24323 static int
24324 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
24326 struct glyph *glyph, *last;
24327 int voffset, face_id;
24329 eassert (s->first_glyph->type == STRETCH_GLYPH);
24331 glyph = s->row->glyphs[s->area] + start;
24332 last = s->row->glyphs[s->area] + end;
24333 face_id = glyph->face_id;
24334 s->face = FACE_FROM_ID (s->f, face_id);
24335 s->font = s->face->font;
24336 s->width = glyph->pixel_width;
24337 s->nchars = 1;
24338 voffset = glyph->voffset;
24340 for (++glyph;
24341 (glyph < last
24342 && glyph->type == STRETCH_GLYPH
24343 && glyph->voffset == voffset
24344 && glyph->face_id == face_id);
24345 ++glyph)
24346 s->width += glyph->pixel_width;
24348 /* Adjust base line for subscript/superscript text. */
24349 s->ybase += voffset;
24351 /* The case that face->gc == 0 is handled when drawing the glyph
24352 string by calling prepare_face_for_display. */
24353 eassert (s->face);
24354 return glyph - s->row->glyphs[s->area];
24357 static struct font_metrics *
24358 get_per_char_metric (struct font *font, XChar2b *char2b)
24360 static struct font_metrics metrics;
24361 unsigned code;
24363 if (! font)
24364 return NULL;
24365 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
24366 if (code == FONT_INVALID_CODE)
24367 return NULL;
24368 font->driver->text_extents (font, &code, 1, &metrics);
24369 return &metrics;
24372 /* EXPORT for RIF:
24373 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
24374 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
24375 assumed to be zero. */
24377 void
24378 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
24380 *left = *right = 0;
24382 if (glyph->type == CHAR_GLYPH)
24384 struct face *face;
24385 XChar2b char2b;
24386 struct font_metrics *pcm;
24388 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
24389 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
24391 if (pcm->rbearing > pcm->width)
24392 *right = pcm->rbearing - pcm->width;
24393 if (pcm->lbearing < 0)
24394 *left = -pcm->lbearing;
24397 else if (glyph->type == COMPOSITE_GLYPH)
24399 if (! glyph->u.cmp.automatic)
24401 struct composition *cmp = composition_table[glyph->u.cmp.id];
24403 if (cmp->rbearing > cmp->pixel_width)
24404 *right = cmp->rbearing - cmp->pixel_width;
24405 if (cmp->lbearing < 0)
24406 *left = - cmp->lbearing;
24408 else
24410 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
24411 struct font_metrics metrics;
24413 composition_gstring_width (gstring, glyph->slice.cmp.from,
24414 glyph->slice.cmp.to + 1, &metrics);
24415 if (metrics.rbearing > metrics.width)
24416 *right = metrics.rbearing - metrics.width;
24417 if (metrics.lbearing < 0)
24418 *left = - metrics.lbearing;
24424 /* Return the index of the first glyph preceding glyph string S that
24425 is overwritten by S because of S's left overhang. Value is -1
24426 if no glyphs are overwritten. */
24428 static int
24429 left_overwritten (struct glyph_string *s)
24431 int k;
24433 if (s->left_overhang)
24435 int x = 0, i;
24436 struct glyph *glyphs = s->row->glyphs[s->area];
24437 int first = s->first_glyph - glyphs;
24439 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
24440 x -= glyphs[i].pixel_width;
24442 k = i + 1;
24444 else
24445 k = -1;
24447 return k;
24451 /* Return the index of the first glyph preceding glyph string S that
24452 is overwriting S because of its right overhang. Value is -1 if no
24453 glyph in front of S overwrites S. */
24455 static int
24456 left_overwriting (struct glyph_string *s)
24458 int i, k, x;
24459 struct glyph *glyphs = s->row->glyphs[s->area];
24460 int first = s->first_glyph - glyphs;
24462 k = -1;
24463 x = 0;
24464 for (i = first - 1; i >= 0; --i)
24466 int left, right;
24467 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24468 if (x + right > 0)
24469 k = i;
24470 x -= glyphs[i].pixel_width;
24473 return k;
24477 /* Return the index of the last glyph following glyph string S that is
24478 overwritten by S because of S's right overhang. Value is -1 if
24479 no such glyph is found. */
24481 static int
24482 right_overwritten (struct glyph_string *s)
24484 int k = -1;
24486 if (s->right_overhang)
24488 int x = 0, i;
24489 struct glyph *glyphs = s->row->glyphs[s->area];
24490 int first = (s->first_glyph - glyphs
24491 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24492 int end = s->row->used[s->area];
24494 for (i = first; i < end && s->right_overhang > x; ++i)
24495 x += glyphs[i].pixel_width;
24497 k = i;
24500 return k;
24504 /* Return the index of the last glyph following glyph string S that
24505 overwrites S because of its left overhang. Value is negative
24506 if no such glyph is found. */
24508 static int
24509 right_overwriting (struct glyph_string *s)
24511 int i, k, x;
24512 int end = s->row->used[s->area];
24513 struct glyph *glyphs = s->row->glyphs[s->area];
24514 int first = (s->first_glyph - glyphs
24515 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
24517 k = -1;
24518 x = 0;
24519 for (i = first; i < end; ++i)
24521 int left, right;
24522 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
24523 if (x - left < 0)
24524 k = i;
24525 x += glyphs[i].pixel_width;
24528 return k;
24532 /* Set background width of glyph string S. START is the index of the
24533 first glyph following S. LAST_X is the right-most x-position + 1
24534 in the drawing area. */
24536 static void
24537 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
24539 /* If the face of this glyph string has to be drawn to the end of
24540 the drawing area, set S->extends_to_end_of_line_p. */
24542 if (start == s->row->used[s->area]
24543 && ((s->row->fill_line_p
24544 && (s->hl == DRAW_NORMAL_TEXT
24545 || s->hl == DRAW_IMAGE_RAISED
24546 || s->hl == DRAW_IMAGE_SUNKEN))
24547 || s->hl == DRAW_MOUSE_FACE))
24548 s->extends_to_end_of_line_p = 1;
24550 /* If S extends its face to the end of the line, set its
24551 background_width to the distance to the right edge of the drawing
24552 area. */
24553 if (s->extends_to_end_of_line_p)
24554 s->background_width = last_x - s->x + 1;
24555 else
24556 s->background_width = s->width;
24560 /* Compute overhangs and x-positions for glyph string S and its
24561 predecessors, or successors. X is the starting x-position for S.
24562 BACKWARD_P non-zero means process predecessors. */
24564 static void
24565 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24567 if (backward_p)
24569 while (s)
24571 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24572 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24573 x -= s->width;
24574 s->x = x;
24575 s = s->prev;
24578 else
24580 while (s)
24582 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
24583 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
24584 s->x = x;
24585 x += s->width;
24586 s = s->next;
24593 /* The following macros are only called from draw_glyphs below.
24594 They reference the following parameters of that function directly:
24595 `w', `row', `area', and `overlap_p'
24596 as well as the following local variables:
24597 `s', `f', and `hdc' (in W32) */
24599 #ifdef HAVE_NTGUI
24600 /* On W32, silently add local `hdc' variable to argument list of
24601 init_glyph_string. */
24602 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24603 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
24604 #else
24605 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
24606 init_glyph_string (s, char2b, w, row, area, start, hl)
24607 #endif
24609 /* Add a glyph string for a stretch glyph to the list of strings
24610 between HEAD and TAIL. START is the index of the stretch glyph in
24611 row area AREA of glyph row ROW. END is the index of the last glyph
24612 in that glyph row area. X is the current output position assigned
24613 to the new glyph string constructed. HL overrides that face of the
24614 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24615 is the right-most x-position of the drawing area. */
24617 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
24618 and below -- keep them on one line. */
24619 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24620 do \
24622 s = alloca (sizeof *s); \
24623 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24624 START = fill_stretch_glyph_string (s, START, END); \
24625 append_glyph_string (&HEAD, &TAIL, s); \
24626 s->x = (X); \
24628 while (0)
24631 /* Add a glyph string for an image glyph to the list of strings
24632 between HEAD and TAIL. START is the index of the image glyph in
24633 row area AREA of glyph row ROW. END is the index of the last glyph
24634 in that glyph row area. X is the current output position assigned
24635 to the new glyph string constructed. HL overrides that face of the
24636 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
24637 is the right-most x-position of the drawing area. */
24639 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24640 do \
24642 s = alloca (sizeof *s); \
24643 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24644 fill_image_glyph_string (s); \
24645 append_glyph_string (&HEAD, &TAIL, s); \
24646 ++START; \
24647 s->x = (X); \
24649 while (0)
24652 /* Add a glyph string for a sequence of character glyphs to the list
24653 of strings between HEAD and TAIL. START is the index of the first
24654 glyph in row area AREA of glyph row ROW that is part of the new
24655 glyph string. END is the index of the last glyph in that glyph row
24656 area. X is the current output position assigned to the new glyph
24657 string constructed. HL overrides that face of the glyph; e.g. it
24658 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
24659 right-most x-position of the drawing area. */
24661 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24662 do \
24664 int face_id; \
24665 XChar2b *char2b; \
24667 face_id = (row)->glyphs[area][START].face_id; \
24669 s = alloca (sizeof *s); \
24670 char2b = alloca ((END - START) * sizeof *char2b); \
24671 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24672 append_glyph_string (&HEAD, &TAIL, s); \
24673 s->x = (X); \
24674 START = fill_glyph_string (s, face_id, START, END, overlaps); \
24676 while (0)
24679 /* Add a glyph string for a composite sequence to the list of strings
24680 between HEAD and TAIL. START is the index of the first glyph in
24681 row area AREA of glyph row ROW that is part of the new glyph
24682 string. END is the index of the last glyph in that glyph row area.
24683 X is the current output position assigned to the new glyph string
24684 constructed. HL overrides that face of the glyph; e.g. it is
24685 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
24686 x-position of the drawing area. */
24688 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24689 do { \
24690 int face_id = (row)->glyphs[area][START].face_id; \
24691 struct face *base_face = FACE_FROM_ID (f, face_id); \
24692 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
24693 struct composition *cmp = composition_table[cmp_id]; \
24694 XChar2b *char2b; \
24695 struct glyph_string *first_s = NULL; \
24696 int n; \
24698 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
24700 /* Make glyph_strings for each glyph sequence that is drawable by \
24701 the same face, and append them to HEAD/TAIL. */ \
24702 for (n = 0; n < cmp->glyph_len;) \
24704 s = alloca (sizeof *s); \
24705 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24706 append_glyph_string (&(HEAD), &(TAIL), s); \
24707 s->cmp = cmp; \
24708 s->cmp_from = n; \
24709 s->x = (X); \
24710 if (n == 0) \
24711 first_s = s; \
24712 n = fill_composite_glyph_string (s, base_face, overlaps); \
24715 ++START; \
24716 s = first_s; \
24717 } while (0)
24720 /* Add a glyph string for a glyph-string sequence to the list of strings
24721 between HEAD and TAIL. */
24723 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24724 do { \
24725 int face_id; \
24726 XChar2b *char2b; \
24727 Lisp_Object gstring; \
24729 face_id = (row)->glyphs[area][START].face_id; \
24730 gstring = (composition_gstring_from_id \
24731 ((row)->glyphs[area][START].u.cmp.id)); \
24732 s = alloca (sizeof *s); \
24733 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
24734 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24735 append_glyph_string (&(HEAD), &(TAIL), s); \
24736 s->x = (X); \
24737 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
24738 } while (0)
24741 /* Add a glyph string for a sequence of glyphless character's glyphs
24742 to the list of strings between HEAD and TAIL. The meanings of
24743 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
24745 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
24746 do \
24748 int face_id; \
24750 face_id = (row)->glyphs[area][START].face_id; \
24752 s = alloca (sizeof *s); \
24753 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
24754 append_glyph_string (&HEAD, &TAIL, s); \
24755 s->x = (X); \
24756 START = fill_glyphless_glyph_string (s, face_id, START, END, \
24757 overlaps); \
24759 while (0)
24762 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
24763 of AREA of glyph row ROW on window W between indices START and END.
24764 HL overrides the face for drawing glyph strings, e.g. it is
24765 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
24766 x-positions of the drawing area.
24768 This is an ugly monster macro construct because we must use alloca
24769 to allocate glyph strings (because draw_glyphs can be called
24770 asynchronously). */
24772 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
24773 do \
24775 HEAD = TAIL = NULL; \
24776 while (START < END) \
24778 struct glyph *first_glyph = (row)->glyphs[area] + START; \
24779 switch (first_glyph->type) \
24781 case CHAR_GLYPH: \
24782 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
24783 HL, X, LAST_X); \
24784 break; \
24786 case COMPOSITE_GLYPH: \
24787 if (first_glyph->u.cmp.automatic) \
24788 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
24789 HL, X, LAST_X); \
24790 else \
24791 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
24792 HL, X, LAST_X); \
24793 break; \
24795 case STRETCH_GLYPH: \
24796 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
24797 HL, X, LAST_X); \
24798 break; \
24800 case IMAGE_GLYPH: \
24801 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
24802 HL, X, LAST_X); \
24803 break; \
24805 case GLYPHLESS_GLYPH: \
24806 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
24807 HL, X, LAST_X); \
24808 break; \
24810 default: \
24811 emacs_abort (); \
24814 if (s) \
24816 set_glyph_string_background_width (s, START, LAST_X); \
24817 (X) += s->width; \
24820 } while (0)
24823 /* Draw glyphs between START and END in AREA of ROW on window W,
24824 starting at x-position X. X is relative to AREA in W. HL is a
24825 face-override with the following meaning:
24827 DRAW_NORMAL_TEXT draw normally
24828 DRAW_CURSOR draw in cursor face
24829 DRAW_MOUSE_FACE draw in mouse face.
24830 DRAW_INVERSE_VIDEO draw in mode line face
24831 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
24832 DRAW_IMAGE_RAISED draw an image with a raised relief around it
24834 If OVERLAPS is non-zero, draw only the foreground of characters and
24835 clip to the physical height of ROW. Non-zero value also defines
24836 the overlapping part to be drawn:
24838 OVERLAPS_PRED overlap with preceding rows
24839 OVERLAPS_SUCC overlap with succeeding rows
24840 OVERLAPS_BOTH overlap with both preceding/succeeding rows
24841 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
24843 Value is the x-position reached, relative to AREA of W. */
24845 static int
24846 draw_glyphs (struct window *w, int x, struct glyph_row *row,
24847 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
24848 enum draw_glyphs_face hl, int overlaps)
24850 struct glyph_string *head, *tail;
24851 struct glyph_string *s;
24852 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
24853 int i, j, x_reached, last_x, area_left = 0;
24854 struct frame *f = XFRAME (WINDOW_FRAME (w));
24855 DECLARE_HDC (hdc);
24857 ALLOCATE_HDC (hdc, f);
24859 /* Let's rather be paranoid than getting a SEGV. */
24860 end = min (end, row->used[area]);
24861 start = clip_to_bounds (0, start, end);
24863 /* Translate X to frame coordinates. Set last_x to the right
24864 end of the drawing area. */
24865 if (row->full_width_p)
24867 /* X is relative to the left edge of W, without scroll bars
24868 or fringes. */
24869 area_left = WINDOW_LEFT_EDGE_X (w);
24870 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
24871 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
24873 else
24875 area_left = window_box_left (w, area);
24876 last_x = area_left + window_box_width (w, area);
24878 x += area_left;
24880 /* Build a doubly-linked list of glyph_string structures between
24881 head and tail from what we have to draw. Note that the macro
24882 BUILD_GLYPH_STRINGS will modify its start parameter. That's
24883 the reason we use a separate variable `i'. */
24884 i = start;
24885 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
24886 if (tail)
24887 x_reached = tail->x + tail->background_width;
24888 else
24889 x_reached = x;
24891 /* If there are any glyphs with lbearing < 0 or rbearing > width in
24892 the row, redraw some glyphs in front or following the glyph
24893 strings built above. */
24894 if (head && !overlaps && row->contains_overlapping_glyphs_p)
24896 struct glyph_string *h, *t;
24897 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24898 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
24899 int check_mouse_face = 0;
24900 int dummy_x = 0;
24902 /* If mouse highlighting is on, we may need to draw adjacent
24903 glyphs using mouse-face highlighting. */
24904 if (area == TEXT_AREA && row->mouse_face_p
24905 && hlinfo->mouse_face_beg_row >= 0
24906 && hlinfo->mouse_face_end_row >= 0)
24908 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
24910 if (row_vpos >= hlinfo->mouse_face_beg_row
24911 && row_vpos <= hlinfo->mouse_face_end_row)
24913 check_mouse_face = 1;
24914 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
24915 ? hlinfo->mouse_face_beg_col : 0;
24916 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
24917 ? hlinfo->mouse_face_end_col
24918 : row->used[TEXT_AREA];
24922 /* Compute overhangs for all glyph strings. */
24923 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
24924 for (s = head; s; s = s->next)
24925 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
24927 /* Prepend glyph strings for glyphs in front of the first glyph
24928 string that are overwritten because of the first glyph
24929 string's left overhang. The background of all strings
24930 prepended must be drawn because the first glyph string
24931 draws over it. */
24932 i = left_overwritten (head);
24933 if (i >= 0)
24935 enum draw_glyphs_face overlap_hl;
24937 /* If this row contains mouse highlighting, attempt to draw
24938 the overlapped glyphs with the correct highlight. This
24939 code fails if the overlap encompasses more than one glyph
24940 and mouse-highlight spans only some of these glyphs.
24941 However, making it work perfectly involves a lot more
24942 code, and I don't know if the pathological case occurs in
24943 practice, so we'll stick to this for now. --- cyd */
24944 if (check_mouse_face
24945 && mouse_beg_col < start && mouse_end_col > i)
24946 overlap_hl = DRAW_MOUSE_FACE;
24947 else
24948 overlap_hl = DRAW_NORMAL_TEXT;
24950 if (hl != overlap_hl)
24951 clip_head = head;
24952 j = i;
24953 BUILD_GLYPH_STRINGS (j, start, h, t,
24954 overlap_hl, dummy_x, last_x);
24955 start = i;
24956 compute_overhangs_and_x (t, head->x, 1);
24957 prepend_glyph_string_lists (&head, &tail, h, t);
24958 if (clip_head == NULL)
24959 clip_head = head;
24962 /* Prepend glyph strings for glyphs in front of the first glyph
24963 string that overwrite that glyph string because of their
24964 right overhang. For these strings, only the foreground must
24965 be drawn, because it draws over the glyph string at `head'.
24966 The background must not be drawn because this would overwrite
24967 right overhangs of preceding glyphs for which no glyph
24968 strings exist. */
24969 i = left_overwriting (head);
24970 if (i >= 0)
24972 enum draw_glyphs_face overlap_hl;
24974 if (check_mouse_face
24975 && mouse_beg_col < start && mouse_end_col > i)
24976 overlap_hl = DRAW_MOUSE_FACE;
24977 else
24978 overlap_hl = DRAW_NORMAL_TEXT;
24980 if (hl == overlap_hl || clip_head == NULL)
24981 clip_head = head;
24982 BUILD_GLYPH_STRINGS (i, start, h, t,
24983 overlap_hl, dummy_x, last_x);
24984 for (s = h; s; s = s->next)
24985 s->background_filled_p = 1;
24986 compute_overhangs_and_x (t, head->x, 1);
24987 prepend_glyph_string_lists (&head, &tail, h, t);
24990 /* Append glyphs strings for glyphs following the last glyph
24991 string tail that are overwritten by tail. The background of
24992 these strings has to be drawn because tail's foreground draws
24993 over it. */
24994 i = right_overwritten (tail);
24995 if (i >= 0)
24997 enum draw_glyphs_face overlap_hl;
24999 if (check_mouse_face
25000 && mouse_beg_col < i && mouse_end_col > end)
25001 overlap_hl = DRAW_MOUSE_FACE;
25002 else
25003 overlap_hl = DRAW_NORMAL_TEXT;
25005 if (hl != overlap_hl)
25006 clip_tail = tail;
25007 BUILD_GLYPH_STRINGS (end, i, h, t,
25008 overlap_hl, x, last_x);
25009 /* Because BUILD_GLYPH_STRINGS updates the first argument,
25010 we don't have `end = i;' here. */
25011 compute_overhangs_and_x (h, tail->x + tail->width, 0);
25012 append_glyph_string_lists (&head, &tail, h, t);
25013 if (clip_tail == NULL)
25014 clip_tail = tail;
25017 /* Append glyph strings for glyphs following the last glyph
25018 string tail that overwrite tail. The foreground of such
25019 glyphs has to be drawn because it writes into the background
25020 of tail. The background must not be drawn because it could
25021 paint over the foreground of following glyphs. */
25022 i = right_overwriting (tail);
25023 if (i >= 0)
25025 enum draw_glyphs_face overlap_hl;
25026 if (check_mouse_face
25027 && mouse_beg_col < i && mouse_end_col > end)
25028 overlap_hl = DRAW_MOUSE_FACE;
25029 else
25030 overlap_hl = DRAW_NORMAL_TEXT;
25032 if (hl == overlap_hl || clip_tail == NULL)
25033 clip_tail = tail;
25034 i++; /* We must include the Ith glyph. */
25035 BUILD_GLYPH_STRINGS (end, i, h, t,
25036 overlap_hl, x, last_x);
25037 for (s = h; s; s = s->next)
25038 s->background_filled_p = 1;
25039 compute_overhangs_and_x (h, tail->x + tail->width, 0);
25040 append_glyph_string_lists (&head, &tail, h, t);
25042 if (clip_head || clip_tail)
25043 for (s = head; s; s = s->next)
25045 s->clip_head = clip_head;
25046 s->clip_tail = clip_tail;
25050 /* Draw all strings. */
25051 for (s = head; s; s = s->next)
25052 FRAME_RIF (f)->draw_glyph_string (s);
25054 #ifndef HAVE_NS
25055 /* When focus a sole frame and move horizontally, this sets on_p to 0
25056 causing a failure to erase prev cursor position. */
25057 if (area == TEXT_AREA
25058 && !row->full_width_p
25059 /* When drawing overlapping rows, only the glyph strings'
25060 foreground is drawn, which doesn't erase a cursor
25061 completely. */
25062 && !overlaps)
25064 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
25065 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
25066 : (tail ? tail->x + tail->background_width : x));
25067 x0 -= area_left;
25068 x1 -= area_left;
25070 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
25071 row->y, MATRIX_ROW_BOTTOM_Y (row));
25073 #endif
25075 /* Value is the x-position up to which drawn, relative to AREA of W.
25076 This doesn't include parts drawn because of overhangs. */
25077 if (row->full_width_p)
25078 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
25079 else
25080 x_reached -= area_left;
25082 RELEASE_HDC (hdc, f);
25084 return x_reached;
25087 /* Expand row matrix if too narrow. Don't expand if area
25088 is not present. */
25090 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
25092 if (!it->f->fonts_changed \
25093 && (it->glyph_row->glyphs[area] \
25094 < it->glyph_row->glyphs[area + 1])) \
25096 it->w->ncols_scale_factor++; \
25097 it->f->fonts_changed = 1; \
25101 /* Store one glyph for IT->char_to_display in IT->glyph_row.
25102 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25104 static void
25105 append_glyph (struct it *it)
25107 struct glyph *glyph;
25108 enum glyph_row_area area = it->area;
25110 eassert (it->glyph_row);
25111 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
25113 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25114 if (glyph < it->glyph_row->glyphs[area + 1])
25116 /* If the glyph row is reversed, we need to prepend the glyph
25117 rather than append it. */
25118 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25120 struct glyph *g;
25122 /* Make room for the additional glyph. */
25123 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25124 g[1] = *g;
25125 glyph = it->glyph_row->glyphs[area];
25127 glyph->charpos = CHARPOS (it->position);
25128 glyph->object = it->object;
25129 if (it->pixel_width > 0)
25131 glyph->pixel_width = it->pixel_width;
25132 glyph->padding_p = 0;
25134 else
25136 /* Assure at least 1-pixel width. Otherwise, cursor can't
25137 be displayed correctly. */
25138 glyph->pixel_width = 1;
25139 glyph->padding_p = 1;
25141 glyph->ascent = it->ascent;
25142 glyph->descent = it->descent;
25143 glyph->voffset = it->voffset;
25144 glyph->type = CHAR_GLYPH;
25145 glyph->avoid_cursor_p = it->avoid_cursor_p;
25146 glyph->multibyte_p = it->multibyte_p;
25147 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25149 /* In R2L rows, the left and the right box edges need to be
25150 drawn in reverse direction. */
25151 glyph->right_box_line_p = it->start_of_box_run_p;
25152 glyph->left_box_line_p = it->end_of_box_run_p;
25154 else
25156 glyph->left_box_line_p = it->start_of_box_run_p;
25157 glyph->right_box_line_p = it->end_of_box_run_p;
25159 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25160 || it->phys_descent > it->descent);
25161 glyph->glyph_not_available_p = it->glyph_not_available_p;
25162 glyph->face_id = it->face_id;
25163 glyph->u.ch = it->char_to_display;
25164 glyph->slice.img = null_glyph_slice;
25165 glyph->font_type = FONT_TYPE_UNKNOWN;
25166 if (it->bidi_p)
25168 glyph->resolved_level = it->bidi_it.resolved_level;
25169 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25170 emacs_abort ();
25171 glyph->bidi_type = it->bidi_it.type;
25173 else
25175 glyph->resolved_level = 0;
25176 glyph->bidi_type = UNKNOWN_BT;
25178 ++it->glyph_row->used[area];
25180 else
25181 IT_EXPAND_MATRIX_WIDTH (it, area);
25184 /* Store one glyph for the composition IT->cmp_it.id in
25185 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
25186 non-null. */
25188 static void
25189 append_composite_glyph (struct it *it)
25191 struct glyph *glyph;
25192 enum glyph_row_area area = it->area;
25194 eassert (it->glyph_row);
25196 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25197 if (glyph < it->glyph_row->glyphs[area + 1])
25199 /* If the glyph row is reversed, we need to prepend the glyph
25200 rather than append it. */
25201 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
25203 struct glyph *g;
25205 /* Make room for the new glyph. */
25206 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
25207 g[1] = *g;
25208 glyph = it->glyph_row->glyphs[it->area];
25210 glyph->charpos = it->cmp_it.charpos;
25211 glyph->object = it->object;
25212 glyph->pixel_width = it->pixel_width;
25213 glyph->ascent = it->ascent;
25214 glyph->descent = it->descent;
25215 glyph->voffset = it->voffset;
25216 glyph->type = COMPOSITE_GLYPH;
25217 if (it->cmp_it.ch < 0)
25219 glyph->u.cmp.automatic = 0;
25220 glyph->u.cmp.id = it->cmp_it.id;
25221 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
25223 else
25225 glyph->u.cmp.automatic = 1;
25226 glyph->u.cmp.id = it->cmp_it.id;
25227 glyph->slice.cmp.from = it->cmp_it.from;
25228 glyph->slice.cmp.to = it->cmp_it.to - 1;
25230 glyph->avoid_cursor_p = it->avoid_cursor_p;
25231 glyph->multibyte_p = it->multibyte_p;
25232 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25234 /* In R2L rows, the left and the right box edges need to be
25235 drawn in reverse direction. */
25236 glyph->right_box_line_p = it->start_of_box_run_p;
25237 glyph->left_box_line_p = it->end_of_box_run_p;
25239 else
25241 glyph->left_box_line_p = it->start_of_box_run_p;
25242 glyph->right_box_line_p = it->end_of_box_run_p;
25244 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25245 || it->phys_descent > it->descent);
25246 glyph->padding_p = 0;
25247 glyph->glyph_not_available_p = 0;
25248 glyph->face_id = it->face_id;
25249 glyph->font_type = FONT_TYPE_UNKNOWN;
25250 if (it->bidi_p)
25252 glyph->resolved_level = it->bidi_it.resolved_level;
25253 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25254 emacs_abort ();
25255 glyph->bidi_type = it->bidi_it.type;
25257 ++it->glyph_row->used[area];
25259 else
25260 IT_EXPAND_MATRIX_WIDTH (it, area);
25264 /* Change IT->ascent and IT->height according to the setting of
25265 IT->voffset. */
25267 static void
25268 take_vertical_position_into_account (struct it *it)
25270 if (it->voffset)
25272 if (it->voffset < 0)
25273 /* Increase the ascent so that we can display the text higher
25274 in the line. */
25275 it->ascent -= it->voffset;
25276 else
25277 /* Increase the descent so that we can display the text lower
25278 in the line. */
25279 it->descent += it->voffset;
25284 /* Produce glyphs/get display metrics for the image IT is loaded with.
25285 See the description of struct display_iterator in dispextern.h for
25286 an overview of struct display_iterator. */
25288 static void
25289 produce_image_glyph (struct it *it)
25291 struct image *img;
25292 struct face *face;
25293 int glyph_ascent, crop;
25294 struct glyph_slice slice;
25296 eassert (it->what == IT_IMAGE);
25298 face = FACE_FROM_ID (it->f, it->face_id);
25299 eassert (face);
25300 /* Make sure X resources of the face is loaded. */
25301 prepare_face_for_display (it->f, face);
25303 if (it->image_id < 0)
25305 /* Fringe bitmap. */
25306 it->ascent = it->phys_ascent = 0;
25307 it->descent = it->phys_descent = 0;
25308 it->pixel_width = 0;
25309 it->nglyphs = 0;
25310 return;
25313 img = IMAGE_FROM_ID (it->f, it->image_id);
25314 eassert (img);
25315 /* Make sure X resources of the image is loaded. */
25316 prepare_image_for_display (it->f, img);
25318 slice.x = slice.y = 0;
25319 slice.width = img->width;
25320 slice.height = img->height;
25322 if (INTEGERP (it->slice.x))
25323 slice.x = XINT (it->slice.x);
25324 else if (FLOATP (it->slice.x))
25325 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
25327 if (INTEGERP (it->slice.y))
25328 slice.y = XINT (it->slice.y);
25329 else if (FLOATP (it->slice.y))
25330 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
25332 if (INTEGERP (it->slice.width))
25333 slice.width = XINT (it->slice.width);
25334 else if (FLOATP (it->slice.width))
25335 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
25337 if (INTEGERP (it->slice.height))
25338 slice.height = XINT (it->slice.height);
25339 else if (FLOATP (it->slice.height))
25340 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
25342 if (slice.x >= img->width)
25343 slice.x = img->width;
25344 if (slice.y >= img->height)
25345 slice.y = img->height;
25346 if (slice.x + slice.width >= img->width)
25347 slice.width = img->width - slice.x;
25348 if (slice.y + slice.height > img->height)
25349 slice.height = img->height - slice.y;
25351 if (slice.width == 0 || slice.height == 0)
25352 return;
25354 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
25356 it->descent = slice.height - glyph_ascent;
25357 if (slice.y == 0)
25358 it->descent += img->vmargin;
25359 if (slice.y + slice.height == img->height)
25360 it->descent += img->vmargin;
25361 it->phys_descent = it->descent;
25363 it->pixel_width = slice.width;
25364 if (slice.x == 0)
25365 it->pixel_width += img->hmargin;
25366 if (slice.x + slice.width == img->width)
25367 it->pixel_width += img->hmargin;
25369 /* It's quite possible for images to have an ascent greater than
25370 their height, so don't get confused in that case. */
25371 if (it->descent < 0)
25372 it->descent = 0;
25374 it->nglyphs = 1;
25376 if (face->box != FACE_NO_BOX)
25378 if (face->box_line_width > 0)
25380 if (slice.y == 0)
25381 it->ascent += face->box_line_width;
25382 if (slice.y + slice.height == img->height)
25383 it->descent += face->box_line_width;
25386 if (it->start_of_box_run_p && slice.x == 0)
25387 it->pixel_width += eabs (face->box_line_width);
25388 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
25389 it->pixel_width += eabs (face->box_line_width);
25392 take_vertical_position_into_account (it);
25394 /* Automatically crop wide image glyphs at right edge so we can
25395 draw the cursor on same display row. */
25396 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
25397 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
25399 it->pixel_width -= crop;
25400 slice.width -= crop;
25403 if (it->glyph_row)
25405 struct glyph *glyph;
25406 enum glyph_row_area area = it->area;
25408 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25409 if (glyph < it->glyph_row->glyphs[area + 1])
25411 glyph->charpos = CHARPOS (it->position);
25412 glyph->object = it->object;
25413 glyph->pixel_width = it->pixel_width;
25414 glyph->ascent = glyph_ascent;
25415 glyph->descent = it->descent;
25416 glyph->voffset = it->voffset;
25417 glyph->type = IMAGE_GLYPH;
25418 glyph->avoid_cursor_p = it->avoid_cursor_p;
25419 glyph->multibyte_p = it->multibyte_p;
25420 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25422 /* In R2L rows, the left and the right box edges need to be
25423 drawn in reverse direction. */
25424 glyph->right_box_line_p = it->start_of_box_run_p;
25425 glyph->left_box_line_p = it->end_of_box_run_p;
25427 else
25429 glyph->left_box_line_p = it->start_of_box_run_p;
25430 glyph->right_box_line_p = it->end_of_box_run_p;
25432 glyph->overlaps_vertically_p = 0;
25433 glyph->padding_p = 0;
25434 glyph->glyph_not_available_p = 0;
25435 glyph->face_id = it->face_id;
25436 glyph->u.img_id = img->id;
25437 glyph->slice.img = slice;
25438 glyph->font_type = FONT_TYPE_UNKNOWN;
25439 if (it->bidi_p)
25441 glyph->resolved_level = it->bidi_it.resolved_level;
25442 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25443 emacs_abort ();
25444 glyph->bidi_type = it->bidi_it.type;
25446 ++it->glyph_row->used[area];
25448 else
25449 IT_EXPAND_MATRIX_WIDTH (it, area);
25454 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
25455 of the glyph, WIDTH and HEIGHT are the width and height of the
25456 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
25458 static void
25459 append_stretch_glyph (struct it *it, Lisp_Object object,
25460 int width, int height, int ascent)
25462 struct glyph *glyph;
25463 enum glyph_row_area area = it->area;
25465 eassert (ascent >= 0 && ascent <= height);
25467 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25468 if (glyph < it->glyph_row->glyphs[area + 1])
25470 /* If the glyph row is reversed, we need to prepend the glyph
25471 rather than append it. */
25472 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25474 struct glyph *g;
25476 /* Make room for the additional glyph. */
25477 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25478 g[1] = *g;
25479 glyph = it->glyph_row->glyphs[area];
25481 /* Decrease the width of the first glyph of the row that
25482 begins before first_visible_x (e.g., due to hscroll).
25483 This is so the overall width of the row becomes smaller
25484 by the scroll amount, and the stretch glyph appended by
25485 extend_face_to_end_of_line will be wider, to shift the
25486 row glyphs to the right. (In L2R rows, the corresponding
25487 left-shift effect is accomplished by setting row->x to a
25488 negative value, which won't work with R2L rows.)
25490 This must leave us with a positive value of WIDTH, since
25491 otherwise the call to move_it_in_display_line_to at the
25492 beginning of display_line would have got past the entire
25493 first glyph, and then it->current_x would have been
25494 greater or equal to it->first_visible_x. */
25495 if (it->current_x < it->first_visible_x)
25496 width -= it->first_visible_x - it->current_x;
25497 eassert (width > 0);
25499 glyph->charpos = CHARPOS (it->position);
25500 glyph->object = object;
25501 glyph->pixel_width = width;
25502 glyph->ascent = ascent;
25503 glyph->descent = height - ascent;
25504 glyph->voffset = it->voffset;
25505 glyph->type = STRETCH_GLYPH;
25506 glyph->avoid_cursor_p = it->avoid_cursor_p;
25507 glyph->multibyte_p = it->multibyte_p;
25508 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25510 /* In R2L rows, the left and the right box edges need to be
25511 drawn in reverse direction. */
25512 glyph->right_box_line_p = it->start_of_box_run_p;
25513 glyph->left_box_line_p = it->end_of_box_run_p;
25515 else
25517 glyph->left_box_line_p = it->start_of_box_run_p;
25518 glyph->right_box_line_p = it->end_of_box_run_p;
25520 glyph->overlaps_vertically_p = 0;
25521 glyph->padding_p = 0;
25522 glyph->glyph_not_available_p = 0;
25523 glyph->face_id = it->face_id;
25524 glyph->u.stretch.ascent = ascent;
25525 glyph->u.stretch.height = height;
25526 glyph->slice.img = null_glyph_slice;
25527 glyph->font_type = FONT_TYPE_UNKNOWN;
25528 if (it->bidi_p)
25530 glyph->resolved_level = it->bidi_it.resolved_level;
25531 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25532 emacs_abort ();
25533 glyph->bidi_type = it->bidi_it.type;
25535 else
25537 glyph->resolved_level = 0;
25538 glyph->bidi_type = UNKNOWN_BT;
25540 ++it->glyph_row->used[area];
25542 else
25543 IT_EXPAND_MATRIX_WIDTH (it, area);
25546 #endif /* HAVE_WINDOW_SYSTEM */
25548 /* Produce a stretch glyph for iterator IT. IT->object is the value
25549 of the glyph property displayed. The value must be a list
25550 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
25551 being recognized:
25553 1. `:width WIDTH' specifies that the space should be WIDTH *
25554 canonical char width wide. WIDTH may be an integer or floating
25555 point number.
25557 2. `:relative-width FACTOR' specifies that the width of the stretch
25558 should be computed from the width of the first character having the
25559 `glyph' property, and should be FACTOR times that width.
25561 3. `:align-to HPOS' specifies that the space should be wide enough
25562 to reach HPOS, a value in canonical character units.
25564 Exactly one of the above pairs must be present.
25566 4. `:height HEIGHT' specifies that the height of the stretch produced
25567 should be HEIGHT, measured in canonical character units.
25569 5. `:relative-height FACTOR' specifies that the height of the
25570 stretch should be FACTOR times the height of the characters having
25571 the glyph property.
25573 Either none or exactly one of 4 or 5 must be present.
25575 6. `:ascent ASCENT' specifies that ASCENT percent of the height
25576 of the stretch should be used for the ascent of the stretch.
25577 ASCENT must be in the range 0 <= ASCENT <= 100. */
25579 void
25580 produce_stretch_glyph (struct it *it)
25582 /* (space :width WIDTH :height HEIGHT ...) */
25583 Lisp_Object prop, plist;
25584 int width = 0, height = 0, align_to = -1;
25585 int zero_width_ok_p = 0;
25586 double tem;
25587 struct font *font = NULL;
25589 #ifdef HAVE_WINDOW_SYSTEM
25590 int ascent = 0;
25591 int zero_height_ok_p = 0;
25593 if (FRAME_WINDOW_P (it->f))
25595 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25596 font = face->font ? face->font : FRAME_FONT (it->f);
25597 prepare_face_for_display (it->f, face);
25599 #endif
25601 /* List should start with `space'. */
25602 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
25603 plist = XCDR (it->object);
25605 /* Compute the width of the stretch. */
25606 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
25607 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
25609 /* Absolute width `:width WIDTH' specified and valid. */
25610 zero_width_ok_p = 1;
25611 width = (int)tem;
25613 #ifdef HAVE_WINDOW_SYSTEM
25614 else if (FRAME_WINDOW_P (it->f)
25615 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
25617 /* Relative width `:relative-width FACTOR' specified and valid.
25618 Compute the width of the characters having the `glyph'
25619 property. */
25620 struct it it2;
25621 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
25623 it2 = *it;
25624 if (it->multibyte_p)
25625 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
25626 else
25628 it2.c = it2.char_to_display = *p, it2.len = 1;
25629 if (! ASCII_CHAR_P (it2.c))
25630 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
25633 it2.glyph_row = NULL;
25634 it2.what = IT_CHARACTER;
25635 x_produce_glyphs (&it2);
25636 width = NUMVAL (prop) * it2.pixel_width;
25638 #endif /* HAVE_WINDOW_SYSTEM */
25639 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
25640 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
25642 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
25643 align_to = (align_to < 0
25645 : align_to - window_box_left_offset (it->w, TEXT_AREA));
25646 else if (align_to < 0)
25647 align_to = window_box_left_offset (it->w, TEXT_AREA);
25648 width = max (0, (int)tem + align_to - it->current_x);
25649 zero_width_ok_p = 1;
25651 else
25652 /* Nothing specified -> width defaults to canonical char width. */
25653 width = FRAME_COLUMN_WIDTH (it->f);
25655 if (width <= 0 && (width < 0 || !zero_width_ok_p))
25656 width = 1;
25658 #ifdef HAVE_WINDOW_SYSTEM
25659 /* Compute height. */
25660 if (FRAME_WINDOW_P (it->f))
25662 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
25663 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25665 height = (int)tem;
25666 zero_height_ok_p = 1;
25668 else if (prop = Fplist_get (plist, QCrelative_height),
25669 NUMVAL (prop) > 0)
25670 height = FONT_HEIGHT (font) * NUMVAL (prop);
25671 else
25672 height = FONT_HEIGHT (font);
25674 if (height <= 0 && (height < 0 || !zero_height_ok_p))
25675 height = 1;
25677 /* Compute percentage of height used for ascent. If
25678 `:ascent ASCENT' is present and valid, use that. Otherwise,
25679 derive the ascent from the font in use. */
25680 if (prop = Fplist_get (plist, QCascent),
25681 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
25682 ascent = height * NUMVAL (prop) / 100.0;
25683 else if (!NILP (prop)
25684 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
25685 ascent = min (max (0, (int)tem), height);
25686 else
25687 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
25689 else
25690 #endif /* HAVE_WINDOW_SYSTEM */
25691 height = 1;
25693 if (width > 0 && it->line_wrap != TRUNCATE
25694 && it->current_x + width > it->last_visible_x)
25696 width = it->last_visible_x - it->current_x;
25697 #ifdef HAVE_WINDOW_SYSTEM
25698 /* Subtract one more pixel from the stretch width, but only on
25699 GUI frames, since on a TTY each glyph is one "pixel" wide. */
25700 width -= FRAME_WINDOW_P (it->f);
25701 #endif
25704 if (width > 0 && height > 0 && it->glyph_row)
25706 Lisp_Object o_object = it->object;
25707 Lisp_Object object = it->stack[it->sp - 1].string;
25708 int n = width;
25710 if (!STRINGP (object))
25711 object = it->w->contents;
25712 #ifdef HAVE_WINDOW_SYSTEM
25713 if (FRAME_WINDOW_P (it->f))
25714 append_stretch_glyph (it, object, width, height, ascent);
25715 else
25716 #endif
25718 it->object = object;
25719 it->char_to_display = ' ';
25720 it->pixel_width = it->len = 1;
25721 while (n--)
25722 tty_append_glyph (it);
25723 it->object = o_object;
25727 it->pixel_width = width;
25728 #ifdef HAVE_WINDOW_SYSTEM
25729 if (FRAME_WINDOW_P (it->f))
25731 it->ascent = it->phys_ascent = ascent;
25732 it->descent = it->phys_descent = height - it->ascent;
25733 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
25734 take_vertical_position_into_account (it);
25736 else
25737 #endif
25738 it->nglyphs = width;
25741 /* Get information about special display element WHAT in an
25742 environment described by IT. WHAT is one of IT_TRUNCATION or
25743 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
25744 non-null glyph_row member. This function ensures that fields like
25745 face_id, c, len of IT are left untouched. */
25747 static void
25748 produce_special_glyphs (struct it *it, enum display_element_type what)
25750 struct it temp_it;
25751 Lisp_Object gc;
25752 GLYPH glyph;
25754 temp_it = *it;
25755 temp_it.object = make_number (0);
25756 memset (&temp_it.current, 0, sizeof temp_it.current);
25758 if (what == IT_CONTINUATION)
25760 /* Continuation glyph. For R2L lines, we mirror it by hand. */
25761 if (it->bidi_it.paragraph_dir == R2L)
25762 SET_GLYPH_FROM_CHAR (glyph, '/');
25763 else
25764 SET_GLYPH_FROM_CHAR (glyph, '\\');
25765 if (it->dp
25766 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25768 /* FIXME: Should we mirror GC for R2L lines? */
25769 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25770 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25773 else if (what == IT_TRUNCATION)
25775 /* Truncation glyph. */
25776 SET_GLYPH_FROM_CHAR (glyph, '$');
25777 if (it->dp
25778 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
25780 /* FIXME: Should we mirror GC for R2L lines? */
25781 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
25782 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
25785 else
25786 emacs_abort ();
25788 #ifdef HAVE_WINDOW_SYSTEM
25789 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
25790 is turned off, we precede the truncation/continuation glyphs by a
25791 stretch glyph whose width is computed such that these special
25792 glyphs are aligned at the window margin, even when very different
25793 fonts are used in different glyph rows. */
25794 if (FRAME_WINDOW_P (temp_it.f)
25795 /* init_iterator calls this with it->glyph_row == NULL, and it
25796 wants only the pixel width of the truncation/continuation
25797 glyphs. */
25798 && temp_it.glyph_row
25799 /* insert_left_trunc_glyphs calls us at the beginning of the
25800 row, and it has its own calculation of the stretch glyph
25801 width. */
25802 && temp_it.glyph_row->used[TEXT_AREA] > 0
25803 && (temp_it.glyph_row->reversed_p
25804 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
25805 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
25807 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
25809 if (stretch_width > 0)
25811 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
25812 struct font *font =
25813 face->font ? face->font : FRAME_FONT (temp_it.f);
25814 int stretch_ascent =
25815 (((temp_it.ascent + temp_it.descent)
25816 * FONT_BASE (font)) / FONT_HEIGHT (font));
25818 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
25819 temp_it.ascent + temp_it.descent,
25820 stretch_ascent);
25823 #endif
25825 temp_it.dp = NULL;
25826 temp_it.what = IT_CHARACTER;
25827 temp_it.len = 1;
25828 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
25829 temp_it.face_id = GLYPH_FACE (glyph);
25830 temp_it.len = CHAR_BYTES (temp_it.c);
25832 PRODUCE_GLYPHS (&temp_it);
25833 it->pixel_width = temp_it.pixel_width;
25834 it->nglyphs = temp_it.pixel_width;
25837 #ifdef HAVE_WINDOW_SYSTEM
25839 /* Calculate line-height and line-spacing properties.
25840 An integer value specifies explicit pixel value.
25841 A float value specifies relative value to current face height.
25842 A cons (float . face-name) specifies relative value to
25843 height of specified face font.
25845 Returns height in pixels, or nil. */
25848 static Lisp_Object
25849 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
25850 int boff, int override)
25852 Lisp_Object face_name = Qnil;
25853 int ascent, descent, height;
25855 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
25856 return val;
25858 if (CONSP (val))
25860 face_name = XCAR (val);
25861 val = XCDR (val);
25862 if (!NUMBERP (val))
25863 val = make_number (1);
25864 if (NILP (face_name))
25866 height = it->ascent + it->descent;
25867 goto scale;
25871 if (NILP (face_name))
25873 font = FRAME_FONT (it->f);
25874 boff = FRAME_BASELINE_OFFSET (it->f);
25876 else if (EQ (face_name, Qt))
25878 override = 0;
25880 else
25882 int face_id;
25883 struct face *face;
25885 face_id = lookup_named_face (it->f, face_name, 0);
25886 if (face_id < 0)
25887 return make_number (-1);
25889 face = FACE_FROM_ID (it->f, face_id);
25890 font = face->font;
25891 if (font == NULL)
25892 return make_number (-1);
25893 boff = font->baseline_offset;
25894 if (font->vertical_centering)
25895 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25898 ascent = FONT_BASE (font) + boff;
25899 descent = FONT_DESCENT (font) - boff;
25901 if (override)
25903 it->override_ascent = ascent;
25904 it->override_descent = descent;
25905 it->override_boff = boff;
25908 height = ascent + descent;
25910 scale:
25911 if (FLOATP (val))
25912 height = (int)(XFLOAT_DATA (val) * height);
25913 else if (INTEGERP (val))
25914 height *= XINT (val);
25916 return make_number (height);
25920 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
25921 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
25922 and only if this is for a character for which no font was found.
25924 If the display method (it->glyphless_method) is
25925 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
25926 length of the acronym or the hexadecimal string, UPPER_XOFF and
25927 UPPER_YOFF are pixel offsets for the upper part of the string,
25928 LOWER_XOFF and LOWER_YOFF are for the lower part.
25930 For the other display methods, LEN through LOWER_YOFF are zero. */
25932 static void
25933 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
25934 short upper_xoff, short upper_yoff,
25935 short lower_xoff, short lower_yoff)
25937 struct glyph *glyph;
25938 enum glyph_row_area area = it->area;
25940 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
25941 if (glyph < it->glyph_row->glyphs[area + 1])
25943 /* If the glyph row is reversed, we need to prepend the glyph
25944 rather than append it. */
25945 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25947 struct glyph *g;
25949 /* Make room for the additional glyph. */
25950 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
25951 g[1] = *g;
25952 glyph = it->glyph_row->glyphs[area];
25954 glyph->charpos = CHARPOS (it->position);
25955 glyph->object = it->object;
25956 glyph->pixel_width = it->pixel_width;
25957 glyph->ascent = it->ascent;
25958 glyph->descent = it->descent;
25959 glyph->voffset = it->voffset;
25960 glyph->type = GLYPHLESS_GLYPH;
25961 glyph->u.glyphless.method = it->glyphless_method;
25962 glyph->u.glyphless.for_no_font = for_no_font;
25963 glyph->u.glyphless.len = len;
25964 glyph->u.glyphless.ch = it->c;
25965 glyph->slice.glyphless.upper_xoff = upper_xoff;
25966 glyph->slice.glyphless.upper_yoff = upper_yoff;
25967 glyph->slice.glyphless.lower_xoff = lower_xoff;
25968 glyph->slice.glyphless.lower_yoff = lower_yoff;
25969 glyph->avoid_cursor_p = it->avoid_cursor_p;
25970 glyph->multibyte_p = it->multibyte_p;
25971 if (it->glyph_row->reversed_p && area == TEXT_AREA)
25973 /* In R2L rows, the left and the right box edges need to be
25974 drawn in reverse direction. */
25975 glyph->right_box_line_p = it->start_of_box_run_p;
25976 glyph->left_box_line_p = it->end_of_box_run_p;
25978 else
25980 glyph->left_box_line_p = it->start_of_box_run_p;
25981 glyph->right_box_line_p = it->end_of_box_run_p;
25983 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
25984 || it->phys_descent > it->descent);
25985 glyph->padding_p = 0;
25986 glyph->glyph_not_available_p = 0;
25987 glyph->face_id = face_id;
25988 glyph->font_type = FONT_TYPE_UNKNOWN;
25989 if (it->bidi_p)
25991 glyph->resolved_level = it->bidi_it.resolved_level;
25992 if ((it->bidi_it.type & 7) != it->bidi_it.type)
25993 emacs_abort ();
25994 glyph->bidi_type = it->bidi_it.type;
25996 ++it->glyph_row->used[area];
25998 else
25999 IT_EXPAND_MATRIX_WIDTH (it, area);
26003 /* Produce a glyph for a glyphless character for iterator IT.
26004 IT->glyphless_method specifies which method to use for displaying
26005 the character. See the description of enum
26006 glyphless_display_method in dispextern.h for the detail.
26008 FOR_NO_FONT is nonzero if and only if this is for a character for
26009 which no font was found. ACRONYM, if non-nil, is an acronym string
26010 for the character. */
26012 static void
26013 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
26015 int face_id;
26016 struct face *face;
26017 struct font *font;
26018 int base_width, base_height, width, height;
26019 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
26020 int len;
26022 /* Get the metrics of the base font. We always refer to the current
26023 ASCII face. */
26024 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
26025 font = face->font ? face->font : FRAME_FONT (it->f);
26026 it->ascent = FONT_BASE (font) + font->baseline_offset;
26027 it->descent = FONT_DESCENT (font) - font->baseline_offset;
26028 base_height = it->ascent + it->descent;
26029 base_width = font->average_width;
26031 face_id = merge_glyphless_glyph_face (it);
26033 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
26035 it->pixel_width = THIN_SPACE_WIDTH;
26036 len = 0;
26037 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26039 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
26041 width = CHAR_WIDTH (it->c);
26042 if (width == 0)
26043 width = 1;
26044 else if (width > 4)
26045 width = 4;
26046 it->pixel_width = base_width * width;
26047 len = 0;
26048 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
26050 else
26052 char buf[7];
26053 const char *str;
26054 unsigned int code[6];
26055 int upper_len;
26056 int ascent, descent;
26057 struct font_metrics metrics_upper, metrics_lower;
26059 face = FACE_FROM_ID (it->f, face_id);
26060 font = face->font ? face->font : FRAME_FONT (it->f);
26061 prepare_face_for_display (it->f, face);
26063 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
26065 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
26066 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
26067 if (CONSP (acronym))
26068 acronym = XCAR (acronym);
26069 str = STRINGP (acronym) ? SSDATA (acronym) : "";
26071 else
26073 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
26074 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
26075 str = buf;
26077 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
26078 code[len] = font->driver->encode_char (font, str[len]);
26079 upper_len = (len + 1) / 2;
26080 font->driver->text_extents (font, code, upper_len,
26081 &metrics_upper);
26082 font->driver->text_extents (font, code + upper_len, len - upper_len,
26083 &metrics_lower);
26087 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
26088 width = max (metrics_upper.width, metrics_lower.width) + 4;
26089 upper_xoff = upper_yoff = 2; /* the typical case */
26090 if (base_width >= width)
26092 /* Align the upper to the left, the lower to the right. */
26093 it->pixel_width = base_width;
26094 lower_xoff = base_width - 2 - metrics_lower.width;
26096 else
26098 /* Center the shorter one. */
26099 it->pixel_width = width;
26100 if (metrics_upper.width >= metrics_lower.width)
26101 lower_xoff = (width - metrics_lower.width) / 2;
26102 else
26104 /* FIXME: This code doesn't look right. It formerly was
26105 missing the "lower_xoff = 0;", which couldn't have
26106 been right since it left lower_xoff uninitialized. */
26107 lower_xoff = 0;
26108 upper_xoff = (width - metrics_upper.width) / 2;
26112 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
26113 top, bottom, and between upper and lower strings. */
26114 height = (metrics_upper.ascent + metrics_upper.descent
26115 + metrics_lower.ascent + metrics_lower.descent) + 5;
26116 /* Center vertically.
26117 H:base_height, D:base_descent
26118 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
26120 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
26121 descent = D - H/2 + h/2;
26122 lower_yoff = descent - 2 - ld;
26123 upper_yoff = lower_yoff - la - 1 - ud; */
26124 ascent = - (it->descent - (base_height + height + 1) / 2);
26125 descent = it->descent - (base_height - height) / 2;
26126 lower_yoff = descent - 2 - metrics_lower.descent;
26127 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
26128 - metrics_upper.descent);
26129 /* Don't make the height shorter than the base height. */
26130 if (height > base_height)
26132 it->ascent = ascent;
26133 it->descent = descent;
26137 it->phys_ascent = it->ascent;
26138 it->phys_descent = it->descent;
26139 if (it->glyph_row)
26140 append_glyphless_glyph (it, face_id, for_no_font, len,
26141 upper_xoff, upper_yoff,
26142 lower_xoff, lower_yoff);
26143 it->nglyphs = 1;
26144 take_vertical_position_into_account (it);
26148 /* RIF:
26149 Produce glyphs/get display metrics for the display element IT is
26150 loaded with. See the description of struct it in dispextern.h
26151 for an overview of struct it. */
26153 void
26154 x_produce_glyphs (struct it *it)
26156 int extra_line_spacing = it->extra_line_spacing;
26158 it->glyph_not_available_p = 0;
26160 if (it->what == IT_CHARACTER)
26162 XChar2b char2b;
26163 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26164 struct font *font = face->font;
26165 struct font_metrics *pcm = NULL;
26166 int boff; /* Baseline offset. */
26168 if (font == NULL)
26170 /* When no suitable font is found, display this character by
26171 the method specified in the first extra slot of
26172 Vglyphless_char_display. */
26173 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
26175 eassert (it->what == IT_GLYPHLESS);
26176 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
26177 goto done;
26180 boff = font->baseline_offset;
26181 if (font->vertical_centering)
26182 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26184 if (it->char_to_display != '\n' && it->char_to_display != '\t')
26186 int stretched_p;
26188 it->nglyphs = 1;
26190 if (it->override_ascent >= 0)
26192 it->ascent = it->override_ascent;
26193 it->descent = it->override_descent;
26194 boff = it->override_boff;
26196 else
26198 it->ascent = FONT_BASE (font) + boff;
26199 it->descent = FONT_DESCENT (font) - boff;
26202 if (get_char_glyph_code (it->char_to_display, font, &char2b))
26204 pcm = get_per_char_metric (font, &char2b);
26205 if (pcm->width == 0
26206 && pcm->rbearing == 0 && pcm->lbearing == 0)
26207 pcm = NULL;
26210 if (pcm)
26212 it->phys_ascent = pcm->ascent + boff;
26213 it->phys_descent = pcm->descent - boff;
26214 it->pixel_width = pcm->width;
26216 else
26218 it->glyph_not_available_p = 1;
26219 it->phys_ascent = it->ascent;
26220 it->phys_descent = it->descent;
26221 it->pixel_width = font->space_width;
26224 if (it->constrain_row_ascent_descent_p)
26226 if (it->descent > it->max_descent)
26228 it->ascent += it->descent - it->max_descent;
26229 it->descent = it->max_descent;
26231 if (it->ascent > it->max_ascent)
26233 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26234 it->ascent = it->max_ascent;
26236 it->phys_ascent = min (it->phys_ascent, it->ascent);
26237 it->phys_descent = min (it->phys_descent, it->descent);
26238 extra_line_spacing = 0;
26241 /* If this is a space inside a region of text with
26242 `space-width' property, change its width. */
26243 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
26244 if (stretched_p)
26245 it->pixel_width *= XFLOATINT (it->space_width);
26247 /* If face has a box, add the box thickness to the character
26248 height. If character has a box line to the left and/or
26249 right, add the box line width to the character's width. */
26250 if (face->box != FACE_NO_BOX)
26252 int thick = face->box_line_width;
26254 if (thick > 0)
26256 it->ascent += thick;
26257 it->descent += thick;
26259 else
26260 thick = -thick;
26262 if (it->start_of_box_run_p)
26263 it->pixel_width += thick;
26264 if (it->end_of_box_run_p)
26265 it->pixel_width += thick;
26268 /* If face has an overline, add the height of the overline
26269 (1 pixel) and a 1 pixel margin to the character height. */
26270 if (face->overline_p)
26271 it->ascent += overline_margin;
26273 if (it->constrain_row_ascent_descent_p)
26275 if (it->ascent > it->max_ascent)
26276 it->ascent = it->max_ascent;
26277 if (it->descent > it->max_descent)
26278 it->descent = it->max_descent;
26281 take_vertical_position_into_account (it);
26283 /* If we have to actually produce glyphs, do it. */
26284 if (it->glyph_row)
26286 if (stretched_p)
26288 /* Translate a space with a `space-width' property
26289 into a stretch glyph. */
26290 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
26291 / FONT_HEIGHT (font));
26292 append_stretch_glyph (it, it->object, it->pixel_width,
26293 it->ascent + it->descent, ascent);
26295 else
26296 append_glyph (it);
26298 /* If characters with lbearing or rbearing are displayed
26299 in this line, record that fact in a flag of the
26300 glyph row. This is used to optimize X output code. */
26301 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
26302 it->glyph_row->contains_overlapping_glyphs_p = 1;
26304 if (! stretched_p && it->pixel_width == 0)
26305 /* We assure that all visible glyphs have at least 1-pixel
26306 width. */
26307 it->pixel_width = 1;
26309 else if (it->char_to_display == '\n')
26311 /* A newline has no width, but we need the height of the
26312 line. But if previous part of the line sets a height,
26313 don't increase that height. */
26315 Lisp_Object height;
26316 Lisp_Object total_height = Qnil;
26318 it->override_ascent = -1;
26319 it->pixel_width = 0;
26320 it->nglyphs = 0;
26322 height = get_it_property (it, Qline_height);
26323 /* Split (line-height total-height) list. */
26324 if (CONSP (height)
26325 && CONSP (XCDR (height))
26326 && NILP (XCDR (XCDR (height))))
26328 total_height = XCAR (XCDR (height));
26329 height = XCAR (height);
26331 height = calc_line_height_property (it, height, font, boff, 1);
26333 if (it->override_ascent >= 0)
26335 it->ascent = it->override_ascent;
26336 it->descent = it->override_descent;
26337 boff = it->override_boff;
26339 else
26341 it->ascent = FONT_BASE (font) + boff;
26342 it->descent = FONT_DESCENT (font) - boff;
26345 if (EQ (height, Qt))
26347 if (it->descent > it->max_descent)
26349 it->ascent += it->descent - it->max_descent;
26350 it->descent = it->max_descent;
26352 if (it->ascent > it->max_ascent)
26354 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
26355 it->ascent = it->max_ascent;
26357 it->phys_ascent = min (it->phys_ascent, it->ascent);
26358 it->phys_descent = min (it->phys_descent, it->descent);
26359 it->constrain_row_ascent_descent_p = 1;
26360 extra_line_spacing = 0;
26362 else
26364 Lisp_Object spacing;
26366 it->phys_ascent = it->ascent;
26367 it->phys_descent = it->descent;
26369 if ((it->max_ascent > 0 || it->max_descent > 0)
26370 && face->box != FACE_NO_BOX
26371 && face->box_line_width > 0)
26373 it->ascent += face->box_line_width;
26374 it->descent += face->box_line_width;
26376 if (!NILP (height)
26377 && XINT (height) > it->ascent + it->descent)
26378 it->ascent = XINT (height) - it->descent;
26380 if (!NILP (total_height))
26381 spacing = calc_line_height_property (it, total_height, font, boff, 0);
26382 else
26384 spacing = get_it_property (it, Qline_spacing);
26385 spacing = calc_line_height_property (it, spacing, font, boff, 0);
26387 if (INTEGERP (spacing))
26389 extra_line_spacing = XINT (spacing);
26390 if (!NILP (total_height))
26391 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
26395 else /* i.e. (it->char_to_display == '\t') */
26397 if (font->space_width > 0)
26399 int tab_width = it->tab_width * font->space_width;
26400 int x = it->current_x + it->continuation_lines_width;
26401 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
26403 /* If the distance from the current position to the next tab
26404 stop is less than a space character width, use the
26405 tab stop after that. */
26406 if (next_tab_x - x < font->space_width)
26407 next_tab_x += tab_width;
26409 it->pixel_width = next_tab_x - x;
26410 it->nglyphs = 1;
26411 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
26412 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
26414 if (it->glyph_row)
26416 append_stretch_glyph (it, it->object, it->pixel_width,
26417 it->ascent + it->descent, it->ascent);
26420 else
26422 it->pixel_width = 0;
26423 it->nglyphs = 1;
26427 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
26429 /* A static composition.
26431 Note: A composition is represented as one glyph in the
26432 glyph matrix. There are no padding glyphs.
26434 Important note: pixel_width, ascent, and descent are the
26435 values of what is drawn by draw_glyphs (i.e. the values of
26436 the overall glyphs composed). */
26437 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26438 int boff; /* baseline offset */
26439 struct composition *cmp = composition_table[it->cmp_it.id];
26440 int glyph_len = cmp->glyph_len;
26441 struct font *font = face->font;
26443 it->nglyphs = 1;
26445 /* If we have not yet calculated pixel size data of glyphs of
26446 the composition for the current face font, calculate them
26447 now. Theoretically, we have to check all fonts for the
26448 glyphs, but that requires much time and memory space. So,
26449 here we check only the font of the first glyph. This may
26450 lead to incorrect display, but it's very rare, and C-l
26451 (recenter-top-bottom) can correct the display anyway. */
26452 if (! cmp->font || cmp->font != font)
26454 /* Ascent and descent of the font of the first character
26455 of this composition (adjusted by baseline offset).
26456 Ascent and descent of overall glyphs should not be less
26457 than these, respectively. */
26458 int font_ascent, font_descent, font_height;
26459 /* Bounding box of the overall glyphs. */
26460 int leftmost, rightmost, lowest, highest;
26461 int lbearing, rbearing;
26462 int i, width, ascent, descent;
26463 int left_padded = 0, right_padded = 0;
26464 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
26465 XChar2b char2b;
26466 struct font_metrics *pcm;
26467 int font_not_found_p;
26468 ptrdiff_t pos;
26470 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
26471 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
26472 break;
26473 if (glyph_len < cmp->glyph_len)
26474 right_padded = 1;
26475 for (i = 0; i < glyph_len; i++)
26477 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
26478 break;
26479 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26481 if (i > 0)
26482 left_padded = 1;
26484 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
26485 : IT_CHARPOS (*it));
26486 /* If no suitable font is found, use the default font. */
26487 font_not_found_p = font == NULL;
26488 if (font_not_found_p)
26490 face = face->ascii_face;
26491 font = face->font;
26493 boff = font->baseline_offset;
26494 if (font->vertical_centering)
26495 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
26496 font_ascent = FONT_BASE (font) + boff;
26497 font_descent = FONT_DESCENT (font) - boff;
26498 font_height = FONT_HEIGHT (font);
26500 cmp->font = font;
26502 pcm = NULL;
26503 if (! font_not_found_p)
26505 get_char_face_and_encoding (it->f, c, it->face_id,
26506 &char2b, 0);
26507 pcm = get_per_char_metric (font, &char2b);
26510 /* Initialize the bounding box. */
26511 if (pcm)
26513 width = cmp->glyph_len > 0 ? pcm->width : 0;
26514 ascent = pcm->ascent;
26515 descent = pcm->descent;
26516 lbearing = pcm->lbearing;
26517 rbearing = pcm->rbearing;
26519 else
26521 width = cmp->glyph_len > 0 ? font->space_width : 0;
26522 ascent = FONT_BASE (font);
26523 descent = FONT_DESCENT (font);
26524 lbearing = 0;
26525 rbearing = width;
26528 rightmost = width;
26529 leftmost = 0;
26530 lowest = - descent + boff;
26531 highest = ascent + boff;
26533 if (! font_not_found_p
26534 && font->default_ascent
26535 && CHAR_TABLE_P (Vuse_default_ascent)
26536 && !NILP (Faref (Vuse_default_ascent,
26537 make_number (it->char_to_display))))
26538 highest = font->default_ascent + boff;
26540 /* Draw the first glyph at the normal position. It may be
26541 shifted to right later if some other glyphs are drawn
26542 at the left. */
26543 cmp->offsets[i * 2] = 0;
26544 cmp->offsets[i * 2 + 1] = boff;
26545 cmp->lbearing = lbearing;
26546 cmp->rbearing = rbearing;
26548 /* Set cmp->offsets for the remaining glyphs. */
26549 for (i++; i < glyph_len; i++)
26551 int left, right, btm, top;
26552 int ch = COMPOSITION_GLYPH (cmp, i);
26553 int face_id;
26554 struct face *this_face;
26556 if (ch == '\t')
26557 ch = ' ';
26558 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
26559 this_face = FACE_FROM_ID (it->f, face_id);
26560 font = this_face->font;
26562 if (font == NULL)
26563 pcm = NULL;
26564 else
26566 get_char_face_and_encoding (it->f, ch, face_id,
26567 &char2b, 0);
26568 pcm = get_per_char_metric (font, &char2b);
26570 if (! pcm)
26571 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
26572 else
26574 width = pcm->width;
26575 ascent = pcm->ascent;
26576 descent = pcm->descent;
26577 lbearing = pcm->lbearing;
26578 rbearing = pcm->rbearing;
26579 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
26581 /* Relative composition with or without
26582 alternate chars. */
26583 left = (leftmost + rightmost - width) / 2;
26584 btm = - descent + boff;
26585 if (font->relative_compose
26586 && (! CHAR_TABLE_P (Vignore_relative_composition)
26587 || NILP (Faref (Vignore_relative_composition,
26588 make_number (ch)))))
26591 if (- descent >= font->relative_compose)
26592 /* One extra pixel between two glyphs. */
26593 btm = highest + 1;
26594 else if (ascent <= 0)
26595 /* One extra pixel between two glyphs. */
26596 btm = lowest - 1 - ascent - descent;
26599 else
26601 /* A composition rule is specified by an integer
26602 value that encodes global and new reference
26603 points (GREF and NREF). GREF and NREF are
26604 specified by numbers as below:
26606 0---1---2 -- ascent
26610 9--10--11 -- center
26612 ---3---4---5--- baseline
26614 6---7---8 -- descent
26616 int rule = COMPOSITION_RULE (cmp, i);
26617 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
26619 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
26620 grefx = gref % 3, nrefx = nref % 3;
26621 grefy = gref / 3, nrefy = nref / 3;
26622 if (xoff)
26623 xoff = font_height * (xoff - 128) / 256;
26624 if (yoff)
26625 yoff = font_height * (yoff - 128) / 256;
26627 left = (leftmost
26628 + grefx * (rightmost - leftmost) / 2
26629 - nrefx * width / 2
26630 + xoff);
26632 btm = ((grefy == 0 ? highest
26633 : grefy == 1 ? 0
26634 : grefy == 2 ? lowest
26635 : (highest + lowest) / 2)
26636 - (nrefy == 0 ? ascent + descent
26637 : nrefy == 1 ? descent - boff
26638 : nrefy == 2 ? 0
26639 : (ascent + descent) / 2)
26640 + yoff);
26643 cmp->offsets[i * 2] = left;
26644 cmp->offsets[i * 2 + 1] = btm + descent;
26646 /* Update the bounding box of the overall glyphs. */
26647 if (width > 0)
26649 right = left + width;
26650 if (left < leftmost)
26651 leftmost = left;
26652 if (right > rightmost)
26653 rightmost = right;
26655 top = btm + descent + ascent;
26656 if (top > highest)
26657 highest = top;
26658 if (btm < lowest)
26659 lowest = btm;
26661 if (cmp->lbearing > left + lbearing)
26662 cmp->lbearing = left + lbearing;
26663 if (cmp->rbearing < left + rbearing)
26664 cmp->rbearing = left + rbearing;
26668 /* If there are glyphs whose x-offsets are negative,
26669 shift all glyphs to the right and make all x-offsets
26670 non-negative. */
26671 if (leftmost < 0)
26673 for (i = 0; i < cmp->glyph_len; i++)
26674 cmp->offsets[i * 2] -= leftmost;
26675 rightmost -= leftmost;
26676 cmp->lbearing -= leftmost;
26677 cmp->rbearing -= leftmost;
26680 if (left_padded && cmp->lbearing < 0)
26682 for (i = 0; i < cmp->glyph_len; i++)
26683 cmp->offsets[i * 2] -= cmp->lbearing;
26684 rightmost -= cmp->lbearing;
26685 cmp->rbearing -= cmp->lbearing;
26686 cmp->lbearing = 0;
26688 if (right_padded && rightmost < cmp->rbearing)
26690 rightmost = cmp->rbearing;
26693 cmp->pixel_width = rightmost;
26694 cmp->ascent = highest;
26695 cmp->descent = - lowest;
26696 if (cmp->ascent < font_ascent)
26697 cmp->ascent = font_ascent;
26698 if (cmp->descent < font_descent)
26699 cmp->descent = font_descent;
26702 if (it->glyph_row
26703 && (cmp->lbearing < 0
26704 || cmp->rbearing > cmp->pixel_width))
26705 it->glyph_row->contains_overlapping_glyphs_p = 1;
26707 it->pixel_width = cmp->pixel_width;
26708 it->ascent = it->phys_ascent = cmp->ascent;
26709 it->descent = it->phys_descent = cmp->descent;
26710 if (face->box != FACE_NO_BOX)
26712 int thick = face->box_line_width;
26714 if (thick > 0)
26716 it->ascent += thick;
26717 it->descent += thick;
26719 else
26720 thick = - thick;
26722 if (it->start_of_box_run_p)
26723 it->pixel_width += thick;
26724 if (it->end_of_box_run_p)
26725 it->pixel_width += thick;
26728 /* If face has an overline, add the height of the overline
26729 (1 pixel) and a 1 pixel margin to the character height. */
26730 if (face->overline_p)
26731 it->ascent += overline_margin;
26733 take_vertical_position_into_account (it);
26734 if (it->ascent < 0)
26735 it->ascent = 0;
26736 if (it->descent < 0)
26737 it->descent = 0;
26739 if (it->glyph_row && cmp->glyph_len > 0)
26740 append_composite_glyph (it);
26742 else if (it->what == IT_COMPOSITION)
26744 /* A dynamic (automatic) composition. */
26745 struct face *face = FACE_FROM_ID (it->f, it->face_id);
26746 Lisp_Object gstring;
26747 struct font_metrics metrics;
26749 it->nglyphs = 1;
26751 gstring = composition_gstring_from_id (it->cmp_it.id);
26752 it->pixel_width
26753 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
26754 &metrics);
26755 if (it->glyph_row
26756 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
26757 it->glyph_row->contains_overlapping_glyphs_p = 1;
26758 it->ascent = it->phys_ascent = metrics.ascent;
26759 it->descent = it->phys_descent = metrics.descent;
26760 if (face->box != FACE_NO_BOX)
26762 int thick = face->box_line_width;
26764 if (thick > 0)
26766 it->ascent += thick;
26767 it->descent += thick;
26769 else
26770 thick = - thick;
26772 if (it->start_of_box_run_p)
26773 it->pixel_width += thick;
26774 if (it->end_of_box_run_p)
26775 it->pixel_width += thick;
26777 /* If face has an overline, add the height of the overline
26778 (1 pixel) and a 1 pixel margin to the character height. */
26779 if (face->overline_p)
26780 it->ascent += overline_margin;
26781 take_vertical_position_into_account (it);
26782 if (it->ascent < 0)
26783 it->ascent = 0;
26784 if (it->descent < 0)
26785 it->descent = 0;
26787 if (it->glyph_row)
26788 append_composite_glyph (it);
26790 else if (it->what == IT_GLYPHLESS)
26791 produce_glyphless_glyph (it, 0, Qnil);
26792 else if (it->what == IT_IMAGE)
26793 produce_image_glyph (it);
26794 else if (it->what == IT_STRETCH)
26795 produce_stretch_glyph (it);
26797 done:
26798 /* Accumulate dimensions. Note: can't assume that it->descent > 0
26799 because this isn't true for images with `:ascent 100'. */
26800 eassert (it->ascent >= 0 && it->descent >= 0);
26801 if (it->area == TEXT_AREA)
26802 it->current_x += it->pixel_width;
26804 if (extra_line_spacing > 0)
26806 it->descent += extra_line_spacing;
26807 if (extra_line_spacing > it->max_extra_line_spacing)
26808 it->max_extra_line_spacing = extra_line_spacing;
26811 it->max_ascent = max (it->max_ascent, it->ascent);
26812 it->max_descent = max (it->max_descent, it->descent);
26813 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
26814 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
26817 /* EXPORT for RIF:
26818 Output LEN glyphs starting at START at the nominal cursor position.
26819 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
26820 being updated, and UPDATED_AREA is the area of that row being updated. */
26822 void
26823 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
26824 struct glyph *start, enum glyph_row_area updated_area, int len)
26826 int x, hpos, chpos = w->phys_cursor.hpos;
26828 eassert (updated_row);
26829 /* When the window is hscrolled, cursor hpos can legitimately be out
26830 of bounds, but we draw the cursor at the corresponding window
26831 margin in that case. */
26832 if (!updated_row->reversed_p && chpos < 0)
26833 chpos = 0;
26834 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
26835 chpos = updated_row->used[TEXT_AREA] - 1;
26837 block_input ();
26839 /* Write glyphs. */
26841 hpos = start - updated_row->glyphs[updated_area];
26842 x = draw_glyphs (w, w->output_cursor.x,
26843 updated_row, updated_area,
26844 hpos, hpos + len,
26845 DRAW_NORMAL_TEXT, 0);
26847 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
26848 if (updated_area == TEXT_AREA
26849 && w->phys_cursor_on_p
26850 && w->phys_cursor.vpos == w->output_cursor.vpos
26851 && chpos >= hpos
26852 && chpos < hpos + len)
26853 w->phys_cursor_on_p = 0;
26855 unblock_input ();
26857 /* Advance the output cursor. */
26858 w->output_cursor.hpos += len;
26859 w->output_cursor.x = x;
26863 /* EXPORT for RIF:
26864 Insert LEN glyphs from START at the nominal cursor position. */
26866 void
26867 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
26868 struct glyph *start, enum glyph_row_area updated_area, int len)
26870 struct frame *f;
26871 int line_height, shift_by_width, shifted_region_width;
26872 struct glyph_row *row;
26873 struct glyph *glyph;
26874 int frame_x, frame_y;
26875 ptrdiff_t hpos;
26877 eassert (updated_row);
26878 block_input ();
26879 f = XFRAME (WINDOW_FRAME (w));
26881 /* Get the height of the line we are in. */
26882 row = updated_row;
26883 line_height = row->height;
26885 /* Get the width of the glyphs to insert. */
26886 shift_by_width = 0;
26887 for (glyph = start; glyph < start + len; ++glyph)
26888 shift_by_width += glyph->pixel_width;
26890 /* Get the width of the region to shift right. */
26891 shifted_region_width = (window_box_width (w, updated_area)
26892 - w->output_cursor.x
26893 - shift_by_width);
26895 /* Shift right. */
26896 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
26897 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
26899 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
26900 line_height, shift_by_width);
26902 /* Write the glyphs. */
26903 hpos = start - row->glyphs[updated_area];
26904 draw_glyphs (w, w->output_cursor.x, row, updated_area,
26905 hpos, hpos + len,
26906 DRAW_NORMAL_TEXT, 0);
26908 /* Advance the output cursor. */
26909 w->output_cursor.hpos += len;
26910 w->output_cursor.x += shift_by_width;
26911 unblock_input ();
26915 /* EXPORT for RIF:
26916 Erase the current text line from the nominal cursor position
26917 (inclusive) to pixel column TO_X (exclusive). The idea is that
26918 everything from TO_X onward is already erased.
26920 TO_X is a pixel position relative to UPDATED_AREA of currently
26921 updated window W. TO_X == -1 means clear to the end of this area. */
26923 void
26924 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
26925 enum glyph_row_area updated_area, int to_x)
26927 struct frame *f;
26928 int max_x, min_y, max_y;
26929 int from_x, from_y, to_y;
26931 eassert (updated_row);
26932 f = XFRAME (w->frame);
26934 if (updated_row->full_width_p)
26935 max_x = (WINDOW_PIXEL_WIDTH (w)
26936 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26937 else
26938 max_x = window_box_width (w, updated_area);
26939 max_y = window_text_bottom_y (w);
26941 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
26942 of window. For TO_X > 0, truncate to end of drawing area. */
26943 if (to_x == 0)
26944 return;
26945 else if (to_x < 0)
26946 to_x = max_x;
26947 else
26948 to_x = min (to_x, max_x);
26950 to_y = min (max_y, w->output_cursor.y + updated_row->height);
26952 /* Notice if the cursor will be cleared by this operation. */
26953 if (!updated_row->full_width_p)
26954 notice_overwritten_cursor (w, updated_area,
26955 w->output_cursor.x, -1,
26956 updated_row->y,
26957 MATRIX_ROW_BOTTOM_Y (updated_row));
26959 from_x = w->output_cursor.x;
26961 /* Translate to frame coordinates. */
26962 if (updated_row->full_width_p)
26964 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
26965 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
26967 else
26969 int area_left = window_box_left (w, updated_area);
26970 from_x += area_left;
26971 to_x += area_left;
26974 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
26975 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
26976 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
26978 /* Prevent inadvertently clearing to end of the X window. */
26979 if (to_x > from_x && to_y > from_y)
26981 block_input ();
26982 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
26983 to_x - from_x, to_y - from_y);
26984 unblock_input ();
26988 #endif /* HAVE_WINDOW_SYSTEM */
26992 /***********************************************************************
26993 Cursor types
26994 ***********************************************************************/
26996 /* Value is the internal representation of the specified cursor type
26997 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
26998 of the bar cursor. */
27000 static enum text_cursor_kinds
27001 get_specified_cursor_type (Lisp_Object arg, int *width)
27003 enum text_cursor_kinds type;
27005 if (NILP (arg))
27006 return NO_CURSOR;
27008 if (EQ (arg, Qbox))
27009 return FILLED_BOX_CURSOR;
27011 if (EQ (arg, Qhollow))
27012 return HOLLOW_BOX_CURSOR;
27014 if (EQ (arg, Qbar))
27016 *width = 2;
27017 return BAR_CURSOR;
27020 if (CONSP (arg)
27021 && EQ (XCAR (arg), Qbar)
27022 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27024 *width = XINT (XCDR (arg));
27025 return BAR_CURSOR;
27028 if (EQ (arg, Qhbar))
27030 *width = 2;
27031 return HBAR_CURSOR;
27034 if (CONSP (arg)
27035 && EQ (XCAR (arg), Qhbar)
27036 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
27038 *width = XINT (XCDR (arg));
27039 return HBAR_CURSOR;
27042 /* Treat anything unknown as "hollow box cursor".
27043 It was bad to signal an error; people have trouble fixing
27044 .Xdefaults with Emacs, when it has something bad in it. */
27045 type = HOLLOW_BOX_CURSOR;
27047 return type;
27050 /* Set the default cursor types for specified frame. */
27051 void
27052 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
27054 int width = 1;
27055 Lisp_Object tem;
27057 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
27058 FRAME_CURSOR_WIDTH (f) = width;
27060 /* By default, set up the blink-off state depending on the on-state. */
27062 tem = Fassoc (arg, Vblink_cursor_alist);
27063 if (!NILP (tem))
27065 FRAME_BLINK_OFF_CURSOR (f)
27066 = get_specified_cursor_type (XCDR (tem), &width);
27067 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
27069 else
27070 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
27072 /* Make sure the cursor gets redrawn. */
27073 f->cursor_type_changed = 1;
27077 #ifdef HAVE_WINDOW_SYSTEM
27079 /* Return the cursor we want to be displayed in window W. Return
27080 width of bar/hbar cursor through WIDTH arg. Return with
27081 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
27082 (i.e. if the `system caret' should track this cursor).
27084 In a mini-buffer window, we want the cursor only to appear if we
27085 are reading input from this window. For the selected window, we
27086 want the cursor type given by the frame parameter or buffer local
27087 setting of cursor-type. If explicitly marked off, draw no cursor.
27088 In all other cases, we want a hollow box cursor. */
27090 static enum text_cursor_kinds
27091 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
27092 int *active_cursor)
27094 struct frame *f = XFRAME (w->frame);
27095 struct buffer *b = XBUFFER (w->contents);
27096 int cursor_type = DEFAULT_CURSOR;
27097 Lisp_Object alt_cursor;
27098 int non_selected = 0;
27100 *active_cursor = 1;
27102 /* Echo area */
27103 if (cursor_in_echo_area
27104 && FRAME_HAS_MINIBUF_P (f)
27105 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
27107 if (w == XWINDOW (echo_area_window))
27109 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
27111 *width = FRAME_CURSOR_WIDTH (f);
27112 return FRAME_DESIRED_CURSOR (f);
27114 else
27115 return get_specified_cursor_type (BVAR (b, cursor_type), width);
27118 *active_cursor = 0;
27119 non_selected = 1;
27122 /* Detect a nonselected window or nonselected frame. */
27123 else if (w != XWINDOW (f->selected_window)
27124 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
27126 *active_cursor = 0;
27128 if (MINI_WINDOW_P (w) && minibuf_level == 0)
27129 return NO_CURSOR;
27131 non_selected = 1;
27134 /* Never display a cursor in a window in which cursor-type is nil. */
27135 if (NILP (BVAR (b, cursor_type)))
27136 return NO_CURSOR;
27138 /* Get the normal cursor type for this window. */
27139 if (EQ (BVAR (b, cursor_type), Qt))
27141 cursor_type = FRAME_DESIRED_CURSOR (f);
27142 *width = FRAME_CURSOR_WIDTH (f);
27144 else
27145 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
27147 /* Use cursor-in-non-selected-windows instead
27148 for non-selected window or frame. */
27149 if (non_selected)
27151 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
27152 if (!EQ (Qt, alt_cursor))
27153 return get_specified_cursor_type (alt_cursor, width);
27154 /* t means modify the normal cursor type. */
27155 if (cursor_type == FILLED_BOX_CURSOR)
27156 cursor_type = HOLLOW_BOX_CURSOR;
27157 else if (cursor_type == BAR_CURSOR && *width > 1)
27158 --*width;
27159 return cursor_type;
27162 /* Use normal cursor if not blinked off. */
27163 if (!w->cursor_off_p)
27165 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27167 if (cursor_type == FILLED_BOX_CURSOR)
27169 /* Using a block cursor on large images can be very annoying.
27170 So use a hollow cursor for "large" images.
27171 If image is not transparent (no mask), also use hollow cursor. */
27172 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27173 if (img != NULL && IMAGEP (img->spec))
27175 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
27176 where N = size of default frame font size.
27177 This should cover most of the "tiny" icons people may use. */
27178 if (!img->mask
27179 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
27180 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
27181 cursor_type = HOLLOW_BOX_CURSOR;
27184 else if (cursor_type != NO_CURSOR)
27186 /* Display current only supports BOX and HOLLOW cursors for images.
27187 So for now, unconditionally use a HOLLOW cursor when cursor is
27188 not a solid box cursor. */
27189 cursor_type = HOLLOW_BOX_CURSOR;
27192 return cursor_type;
27195 /* Cursor is blinked off, so determine how to "toggle" it. */
27197 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
27198 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
27199 return get_specified_cursor_type (XCDR (alt_cursor), width);
27201 /* Then see if frame has specified a specific blink off cursor type. */
27202 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
27204 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
27205 return FRAME_BLINK_OFF_CURSOR (f);
27208 #if 0
27209 /* Some people liked having a permanently visible blinking cursor,
27210 while others had very strong opinions against it. So it was
27211 decided to remove it. KFS 2003-09-03 */
27213 /* Finally perform built-in cursor blinking:
27214 filled box <-> hollow box
27215 wide [h]bar <-> narrow [h]bar
27216 narrow [h]bar <-> no cursor
27217 other type <-> no cursor */
27219 if (cursor_type == FILLED_BOX_CURSOR)
27220 return HOLLOW_BOX_CURSOR;
27222 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
27224 *width = 1;
27225 return cursor_type;
27227 #endif
27229 return NO_CURSOR;
27233 /* Notice when the text cursor of window W has been completely
27234 overwritten by a drawing operation that outputs glyphs in AREA
27235 starting at X0 and ending at X1 in the line starting at Y0 and
27236 ending at Y1. X coordinates are area-relative. X1 < 0 means all
27237 the rest of the line after X0 has been written. Y coordinates
27238 are window-relative. */
27240 static void
27241 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
27242 int x0, int x1, int y0, int y1)
27244 int cx0, cx1, cy0, cy1;
27245 struct glyph_row *row;
27247 if (!w->phys_cursor_on_p)
27248 return;
27249 if (area != TEXT_AREA)
27250 return;
27252 if (w->phys_cursor.vpos < 0
27253 || w->phys_cursor.vpos >= w->current_matrix->nrows
27254 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
27255 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
27256 return;
27258 if (row->cursor_in_fringe_p)
27260 row->cursor_in_fringe_p = 0;
27261 draw_fringe_bitmap (w, row, row->reversed_p);
27262 w->phys_cursor_on_p = 0;
27263 return;
27266 cx0 = w->phys_cursor.x;
27267 cx1 = cx0 + w->phys_cursor_width;
27268 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
27269 return;
27271 /* The cursor image will be completely removed from the
27272 screen if the output area intersects the cursor area in
27273 y-direction. When we draw in [y0 y1[, and some part of
27274 the cursor is at y < y0, that part must have been drawn
27275 before. When scrolling, the cursor is erased before
27276 actually scrolling, so we don't come here. When not
27277 scrolling, the rows above the old cursor row must have
27278 changed, and in this case these rows must have written
27279 over the cursor image.
27281 Likewise if part of the cursor is below y1, with the
27282 exception of the cursor being in the first blank row at
27283 the buffer and window end because update_text_area
27284 doesn't draw that row. (Except when it does, but
27285 that's handled in update_text_area.) */
27287 cy0 = w->phys_cursor.y;
27288 cy1 = cy0 + w->phys_cursor_height;
27289 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
27290 return;
27292 w->phys_cursor_on_p = 0;
27295 #endif /* HAVE_WINDOW_SYSTEM */
27298 /************************************************************************
27299 Mouse Face
27300 ************************************************************************/
27302 #ifdef HAVE_WINDOW_SYSTEM
27304 /* EXPORT for RIF:
27305 Fix the display of area AREA of overlapping row ROW in window W
27306 with respect to the overlapping part OVERLAPS. */
27308 void
27309 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
27310 enum glyph_row_area area, int overlaps)
27312 int i, x;
27314 block_input ();
27316 x = 0;
27317 for (i = 0; i < row->used[area];)
27319 if (row->glyphs[area][i].overlaps_vertically_p)
27321 int start = i, start_x = x;
27325 x += row->glyphs[area][i].pixel_width;
27326 ++i;
27328 while (i < row->used[area]
27329 && row->glyphs[area][i].overlaps_vertically_p);
27331 draw_glyphs (w, start_x, row, area,
27332 start, i,
27333 DRAW_NORMAL_TEXT, overlaps);
27335 else
27337 x += row->glyphs[area][i].pixel_width;
27338 ++i;
27342 unblock_input ();
27346 /* EXPORT:
27347 Draw the cursor glyph of window W in glyph row ROW. See the
27348 comment of draw_glyphs for the meaning of HL. */
27350 void
27351 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
27352 enum draw_glyphs_face hl)
27354 /* If cursor hpos is out of bounds, don't draw garbage. This can
27355 happen in mini-buffer windows when switching between echo area
27356 glyphs and mini-buffer. */
27357 if ((row->reversed_p
27358 ? (w->phys_cursor.hpos >= 0)
27359 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
27361 int on_p = w->phys_cursor_on_p;
27362 int x1;
27363 int hpos = w->phys_cursor.hpos;
27365 /* When the window is hscrolled, cursor hpos can legitimately be
27366 out of bounds, but we draw the cursor at the corresponding
27367 window margin in that case. */
27368 if (!row->reversed_p && hpos < 0)
27369 hpos = 0;
27370 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27371 hpos = row->used[TEXT_AREA] - 1;
27373 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
27374 hl, 0);
27375 w->phys_cursor_on_p = on_p;
27377 if (hl == DRAW_CURSOR)
27378 w->phys_cursor_width = x1 - w->phys_cursor.x;
27379 /* When we erase the cursor, and ROW is overlapped by other
27380 rows, make sure that these overlapping parts of other rows
27381 are redrawn. */
27382 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
27384 w->phys_cursor_width = x1 - w->phys_cursor.x;
27386 if (row > w->current_matrix->rows
27387 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
27388 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
27389 OVERLAPS_ERASED_CURSOR);
27391 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
27392 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
27393 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
27394 OVERLAPS_ERASED_CURSOR);
27400 /* Erase the image of a cursor of window W from the screen. */
27402 void
27403 erase_phys_cursor (struct window *w)
27405 struct frame *f = XFRAME (w->frame);
27406 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27407 int hpos = w->phys_cursor.hpos;
27408 int vpos = w->phys_cursor.vpos;
27409 int mouse_face_here_p = 0;
27410 struct glyph_matrix *active_glyphs = w->current_matrix;
27411 struct glyph_row *cursor_row;
27412 struct glyph *cursor_glyph;
27413 enum draw_glyphs_face hl;
27415 /* No cursor displayed or row invalidated => nothing to do on the
27416 screen. */
27417 if (w->phys_cursor_type == NO_CURSOR)
27418 goto mark_cursor_off;
27420 /* VPOS >= active_glyphs->nrows means that window has been resized.
27421 Don't bother to erase the cursor. */
27422 if (vpos >= active_glyphs->nrows)
27423 goto mark_cursor_off;
27425 /* If row containing cursor is marked invalid, there is nothing we
27426 can do. */
27427 cursor_row = MATRIX_ROW (active_glyphs, vpos);
27428 if (!cursor_row->enabled_p)
27429 goto mark_cursor_off;
27431 /* If line spacing is > 0, old cursor may only be partially visible in
27432 window after split-window. So adjust visible height. */
27433 cursor_row->visible_height = min (cursor_row->visible_height,
27434 window_text_bottom_y (w) - cursor_row->y);
27436 /* If row is completely invisible, don't attempt to delete a cursor which
27437 isn't there. This can happen if cursor is at top of a window, and
27438 we switch to a buffer with a header line in that window. */
27439 if (cursor_row->visible_height <= 0)
27440 goto mark_cursor_off;
27442 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
27443 if (cursor_row->cursor_in_fringe_p)
27445 cursor_row->cursor_in_fringe_p = 0;
27446 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
27447 goto mark_cursor_off;
27450 /* This can happen when the new row is shorter than the old one.
27451 In this case, either draw_glyphs or clear_end_of_line
27452 should have cleared the cursor. Note that we wouldn't be
27453 able to erase the cursor in this case because we don't have a
27454 cursor glyph at hand. */
27455 if ((cursor_row->reversed_p
27456 ? (w->phys_cursor.hpos < 0)
27457 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
27458 goto mark_cursor_off;
27460 /* When the window is hscrolled, cursor hpos can legitimately be out
27461 of bounds, but we draw the cursor at the corresponding window
27462 margin in that case. */
27463 if (!cursor_row->reversed_p && hpos < 0)
27464 hpos = 0;
27465 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
27466 hpos = cursor_row->used[TEXT_AREA] - 1;
27468 /* If the cursor is in the mouse face area, redisplay that when
27469 we clear the cursor. */
27470 if (! NILP (hlinfo->mouse_face_window)
27471 && coords_in_mouse_face_p (w, hpos, vpos)
27472 /* Don't redraw the cursor's spot in mouse face if it is at the
27473 end of a line (on a newline). The cursor appears there, but
27474 mouse highlighting does not. */
27475 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
27476 mouse_face_here_p = 1;
27478 /* Maybe clear the display under the cursor. */
27479 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
27481 int x, y;
27482 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
27483 int width;
27485 cursor_glyph = get_phys_cursor_glyph (w);
27486 if (cursor_glyph == NULL)
27487 goto mark_cursor_off;
27489 width = cursor_glyph->pixel_width;
27490 x = w->phys_cursor.x;
27491 if (x < 0)
27493 width += x;
27494 x = 0;
27496 width = min (width, window_box_width (w, TEXT_AREA) - x);
27497 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
27498 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
27500 if (width > 0)
27501 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
27504 /* Erase the cursor by redrawing the character underneath it. */
27505 if (mouse_face_here_p)
27506 hl = DRAW_MOUSE_FACE;
27507 else
27508 hl = DRAW_NORMAL_TEXT;
27509 draw_phys_cursor_glyph (w, cursor_row, hl);
27511 mark_cursor_off:
27512 w->phys_cursor_on_p = 0;
27513 w->phys_cursor_type = NO_CURSOR;
27517 /* EXPORT:
27518 Display or clear cursor of window W. If ON is zero, clear the
27519 cursor. If it is non-zero, display the cursor. If ON is nonzero,
27520 where to put the cursor is specified by HPOS, VPOS, X and Y. */
27522 void
27523 display_and_set_cursor (struct window *w, bool on,
27524 int hpos, int vpos, int x, int y)
27526 struct frame *f = XFRAME (w->frame);
27527 int new_cursor_type;
27528 int new_cursor_width;
27529 int active_cursor;
27530 struct glyph_row *glyph_row;
27531 struct glyph *glyph;
27533 /* This is pointless on invisible frames, and dangerous on garbaged
27534 windows and frames; in the latter case, the frame or window may
27535 be in the midst of changing its size, and x and y may be off the
27536 window. */
27537 if (! FRAME_VISIBLE_P (f)
27538 || FRAME_GARBAGED_P (f)
27539 || vpos >= w->current_matrix->nrows
27540 || hpos >= w->current_matrix->matrix_w)
27541 return;
27543 /* If cursor is off and we want it off, return quickly. */
27544 if (!on && !w->phys_cursor_on_p)
27545 return;
27547 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
27548 /* If cursor row is not enabled, we don't really know where to
27549 display the cursor. */
27550 if (!glyph_row->enabled_p)
27552 w->phys_cursor_on_p = 0;
27553 return;
27556 glyph = NULL;
27557 if (!glyph_row->exact_window_width_line_p
27558 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
27559 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
27561 eassert (input_blocked_p ());
27563 /* Set new_cursor_type to the cursor we want to be displayed. */
27564 new_cursor_type = get_window_cursor_type (w, glyph,
27565 &new_cursor_width, &active_cursor);
27567 /* If cursor is currently being shown and we don't want it to be or
27568 it is in the wrong place, or the cursor type is not what we want,
27569 erase it. */
27570 if (w->phys_cursor_on_p
27571 && (!on
27572 || w->phys_cursor.x != x
27573 || w->phys_cursor.y != y
27574 || new_cursor_type != w->phys_cursor_type
27575 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
27576 && new_cursor_width != w->phys_cursor_width)))
27577 erase_phys_cursor (w);
27579 /* Don't check phys_cursor_on_p here because that flag is only set
27580 to zero in some cases where we know that the cursor has been
27581 completely erased, to avoid the extra work of erasing the cursor
27582 twice. In other words, phys_cursor_on_p can be 1 and the cursor
27583 still not be visible, or it has only been partly erased. */
27584 if (on)
27586 w->phys_cursor_ascent = glyph_row->ascent;
27587 w->phys_cursor_height = glyph_row->height;
27589 /* Set phys_cursor_.* before x_draw_.* is called because some
27590 of them may need the information. */
27591 w->phys_cursor.x = x;
27592 w->phys_cursor.y = glyph_row->y;
27593 w->phys_cursor.hpos = hpos;
27594 w->phys_cursor.vpos = vpos;
27597 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
27598 new_cursor_type, new_cursor_width,
27599 on, active_cursor);
27603 /* Switch the display of W's cursor on or off, according to the value
27604 of ON. */
27606 static void
27607 update_window_cursor (struct window *w, bool on)
27609 /* Don't update cursor in windows whose frame is in the process
27610 of being deleted. */
27611 if (w->current_matrix)
27613 int hpos = w->phys_cursor.hpos;
27614 int vpos = w->phys_cursor.vpos;
27615 struct glyph_row *row;
27617 if (vpos >= w->current_matrix->nrows
27618 || hpos >= w->current_matrix->matrix_w)
27619 return;
27621 row = MATRIX_ROW (w->current_matrix, vpos);
27623 /* When the window is hscrolled, cursor hpos can legitimately be
27624 out of bounds, but we draw the cursor at the corresponding
27625 window margin in that case. */
27626 if (!row->reversed_p && hpos < 0)
27627 hpos = 0;
27628 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27629 hpos = row->used[TEXT_AREA] - 1;
27631 block_input ();
27632 display_and_set_cursor (w, on, hpos, vpos,
27633 w->phys_cursor.x, w->phys_cursor.y);
27634 unblock_input ();
27639 /* Call update_window_cursor with parameter ON_P on all leaf windows
27640 in the window tree rooted at W. */
27642 static void
27643 update_cursor_in_window_tree (struct window *w, bool on_p)
27645 while (w)
27647 if (WINDOWP (w->contents))
27648 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
27649 else
27650 update_window_cursor (w, on_p);
27652 w = NILP (w->next) ? 0 : XWINDOW (w->next);
27657 /* EXPORT:
27658 Display the cursor on window W, or clear it, according to ON_P.
27659 Don't change the cursor's position. */
27661 void
27662 x_update_cursor (struct frame *f, bool on_p)
27664 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
27668 /* EXPORT:
27669 Clear the cursor of window W to background color, and mark the
27670 cursor as not shown. This is used when the text where the cursor
27671 is about to be rewritten. */
27673 void
27674 x_clear_cursor (struct window *w)
27676 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
27677 update_window_cursor (w, 0);
27680 #endif /* HAVE_WINDOW_SYSTEM */
27682 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
27683 and MSDOS. */
27684 static void
27685 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
27686 int start_hpos, int end_hpos,
27687 enum draw_glyphs_face draw)
27689 #ifdef HAVE_WINDOW_SYSTEM
27690 if (FRAME_WINDOW_P (XFRAME (w->frame)))
27692 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
27693 return;
27695 #endif
27696 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
27697 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
27698 #endif
27701 /* Display the active region described by mouse_face_* according to DRAW. */
27703 static void
27704 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
27706 struct window *w = XWINDOW (hlinfo->mouse_face_window);
27707 struct frame *f = XFRAME (WINDOW_FRAME (w));
27709 if (/* If window is in the process of being destroyed, don't bother
27710 to do anything. */
27711 w->current_matrix != NULL
27712 /* Don't update mouse highlight if hidden. */
27713 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
27714 /* Recognize when we are called to operate on rows that don't exist
27715 anymore. This can happen when a window is split. */
27716 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
27718 int phys_cursor_on_p = w->phys_cursor_on_p;
27719 struct glyph_row *row, *first, *last;
27721 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
27722 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
27724 for (row = first; row <= last && row->enabled_p; ++row)
27726 int start_hpos, end_hpos, start_x;
27728 /* For all but the first row, the highlight starts at column 0. */
27729 if (row == first)
27731 /* R2L rows have BEG and END in reversed order, but the
27732 screen drawing geometry is always left to right. So
27733 we need to mirror the beginning and end of the
27734 highlighted area in R2L rows. */
27735 if (!row->reversed_p)
27737 start_hpos = hlinfo->mouse_face_beg_col;
27738 start_x = hlinfo->mouse_face_beg_x;
27740 else if (row == last)
27742 start_hpos = hlinfo->mouse_face_end_col;
27743 start_x = hlinfo->mouse_face_end_x;
27745 else
27747 start_hpos = 0;
27748 start_x = 0;
27751 else if (row->reversed_p && row == last)
27753 start_hpos = hlinfo->mouse_face_end_col;
27754 start_x = hlinfo->mouse_face_end_x;
27756 else
27758 start_hpos = 0;
27759 start_x = 0;
27762 if (row == last)
27764 if (!row->reversed_p)
27765 end_hpos = hlinfo->mouse_face_end_col;
27766 else if (row == first)
27767 end_hpos = hlinfo->mouse_face_beg_col;
27768 else
27770 end_hpos = row->used[TEXT_AREA];
27771 if (draw == DRAW_NORMAL_TEXT)
27772 row->fill_line_p = 1; /* Clear to end of line */
27775 else if (row->reversed_p && row == first)
27776 end_hpos = hlinfo->mouse_face_beg_col;
27777 else
27779 end_hpos = row->used[TEXT_AREA];
27780 if (draw == DRAW_NORMAL_TEXT)
27781 row->fill_line_p = 1; /* Clear to end of line */
27784 if (end_hpos > start_hpos)
27786 draw_row_with_mouse_face (w, start_x, row,
27787 start_hpos, end_hpos, draw);
27789 row->mouse_face_p
27790 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
27794 #ifdef HAVE_WINDOW_SYSTEM
27795 /* When we've written over the cursor, arrange for it to
27796 be displayed again. */
27797 if (FRAME_WINDOW_P (f)
27798 && phys_cursor_on_p && !w->phys_cursor_on_p)
27800 int hpos = w->phys_cursor.hpos;
27802 /* When the window is hscrolled, cursor hpos can legitimately be
27803 out of bounds, but we draw the cursor at the corresponding
27804 window margin in that case. */
27805 if (!row->reversed_p && hpos < 0)
27806 hpos = 0;
27807 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27808 hpos = row->used[TEXT_AREA] - 1;
27810 block_input ();
27811 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
27812 w->phys_cursor.x, w->phys_cursor.y);
27813 unblock_input ();
27815 #endif /* HAVE_WINDOW_SYSTEM */
27818 #ifdef HAVE_WINDOW_SYSTEM
27819 /* Change the mouse cursor. */
27820 if (FRAME_WINDOW_P (f))
27822 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
27823 if (draw == DRAW_NORMAL_TEXT
27824 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
27825 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
27826 else
27827 #endif
27828 if (draw == DRAW_MOUSE_FACE)
27829 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
27830 else
27831 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
27833 #endif /* HAVE_WINDOW_SYSTEM */
27836 /* EXPORT:
27837 Clear out the mouse-highlighted active region.
27838 Redraw it un-highlighted first. Value is non-zero if mouse
27839 face was actually drawn unhighlighted. */
27842 clear_mouse_face (Mouse_HLInfo *hlinfo)
27844 int cleared = 0;
27846 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
27848 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
27849 cleared = 1;
27852 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27853 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27854 hlinfo->mouse_face_window = Qnil;
27855 hlinfo->mouse_face_overlay = Qnil;
27856 return cleared;
27859 /* Return true if the coordinates HPOS and VPOS on windows W are
27860 within the mouse face on that window. */
27861 static bool
27862 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
27864 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
27866 /* Quickly resolve the easy cases. */
27867 if (!(WINDOWP (hlinfo->mouse_face_window)
27868 && XWINDOW (hlinfo->mouse_face_window) == w))
27869 return false;
27870 if (vpos < hlinfo->mouse_face_beg_row
27871 || vpos > hlinfo->mouse_face_end_row)
27872 return false;
27873 if (vpos > hlinfo->mouse_face_beg_row
27874 && vpos < hlinfo->mouse_face_end_row)
27875 return true;
27877 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
27879 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
27881 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
27882 return true;
27884 else if ((vpos == hlinfo->mouse_face_beg_row
27885 && hpos >= hlinfo->mouse_face_beg_col)
27886 || (vpos == hlinfo->mouse_face_end_row
27887 && hpos < hlinfo->mouse_face_end_col))
27888 return true;
27890 else
27892 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
27894 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
27895 return true;
27897 else if ((vpos == hlinfo->mouse_face_beg_row
27898 && hpos <= hlinfo->mouse_face_beg_col)
27899 || (vpos == hlinfo->mouse_face_end_row
27900 && hpos > hlinfo->mouse_face_end_col))
27901 return true;
27903 return false;
27907 /* EXPORT:
27908 True if physical cursor of window W is within mouse face. */
27910 bool
27911 cursor_in_mouse_face_p (struct window *w)
27913 int hpos = w->phys_cursor.hpos;
27914 int vpos = w->phys_cursor.vpos;
27915 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
27917 /* When the window is hscrolled, cursor hpos can legitimately be out
27918 of bounds, but we draw the cursor at the corresponding window
27919 margin in that case. */
27920 if (!row->reversed_p && hpos < 0)
27921 hpos = 0;
27922 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
27923 hpos = row->used[TEXT_AREA] - 1;
27925 return coords_in_mouse_face_p (w, hpos, vpos);
27930 /* Find the glyph rows START_ROW and END_ROW of window W that display
27931 characters between buffer positions START_CHARPOS and END_CHARPOS
27932 (excluding END_CHARPOS). DISP_STRING is a display string that
27933 covers these buffer positions. This is similar to
27934 row_containing_pos, but is more accurate when bidi reordering makes
27935 buffer positions change non-linearly with glyph rows. */
27936 static void
27937 rows_from_pos_range (struct window *w,
27938 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
27939 Lisp_Object disp_string,
27940 struct glyph_row **start, struct glyph_row **end)
27942 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27943 int last_y = window_text_bottom_y (w);
27944 struct glyph_row *row;
27946 *start = NULL;
27947 *end = NULL;
27949 while (!first->enabled_p
27950 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
27951 first++;
27953 /* Find the START row. */
27954 for (row = first;
27955 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
27956 row++)
27958 /* A row can potentially be the START row if the range of the
27959 characters it displays intersects the range
27960 [START_CHARPOS..END_CHARPOS). */
27961 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
27962 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
27963 /* See the commentary in row_containing_pos, for the
27964 explanation of the complicated way to check whether
27965 some position is beyond the end of the characters
27966 displayed by a row. */
27967 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
27968 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
27969 && !row->ends_at_zv_p
27970 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
27971 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
27972 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
27973 && !row->ends_at_zv_p
27974 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
27976 /* Found a candidate row. Now make sure at least one of the
27977 glyphs it displays has a charpos from the range
27978 [START_CHARPOS..END_CHARPOS).
27980 This is not obvious because bidi reordering could make
27981 buffer positions of a row be 1,2,3,102,101,100, and if we
27982 want to highlight characters in [50..60), we don't want
27983 this row, even though [50..60) does intersect [1..103),
27984 the range of character positions given by the row's start
27985 and end positions. */
27986 struct glyph *g = row->glyphs[TEXT_AREA];
27987 struct glyph *e = g + row->used[TEXT_AREA];
27989 while (g < e)
27991 if (((BUFFERP (g->object) || INTEGERP (g->object))
27992 && start_charpos <= g->charpos && g->charpos < end_charpos)
27993 /* A glyph that comes from DISP_STRING is by
27994 definition to be highlighted. */
27995 || EQ (g->object, disp_string))
27996 *start = row;
27997 g++;
27999 if (*start)
28000 break;
28004 /* Find the END row. */
28005 if (!*start
28006 /* If the last row is partially visible, start looking for END
28007 from that row, instead of starting from FIRST. */
28008 && !(row->enabled_p
28009 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
28010 row = first;
28011 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
28013 struct glyph_row *next = row + 1;
28014 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
28016 if (!next->enabled_p
28017 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
28018 /* The first row >= START whose range of displayed characters
28019 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
28020 is the row END + 1. */
28021 || (start_charpos < next_start
28022 && end_charpos < next_start)
28023 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
28024 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
28025 && !next->ends_at_zv_p
28026 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
28027 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
28028 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
28029 && !next->ends_at_zv_p
28030 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
28032 *end = row;
28033 break;
28035 else
28037 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
28038 but none of the characters it displays are in the range, it is
28039 also END + 1. */
28040 struct glyph *g = next->glyphs[TEXT_AREA];
28041 struct glyph *s = g;
28042 struct glyph *e = g + next->used[TEXT_AREA];
28044 while (g < e)
28046 if (((BUFFERP (g->object) || INTEGERP (g->object))
28047 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
28048 /* If the buffer position of the first glyph in
28049 the row is equal to END_CHARPOS, it means
28050 the last character to be highlighted is the
28051 newline of ROW, and we must consider NEXT as
28052 END, not END+1. */
28053 || (((!next->reversed_p && g == s)
28054 || (next->reversed_p && g == e - 1))
28055 && (g->charpos == end_charpos
28056 /* Special case for when NEXT is an
28057 empty line at ZV. */
28058 || (g->charpos == -1
28059 && !row->ends_at_zv_p
28060 && next_start == end_charpos)))))
28061 /* A glyph that comes from DISP_STRING is by
28062 definition to be highlighted. */
28063 || EQ (g->object, disp_string))
28064 break;
28065 g++;
28067 if (g == e)
28069 *end = row;
28070 break;
28072 /* The first row that ends at ZV must be the last to be
28073 highlighted. */
28074 else if (next->ends_at_zv_p)
28076 *end = next;
28077 break;
28083 /* This function sets the mouse_face_* elements of HLINFO, assuming
28084 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
28085 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
28086 for the overlay or run of text properties specifying the mouse
28087 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
28088 before-string and after-string that must also be highlighted.
28089 DISP_STRING, if non-nil, is a display string that may cover some
28090 or all of the highlighted text. */
28092 static void
28093 mouse_face_from_buffer_pos (Lisp_Object window,
28094 Mouse_HLInfo *hlinfo,
28095 ptrdiff_t mouse_charpos,
28096 ptrdiff_t start_charpos,
28097 ptrdiff_t end_charpos,
28098 Lisp_Object before_string,
28099 Lisp_Object after_string,
28100 Lisp_Object disp_string)
28102 struct window *w = XWINDOW (window);
28103 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28104 struct glyph_row *r1, *r2;
28105 struct glyph *glyph, *end;
28106 ptrdiff_t ignore, pos;
28107 int x;
28109 eassert (NILP (disp_string) || STRINGP (disp_string));
28110 eassert (NILP (before_string) || STRINGP (before_string));
28111 eassert (NILP (after_string) || STRINGP (after_string));
28113 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
28114 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
28115 if (r1 == NULL)
28116 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28117 /* If the before-string or display-string contains newlines,
28118 rows_from_pos_range skips to its last row. Move back. */
28119 if (!NILP (before_string) || !NILP (disp_string))
28121 struct glyph_row *prev;
28122 while ((prev = r1 - 1, prev >= first)
28123 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
28124 && prev->used[TEXT_AREA] > 0)
28126 struct glyph *beg = prev->glyphs[TEXT_AREA];
28127 glyph = beg + prev->used[TEXT_AREA];
28128 while (--glyph >= beg && INTEGERP (glyph->object));
28129 if (glyph < beg
28130 || !(EQ (glyph->object, before_string)
28131 || EQ (glyph->object, disp_string)))
28132 break;
28133 r1 = prev;
28136 if (r2 == NULL)
28138 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28139 hlinfo->mouse_face_past_end = 1;
28141 else if (!NILP (after_string))
28143 /* If the after-string has newlines, advance to its last row. */
28144 struct glyph_row *next;
28145 struct glyph_row *last
28146 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
28148 for (next = r2 + 1;
28149 next <= last
28150 && next->used[TEXT_AREA] > 0
28151 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
28152 ++next)
28153 r2 = next;
28155 /* The rest of the display engine assumes that mouse_face_beg_row is
28156 either above mouse_face_end_row or identical to it. But with
28157 bidi-reordered continued lines, the row for START_CHARPOS could
28158 be below the row for END_CHARPOS. If so, swap the rows and store
28159 them in correct order. */
28160 if (r1->y > r2->y)
28162 struct glyph_row *tem = r2;
28164 r2 = r1;
28165 r1 = tem;
28168 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
28169 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
28171 /* For a bidi-reordered row, the positions of BEFORE_STRING,
28172 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
28173 could be anywhere in the row and in any order. The strategy
28174 below is to find the leftmost and the rightmost glyph that
28175 belongs to either of these 3 strings, or whose position is
28176 between START_CHARPOS and END_CHARPOS, and highlight all the
28177 glyphs between those two. This may cover more than just the text
28178 between START_CHARPOS and END_CHARPOS if the range of characters
28179 strides the bidi level boundary, e.g. if the beginning is in R2L
28180 text while the end is in L2R text or vice versa. */
28181 if (!r1->reversed_p)
28183 /* This row is in a left to right paragraph. Scan it left to
28184 right. */
28185 glyph = r1->glyphs[TEXT_AREA];
28186 end = glyph + r1->used[TEXT_AREA];
28187 x = r1->x;
28189 /* Skip truncation glyphs at the start of the glyph row. */
28190 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28191 for (; glyph < end
28192 && INTEGERP (glyph->object)
28193 && glyph->charpos < 0;
28194 ++glyph)
28195 x += glyph->pixel_width;
28197 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28198 or DISP_STRING, and the first glyph from buffer whose
28199 position is between START_CHARPOS and END_CHARPOS. */
28200 for (; glyph < end
28201 && !INTEGERP (glyph->object)
28202 && !EQ (glyph->object, disp_string)
28203 && !(BUFFERP (glyph->object)
28204 && (glyph->charpos >= start_charpos
28205 && glyph->charpos < end_charpos));
28206 ++glyph)
28208 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28209 are present at buffer positions between START_CHARPOS and
28210 END_CHARPOS, or if they come from an overlay. */
28211 if (EQ (glyph->object, before_string))
28213 pos = string_buffer_position (before_string,
28214 start_charpos);
28215 /* If pos == 0, it means before_string came from an
28216 overlay, not from a buffer position. */
28217 if (!pos || (pos >= start_charpos && pos < end_charpos))
28218 break;
28220 else if (EQ (glyph->object, after_string))
28222 pos = string_buffer_position (after_string, end_charpos);
28223 if (!pos || (pos >= start_charpos && pos < end_charpos))
28224 break;
28226 x += glyph->pixel_width;
28228 hlinfo->mouse_face_beg_x = x;
28229 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28231 else
28233 /* This row is in a right to left paragraph. Scan it right to
28234 left. */
28235 struct glyph *g;
28237 end = r1->glyphs[TEXT_AREA] - 1;
28238 glyph = end + r1->used[TEXT_AREA];
28240 /* Skip truncation glyphs at the start of the glyph row. */
28241 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
28242 for (; glyph > end
28243 && INTEGERP (glyph->object)
28244 && glyph->charpos < 0;
28245 --glyph)
28248 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
28249 or DISP_STRING, and the first glyph from buffer whose
28250 position is between START_CHARPOS and END_CHARPOS. */
28251 for (; glyph > end
28252 && !INTEGERP (glyph->object)
28253 && !EQ (glyph->object, disp_string)
28254 && !(BUFFERP (glyph->object)
28255 && (glyph->charpos >= start_charpos
28256 && glyph->charpos < end_charpos));
28257 --glyph)
28259 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28260 are present at buffer positions between START_CHARPOS and
28261 END_CHARPOS, or if they come from an overlay. */
28262 if (EQ (glyph->object, before_string))
28264 pos = string_buffer_position (before_string, start_charpos);
28265 /* If pos == 0, it means before_string came from an
28266 overlay, not from a buffer position. */
28267 if (!pos || (pos >= start_charpos && pos < end_charpos))
28268 break;
28270 else if (EQ (glyph->object, after_string))
28272 pos = string_buffer_position (after_string, end_charpos);
28273 if (!pos || (pos >= start_charpos && pos < end_charpos))
28274 break;
28278 glyph++; /* first glyph to the right of the highlighted area */
28279 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
28280 x += g->pixel_width;
28281 hlinfo->mouse_face_beg_x = x;
28282 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
28285 /* If the highlight ends in a different row, compute GLYPH and END
28286 for the end row. Otherwise, reuse the values computed above for
28287 the row where the highlight begins. */
28288 if (r2 != r1)
28290 if (!r2->reversed_p)
28292 glyph = r2->glyphs[TEXT_AREA];
28293 end = glyph + r2->used[TEXT_AREA];
28294 x = r2->x;
28296 else
28298 end = r2->glyphs[TEXT_AREA] - 1;
28299 glyph = end + r2->used[TEXT_AREA];
28303 if (!r2->reversed_p)
28305 /* Skip truncation and continuation glyphs near the end of the
28306 row, and also blanks and stretch glyphs inserted by
28307 extend_face_to_end_of_line. */
28308 while (end > glyph
28309 && INTEGERP ((end - 1)->object))
28310 --end;
28311 /* Scan the rest of the glyph row from the end, looking for the
28312 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28313 DISP_STRING, or whose position is between START_CHARPOS
28314 and END_CHARPOS */
28315 for (--end;
28316 end > glyph
28317 && !INTEGERP (end->object)
28318 && !EQ (end->object, disp_string)
28319 && !(BUFFERP (end->object)
28320 && (end->charpos >= start_charpos
28321 && end->charpos < end_charpos));
28322 --end)
28324 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28325 are present at buffer positions between START_CHARPOS and
28326 END_CHARPOS, or if they come from an overlay. */
28327 if (EQ (end->object, before_string))
28329 pos = string_buffer_position (before_string, start_charpos);
28330 if (!pos || (pos >= start_charpos && pos < end_charpos))
28331 break;
28333 else if (EQ (end->object, after_string))
28335 pos = string_buffer_position (after_string, end_charpos);
28336 if (!pos || (pos >= start_charpos && pos < end_charpos))
28337 break;
28340 /* Find the X coordinate of the last glyph to be highlighted. */
28341 for (; glyph <= end; ++glyph)
28342 x += glyph->pixel_width;
28344 hlinfo->mouse_face_end_x = x;
28345 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
28347 else
28349 /* Skip truncation and continuation glyphs near the end of the
28350 row, and also blanks and stretch glyphs inserted by
28351 extend_face_to_end_of_line. */
28352 x = r2->x;
28353 end++;
28354 while (end < glyph
28355 && INTEGERP (end->object))
28357 x += end->pixel_width;
28358 ++end;
28360 /* Scan the rest of the glyph row from the end, looking for the
28361 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
28362 DISP_STRING, or whose position is between START_CHARPOS
28363 and END_CHARPOS */
28364 for ( ;
28365 end < glyph
28366 && !INTEGERP (end->object)
28367 && !EQ (end->object, disp_string)
28368 && !(BUFFERP (end->object)
28369 && (end->charpos >= start_charpos
28370 && end->charpos < end_charpos));
28371 ++end)
28373 /* BEFORE_STRING or AFTER_STRING are only relevant if they
28374 are present at buffer positions between START_CHARPOS and
28375 END_CHARPOS, or if they come from an overlay. */
28376 if (EQ (end->object, before_string))
28378 pos = string_buffer_position (before_string, start_charpos);
28379 if (!pos || (pos >= start_charpos && pos < end_charpos))
28380 break;
28382 else if (EQ (end->object, after_string))
28384 pos = string_buffer_position (after_string, end_charpos);
28385 if (!pos || (pos >= start_charpos && pos < end_charpos))
28386 break;
28388 x += end->pixel_width;
28390 /* If we exited the above loop because we arrived at the last
28391 glyph of the row, and its buffer position is still not in
28392 range, it means the last character in range is the preceding
28393 newline. Bump the end column and x values to get past the
28394 last glyph. */
28395 if (end == glyph
28396 && BUFFERP (end->object)
28397 && (end->charpos < start_charpos
28398 || end->charpos >= end_charpos))
28400 x += end->pixel_width;
28401 ++end;
28403 hlinfo->mouse_face_end_x = x;
28404 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
28407 hlinfo->mouse_face_window = window;
28408 hlinfo->mouse_face_face_id
28409 = face_at_buffer_position (w, mouse_charpos, &ignore,
28410 mouse_charpos + 1,
28411 !hlinfo->mouse_face_hidden, -1);
28412 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28415 /* The following function is not used anymore (replaced with
28416 mouse_face_from_string_pos), but I leave it here for the time
28417 being, in case someone would. */
28419 #if 0 /* not used */
28421 /* Find the position of the glyph for position POS in OBJECT in
28422 window W's current matrix, and return in *X, *Y the pixel
28423 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
28425 RIGHT_P non-zero means return the position of the right edge of the
28426 glyph, RIGHT_P zero means return the left edge position.
28428 If no glyph for POS exists in the matrix, return the position of
28429 the glyph with the next smaller position that is in the matrix, if
28430 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
28431 exists in the matrix, return the position of the glyph with the
28432 next larger position in OBJECT.
28434 Value is non-zero if a glyph was found. */
28436 static int
28437 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
28438 int *hpos, int *vpos, int *x, int *y, int right_p)
28440 int yb = window_text_bottom_y (w);
28441 struct glyph_row *r;
28442 struct glyph *best_glyph = NULL;
28443 struct glyph_row *best_row = NULL;
28444 int best_x = 0;
28446 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28447 r->enabled_p && r->y < yb;
28448 ++r)
28450 struct glyph *g = r->glyphs[TEXT_AREA];
28451 struct glyph *e = g + r->used[TEXT_AREA];
28452 int gx;
28454 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28455 if (EQ (g->object, object))
28457 if (g->charpos == pos)
28459 best_glyph = g;
28460 best_x = gx;
28461 best_row = r;
28462 goto found;
28464 else if (best_glyph == NULL
28465 || ((eabs (g->charpos - pos)
28466 < eabs (best_glyph->charpos - pos))
28467 && (right_p
28468 ? g->charpos < pos
28469 : g->charpos > pos)))
28471 best_glyph = g;
28472 best_x = gx;
28473 best_row = r;
28478 found:
28480 if (best_glyph)
28482 *x = best_x;
28483 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
28485 if (right_p)
28487 *x += best_glyph->pixel_width;
28488 ++*hpos;
28491 *y = best_row->y;
28492 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
28495 return best_glyph != NULL;
28497 #endif /* not used */
28499 /* Find the positions of the first and the last glyphs in window W's
28500 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
28501 (assumed to be a string), and return in HLINFO's mouse_face_*
28502 members the pixel and column/row coordinates of those glyphs. */
28504 static void
28505 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
28506 Lisp_Object object,
28507 ptrdiff_t startpos, ptrdiff_t endpos)
28509 int yb = window_text_bottom_y (w);
28510 struct glyph_row *r;
28511 struct glyph *g, *e;
28512 int gx;
28513 int found = 0;
28515 /* Find the glyph row with at least one position in the range
28516 [STARTPOS..ENDPOS), and the first glyph in that row whose
28517 position belongs to that range. */
28518 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
28519 r->enabled_p && r->y < yb;
28520 ++r)
28522 if (!r->reversed_p)
28524 g = r->glyphs[TEXT_AREA];
28525 e = g + r->used[TEXT_AREA];
28526 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
28527 if (EQ (g->object, object)
28528 && startpos <= g->charpos && g->charpos < endpos)
28530 hlinfo->mouse_face_beg_row
28531 = MATRIX_ROW_VPOS (r, w->current_matrix);
28532 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28533 hlinfo->mouse_face_beg_x = gx;
28534 found = 1;
28535 break;
28538 else
28540 struct glyph *g1;
28542 e = r->glyphs[TEXT_AREA];
28543 g = e + r->used[TEXT_AREA];
28544 for ( ; g > e; --g)
28545 if (EQ ((g-1)->object, object)
28546 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
28548 hlinfo->mouse_face_beg_row
28549 = MATRIX_ROW_VPOS (r, w->current_matrix);
28550 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
28551 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
28552 gx += g1->pixel_width;
28553 hlinfo->mouse_face_beg_x = gx;
28554 found = 1;
28555 break;
28558 if (found)
28559 break;
28562 if (!found)
28563 return;
28565 /* Starting with the next row, look for the first row which does NOT
28566 include any glyphs whose positions are in the range. */
28567 for (++r; r->enabled_p && r->y < yb; ++r)
28569 g = r->glyphs[TEXT_AREA];
28570 e = g + r->used[TEXT_AREA];
28571 found = 0;
28572 for ( ; g < e; ++g)
28573 if (EQ (g->object, object)
28574 && startpos <= g->charpos && g->charpos < endpos)
28576 found = 1;
28577 break;
28579 if (!found)
28580 break;
28583 /* The highlighted region ends on the previous row. */
28584 r--;
28586 /* Set the end row. */
28587 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
28589 /* Compute and set the end column and the end column's horizontal
28590 pixel coordinate. */
28591 if (!r->reversed_p)
28593 g = r->glyphs[TEXT_AREA];
28594 e = g + r->used[TEXT_AREA];
28595 for ( ; e > g; --e)
28596 if (EQ ((e-1)->object, object)
28597 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
28598 break;
28599 hlinfo->mouse_face_end_col = e - g;
28601 for (gx = r->x; g < e; ++g)
28602 gx += g->pixel_width;
28603 hlinfo->mouse_face_end_x = gx;
28605 else
28607 e = r->glyphs[TEXT_AREA];
28608 g = e + r->used[TEXT_AREA];
28609 for (gx = r->x ; e < g; ++e)
28611 if (EQ (e->object, object)
28612 && startpos <= e->charpos && e->charpos < endpos)
28613 break;
28614 gx += e->pixel_width;
28616 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
28617 hlinfo->mouse_face_end_x = gx;
28621 #ifdef HAVE_WINDOW_SYSTEM
28623 /* See if position X, Y is within a hot-spot of an image. */
28625 static int
28626 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
28628 if (!CONSP (hot_spot))
28629 return 0;
28631 if (EQ (XCAR (hot_spot), Qrect))
28633 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
28634 Lisp_Object rect = XCDR (hot_spot);
28635 Lisp_Object tem;
28636 if (!CONSP (rect))
28637 return 0;
28638 if (!CONSP (XCAR (rect)))
28639 return 0;
28640 if (!CONSP (XCDR (rect)))
28641 return 0;
28642 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
28643 return 0;
28644 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
28645 return 0;
28646 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
28647 return 0;
28648 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
28649 return 0;
28650 return 1;
28652 else if (EQ (XCAR (hot_spot), Qcircle))
28654 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
28655 Lisp_Object circ = XCDR (hot_spot);
28656 Lisp_Object lr, lx0, ly0;
28657 if (CONSP (circ)
28658 && CONSP (XCAR (circ))
28659 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
28660 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
28661 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
28663 double r = XFLOATINT (lr);
28664 double dx = XINT (lx0) - x;
28665 double dy = XINT (ly0) - y;
28666 return (dx * dx + dy * dy <= r * r);
28669 else if (EQ (XCAR (hot_spot), Qpoly))
28671 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
28672 if (VECTORP (XCDR (hot_spot)))
28674 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
28675 Lisp_Object *poly = v->contents;
28676 ptrdiff_t n = v->header.size;
28677 ptrdiff_t i;
28678 int inside = 0;
28679 Lisp_Object lx, ly;
28680 int x0, y0;
28682 /* Need an even number of coordinates, and at least 3 edges. */
28683 if (n < 6 || n & 1)
28684 return 0;
28686 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
28687 If count is odd, we are inside polygon. Pixels on edges
28688 may or may not be included depending on actual geometry of the
28689 polygon. */
28690 if ((lx = poly[n-2], !INTEGERP (lx))
28691 || (ly = poly[n-1], !INTEGERP (lx)))
28692 return 0;
28693 x0 = XINT (lx), y0 = XINT (ly);
28694 for (i = 0; i < n; i += 2)
28696 int x1 = x0, y1 = y0;
28697 if ((lx = poly[i], !INTEGERP (lx))
28698 || (ly = poly[i+1], !INTEGERP (ly)))
28699 return 0;
28700 x0 = XINT (lx), y0 = XINT (ly);
28702 /* Does this segment cross the X line? */
28703 if (x0 >= x)
28705 if (x1 >= x)
28706 continue;
28708 else if (x1 < x)
28709 continue;
28710 if (y > y0 && y > y1)
28711 continue;
28712 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
28713 inside = !inside;
28715 return inside;
28718 return 0;
28721 Lisp_Object
28722 find_hot_spot (Lisp_Object map, int x, int y)
28724 while (CONSP (map))
28726 if (CONSP (XCAR (map))
28727 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
28728 return XCAR (map);
28729 map = XCDR (map);
28732 return Qnil;
28735 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
28736 3, 3, 0,
28737 doc: /* Lookup in image map MAP coordinates X and Y.
28738 An image map is an alist where each element has the format (AREA ID PLIST).
28739 An AREA is specified as either a rectangle, a circle, or a polygon:
28740 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
28741 pixel coordinates of the upper left and bottom right corners.
28742 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
28743 and the radius of the circle; r may be a float or integer.
28744 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
28745 vector describes one corner in the polygon.
28746 Returns the alist element for the first matching AREA in MAP. */)
28747 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
28749 if (NILP (map))
28750 return Qnil;
28752 CHECK_NUMBER (x);
28753 CHECK_NUMBER (y);
28755 return find_hot_spot (map,
28756 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
28757 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
28761 /* Display frame CURSOR, optionally using shape defined by POINTER. */
28762 static void
28763 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
28765 /* Do not change cursor shape while dragging mouse. */
28766 if (!NILP (do_mouse_tracking))
28767 return;
28769 if (!NILP (pointer))
28771 if (EQ (pointer, Qarrow))
28772 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28773 else if (EQ (pointer, Qhand))
28774 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
28775 else if (EQ (pointer, Qtext))
28776 cursor = FRAME_X_OUTPUT (f)->text_cursor;
28777 else if (EQ (pointer, intern ("hdrag")))
28778 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28779 else if (EQ (pointer, intern ("nhdrag")))
28780 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
28781 #ifdef HAVE_X_WINDOWS
28782 else if (EQ (pointer, intern ("vdrag")))
28783 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28784 #endif
28785 else if (EQ (pointer, intern ("hourglass")))
28786 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
28787 else if (EQ (pointer, Qmodeline))
28788 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
28789 else
28790 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28793 if (cursor != No_Cursor)
28794 FRAME_RIF (f)->define_frame_cursor (f, cursor);
28797 #endif /* HAVE_WINDOW_SYSTEM */
28799 /* Take proper action when mouse has moved to the mode or header line
28800 or marginal area AREA of window W, x-position X and y-position Y.
28801 X is relative to the start of the text display area of W, so the
28802 width of bitmap areas and scroll bars must be subtracted to get a
28803 position relative to the start of the mode line. */
28805 static void
28806 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
28807 enum window_part area)
28809 struct window *w = XWINDOW (window);
28810 struct frame *f = XFRAME (w->frame);
28811 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28812 #ifdef HAVE_WINDOW_SYSTEM
28813 Display_Info *dpyinfo;
28814 #endif
28815 Cursor cursor = No_Cursor;
28816 Lisp_Object pointer = Qnil;
28817 int dx, dy, width, height;
28818 ptrdiff_t charpos;
28819 Lisp_Object string, object = Qnil;
28820 Lisp_Object pos IF_LINT (= Qnil), help;
28822 Lisp_Object mouse_face;
28823 int original_x_pixel = x;
28824 struct glyph * glyph = NULL, * row_start_glyph = NULL;
28825 struct glyph_row *row IF_LINT (= 0);
28827 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
28829 int x0;
28830 struct glyph *end;
28832 /* Kludge alert: mode_line_string takes X/Y in pixels, but
28833 returns them in row/column units! */
28834 string = mode_line_string (w, area, &x, &y, &charpos,
28835 &object, &dx, &dy, &width, &height);
28837 row = (area == ON_MODE_LINE
28838 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
28839 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
28841 /* Find the glyph under the mouse pointer. */
28842 if (row->mode_line_p && row->enabled_p)
28844 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
28845 end = glyph + row->used[TEXT_AREA];
28847 for (x0 = original_x_pixel;
28848 glyph < end && x0 >= glyph->pixel_width;
28849 ++glyph)
28850 x0 -= glyph->pixel_width;
28852 if (glyph >= end)
28853 glyph = NULL;
28856 else
28858 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
28859 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
28860 returns them in row/column units! */
28861 string = marginal_area_string (w, area, &x, &y, &charpos,
28862 &object, &dx, &dy, &width, &height);
28865 help = Qnil;
28867 #ifdef HAVE_WINDOW_SYSTEM
28868 if (IMAGEP (object))
28870 Lisp_Object image_map, hotspot;
28871 if ((image_map = Fplist_get (XCDR (object), QCmap),
28872 !NILP (image_map))
28873 && (hotspot = find_hot_spot (image_map, dx, dy),
28874 CONSP (hotspot))
28875 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
28877 Lisp_Object plist;
28879 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
28880 If so, we could look for mouse-enter, mouse-leave
28881 properties in PLIST (and do something...). */
28882 hotspot = XCDR (hotspot);
28883 if (CONSP (hotspot)
28884 && (plist = XCAR (hotspot), CONSP (plist)))
28886 pointer = Fplist_get (plist, Qpointer);
28887 if (NILP (pointer))
28888 pointer = Qhand;
28889 help = Fplist_get (plist, Qhelp_echo);
28890 if (!NILP (help))
28892 help_echo_string = help;
28893 XSETWINDOW (help_echo_window, w);
28894 help_echo_object = w->contents;
28895 help_echo_pos = charpos;
28899 if (NILP (pointer))
28900 pointer = Fplist_get (XCDR (object), QCpointer);
28902 #endif /* HAVE_WINDOW_SYSTEM */
28904 if (STRINGP (string))
28905 pos = make_number (charpos);
28907 /* Set the help text and mouse pointer. If the mouse is on a part
28908 of the mode line without any text (e.g. past the right edge of
28909 the mode line text), use the default help text and pointer. */
28910 if (STRINGP (string) || area == ON_MODE_LINE)
28912 /* Arrange to display the help by setting the global variables
28913 help_echo_string, help_echo_object, and help_echo_pos. */
28914 if (NILP (help))
28916 if (STRINGP (string))
28917 help = Fget_text_property (pos, Qhelp_echo, string);
28919 if (!NILP (help))
28921 help_echo_string = help;
28922 XSETWINDOW (help_echo_window, w);
28923 help_echo_object = string;
28924 help_echo_pos = charpos;
28926 else if (area == ON_MODE_LINE)
28928 Lisp_Object default_help
28929 = buffer_local_value (Qmode_line_default_help_echo,
28930 w->contents);
28932 if (STRINGP (default_help))
28934 help_echo_string = default_help;
28935 XSETWINDOW (help_echo_window, w);
28936 help_echo_object = Qnil;
28937 help_echo_pos = -1;
28942 #ifdef HAVE_WINDOW_SYSTEM
28943 /* Change the mouse pointer according to what is under it. */
28944 if (FRAME_WINDOW_P (f))
28946 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
28947 || minibuf_level
28948 || NILP (Vresize_mini_windows));
28950 dpyinfo = FRAME_DISPLAY_INFO (f);
28951 if (STRINGP (string))
28953 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28955 if (NILP (pointer))
28956 pointer = Fget_text_property (pos, Qpointer, string);
28958 /* Change the mouse pointer according to what is under X/Y. */
28959 if (NILP (pointer)
28960 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
28962 Lisp_Object map;
28963 map = Fget_text_property (pos, Qlocal_map, string);
28964 if (!KEYMAPP (map))
28965 map = Fget_text_property (pos, Qkeymap, string);
28966 if (!KEYMAPP (map) && draggable)
28967 cursor = dpyinfo->vertical_scroll_bar_cursor;
28970 else if (draggable)
28971 /* Default mode-line pointer. */
28972 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
28974 #endif
28977 /* Change the mouse face according to what is under X/Y. */
28978 if (STRINGP (string))
28980 mouse_face = Fget_text_property (pos, Qmouse_face, string);
28981 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
28982 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
28983 && glyph)
28985 Lisp_Object b, e;
28987 struct glyph * tmp_glyph;
28989 int gpos;
28990 int gseq_length;
28991 int total_pixel_width;
28992 ptrdiff_t begpos, endpos, ignore;
28994 int vpos, hpos;
28996 b = Fprevious_single_property_change (make_number (charpos + 1),
28997 Qmouse_face, string, Qnil);
28998 if (NILP (b))
28999 begpos = 0;
29000 else
29001 begpos = XINT (b);
29003 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
29004 if (NILP (e))
29005 endpos = SCHARS (string);
29006 else
29007 endpos = XINT (e);
29009 /* Calculate the glyph position GPOS of GLYPH in the
29010 displayed string, relative to the beginning of the
29011 highlighted part of the string.
29013 Note: GPOS is different from CHARPOS. CHARPOS is the
29014 position of GLYPH in the internal string object. A mode
29015 line string format has structures which are converted to
29016 a flattened string by the Emacs Lisp interpreter. The
29017 internal string is an element of those structures. The
29018 displayed string is the flattened string. */
29019 tmp_glyph = row_start_glyph;
29020 while (tmp_glyph < glyph
29021 && (!(EQ (tmp_glyph->object, glyph->object)
29022 && begpos <= tmp_glyph->charpos
29023 && tmp_glyph->charpos < endpos)))
29024 tmp_glyph++;
29025 gpos = glyph - tmp_glyph;
29027 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
29028 the highlighted part of the displayed string to which
29029 GLYPH belongs. Note: GSEQ_LENGTH is different from
29030 SCHARS (STRING), because the latter returns the length of
29031 the internal string. */
29032 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
29033 tmp_glyph > glyph
29034 && (!(EQ (tmp_glyph->object, glyph->object)
29035 && begpos <= tmp_glyph->charpos
29036 && tmp_glyph->charpos < endpos));
29037 tmp_glyph--)
29039 gseq_length = gpos + (tmp_glyph - glyph) + 1;
29041 /* Calculate the total pixel width of all the glyphs between
29042 the beginning of the highlighted area and GLYPH. */
29043 total_pixel_width = 0;
29044 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
29045 total_pixel_width += tmp_glyph->pixel_width;
29047 /* Pre calculation of re-rendering position. Note: X is in
29048 column units here, after the call to mode_line_string or
29049 marginal_area_string. */
29050 hpos = x - gpos;
29051 vpos = (area == ON_MODE_LINE
29052 ? (w->current_matrix)->nrows - 1
29053 : 0);
29055 /* If GLYPH's position is included in the region that is
29056 already drawn in mouse face, we have nothing to do. */
29057 if ( EQ (window, hlinfo->mouse_face_window)
29058 && (!row->reversed_p
29059 ? (hlinfo->mouse_face_beg_col <= hpos
29060 && hpos < hlinfo->mouse_face_end_col)
29061 /* In R2L rows we swap BEG and END, see below. */
29062 : (hlinfo->mouse_face_end_col <= hpos
29063 && hpos < hlinfo->mouse_face_beg_col))
29064 && hlinfo->mouse_face_beg_row == vpos )
29065 return;
29067 if (clear_mouse_face (hlinfo))
29068 cursor = No_Cursor;
29070 if (!row->reversed_p)
29072 hlinfo->mouse_face_beg_col = hpos;
29073 hlinfo->mouse_face_beg_x = original_x_pixel
29074 - (total_pixel_width + dx);
29075 hlinfo->mouse_face_end_col = hpos + gseq_length;
29076 hlinfo->mouse_face_end_x = 0;
29078 else
29080 /* In R2L rows, show_mouse_face expects BEG and END
29081 coordinates to be swapped. */
29082 hlinfo->mouse_face_end_col = hpos;
29083 hlinfo->mouse_face_end_x = original_x_pixel
29084 - (total_pixel_width + dx);
29085 hlinfo->mouse_face_beg_col = hpos + gseq_length;
29086 hlinfo->mouse_face_beg_x = 0;
29089 hlinfo->mouse_face_beg_row = vpos;
29090 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
29091 hlinfo->mouse_face_past_end = 0;
29092 hlinfo->mouse_face_window = window;
29094 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
29095 charpos,
29096 0, &ignore,
29097 glyph->face_id,
29099 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29101 if (NILP (pointer))
29102 pointer = Qhand;
29104 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
29105 clear_mouse_face (hlinfo);
29107 #ifdef HAVE_WINDOW_SYSTEM
29108 if (FRAME_WINDOW_P (f))
29109 define_frame_cursor1 (f, cursor, pointer);
29110 #endif
29114 /* EXPORT:
29115 Take proper action when the mouse has moved to position X, Y on
29116 frame F with regards to highlighting portions of display that have
29117 mouse-face properties. Also de-highlight portions of display where
29118 the mouse was before, set the mouse pointer shape as appropriate
29119 for the mouse coordinates, and activate help echo (tooltips).
29120 X and Y can be negative or out of range. */
29122 void
29123 note_mouse_highlight (struct frame *f, int x, int y)
29125 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29126 enum window_part part = ON_NOTHING;
29127 Lisp_Object window;
29128 struct window *w;
29129 Cursor cursor = No_Cursor;
29130 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
29131 struct buffer *b;
29133 /* When a menu is active, don't highlight because this looks odd. */
29134 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
29135 if (popup_activated ())
29136 return;
29137 #endif
29139 if (!f->glyphs_initialized_p
29140 || f->pointer_invisible)
29141 return;
29143 hlinfo->mouse_face_mouse_x = x;
29144 hlinfo->mouse_face_mouse_y = y;
29145 hlinfo->mouse_face_mouse_frame = f;
29147 if (hlinfo->mouse_face_defer)
29148 return;
29150 /* Which window is that in? */
29151 window = window_from_coordinates (f, x, y, &part, 1);
29153 /* If displaying active text in another window, clear that. */
29154 if (! EQ (window, hlinfo->mouse_face_window)
29155 /* Also clear if we move out of text area in same window. */
29156 || (!NILP (hlinfo->mouse_face_window)
29157 && !NILP (window)
29158 && part != ON_TEXT
29159 && part != ON_MODE_LINE
29160 && part != ON_HEADER_LINE))
29161 clear_mouse_face (hlinfo);
29163 /* Not on a window -> return. */
29164 if (!WINDOWP (window))
29165 return;
29167 /* Reset help_echo_string. It will get recomputed below. */
29168 help_echo_string = Qnil;
29170 /* Convert to window-relative pixel coordinates. */
29171 w = XWINDOW (window);
29172 frame_to_window_pixel_xy (w, &x, &y);
29174 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
29175 /* Handle tool-bar window differently since it doesn't display a
29176 buffer. */
29177 if (EQ (window, f->tool_bar_window))
29179 note_tool_bar_highlight (f, x, y);
29180 return;
29182 #endif
29184 /* Mouse is on the mode, header line or margin? */
29185 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
29186 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29188 note_mode_line_or_margin_highlight (window, x, y, part);
29190 #ifdef HAVE_WINDOW_SYSTEM
29191 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
29193 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29194 /* Show non-text cursor (Bug#16647). */
29195 goto set_cursor;
29197 else
29198 #endif
29199 return;
29202 #ifdef HAVE_WINDOW_SYSTEM
29203 if (part == ON_VERTICAL_BORDER)
29205 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29206 help_echo_string = build_string ("drag-mouse-1: resize");
29208 else if (part == ON_RIGHT_DIVIDER)
29210 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
29211 help_echo_string = build_string ("drag-mouse-1: resize");
29213 else if (part == ON_BOTTOM_DIVIDER)
29214 if (! WINDOW_BOTTOMMOST_P (w)
29215 || minibuf_level
29216 || NILP (Vresize_mini_windows))
29218 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
29219 help_echo_string = build_string ("drag-mouse-1: resize");
29221 else
29222 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29223 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
29224 || part == ON_VERTICAL_SCROLL_BAR
29225 || part == ON_HORIZONTAL_SCROLL_BAR)
29226 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29227 else
29228 cursor = FRAME_X_OUTPUT (f)->text_cursor;
29229 #endif
29231 /* Are we in a window whose display is up to date?
29232 And verify the buffer's text has not changed. */
29233 b = XBUFFER (w->contents);
29234 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
29236 int hpos, vpos, dx, dy, area = LAST_AREA;
29237 ptrdiff_t pos;
29238 struct glyph *glyph;
29239 Lisp_Object object;
29240 Lisp_Object mouse_face = Qnil, position;
29241 Lisp_Object *overlay_vec = NULL;
29242 ptrdiff_t i, noverlays;
29243 struct buffer *obuf;
29244 ptrdiff_t obegv, ozv;
29245 int same_region;
29247 /* Find the glyph under X/Y. */
29248 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
29250 #ifdef HAVE_WINDOW_SYSTEM
29251 /* Look for :pointer property on image. */
29252 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29254 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
29255 if (img != NULL && IMAGEP (img->spec))
29257 Lisp_Object image_map, hotspot;
29258 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
29259 !NILP (image_map))
29260 && (hotspot = find_hot_spot (image_map,
29261 glyph->slice.img.x + dx,
29262 glyph->slice.img.y + dy),
29263 CONSP (hotspot))
29264 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
29266 Lisp_Object plist;
29268 /* Could check XCAR (hotspot) to see if we enter/leave
29269 this hot-spot.
29270 If so, we could look for mouse-enter, mouse-leave
29271 properties in PLIST (and do something...). */
29272 hotspot = XCDR (hotspot);
29273 if (CONSP (hotspot)
29274 && (plist = XCAR (hotspot), CONSP (plist)))
29276 pointer = Fplist_get (plist, Qpointer);
29277 if (NILP (pointer))
29278 pointer = Qhand;
29279 help_echo_string = Fplist_get (plist, Qhelp_echo);
29280 if (!NILP (help_echo_string))
29282 help_echo_window = window;
29283 help_echo_object = glyph->object;
29284 help_echo_pos = glyph->charpos;
29288 if (NILP (pointer))
29289 pointer = Fplist_get (XCDR (img->spec), QCpointer);
29292 #endif /* HAVE_WINDOW_SYSTEM */
29294 /* Clear mouse face if X/Y not over text. */
29295 if (glyph == NULL
29296 || area != TEXT_AREA
29297 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
29298 /* Glyph's OBJECT is an integer for glyphs inserted by the
29299 display engine for its internal purposes, like truncation
29300 and continuation glyphs and blanks beyond the end of
29301 line's text on text terminals. If we are over such a
29302 glyph, we are not over any text. */
29303 || INTEGERP (glyph->object)
29304 /* R2L rows have a stretch glyph at their front, which
29305 stands for no text, whereas L2R rows have no glyphs at
29306 all beyond the end of text. Treat such stretch glyphs
29307 like we do with NULL glyphs in L2R rows. */
29308 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
29309 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
29310 && glyph->type == STRETCH_GLYPH
29311 && glyph->avoid_cursor_p))
29313 if (clear_mouse_face (hlinfo))
29314 cursor = No_Cursor;
29315 #ifdef HAVE_WINDOW_SYSTEM
29316 if (FRAME_WINDOW_P (f) && NILP (pointer))
29318 if (area != TEXT_AREA)
29319 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
29320 else
29321 pointer = Vvoid_text_area_pointer;
29323 #endif
29324 goto set_cursor;
29327 pos = glyph->charpos;
29328 object = glyph->object;
29329 if (!STRINGP (object) && !BUFFERP (object))
29330 goto set_cursor;
29332 /* If we get an out-of-range value, return now; avoid an error. */
29333 if (BUFFERP (object) && pos > BUF_Z (b))
29334 goto set_cursor;
29336 /* Make the window's buffer temporarily current for
29337 overlays_at and compute_char_face. */
29338 obuf = current_buffer;
29339 current_buffer = b;
29340 obegv = BEGV;
29341 ozv = ZV;
29342 BEGV = BEG;
29343 ZV = Z;
29345 /* Is this char mouse-active or does it have help-echo? */
29346 position = make_number (pos);
29348 if (BUFFERP (object))
29350 /* Put all the overlays we want in a vector in overlay_vec. */
29351 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
29352 /* Sort overlays into increasing priority order. */
29353 noverlays = sort_overlays (overlay_vec, noverlays, w);
29355 else
29356 noverlays = 0;
29358 if (NILP (Vmouse_highlight))
29360 clear_mouse_face (hlinfo);
29361 goto check_help_echo;
29364 same_region = coords_in_mouse_face_p (w, hpos, vpos);
29366 if (same_region)
29367 cursor = No_Cursor;
29369 /* Check mouse-face highlighting. */
29370 if (! same_region
29371 /* If there exists an overlay with mouse-face overlapping
29372 the one we are currently highlighting, we have to
29373 check if we enter the overlapping overlay, and then
29374 highlight only that. */
29375 || (OVERLAYP (hlinfo->mouse_face_overlay)
29376 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
29378 /* Find the highest priority overlay with a mouse-face. */
29379 Lisp_Object overlay = Qnil;
29380 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
29382 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
29383 if (!NILP (mouse_face))
29384 overlay = overlay_vec[i];
29387 /* If we're highlighting the same overlay as before, there's
29388 no need to do that again. */
29389 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
29390 goto check_help_echo;
29391 hlinfo->mouse_face_overlay = overlay;
29393 /* Clear the display of the old active region, if any. */
29394 if (clear_mouse_face (hlinfo))
29395 cursor = No_Cursor;
29397 /* If no overlay applies, get a text property. */
29398 if (NILP (overlay))
29399 mouse_face = Fget_text_property (position, Qmouse_face, object);
29401 /* Next, compute the bounds of the mouse highlighting and
29402 display it. */
29403 if (!NILP (mouse_face) && STRINGP (object))
29405 /* The mouse-highlighting comes from a display string
29406 with a mouse-face. */
29407 Lisp_Object s, e;
29408 ptrdiff_t ignore;
29410 s = Fprevious_single_property_change
29411 (make_number (pos + 1), Qmouse_face, object, Qnil);
29412 e = Fnext_single_property_change
29413 (position, Qmouse_face, object, Qnil);
29414 if (NILP (s))
29415 s = make_number (0);
29416 if (NILP (e))
29417 e = make_number (SCHARS (object));
29418 mouse_face_from_string_pos (w, hlinfo, object,
29419 XINT (s), XINT (e));
29420 hlinfo->mouse_face_past_end = 0;
29421 hlinfo->mouse_face_window = window;
29422 hlinfo->mouse_face_face_id
29423 = face_at_string_position (w, object, pos, 0, &ignore,
29424 glyph->face_id, 1);
29425 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
29426 cursor = No_Cursor;
29428 else
29430 /* The mouse-highlighting, if any, comes from an overlay
29431 or text property in the buffer. */
29432 Lisp_Object buffer IF_LINT (= Qnil);
29433 Lisp_Object disp_string IF_LINT (= Qnil);
29435 if (STRINGP (object))
29437 /* If we are on a display string with no mouse-face,
29438 check if the text under it has one. */
29439 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
29440 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29441 pos = string_buffer_position (object, start);
29442 if (pos > 0)
29444 mouse_face = get_char_property_and_overlay
29445 (make_number (pos), Qmouse_face, w->contents, &overlay);
29446 buffer = w->contents;
29447 disp_string = object;
29450 else
29452 buffer = object;
29453 disp_string = Qnil;
29456 if (!NILP (mouse_face))
29458 Lisp_Object before, after;
29459 Lisp_Object before_string, after_string;
29460 /* To correctly find the limits of mouse highlight
29461 in a bidi-reordered buffer, we must not use the
29462 optimization of limiting the search in
29463 previous-single-property-change and
29464 next-single-property-change, because
29465 rows_from_pos_range needs the real start and end
29466 positions to DTRT in this case. That's because
29467 the first row visible in a window does not
29468 necessarily display the character whose position
29469 is the smallest. */
29470 Lisp_Object lim1
29471 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29472 ? Fmarker_position (w->start)
29473 : Qnil;
29474 Lisp_Object lim2
29475 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
29476 ? make_number (BUF_Z (XBUFFER (buffer))
29477 - w->window_end_pos)
29478 : Qnil;
29480 if (NILP (overlay))
29482 /* Handle the text property case. */
29483 before = Fprevious_single_property_change
29484 (make_number (pos + 1), Qmouse_face, buffer, lim1);
29485 after = Fnext_single_property_change
29486 (make_number (pos), Qmouse_face, buffer, lim2);
29487 before_string = after_string = Qnil;
29489 else
29491 /* Handle the overlay case. */
29492 before = Foverlay_start (overlay);
29493 after = Foverlay_end (overlay);
29494 before_string = Foverlay_get (overlay, Qbefore_string);
29495 after_string = Foverlay_get (overlay, Qafter_string);
29497 if (!STRINGP (before_string)) before_string = Qnil;
29498 if (!STRINGP (after_string)) after_string = Qnil;
29501 mouse_face_from_buffer_pos (window, hlinfo, pos,
29502 NILP (before)
29504 : XFASTINT (before),
29505 NILP (after)
29506 ? BUF_Z (XBUFFER (buffer))
29507 : XFASTINT (after),
29508 before_string, after_string,
29509 disp_string);
29510 cursor = No_Cursor;
29515 check_help_echo:
29517 /* Look for a `help-echo' property. */
29518 if (NILP (help_echo_string)) {
29519 Lisp_Object help, overlay;
29521 /* Check overlays first. */
29522 help = overlay = Qnil;
29523 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
29525 overlay = overlay_vec[i];
29526 help = Foverlay_get (overlay, Qhelp_echo);
29529 if (!NILP (help))
29531 help_echo_string = help;
29532 help_echo_window = window;
29533 help_echo_object = overlay;
29534 help_echo_pos = pos;
29536 else
29538 Lisp_Object obj = glyph->object;
29539 ptrdiff_t charpos = glyph->charpos;
29541 /* Try text properties. */
29542 if (STRINGP (obj)
29543 && charpos >= 0
29544 && charpos < SCHARS (obj))
29546 help = Fget_text_property (make_number (charpos),
29547 Qhelp_echo, obj);
29548 if (NILP (help))
29550 /* If the string itself doesn't specify a help-echo,
29551 see if the buffer text ``under'' it does. */
29552 struct glyph_row *r
29553 = MATRIX_ROW (w->current_matrix, vpos);
29554 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29555 ptrdiff_t p = string_buffer_position (obj, start);
29556 if (p > 0)
29558 help = Fget_char_property (make_number (p),
29559 Qhelp_echo, w->contents);
29560 if (!NILP (help))
29562 charpos = p;
29563 obj = w->contents;
29568 else if (BUFFERP (obj)
29569 && charpos >= BEGV
29570 && charpos < ZV)
29571 help = Fget_text_property (make_number (charpos), Qhelp_echo,
29572 obj);
29574 if (!NILP (help))
29576 help_echo_string = help;
29577 help_echo_window = window;
29578 help_echo_object = obj;
29579 help_echo_pos = charpos;
29584 #ifdef HAVE_WINDOW_SYSTEM
29585 /* Look for a `pointer' property. */
29586 if (FRAME_WINDOW_P (f) && NILP (pointer))
29588 /* Check overlays first. */
29589 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
29590 pointer = Foverlay_get (overlay_vec[i], Qpointer);
29592 if (NILP (pointer))
29594 Lisp_Object obj = glyph->object;
29595 ptrdiff_t charpos = glyph->charpos;
29597 /* Try text properties. */
29598 if (STRINGP (obj)
29599 && charpos >= 0
29600 && charpos < SCHARS (obj))
29602 pointer = Fget_text_property (make_number (charpos),
29603 Qpointer, obj);
29604 if (NILP (pointer))
29606 /* If the string itself doesn't specify a pointer,
29607 see if the buffer text ``under'' it does. */
29608 struct glyph_row *r
29609 = MATRIX_ROW (w->current_matrix, vpos);
29610 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
29611 ptrdiff_t p = string_buffer_position (obj, start);
29612 if (p > 0)
29613 pointer = Fget_char_property (make_number (p),
29614 Qpointer, w->contents);
29617 else if (BUFFERP (obj)
29618 && charpos >= BEGV
29619 && charpos < ZV)
29620 pointer = Fget_text_property (make_number (charpos),
29621 Qpointer, obj);
29624 #endif /* HAVE_WINDOW_SYSTEM */
29626 BEGV = obegv;
29627 ZV = ozv;
29628 current_buffer = obuf;
29631 set_cursor:
29633 #ifdef HAVE_WINDOW_SYSTEM
29634 if (FRAME_WINDOW_P (f))
29635 define_frame_cursor1 (f, cursor, pointer);
29636 #else
29637 /* This is here to prevent a compiler error, about "label at end of
29638 compound statement". */
29639 return;
29640 #endif
29644 /* EXPORT for RIF:
29645 Clear any mouse-face on window W. This function is part of the
29646 redisplay interface, and is called from try_window_id and similar
29647 functions to ensure the mouse-highlight is off. */
29649 void
29650 x_clear_window_mouse_face (struct window *w)
29652 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29653 Lisp_Object window;
29655 block_input ();
29656 XSETWINDOW (window, w);
29657 if (EQ (window, hlinfo->mouse_face_window))
29658 clear_mouse_face (hlinfo);
29659 unblock_input ();
29663 /* EXPORT:
29664 Just discard the mouse face information for frame F, if any.
29665 This is used when the size of F is changed. */
29667 void
29668 cancel_mouse_face (struct frame *f)
29670 Lisp_Object window;
29671 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29673 window = hlinfo->mouse_face_window;
29674 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
29675 reset_mouse_highlight (hlinfo);
29680 /***********************************************************************
29681 Exposure Events
29682 ***********************************************************************/
29684 #ifdef HAVE_WINDOW_SYSTEM
29686 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
29687 which intersects rectangle R. R is in window-relative coordinates. */
29689 static void
29690 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
29691 enum glyph_row_area area)
29693 struct glyph *first = row->glyphs[area];
29694 struct glyph *end = row->glyphs[area] + row->used[area];
29695 struct glyph *last;
29696 int first_x, start_x, x;
29698 if (area == TEXT_AREA && row->fill_line_p)
29699 /* If row extends face to end of line write the whole line. */
29700 draw_glyphs (w, 0, row, area,
29701 0, row->used[area],
29702 DRAW_NORMAL_TEXT, 0);
29703 else
29705 /* Set START_X to the window-relative start position for drawing glyphs of
29706 AREA. The first glyph of the text area can be partially visible.
29707 The first glyphs of other areas cannot. */
29708 start_x = window_box_left_offset (w, area);
29709 x = start_x;
29710 if (area == TEXT_AREA)
29711 x += row->x;
29713 /* Find the first glyph that must be redrawn. */
29714 while (first < end
29715 && x + first->pixel_width < r->x)
29717 x += first->pixel_width;
29718 ++first;
29721 /* Find the last one. */
29722 last = first;
29723 first_x = x;
29724 while (last < end
29725 && x < r->x + r->width)
29727 x += last->pixel_width;
29728 ++last;
29731 /* Repaint. */
29732 if (last > first)
29733 draw_glyphs (w, first_x - start_x, row, area,
29734 first - row->glyphs[area], last - row->glyphs[area],
29735 DRAW_NORMAL_TEXT, 0);
29740 /* Redraw the parts of the glyph row ROW on window W intersecting
29741 rectangle R. R is in window-relative coordinates. Value is
29742 non-zero if mouse-face was overwritten. */
29744 static int
29745 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
29747 eassert (row->enabled_p);
29749 if (row->mode_line_p || w->pseudo_window_p)
29750 draw_glyphs (w, 0, row, TEXT_AREA,
29751 0, row->used[TEXT_AREA],
29752 DRAW_NORMAL_TEXT, 0);
29753 else
29755 if (row->used[LEFT_MARGIN_AREA])
29756 expose_area (w, row, r, LEFT_MARGIN_AREA);
29757 if (row->used[TEXT_AREA])
29758 expose_area (w, row, r, TEXT_AREA);
29759 if (row->used[RIGHT_MARGIN_AREA])
29760 expose_area (w, row, r, RIGHT_MARGIN_AREA);
29761 draw_row_fringe_bitmaps (w, row);
29764 return row->mouse_face_p;
29768 /* Redraw those parts of glyphs rows during expose event handling that
29769 overlap other rows. Redrawing of an exposed line writes over parts
29770 of lines overlapping that exposed line; this function fixes that.
29772 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
29773 row in W's current matrix that is exposed and overlaps other rows.
29774 LAST_OVERLAPPING_ROW is the last such row. */
29776 static void
29777 expose_overlaps (struct window *w,
29778 struct glyph_row *first_overlapping_row,
29779 struct glyph_row *last_overlapping_row,
29780 XRectangle *r)
29782 struct glyph_row *row;
29784 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
29785 if (row->overlapping_p)
29787 eassert (row->enabled_p && !row->mode_line_p);
29789 row->clip = r;
29790 if (row->used[LEFT_MARGIN_AREA])
29791 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
29793 if (row->used[TEXT_AREA])
29794 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
29796 if (row->used[RIGHT_MARGIN_AREA])
29797 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
29798 row->clip = NULL;
29803 /* Return non-zero if W's cursor intersects rectangle R. */
29805 static int
29806 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
29808 XRectangle cr, result;
29809 struct glyph *cursor_glyph;
29810 struct glyph_row *row;
29812 if (w->phys_cursor.vpos >= 0
29813 && w->phys_cursor.vpos < w->current_matrix->nrows
29814 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
29815 row->enabled_p)
29816 && row->cursor_in_fringe_p)
29818 /* Cursor is in the fringe. */
29819 cr.x = window_box_right_offset (w,
29820 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
29821 ? RIGHT_MARGIN_AREA
29822 : TEXT_AREA));
29823 cr.y = row->y;
29824 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
29825 cr.height = row->height;
29826 return x_intersect_rectangles (&cr, r, &result);
29829 cursor_glyph = get_phys_cursor_glyph (w);
29830 if (cursor_glyph)
29832 /* r is relative to W's box, but w->phys_cursor.x is relative
29833 to left edge of W's TEXT area. Adjust it. */
29834 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
29835 cr.y = w->phys_cursor.y;
29836 cr.width = cursor_glyph->pixel_width;
29837 cr.height = w->phys_cursor_height;
29838 /* ++KFS: W32 version used W32-specific IntersectRect here, but
29839 I assume the effect is the same -- and this is portable. */
29840 return x_intersect_rectangles (&cr, r, &result);
29842 /* If we don't understand the format, pretend we're not in the hot-spot. */
29843 return 0;
29847 /* EXPORT:
29848 Draw a vertical window border to the right of window W if W doesn't
29849 have vertical scroll bars. */
29851 void
29852 x_draw_vertical_border (struct window *w)
29854 struct frame *f = XFRAME (WINDOW_FRAME (w));
29856 /* We could do better, if we knew what type of scroll-bar the adjacent
29857 windows (on either side) have... But we don't :-(
29858 However, I think this works ok. ++KFS 2003-04-25 */
29860 /* Redraw borders between horizontally adjacent windows. Don't
29861 do it for frames with vertical scroll bars because either the
29862 right scroll bar of a window, or the left scroll bar of its
29863 neighbor will suffice as a border. */
29864 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
29865 return;
29867 /* Note: It is necessary to redraw both the left and the right
29868 borders, for when only this single window W is being
29869 redisplayed. */
29870 if (!WINDOW_RIGHTMOST_P (w)
29871 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
29873 int x0, x1, y0, y1;
29875 window_box_edges (w, &x0, &y0, &x1, &y1);
29876 y1 -= 1;
29878 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
29879 x1 -= 1;
29881 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
29884 if (!WINDOW_LEFTMOST_P (w)
29885 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
29887 int x0, x1, y0, y1;
29889 window_box_edges (w, &x0, &y0, &x1, &y1);
29890 y1 -= 1;
29892 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
29893 x0 -= 1;
29895 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
29900 /* Draw window dividers for window W. */
29902 void
29903 x_draw_right_divider (struct window *w)
29905 struct frame *f = WINDOW_XFRAME (w);
29907 if (w->mini || w->pseudo_window_p)
29908 return;
29909 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
29911 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
29912 int x1 = WINDOW_RIGHT_EDGE_X (w);
29913 int y0 = WINDOW_TOP_EDGE_Y (w);
29914 /* The bottom divider prevails. */
29915 int y1 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29917 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29921 static void
29922 x_draw_bottom_divider (struct window *w)
29924 struct frame *f = XFRAME (WINDOW_FRAME (w));
29926 if (w->mini || w->pseudo_window_p)
29927 return;
29928 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
29930 int x0 = WINDOW_LEFT_EDGE_X (w);
29931 int x1 = WINDOW_RIGHT_EDGE_X (w);
29932 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29933 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
29935 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29939 /* Redraw the part of window W intersection rectangle FR. Pixel
29940 coordinates in FR are frame-relative. Call this function with
29941 input blocked. Value is non-zero if the exposure overwrites
29942 mouse-face. */
29944 static int
29945 expose_window (struct window *w, XRectangle *fr)
29947 struct frame *f = XFRAME (w->frame);
29948 XRectangle wr, r;
29949 int mouse_face_overwritten_p = 0;
29951 /* If window is not yet fully initialized, do nothing. This can
29952 happen when toolkit scroll bars are used and a window is split.
29953 Reconfiguring the scroll bar will generate an expose for a newly
29954 created window. */
29955 if (w->current_matrix == NULL)
29956 return 0;
29958 /* When we're currently updating the window, display and current
29959 matrix usually don't agree. Arrange for a thorough display
29960 later. */
29961 if (w->must_be_updated_p)
29963 SET_FRAME_GARBAGED (f);
29964 return 0;
29967 /* Frame-relative pixel rectangle of W. */
29968 wr.x = WINDOW_LEFT_EDGE_X (w);
29969 wr.y = WINDOW_TOP_EDGE_Y (w);
29970 wr.width = WINDOW_PIXEL_WIDTH (w);
29971 wr.height = WINDOW_PIXEL_HEIGHT (w);
29973 if (x_intersect_rectangles (fr, &wr, &r))
29975 int yb = window_text_bottom_y (w);
29976 struct glyph_row *row;
29977 int cursor_cleared_p, phys_cursor_on_p;
29978 struct glyph_row *first_overlapping_row, *last_overlapping_row;
29980 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
29981 r.x, r.y, r.width, r.height));
29983 /* Convert to window coordinates. */
29984 r.x -= WINDOW_LEFT_EDGE_X (w);
29985 r.y -= WINDOW_TOP_EDGE_Y (w);
29987 /* Turn off the cursor. */
29988 if (!w->pseudo_window_p
29989 && phys_cursor_in_rect_p (w, &r))
29991 x_clear_cursor (w);
29992 cursor_cleared_p = 1;
29994 else
29995 cursor_cleared_p = 0;
29997 /* If the row containing the cursor extends face to end of line,
29998 then expose_area might overwrite the cursor outside the
29999 rectangle and thus notice_overwritten_cursor might clear
30000 w->phys_cursor_on_p. We remember the original value and
30001 check later if it is changed. */
30002 phys_cursor_on_p = w->phys_cursor_on_p;
30004 /* Update lines intersecting rectangle R. */
30005 first_overlapping_row = last_overlapping_row = NULL;
30006 for (row = w->current_matrix->rows;
30007 row->enabled_p;
30008 ++row)
30010 int y0 = row->y;
30011 int y1 = MATRIX_ROW_BOTTOM_Y (row);
30013 if ((y0 >= r.y && y0 < r.y + r.height)
30014 || (y1 > r.y && y1 < r.y + r.height)
30015 || (r.y >= y0 && r.y < y1)
30016 || (r.y + r.height > y0 && r.y + r.height < y1))
30018 /* A header line may be overlapping, but there is no need
30019 to fix overlapping areas for them. KFS 2005-02-12 */
30020 if (row->overlapping_p && !row->mode_line_p)
30022 if (first_overlapping_row == NULL)
30023 first_overlapping_row = row;
30024 last_overlapping_row = row;
30027 row->clip = fr;
30028 if (expose_line (w, row, &r))
30029 mouse_face_overwritten_p = 1;
30030 row->clip = NULL;
30032 else if (row->overlapping_p)
30034 /* We must redraw a row overlapping the exposed area. */
30035 if (y0 < r.y
30036 ? y0 + row->phys_height > r.y
30037 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
30039 if (first_overlapping_row == NULL)
30040 first_overlapping_row = row;
30041 last_overlapping_row = row;
30045 if (y1 >= yb)
30046 break;
30049 /* Display the mode line if there is one. */
30050 if (WINDOW_WANTS_MODELINE_P (w)
30051 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
30052 row->enabled_p)
30053 && row->y < r.y + r.height)
30055 if (expose_line (w, row, &r))
30056 mouse_face_overwritten_p = 1;
30059 if (!w->pseudo_window_p)
30061 /* Fix the display of overlapping rows. */
30062 if (first_overlapping_row)
30063 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
30064 fr);
30066 /* Draw border between windows. */
30067 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
30068 x_draw_right_divider (w);
30069 else
30070 x_draw_vertical_border (w);
30072 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
30073 x_draw_bottom_divider (w);
30075 /* Turn the cursor on again. */
30076 if (cursor_cleared_p
30077 || (phys_cursor_on_p && !w->phys_cursor_on_p))
30078 update_window_cursor (w, 1);
30082 return mouse_face_overwritten_p;
30087 /* Redraw (parts) of all windows in the window tree rooted at W that
30088 intersect R. R contains frame pixel coordinates. Value is
30089 non-zero if the exposure overwrites mouse-face. */
30091 static int
30092 expose_window_tree (struct window *w, XRectangle *r)
30094 struct frame *f = XFRAME (w->frame);
30095 int mouse_face_overwritten_p = 0;
30097 while (w && !FRAME_GARBAGED_P (f))
30099 if (WINDOWP (w->contents))
30100 mouse_face_overwritten_p
30101 |= expose_window_tree (XWINDOW (w->contents), r);
30102 else
30103 mouse_face_overwritten_p |= expose_window (w, r);
30105 w = NILP (w->next) ? NULL : XWINDOW (w->next);
30108 return mouse_face_overwritten_p;
30112 /* EXPORT:
30113 Redisplay an exposed area of frame F. X and Y are the upper-left
30114 corner of the exposed rectangle. W and H are width and height of
30115 the exposed area. All are pixel values. W or H zero means redraw
30116 the entire frame. */
30118 void
30119 expose_frame (struct frame *f, int x, int y, int w, int h)
30121 XRectangle r;
30122 int mouse_face_overwritten_p = 0;
30124 TRACE ((stderr, "expose_frame "));
30126 /* No need to redraw if frame will be redrawn soon. */
30127 if (FRAME_GARBAGED_P (f))
30129 TRACE ((stderr, " garbaged\n"));
30130 return;
30133 /* If basic faces haven't been realized yet, there is no point in
30134 trying to redraw anything. This can happen when we get an expose
30135 event while Emacs is starting, e.g. by moving another window. */
30136 if (FRAME_FACE_CACHE (f) == NULL
30137 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
30139 TRACE ((stderr, " no faces\n"));
30140 return;
30143 if (w == 0 || h == 0)
30145 r.x = r.y = 0;
30146 r.width = FRAME_TEXT_WIDTH (f);
30147 r.height = FRAME_TEXT_HEIGHT (f);
30148 /** r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); **/
30149 /** r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); **/
30151 else
30153 r.x = x;
30154 r.y = y;
30155 r.width = w;
30156 r.height = h;
30159 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
30160 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
30162 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
30163 if (WINDOWP (f->tool_bar_window))
30164 mouse_face_overwritten_p
30165 |= expose_window (XWINDOW (f->tool_bar_window), &r);
30166 #endif
30168 #ifdef HAVE_X_WINDOWS
30169 #ifndef MSDOS
30170 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
30171 if (WINDOWP (f->menu_bar_window))
30172 mouse_face_overwritten_p
30173 |= expose_window (XWINDOW (f->menu_bar_window), &r);
30174 #endif /* not USE_X_TOOLKIT and not USE_GTK */
30175 #endif
30176 #endif
30178 /* Some window managers support a focus-follows-mouse style with
30179 delayed raising of frames. Imagine a partially obscured frame,
30180 and moving the mouse into partially obscured mouse-face on that
30181 frame. The visible part of the mouse-face will be highlighted,
30182 then the WM raises the obscured frame. With at least one WM, KDE
30183 2.1, Emacs is not getting any event for the raising of the frame
30184 (even tried with SubstructureRedirectMask), only Expose events.
30185 These expose events will draw text normally, i.e. not
30186 highlighted. Which means we must redo the highlight here.
30187 Subsume it under ``we love X''. --gerd 2001-08-15 */
30188 /* Included in Windows version because Windows most likely does not
30189 do the right thing if any third party tool offers
30190 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
30191 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
30193 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30194 if (f == hlinfo->mouse_face_mouse_frame)
30196 int mouse_x = hlinfo->mouse_face_mouse_x;
30197 int mouse_y = hlinfo->mouse_face_mouse_y;
30198 clear_mouse_face (hlinfo);
30199 note_mouse_highlight (f, mouse_x, mouse_y);
30205 /* EXPORT:
30206 Determine the intersection of two rectangles R1 and R2. Return
30207 the intersection in *RESULT. Value is non-zero if RESULT is not
30208 empty. */
30211 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
30213 XRectangle *left, *right;
30214 XRectangle *upper, *lower;
30215 int intersection_p = 0;
30217 /* Rearrange so that R1 is the left-most rectangle. */
30218 if (r1->x < r2->x)
30219 left = r1, right = r2;
30220 else
30221 left = r2, right = r1;
30223 /* X0 of the intersection is right.x0, if this is inside R1,
30224 otherwise there is no intersection. */
30225 if (right->x <= left->x + left->width)
30227 result->x = right->x;
30229 /* The right end of the intersection is the minimum of
30230 the right ends of left and right. */
30231 result->width = (min (left->x + left->width, right->x + right->width)
30232 - result->x);
30234 /* Same game for Y. */
30235 if (r1->y < r2->y)
30236 upper = r1, lower = r2;
30237 else
30238 upper = r2, lower = r1;
30240 /* The upper end of the intersection is lower.y0, if this is inside
30241 of upper. Otherwise, there is no intersection. */
30242 if (lower->y <= upper->y + upper->height)
30244 result->y = lower->y;
30246 /* The lower end of the intersection is the minimum of the lower
30247 ends of upper and lower. */
30248 result->height = (min (lower->y + lower->height,
30249 upper->y + upper->height)
30250 - result->y);
30251 intersection_p = 1;
30255 return intersection_p;
30258 #endif /* HAVE_WINDOW_SYSTEM */
30261 /***********************************************************************
30262 Initialization
30263 ***********************************************************************/
30265 void
30266 syms_of_xdisp (void)
30268 Vwith_echo_area_save_vector = Qnil;
30269 staticpro (&Vwith_echo_area_save_vector);
30271 Vmessage_stack = Qnil;
30272 staticpro (&Vmessage_stack);
30274 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
30275 DEFSYM (Qredisplay_internal, "redisplay_internal (C function)");
30277 message_dolog_marker1 = Fmake_marker ();
30278 staticpro (&message_dolog_marker1);
30279 message_dolog_marker2 = Fmake_marker ();
30280 staticpro (&message_dolog_marker2);
30281 message_dolog_marker3 = Fmake_marker ();
30282 staticpro (&message_dolog_marker3);
30284 #ifdef GLYPH_DEBUG
30285 defsubr (&Sdump_frame_glyph_matrix);
30286 defsubr (&Sdump_glyph_matrix);
30287 defsubr (&Sdump_glyph_row);
30288 defsubr (&Sdump_tool_bar_row);
30289 defsubr (&Strace_redisplay);
30290 defsubr (&Strace_to_stderr);
30291 #endif
30292 #ifdef HAVE_WINDOW_SYSTEM
30293 defsubr (&Stool_bar_height);
30294 defsubr (&Slookup_image_map);
30295 #endif
30296 defsubr (&Sline_pixel_height);
30297 defsubr (&Sformat_mode_line);
30298 defsubr (&Sinvisible_p);
30299 defsubr (&Scurrent_bidi_paragraph_direction);
30300 defsubr (&Swindow_text_pixel_size);
30301 defsubr (&Smove_point_visually);
30303 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
30304 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
30305 DEFSYM (Qoverriding_local_map, "overriding-local-map");
30306 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
30307 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
30308 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
30309 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
30310 DEFSYM (Qeval, "eval");
30311 DEFSYM (QCdata, ":data");
30312 DEFSYM (Qdisplay, "display");
30313 DEFSYM (Qspace_width, "space-width");
30314 DEFSYM (Qraise, "raise");
30315 DEFSYM (Qslice, "slice");
30316 DEFSYM (Qspace, "space");
30317 DEFSYM (Qmargin, "margin");
30318 DEFSYM (Qpointer, "pointer");
30319 DEFSYM (Qleft_margin, "left-margin");
30320 DEFSYM (Qright_margin, "right-margin");
30321 DEFSYM (Qcenter, "center");
30322 DEFSYM (Qline_height, "line-height");
30323 DEFSYM (QCalign_to, ":align-to");
30324 DEFSYM (QCrelative_width, ":relative-width");
30325 DEFSYM (QCrelative_height, ":relative-height");
30326 DEFSYM (QCeval, ":eval");
30327 DEFSYM (QCpropertize, ":propertize");
30328 DEFSYM (QCfile, ":file");
30329 DEFSYM (Qfontified, "fontified");
30330 DEFSYM (Qfontification_functions, "fontification-functions");
30331 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
30332 DEFSYM (Qescape_glyph, "escape-glyph");
30333 DEFSYM (Qnobreak_space, "nobreak-space");
30334 DEFSYM (Qimage, "image");
30335 DEFSYM (Qtext, "text");
30336 DEFSYM (Qboth, "both");
30337 DEFSYM (Qboth_horiz, "both-horiz");
30338 DEFSYM (Qtext_image_horiz, "text-image-horiz");
30339 DEFSYM (QCmap, ":map");
30340 DEFSYM (QCpointer, ":pointer");
30341 DEFSYM (Qrect, "rect");
30342 DEFSYM (Qcircle, "circle");
30343 DEFSYM (Qpoly, "poly");
30344 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
30345 DEFSYM (Qgrow_only, "grow-only");
30346 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
30347 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
30348 DEFSYM (Qposition, "position");
30349 DEFSYM (Qbuffer_position, "buffer-position");
30350 DEFSYM (Qobject, "object");
30351 DEFSYM (Qbar, "bar");
30352 DEFSYM (Qhbar, "hbar");
30353 DEFSYM (Qbox, "box");
30354 DEFSYM (Qhollow, "hollow");
30355 DEFSYM (Qhand, "hand");
30356 DEFSYM (Qarrow, "arrow");
30357 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
30359 list_of_error = list1 (list2 (intern_c_string ("error"),
30360 intern_c_string ("void-variable")));
30361 staticpro (&list_of_error);
30363 DEFSYM (Qlast_arrow_position, "last-arrow-position");
30364 DEFSYM (Qlast_arrow_string, "last-arrow-string");
30365 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
30366 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
30368 echo_buffer[0] = echo_buffer[1] = Qnil;
30369 staticpro (&echo_buffer[0]);
30370 staticpro (&echo_buffer[1]);
30372 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
30373 staticpro (&echo_area_buffer[0]);
30374 staticpro (&echo_area_buffer[1]);
30376 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
30377 staticpro (&Vmessages_buffer_name);
30379 mode_line_proptrans_alist = Qnil;
30380 staticpro (&mode_line_proptrans_alist);
30381 mode_line_string_list = Qnil;
30382 staticpro (&mode_line_string_list);
30383 mode_line_string_face = Qnil;
30384 staticpro (&mode_line_string_face);
30385 mode_line_string_face_prop = Qnil;
30386 staticpro (&mode_line_string_face_prop);
30387 Vmode_line_unwind_vector = Qnil;
30388 staticpro (&Vmode_line_unwind_vector);
30390 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
30392 help_echo_string = Qnil;
30393 staticpro (&help_echo_string);
30394 help_echo_object = Qnil;
30395 staticpro (&help_echo_object);
30396 help_echo_window = Qnil;
30397 staticpro (&help_echo_window);
30398 previous_help_echo_string = Qnil;
30399 staticpro (&previous_help_echo_string);
30400 help_echo_pos = -1;
30402 DEFSYM (Qright_to_left, "right-to-left");
30403 DEFSYM (Qleft_to_right, "left-to-right");
30404 defsubr (&Sbidi_resolved_levels);
30406 #ifdef HAVE_WINDOW_SYSTEM
30407 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
30408 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
30409 For example, if a block cursor is over a tab, it will be drawn as
30410 wide as that tab on the display. */);
30411 x_stretch_cursor_p = 0;
30412 #endif
30414 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
30415 doc: /* Non-nil means highlight trailing whitespace.
30416 The face used for trailing whitespace is `trailing-whitespace'. */);
30417 Vshow_trailing_whitespace = Qnil;
30419 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
30420 doc: /* Control highlighting of non-ASCII space and hyphen chars.
30421 If the value is t, Emacs highlights non-ASCII chars which have the
30422 same appearance as an ASCII space or hyphen, using the `nobreak-space'
30423 or `escape-glyph' face respectively.
30425 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
30426 U+2011 (non-breaking hyphen) are affected.
30428 Any other non-nil value means to display these characters as a escape
30429 glyph followed by an ordinary space or hyphen.
30431 A value of nil means no special handling of these characters. */);
30432 Vnobreak_char_display = Qt;
30434 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
30435 doc: /* The pointer shape to show in void text areas.
30436 A value of nil means to show the text pointer. Other options are
30437 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
30438 `hourglass'. */);
30439 Vvoid_text_area_pointer = Qarrow;
30441 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
30442 doc: /* Non-nil means don't actually do any redisplay.
30443 This is used for internal purposes. */);
30444 Vinhibit_redisplay = Qnil;
30446 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
30447 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
30448 Vglobal_mode_string = Qnil;
30450 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
30451 doc: /* Marker for where to display an arrow on top of the buffer text.
30452 This must be the beginning of a line in order to work.
30453 See also `overlay-arrow-string'. */);
30454 Voverlay_arrow_position = Qnil;
30456 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
30457 doc: /* String to display as an arrow in non-window frames.
30458 See also `overlay-arrow-position'. */);
30459 Voverlay_arrow_string = build_pure_c_string ("=>");
30461 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
30462 doc: /* List of variables (symbols) which hold markers for overlay arrows.
30463 The symbols on this list are examined during redisplay to determine
30464 where to display overlay arrows. */);
30465 Voverlay_arrow_variable_list
30466 = list1 (intern_c_string ("overlay-arrow-position"));
30468 DEFVAR_INT ("scroll-step", emacs_scroll_step,
30469 doc: /* The number of lines to try scrolling a window by when point moves out.
30470 If that fails to bring point back on frame, point is centered instead.
30471 If this is zero, point is always centered after it moves off frame.
30472 If you want scrolling to always be a line at a time, you should set
30473 `scroll-conservatively' to a large value rather than set this to 1. */);
30475 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
30476 doc: /* Scroll up to this many lines, to bring point back on screen.
30477 If point moves off-screen, redisplay will scroll by up to
30478 `scroll-conservatively' lines in order to bring point just barely
30479 onto the screen again. If that cannot be done, then redisplay
30480 recenters point as usual.
30482 If the value is greater than 100, redisplay will never recenter point,
30483 but will always scroll just enough text to bring point into view, even
30484 if you move far away.
30486 A value of zero means always recenter point if it moves off screen. */);
30487 scroll_conservatively = 0;
30489 DEFVAR_INT ("scroll-margin", scroll_margin,
30490 doc: /* Number of lines of margin at the top and bottom of a window.
30491 Recenter the window whenever point gets within this many lines
30492 of the top or bottom of the window. */);
30493 scroll_margin = 0;
30495 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
30496 doc: /* Pixels per inch value for non-window system displays.
30497 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
30498 Vdisplay_pixels_per_inch = make_float (72.0);
30500 #ifdef GLYPH_DEBUG
30501 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
30502 #endif
30504 DEFVAR_LISP ("truncate-partial-width-windows",
30505 Vtruncate_partial_width_windows,
30506 doc: /* Non-nil means truncate lines in windows narrower than the frame.
30507 For an integer value, truncate lines in each window narrower than the
30508 full frame width, provided the window width is less than that integer;
30509 otherwise, respect the value of `truncate-lines'.
30511 For any other non-nil value, truncate lines in all windows that do
30512 not span the full frame width.
30514 A value of nil means to respect the value of `truncate-lines'.
30516 If `word-wrap' is enabled, you might want to reduce this. */);
30517 Vtruncate_partial_width_windows = make_number (50);
30519 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
30520 doc: /* Maximum buffer size for which line number should be displayed.
30521 If the buffer is bigger than this, the line number does not appear
30522 in the mode line. A value of nil means no limit. */);
30523 Vline_number_display_limit = Qnil;
30525 DEFVAR_INT ("line-number-display-limit-width",
30526 line_number_display_limit_width,
30527 doc: /* Maximum line width (in characters) for line number display.
30528 If the average length of the lines near point is bigger than this, then the
30529 line number may be omitted from the mode line. */);
30530 line_number_display_limit_width = 200;
30532 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
30533 doc: /* Non-nil means highlight region even in nonselected windows. */);
30534 highlight_nonselected_windows = 0;
30536 DEFVAR_BOOL ("multiple-frames", multiple_frames,
30537 doc: /* Non-nil if more than one frame is visible on this display.
30538 Minibuffer-only frames don't count, but iconified frames do.
30539 This variable is not guaranteed to be accurate except while processing
30540 `frame-title-format' and `icon-title-format'. */);
30542 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
30543 doc: /* Template for displaying the title bar of visible frames.
30544 \(Assuming the window manager supports this feature.)
30546 This variable has the same structure as `mode-line-format', except that
30547 the %c and %l constructs are ignored. It is used only on frames for
30548 which no explicit name has been set \(see `modify-frame-parameters'). */);
30550 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
30551 doc: /* Template for displaying the title bar of an iconified frame.
30552 \(Assuming the window manager supports this feature.)
30553 This variable has the same structure as `mode-line-format' (which see),
30554 and is used only on frames for which no explicit name has been set
30555 \(see `modify-frame-parameters'). */);
30556 Vicon_title_format
30557 = Vframe_title_format
30558 = listn (CONSTYPE_PURE, 3,
30559 intern_c_string ("multiple-frames"),
30560 build_pure_c_string ("%b"),
30561 listn (CONSTYPE_PURE, 4,
30562 empty_unibyte_string,
30563 intern_c_string ("invocation-name"),
30564 build_pure_c_string ("@"),
30565 intern_c_string ("system-name")));
30567 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
30568 doc: /* Maximum number of lines to keep in the message log buffer.
30569 If nil, disable message logging. If t, log messages but don't truncate
30570 the buffer when it becomes large. */);
30571 Vmessage_log_max = make_number (1000);
30573 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
30574 doc: /* Functions called before redisplay, if window sizes have changed.
30575 The value should be a list of functions that take one argument.
30576 Just before redisplay, for each frame, if any of its windows have changed
30577 size since the last redisplay, or have been split or deleted,
30578 all the functions in the list are called, with the frame as argument. */);
30579 Vwindow_size_change_functions = Qnil;
30581 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
30582 doc: /* List of functions to call before redisplaying a window with scrolling.
30583 Each function is called with two arguments, the window and its new
30584 display-start position. Note that these functions are also called by
30585 `set-window-buffer'. Also note that the value of `window-end' is not
30586 valid when these functions are called.
30588 Warning: Do not use this feature to alter the way the window
30589 is scrolled. It is not designed for that, and such use probably won't
30590 work. */);
30591 Vwindow_scroll_functions = Qnil;
30593 DEFVAR_LISP ("window-text-change-functions",
30594 Vwindow_text_change_functions,
30595 doc: /* Functions to call in redisplay when text in the window might change. */);
30596 Vwindow_text_change_functions = Qnil;
30598 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
30599 doc: /* Functions called when redisplay of a window reaches the end trigger.
30600 Each function is called with two arguments, the window and the end trigger value.
30601 See `set-window-redisplay-end-trigger'. */);
30602 Vredisplay_end_trigger_functions = Qnil;
30604 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
30605 doc: /* Non-nil means autoselect window with mouse pointer.
30606 If nil, do not autoselect windows.
30607 A positive number means delay autoselection by that many seconds: a
30608 window is autoselected only after the mouse has remained in that
30609 window for the duration of the delay.
30610 A negative number has a similar effect, but causes windows to be
30611 autoselected only after the mouse has stopped moving. \(Because of
30612 the way Emacs compares mouse events, you will occasionally wait twice
30613 that time before the window gets selected.\)
30614 Any other value means to autoselect window instantaneously when the
30615 mouse pointer enters it.
30617 Autoselection selects the minibuffer only if it is active, and never
30618 unselects the minibuffer if it is active.
30620 When customizing this variable make sure that the actual value of
30621 `focus-follows-mouse' matches the behavior of your window manager. */);
30622 Vmouse_autoselect_window = Qnil;
30624 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
30625 doc: /* Non-nil means automatically resize tool-bars.
30626 This dynamically changes the tool-bar's height to the minimum height
30627 that is needed to make all tool-bar items visible.
30628 If value is `grow-only', the tool-bar's height is only increased
30629 automatically; to decrease the tool-bar height, use \\[recenter]. */);
30630 Vauto_resize_tool_bars = Qt;
30632 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
30633 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
30634 auto_raise_tool_bar_buttons_p = 1;
30636 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
30637 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
30638 make_cursor_line_fully_visible_p = 1;
30640 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
30641 doc: /* Border below tool-bar in pixels.
30642 If an integer, use it as the height of the border.
30643 If it is one of `internal-border-width' or `border-width', use the
30644 value of the corresponding frame parameter.
30645 Otherwise, no border is added below the tool-bar. */);
30646 Vtool_bar_border = Qinternal_border_width;
30648 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
30649 doc: /* Margin around tool-bar buttons in pixels.
30650 If an integer, use that for both horizontal and vertical margins.
30651 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
30652 HORZ specifying the horizontal margin, and VERT specifying the
30653 vertical margin. */);
30654 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
30656 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
30657 doc: /* Relief thickness of tool-bar buttons. */);
30658 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
30660 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
30661 doc: /* Tool bar style to use.
30662 It can be one of
30663 image - show images only
30664 text - show text only
30665 both - show both, text below image
30666 both-horiz - show text to the right of the image
30667 text-image-horiz - show text to the left of the image
30668 any other - use system default or image if no system default.
30670 This variable only affects the GTK+ toolkit version of Emacs. */);
30671 Vtool_bar_style = Qnil;
30673 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
30674 doc: /* Maximum number of characters a label can have to be shown.
30675 The tool bar style must also show labels for this to have any effect, see
30676 `tool-bar-style'. */);
30677 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
30679 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
30680 doc: /* List of functions to call to fontify regions of text.
30681 Each function is called with one argument POS. Functions must
30682 fontify a region starting at POS in the current buffer, and give
30683 fontified regions the property `fontified'. */);
30684 Vfontification_functions = Qnil;
30685 Fmake_variable_buffer_local (Qfontification_functions);
30687 DEFVAR_BOOL ("unibyte-display-via-language-environment",
30688 unibyte_display_via_language_environment,
30689 doc: /* Non-nil means display unibyte text according to language environment.
30690 Specifically, this means that raw bytes in the range 160-255 decimal
30691 are displayed by converting them to the equivalent multibyte characters
30692 according to the current language environment. As a result, they are
30693 displayed according to the current fontset.
30695 Note that this variable affects only how these bytes are displayed,
30696 but does not change the fact they are interpreted as raw bytes. */);
30697 unibyte_display_via_language_environment = 0;
30699 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
30700 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
30701 If a float, it specifies a fraction of the mini-window frame's height.
30702 If an integer, it specifies a number of lines. */);
30703 Vmax_mini_window_height = make_float (0.25);
30705 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
30706 doc: /* How to resize mini-windows (the minibuffer and the echo area).
30707 A value of nil means don't automatically resize mini-windows.
30708 A value of t means resize them to fit the text displayed in them.
30709 A value of `grow-only', the default, means let mini-windows grow only;
30710 they return to their normal size when the minibuffer is closed, or the
30711 echo area becomes empty. */);
30712 Vresize_mini_windows = Qgrow_only;
30714 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
30715 doc: /* Alist specifying how to blink the cursor off.
30716 Each element has the form (ON-STATE . OFF-STATE). Whenever the
30717 `cursor-type' frame-parameter or variable equals ON-STATE,
30718 comparing using `equal', Emacs uses OFF-STATE to specify
30719 how to blink it off. ON-STATE and OFF-STATE are values for
30720 the `cursor-type' frame parameter.
30722 If a frame's ON-STATE has no entry in this list,
30723 the frame's other specifications determine how to blink the cursor off. */);
30724 Vblink_cursor_alist = Qnil;
30726 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
30727 doc: /* Allow or disallow automatic horizontal scrolling of windows.
30728 If non-nil, windows are automatically scrolled horizontally to make
30729 point visible. */);
30730 automatic_hscrolling_p = 1;
30731 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
30733 DEFVAR_INT ("hscroll-margin", hscroll_margin,
30734 doc: /* How many columns away from the window edge point is allowed to get
30735 before automatic hscrolling will horizontally scroll the window. */);
30736 hscroll_margin = 5;
30738 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
30739 doc: /* How many columns to scroll the window when point gets too close to the edge.
30740 When point is less than `hscroll-margin' columns from the window
30741 edge, automatic hscrolling will scroll the window by the amount of columns
30742 determined by this variable. If its value is a positive integer, scroll that
30743 many columns. If it's a positive floating-point number, it specifies the
30744 fraction of the window's width to scroll. If it's nil or zero, point will be
30745 centered horizontally after the scroll. Any other value, including negative
30746 numbers, are treated as if the value were zero.
30748 Automatic hscrolling always moves point outside the scroll margin, so if
30749 point was more than scroll step columns inside the margin, the window will
30750 scroll more than the value given by the scroll step.
30752 Note that the lower bound for automatic hscrolling specified by `scroll-left'
30753 and `scroll-right' overrides this variable's effect. */);
30754 Vhscroll_step = make_number (0);
30756 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
30757 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
30758 Bind this around calls to `message' to let it take effect. */);
30759 message_truncate_lines = 0;
30761 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
30762 doc: /* Normal hook run to update the menu bar definitions.
30763 Redisplay runs this hook before it redisplays the menu bar.
30764 This is used to update menus such as Buffers, whose contents depend on
30765 various data. */);
30766 Vmenu_bar_update_hook = Qnil;
30768 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
30769 doc: /* Frame for which we are updating a menu.
30770 The enable predicate for a menu binding should check this variable. */);
30771 Vmenu_updating_frame = Qnil;
30773 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
30774 doc: /* Non-nil means don't update menu bars. Internal use only. */);
30775 inhibit_menubar_update = 0;
30777 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
30778 doc: /* Prefix prepended to all continuation lines at display time.
30779 The value may be a string, an image, or a stretch-glyph; it is
30780 interpreted in the same way as the value of a `display' text property.
30782 This variable is overridden by any `wrap-prefix' text or overlay
30783 property.
30785 To add a prefix to non-continuation lines, use `line-prefix'. */);
30786 Vwrap_prefix = Qnil;
30787 DEFSYM (Qwrap_prefix, "wrap-prefix");
30788 Fmake_variable_buffer_local (Qwrap_prefix);
30790 DEFVAR_LISP ("line-prefix", Vline_prefix,
30791 doc: /* Prefix prepended to all non-continuation lines at display time.
30792 The value may be a string, an image, or a stretch-glyph; it is
30793 interpreted in the same way as the value of a `display' text property.
30795 This variable is overridden by any `line-prefix' text or overlay
30796 property.
30798 To add a prefix to continuation lines, use `wrap-prefix'. */);
30799 Vline_prefix = Qnil;
30800 DEFSYM (Qline_prefix, "line-prefix");
30801 Fmake_variable_buffer_local (Qline_prefix);
30803 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
30804 doc: /* Non-nil means don't eval Lisp during redisplay. */);
30805 inhibit_eval_during_redisplay = 0;
30807 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
30808 doc: /* Non-nil means don't free realized faces. Internal use only. */);
30809 inhibit_free_realized_faces = 0;
30811 #ifdef GLYPH_DEBUG
30812 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
30813 doc: /* Inhibit try_window_id display optimization. */);
30814 inhibit_try_window_id = 0;
30816 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
30817 doc: /* Inhibit try_window_reusing display optimization. */);
30818 inhibit_try_window_reusing = 0;
30820 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
30821 doc: /* Inhibit try_cursor_movement display optimization. */);
30822 inhibit_try_cursor_movement = 0;
30823 #endif /* GLYPH_DEBUG */
30825 DEFVAR_INT ("overline-margin", overline_margin,
30826 doc: /* Space between overline and text, in pixels.
30827 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
30828 margin to the character height. */);
30829 overline_margin = 2;
30831 DEFVAR_INT ("underline-minimum-offset",
30832 underline_minimum_offset,
30833 doc: /* Minimum distance between baseline and underline.
30834 This can improve legibility of underlined text at small font sizes,
30835 particularly when using variable `x-use-underline-position-properties'
30836 with fonts that specify an UNDERLINE_POSITION relatively close to the
30837 baseline. The default value is 1. */);
30838 underline_minimum_offset = 1;
30840 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
30841 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
30842 This feature only works when on a window system that can change
30843 cursor shapes. */);
30844 display_hourglass_p = 1;
30846 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
30847 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
30848 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
30850 #ifdef HAVE_WINDOW_SYSTEM
30851 hourglass_atimer = NULL;
30852 hourglass_shown_p = 0;
30853 #endif /* HAVE_WINDOW_SYSTEM */
30855 DEFSYM (Qglyphless_char, "glyphless-char");
30856 DEFSYM (Qhex_code, "hex-code");
30857 DEFSYM (Qempty_box, "empty-box");
30858 DEFSYM (Qthin_space, "thin-space");
30859 DEFSYM (Qzero_width, "zero-width");
30861 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
30862 doc: /* Function run just before redisplay.
30863 It is called with one argument, which is the set of windows that are to
30864 be redisplayed. This set can be nil (meaning, only the selected window),
30865 or t (meaning all windows). */);
30866 Vpre_redisplay_function = intern ("ignore");
30868 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
30869 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
30871 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
30872 doc: /* Char-table defining glyphless characters.
30873 Each element, if non-nil, should be one of the following:
30874 an ASCII acronym string: display this string in a box
30875 `hex-code': display the hexadecimal code of a character in a box
30876 `empty-box': display as an empty box
30877 `thin-space': display as 1-pixel width space
30878 `zero-width': don't display
30879 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
30880 display method for graphical terminals and text terminals respectively.
30881 GRAPHICAL and TEXT should each have one of the values listed above.
30883 The char-table has one extra slot to control the display of a character for
30884 which no font is found. This slot only takes effect on graphical terminals.
30885 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
30886 `thin-space'. The default is `empty-box'.
30888 If a character has a non-nil entry in an active display table, the
30889 display table takes effect; in this case, Emacs does not consult
30890 `glyphless-char-display' at all. */);
30891 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
30892 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
30893 Qempty_box);
30895 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
30896 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
30897 Vdebug_on_message = Qnil;
30899 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
30900 doc: /* */);
30901 Vredisplay__all_windows_cause
30902 = Fmake_vector (make_number (100), make_number (0));
30904 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
30905 doc: /* */);
30906 Vredisplay__mode_lines_cause
30907 = Fmake_vector (make_number (100), make_number (0));
30911 /* Initialize this module when Emacs starts. */
30913 void
30914 init_xdisp (void)
30916 CHARPOS (this_line_start_pos) = 0;
30918 if (!noninteractive)
30920 struct window *m = XWINDOW (minibuf_window);
30921 Lisp_Object frame = m->frame;
30922 struct frame *f = XFRAME (frame);
30923 Lisp_Object root = FRAME_ROOT_WINDOW (f);
30924 struct window *r = XWINDOW (root);
30925 int i;
30927 echo_area_window = minibuf_window;
30929 r->top_line = FRAME_TOP_MARGIN (f);
30930 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
30931 r->total_cols = FRAME_COLS (f);
30932 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
30933 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
30934 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
30936 m->top_line = FRAME_TOTAL_LINES (f) - 1;
30937 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
30938 m->total_cols = FRAME_COLS (f);
30939 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
30940 m->total_lines = 1;
30941 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
30943 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
30944 scratch_glyph_row.glyphs[TEXT_AREA + 1]
30945 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
30947 /* The default ellipsis glyphs `...'. */
30948 for (i = 0; i < 3; ++i)
30949 default_invis_vector[i] = make_number ('.');
30953 /* Allocate the buffer for frame titles.
30954 Also used for `format-mode-line'. */
30955 int size = 100;
30956 mode_line_noprop_buf = xmalloc (size);
30957 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
30958 mode_line_noprop_ptr = mode_line_noprop_buf;
30959 mode_line_target = MODE_LINE_DISPLAY;
30962 help_echo_showing_p = 0;
30965 #ifdef HAVE_WINDOW_SYSTEM
30967 /* Platform-independent portion of hourglass implementation. */
30969 /* Timer function of hourglass_atimer. */
30971 static void
30972 show_hourglass (struct atimer *timer)
30974 /* The timer implementation will cancel this timer automatically
30975 after this function has run. Set hourglass_atimer to null
30976 so that we know the timer doesn't have to be canceled. */
30977 hourglass_atimer = NULL;
30979 if (!hourglass_shown_p)
30981 Lisp_Object tail, frame;
30983 block_input ();
30985 FOR_EACH_FRAME (tail, frame)
30987 struct frame *f = XFRAME (frame);
30989 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
30990 && FRAME_RIF (f)->show_hourglass)
30991 FRAME_RIF (f)->show_hourglass (f);
30994 hourglass_shown_p = 1;
30995 unblock_input ();
30999 /* Cancel a currently active hourglass timer, and start a new one. */
31001 void
31002 start_hourglass (void)
31004 struct timespec delay;
31006 cancel_hourglass ();
31008 if (INTEGERP (Vhourglass_delay)
31009 && XINT (Vhourglass_delay) > 0)
31010 delay = make_timespec (min (XINT (Vhourglass_delay),
31011 TYPE_MAXIMUM (time_t)),
31013 else if (FLOATP (Vhourglass_delay)
31014 && XFLOAT_DATA (Vhourglass_delay) > 0)
31015 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
31016 else
31017 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
31019 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
31020 show_hourglass, NULL);
31023 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
31024 shown. */
31026 void
31027 cancel_hourglass (void)
31029 if (hourglass_atimer)
31031 cancel_atimer (hourglass_atimer);
31032 hourglass_atimer = NULL;
31035 if (hourglass_shown_p)
31037 Lisp_Object tail, frame;
31039 block_input ();
31041 FOR_EACH_FRAME (tail, frame)
31043 struct frame *f = XFRAME (frame);
31045 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
31046 && FRAME_RIF (f)->hide_hourglass)
31047 FRAME_RIF (f)->hide_hourglass (f);
31048 #ifdef HAVE_NTGUI
31049 /* No cursors on non GUI frames - restore to stock arrow cursor. */
31050 else if (!FRAME_W32_P (f))
31051 w32_arrow_cursor ();
31052 #endif
31055 hourglass_shown_p = 0;
31056 unblock_input ();
31060 #endif /* HAVE_WINDOW_SYSTEM */